Skip to content

fix: close final runtime evidence blockers - #55

Merged
bateau84 merged 10 commits into
refactor/trusted-checkout-evidencefrom
fix/final-runtime-evidence-blockers
Oct 6, 2026
Merged

bateau84 merged 10 commits into
refactor/trusted-checkout-evidencefrom
fix/final-runtime-evidence-blockers

Conversation

@bateau84

@bateau84 bateau84 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Scope

Focused corrective child of #45, targeting refactor/trusted-checkout-evidence.

The base now includes merged #54 (b10c8e9), which closes the authoritative outer Code Mode execute blocker. This PR is rebased directly on that commit and contains only the remaining authoritative-capture transport correction plus its regression coverage.

Stock OpenCode remains 2.0.23. No threat-model expansion.

Blocker 1 — outer Code Mode execute

Closed in the base by #54 and revalidated here.

The current integrated runtime evidence:

  • observes the real synthetic outer execute at the supported stock execute.before boundary;
  • records Session, agent, message, real CallID, supported hook input, and a unique runtime invocation ID;
  • uses stock session.tool.success / session.tool.failed as terminal authority;
  • binds every inner Code Mode call to that exact observed outer invocation;
  • rejects dangling or identity-mismatched parents;
  • keeps exact Code Mode caller-finality explicitly unsupported.

The Code Mode probe remains green after the capture-transport change.

Blocker 2 — remove target-writable authoritative capture

The production observer no longer uses:

/tmp/runtime/runtime-observer.jsonl

Authoritative observer records now cross the process boundary through a runner-owned one-connection loopback stream:

  1. the runner binds an ephemeral listener on 127.0.0.1 immediately before the real OpenCode invocation;
  2. the trusted observer connects during plugin startup;
  3. the listener closes after accepting that one connection;
  4. the observer removes the endpoint from process.env before evaluated tool subprocesses run;
  5. sanitized observer records flow over the established stream;
  6. the runner drains and validates those bytes through the existing canonical builder/validator/accounting path.

A direct inherited memfd/FD was tried first, but stock @opencode/cli@2.0.23 crosses an internal process boundary that does not preserve arbitrary extra descriptors. The one-connection stream keeps stock OpenCode unchanged and avoids filesystem authority without introducing security-platform machinery.

Protection against a deliberately malicious same-process plugin remains explicitly out of scope.

Tamper regression

Provider-free acceptance includes an evaluated tool that spawns /bin/sh and:

  • creates the old capture path;
  • deletes it;
  • recreates it;
  • appends a forged observer record.

The scenario passes only if the shell tamper completes, authoritative evidence remains complete/eligible, the real tamper tool is observed, and the forged invocation/tool never appears in runtime_evidence.

Preserved

  • opencode-eval-runner/runtime-evidence/v1;
  • canonical builder / validator / accounting;
  • pre-sink credential sanitization;
  • stock Session terminal authority;
  • Code Mode exact caller-finality remains unsupported;
  • normal invoke behavior;
  • assertion-scoped eligibility;
  • stock OpenCode 2.0.23 only.

No signing/HMAC, protected channel, remote PluginHost, capability broker, hostile-plugin isolation, or OpenCode patch is introduced.

Validation

Current clean head is based directly on merged #54 and is mergeable.

  • CI #329 / run 37532684965 — PASS
    • 95/95 Python tests
    • stock Code Mode probe: PASS (diagnostics_passed: true)
    • OpenCode 2.0.23
  • Provider-free runtime evidence acceptance [SUPERSEDED by #45] docs: plan TRUST-001 experiment on stock OpenCode #43 / run 37532684985 — PASS
    • all 11/11 scenarios:
      • native_success
      • native_error
      • code_success
      • code_caught_error
      • concurrent_reverse
      • delegation
      • timeout
      • interrupted
      • redaction
      • collector
      • capture_tamper
  • Stock native observer integration fix: close final runtime evidence blockers #55 / run 37532684878 — PASS
    • stock OpenCode 2.0.23
    • capture complete
    • provider-free native observation

Merge scope

This PR is ready for review against refactor/trusted-checkout-evidence.

Do not merge PR #45 as part of this change.

@bateau84 bateau84 closed this Oct 6, 2026
@bateau84 bateau84 reopened this Oct 6, 2026
@bateau84
bateau84 force-pushed the fix/final-runtime-evidence-blockers branch from fa7f3e0 to a0b2a60 Compare October 6, 2026 21:16
@bateau84
bateau84 marked this pull request as ready for review October 6, 2026 21:19

@bateau84 bateau84 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — READY

The final capture-transport blocker is closed.

  • Production authority no longer reads /tmp/runtime/runtime-observer.jsonl.
  • The runner parent owns a loopback listener and accepts one connection only.
  • The trusted observer connects during plugin startup, then the listener closes.
  • The endpoint is removed from the runtime process environment before evaluated tool subprocesses execute.
  • Capture bytes are drained directly into the existing parser/builder/validator and transport failures remain fail-closed.
  • The old path can be created/deleted/recreated/appended by evaluated shell code without affecting authoritative evidence.
  • Outer Code Mode execute authority from #54 remains intact.
  • Stock OpenCode 2.0.23 and the reduced trusted-checkout threat model are preserved.

Validation confirmed: 95/95 unit tests, 11/11 provider-free scenarios including capture_tamper, stock Code Mode probe PASS, and native observer integration PASS.

No BLOCKING, IMPORTANT, or MINOR correctness findings requiring changes.

Verdict: READY TO MERGE #55.

@bateau84
bateau84 merged commit e3eb017 into refactor/trusted-checkout-evidence Oct 6, 2026
3 checks passed
@bateau84
bateau84 deleted the fix/final-runtime-evidence-blockers branch October 6, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant