Skip to content

fix(review): reject results when candidate input is unreadable or capture is truncated #1867

Description

@Benja-M24

Pre-flight Checklist

  • I have searched existing issues and this is not a duplicate
  • I understand that PRs will be rejected if the linked issue does not have status:approved

📝 Bug Description

Impact: Review approval cannot be trusted when a schema-valid zero-finding result is admitted despite explicitly stating that the immutable candidate input could not be inspected. The same failure can instead strand authority in a nonterminal state, while managed capture can preserve truncated JSON.

A read-only audit found six confirmed unrecovered access/admission failures across three independent repositories:

  • Three results received approved receipts without genuine candidate inspection.
  • Three remained in reviewing or validating without receipts.
  • Four managed captures ended mid-string and failed JSON parsing.
  • Four explicit successor chains later completed genuine candidate inspection and received approved receipts, proving recovery is possible.

A fourth configured repository completed candidate inspection successfully and did not exhibit the symptom. This is therefore a multi-repository failure, but it is not universally systemic.

Zero findings are valid only after inspection. A result whose own evidence says the frozen or provider-owned candidate input was unreadable must not be treated as a clean review.

🔄 Steps to Reproduce

Track 1: Inaccessible immutable candidate input

  1. Install Gentle AI 2.1.11 through Homebrew on Linux and use OpenCode with bash.
  2. Create a disposable repository containing a non-sensitive synthetic candidate.
  3. Start a review where the immutable candidate subject is provider-owned or frozen, but unavailable to the reviewer’s filesystem or read tools.
  4. Return a schema-valid v2 result with findings: [] while its evidence explicitly states that candidate inspection could not occur.
  5. Submit the result through the normal admission path.
  6. Observe that the result can either receive an approved receipt or leave authority in reviewing or validating without a receipt.

Track 2: Truncated managed capture

  1. Use a disposable repository and a synthetic schema-valid reviewer result containing a non-sensitive string field.
  2. Exercise managed capture with fault injection that truncates the response after capture begins and before the string closes.
  3. Inspect the preserved capture and authority state.
  4. Verify that the raw ends mid-string and fails strict JSON parsing.
  5. Retry within the same lineage.
  6. Observe that a later valid capture can recover some lineages, while another lineage can retain the malformed raw without a receipt.

Neither track requires proprietary source material.

✅ Expected Behavior

  • The reviewer must have reliable access to the complete immutable candidate input before its result is admissible.
  • A clean result may be approved only when candidate-specific evidence demonstrates that inspection occurred.
  • An explicit statement that input could not be read must override findings: [] and produce a typed, recoverable access/admission failure.
  • Failed admission must not create an approved receipt.
  • Failed admission must not indefinitely strand authority in reviewing or validating.
  • Managed capture must validate and persist atomically so partial JSON cannot be treated as a completed result.
  • A malformed capture may be retained for audit, but it must be marked unusable and must not authorize a receipt.
  • Same-lineage retries must be deterministic, idempotent, and bound to the same content-addressed candidate.
  • Existing v2 authority and receipt schemas must remain supported.

❌ Actual Behavior

  • Three zero-finding results were approved even though their own evidence stated that genuine candidate inspection could not occur.
  • Three matching access/admission failures remained nonterminal without receipts.
  • Four of 209 preserved incident raws were truncated mid-string.
  • The malformed raws were 126, 457, 486, and 862 bytes.
  • Parser failures were classified as unterminated string or unfinished string at EOF.
  • Two affected lineages later captured valid JSON in the same lineage.
  • One unrecovered lineage retained malformed capture evidence and had no receipt.
  • Successful counterexamples contained candidate-specific inspection evidence, demonstrating that zero findings alone are insufficient proof.

Gentle AI Version

2.1.11, installed through Homebrew

Operating System

Linux (Other)

AI Agent / Client

OpenCode

📋 Affected Area

Other

💡 Logs / Error Output

Raw logs are intentionally excluded. Sanitized parser classifications:

  • Unterminated string at EOF
  • Unfinished string at EOF

Additional Context

Shell: bash.

The evidence was content-addressed and inspected statically without running Gentle AI lifecycle commands. The terminal snapshot changed concurrently, so local HEAD and status details are intentionally excluded.

Antecedent Analysis

States and links were verified on 2026-07-26.

Antecedent Current state Overlap Remaining gap
#1411 Closed Preserved capture incidents and nonterminal lineages Focused on binding/current-working-directory behavior, not provider visibility, EOF truncation, or approved-but-uninspected receipts
#1454 / PR #1517 Closed / merged Exposes immutable candidate material and a changed-path manifest Current incidents show that artifacts may exist but remain unreadable inside the reviewer context
#1469 Closed Stranded lineages and malformed preserved results Current evidence adds concrete mid-string EOF truncation and approved receipts created without inspection
#1555 / PR #1550 Closed / merged Exact overlap: an inaccessible zero-finding result can be treated as clean Reproduction on 2.1.11 indicates regression or incomplete coverage for schema-valid, self-invalidating results
#1575 / PR #1550 Closed / merged validating authority without a receipt Current evidence also covers reviewing, approved false-clean receipts, and inconsistent recovery
#1689 / PR #1796 Open / open Provider-owned capture subject and evidence binding Current evidence adds actual reviewer read denial, unsafe result admission, and capture atomicity failures
#1710 Open Adjacent frozen-context transport behavior Context overflow is not present in these incidents; visibility and admission are the demonstrated failures
#1789 Open Unparseable managed capture That issue concerns leading prose; these captures are valid JSON prefixes ending mid-string at EOF
#1856 Open Adjacent status/retry behavior after unavailable context It is a zero-lens/status retry case, not a duplicate of false approval plus EOF truncation

PR #1517 has a verified closing reference to #1454. PR #1550 has verified closing references to #1555 and #1575. Open PR #1796 has a verified closing reference to #1689.

Broader duplicate searches also surfaced #1443 and #1742 for truncation-related terms. Neither combines reviewer input denial, admission of a self-invalidating clean result, and EOF-truncated managed capture.

Root-Cause Assessment

Established facts

  • Reviewer filesystem/read tools could not access provider-owned or frozen immutable candidate input.
  • Schema-valid zero-finding results could contradict themselves by stating that inspection did not occur.
  • Admission still produced three approved receipts from those results.
  • Matching failures also left three nonterminal authorities without receipts.
  • Managed capture preserved four JSON prefixes ending inside strings.
  • All active authority and receipt records parsed successfully and used v2 schemas.

Strongest inferences

  • There is a sandbox or tool-visibility mismatch between immutable candidate ownership and the reviewer execution context.
  • Admission checks validate structure or completion without rejecting semantic evidence that inspection was impossible.
  • Managed capture persistence or failure handling is insufficiently atomic when the provider response ends early.

Not established

  • A provider API outage is not proven.
  • Context overflow is not the observed cause.
  • There is no evidence of v1/v2 schema incompatibility.
  • There is no evidence of receipt-discovery ambiguity.

Acceptance Criteria

  • A reviewer can inspect the complete immutable candidate through a sandbox-safe, provider-agnostic handoff.
  • Admission rejects any result whose evidence states or proves that candidate inspection did not occur.
  • findings: [] remains valid when candidate-specific inspection evidence is present.
  • An inaccessible candidate produces a typed failure and never an approved receipt.
  • Both reviewing and validating failures have a deterministic recovery path.
  • Capture is validated before it can affect authority or receipt state.
  • Partial JSON is retained only as explicitly invalid audit evidence.
  • Same-lineage retry can replace or supersede an invalid capture without losing audit history or creating duplicate authority.
  • Tests cover inaccessible input, valid inspected zero findings, approved-receipt rejection, both nonterminal states, mid-string EOF truncation, and same-lineage recovery.
  • Status output distinguishes access denial, capture parsing failure, and provider failure without claiming an unproven API outage.
  • Existing gentle-ai.review-state-record/v2, gentle-ai.review-state/v2, and gentle-ai.review-receipt/v2 records remain supported.

Curated Evidence (Privacy-Preserving)

Metric Sanitized evidence
Audit scope 18 Git repositories inspected read-only
Configured repositories Four contained Gentle AI state
Symptom scope Repository A, Repository B, and Repository C
Counterexample A fourth configured repository completed candidate inspection successfully
Active review lineages 230
Authority distribution 202 approved, 14 escalated, 14 nonterminal
Existing receipts 216
Confirmed unrecovered access/admission failures Six
False-clean approvals Three approved receipts without genuine candidate inspection
Stranded failures Three nonterminal authorities without receipts
Explicit successful successor chains Four
Preserved incident raws 209
Malformed raws Four
Authority/receipt parsing All successful
Schemas gentle-ai.review-state-record/v2, gentle-ai.review-state/v2, gentle-ai.review-receipt/v2
Anonymized cases Authority state Receipt Lens behavior Disposition
ACCESS-APP-01 through ACCESS-APP-03 approved Present findings: []; evidence says immutable input was unreadable Unrecovered false-clean admission
ACCESS-NT-01 through ACCESS-NT-03 reviewing or validating Absent Genuine candidate inspection did not occur Unrecovered nonterminal state
REC-01 through REC-04 approved Present Candidate-specific inspection evidence present Successful successor recovery

The sanitized evidence does not map each nonterminal case to one of the two authority states, so no per-case assignment is inferred.

Raw case Byte length Parser class
RAW-01 126 EOF string truncation
RAW-02 457 EOF string truncation
RAW-03 486 EOF string truncation
RAW-04 862 EOF string truncation

Across those raws, parser wording was either “unterminated string at EOF” or “unfinished string at EOF.” Exact raw-to-wording mapping is retained privately.

Capture lineage Receipt evidence Recovery disposition
CAP-REC-01 Not required for capture-only classification Later valid capture in the same lineage
CAP-REC-02 Not required for capture-only classification Later valid capture in the same lineage
CAP-UNREC-01 Absent Malformed raw retained; unrecovered

The exact literal captured_artifacts_unverifiable was absent from preserved metadata for the principal incidents. It appears only in antecedent discussion context for #1689 and #1856 and must not be attributed to the principal cases.

Withheld from this public report:

  • Repository identities beyond Repository A, Repository B, and Repository C
  • Local project, change, component, file, and documentation names
  • Source paths, branch names, commit/tree identifiers, target identities, and path digests
  • Local HEAD/status details
  • Raw bodies, diffs, code, encoded content, credentials, and full reviewer output
  • Exact case-to-repository mapping
  • Full cryptographic hashes

Cryptographic hashes, detailed lineage mappings, and supporting private evidence are retained and can be provided to maintainers through a secure channel.

Metadata

Metadata

Assignees

Labels

priority:highHigh prioritystatus:approvedApproved for implementation — PRs can now be openedtype:bugBug fix

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions