Skip to content

Remove unsupported signed-launch enforcement - #374

Merged
justin808 merged 9 commits into
mainfrom
codex/remove-host-signing-299
Aug 7, 2026
Merged

Remove unsupported signed-launch enforcement#374
justin808 merged 9 commits into
mainfrom
codex/remove-host-signing-299

Conversation

@justin808

@justin808 justin808 commented Aug 7, 2026

Copy link
Copy Markdown
Member

Summary

  • remove the unsupported project-level signed launch and signed lifecycle activation contracts
  • make model and effort routes advisory across coordinator, worker, checker, and auditor roles, with closest/runtime-default fallback and honest host observations or UNKNOWN
  • replace signed lifecycle receipts with ordinary durable lane state while preserving replay, duplicate prevention, replacement fencing, serialization, dependency/collision validation, exact-head CI, merge assurance, and guarded submission
  • prove clean Codex and Claude installations can dispatch and advance lifecycle state without signing material, trust anchors, or waivers
  • add the incident postmortem and prevention/rollout ownership contract

Maintainer decision implemented

Facts owned by Codex or Claude no longer require Agent Workflows project signing, trust anchors, launch/lifecycle receipts, hard route binding, or signed-launch waivers. Preferred routes remain recommendations. A route mismatch, unavailable preference, or UNKNOWN observation does not block an otherwise valid workflow.

Only dispatcher substitution requires explicit dispatch authority. Route preference changes remain authority-free metadata and replay deterministically.

Preserved controls

  • one active assignment and idempotent launch-token replay
  • duplicate prevention and exact dispatcher/instance replacement fencing
  • lane ownership and blocked/active/completed serialization behavior
  • batch-plan schema, dependency, collision, capacity, and active-wave validation
  • exact-head CI, merge assurance, autonomous eligibility, and guarded submission
  • existing security preflight, review, QA, and completed-batch evidence gates

Validation

  • bin/validate — PASS; RuboCop inspected 117 files with no offenses
  • dispatcher preflight — 32 runs / 232 assertions
  • batch-plan preflight — 52 / 416
  • model-routing contract — 14 / 963
  • coordination telemetry — 29 / 2,726
  • stage dependency — 45 / 1,399
  • CI readiness — 108 / 612
  • merge assurance — 51 / 140
  • guarded merge submission — 89 / 735
  • goal/prompt contract — 76 / 1,102
  • review wave — 5 / 98
  • stale assignment sweep — 47 / 318
  • seam doctor — 280 / 2,404
  • installer matrix — PASS, including unsigned Codex and Claude installed-helper probes
  • prompt-size contract — PASS with 313–314 characters of Codex headroom
  • git diff --check — PASS

Independent QA

Fresh read-only exact-head QA passed at 2e8fc1f27f1ac2782af28e128f9870482eea2f47 against base 282a87aaf4bf1dd602723efddc78252f7a138235. The final isolated autoreview found no actionable correctness defects. Observed host was Codex; model and effort were UNKNOWN and were not used as verdict gates.

Postmortem

docs/postmortems/2026-08-06-unsupported-signed-launch-enforcement.md records the confirmed timeline and impact, separates root cause from inference, explains why fixture-heavy verification missed the absent host producer/provisioner/installer, covers large-PR and rollout factors, and maps prevention actions to implemented contracts or owned follow-ups.

Related work remains separate: #151, #372, and #273. Closed PR #306 was not reused or cherry-picked.

Closes #299

Completed-batch audit

Status: Clean — no outstanding findings or follow-ups. Durable receipt.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@justin808, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f39b6d2d-cce5-4cd2-a5af-4bcd95185096

📥 Commits

Reviewing files that changed from the base of the PR and between 282a87a and e2845cb.

📒 Files selected for processing (30)
  • CHANGELOG.md
  • CONTEXT.md
  • README.md
  • bin/install-agent-workflows-test.bash
  • docs/README.md
  • docs/agent-workflows-model-routing.md
  • docs/coordination-backend.md
  • docs/host-adapter/contract.md
  • docs/installation-and-upgrades.md
  • docs/postmortems/2026-08-06-unsupported-signed-launch-enforcement.md
  • docs/pr-batch-skills.md
  • skills/adversarial-pr-review/SKILL.md
  • skills/plan-pr-batch/SKILL.md
  • skills/plan-pr-batch/bin/batch-plan-preflight
  • skills/plan-pr-batch/bin/batch-plan-preflight-test.rb
  • skills/plan-pr-batch/fixtures/ror-wave-a-plan-replay.json
  • skills/plan-pr-batch/fixtures/unsigned-lifecycle-smoke.json
  • skills/plan-pr-batch/scripts/check_goal_prompt_size.rb
  • skills/post-merge-audit/SKILL.md
  • skills/pr-batch/SKILL.md
  • skills/pr-batch/bin/coordination-telemetry-contract-test.rb
  • skills/pr-batch/bin/dispatcher-capability-preflight
  • skills/pr-batch/bin/dispatcher-capability-preflight-test.rb
  • skills/pr-batch/bin/model-routing-contract-test.rb
  • skills/pr-batch/fixtures/unsigned-dispatch-smoke.json
  • skills/triage/SKILL.md
  • workflows/adversarial-pr-review.md
  • workflows/continuous-evaluation-loop.md
  • workflows/post-merge-audit.md
  • workflows/pr-processing.md
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/remove-host-signing-299

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@claude

claude Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review: Remove unsupported signed-launch enforcement (#374)

Summary

This PR removes the cryptographic signing/trust-anchor layer (launch-confirmation v2, dispatcher-launch-trust.json, workflow-control-lifecycle-trust.json, RSA-SHA256 signature verification, hard route binding) from dispatcher-capability-preflight and batch-plan-preflight, replacing it with advisory model/effort routing and ordinary durable lane lifecycle state (launch-pending/active, planned/claimed/active/blocked/completed). It's driven by a well-documented postmortem (docs/postmortems/2026-08-06-unsupported-signed-launch-enforcement.md): the signed evidence contract became mandatory before either supported host (Codex or Claude) had any way to produce it, so the "fail-closed" control was actually a dead-end that blocked all launches.

Code quality / correctness

  • Read the full core-logic diff in both Ruby helpers. The refactor is coherent: fallback_authorized? now short-circuits true when candidate["dispatcher"] == requested["dispatcher"] (matching a requested dispatcher needs no special authority), while a different dispatcher still requires fallback_authorized: true + authority.dispatch == true. route_preference_changed handling correctly regenerates viable_fallback_choices and bumps the decision-request revision when only the route (not dispatcher) changes, while requested_policy_equal? intentionally compares dispatcher only, matching the stated design that route is pure metadata for replay identity.
  • observed_host (new advisory {host, model, effort, observed_at, evidence_ref}) normalizes cleanly to field-granular UNKNOWN sentinels and never gates selection — consistent with the stated design.
  • batch-plan-preflight's launch_partition correctly extends serialization-group holding to lanes whose group already has an active or blocked occupant, not just completed.
  • Removed code (OpenSSL signing/verification, uid/permission-based trust-anchor file checks, launch_confirmation handling, hard_route) is fully excised — no dangling references found via repo-wide grep for dispatcher-launch-trust, workflow-control-lifecycle-trust, dispatcher_trust_anchor, etc. (The unrelated agent-workflows-trust-audit / .agents/trusted-github-actors.yml PR-review trust system is untouched and still valid — different subsystem.)

Test coverage

Had a second reviewer pass independently verify the two large test files, contract tests, and fixtures against the production diff. Findings:

  • Field names/reason strings in tests match the production code exactly (preferred-route-and-dispatcher, advisory-route-fallback, authorized-dispatcher-fallback, etc.).
  • Dedicated tests cover the interesting new behaviors: route mismatch never blocking, invalid vs. absent observed_host shape, same-dispatcher fallback needing no fallback_authorized: true, cross-dispatcher fallback still requiring explicit authority, blocked-lane serialization-group holding, and legacy confirmed-active/launch_confirmation input now being inert (fails closed / ignored, not silently activated).
  • Fixtures (unsigned-dispatch-smoke.json, unsigned-lifecycle-smoke.json) contain no signature/key material and are exercised by clean-install acceptance tests added in bin/install-agent-workflows-test.bash, directly validating the postmortem's motivating scenario.
  • Minor: test_helper_has_no_project_signing_trust_or_hard_route_activation_contract-style tests are literal-string refute_includes guardrails — fine as a belt-and-suspenders check, but they only catch reintroduction of the same string, not equivalent logic under a new name. Not a blocker given the substantive behavioral tests are present.

Documentation

Every doc/skill/workflow file that referenced the old "launch assurance"/exact-binding/signed-receipt vocabulary was updated consistently (CHANGELOG.md, CONTEXT.md, README.md, docs/agent-workflows-model-routing.md, docs/coordination-backend.md, docs/host-adapter/contract.md, docs/installation-and-upgrades.md, docs/pr-batch-skills.md, all skills/*/SKILL.md, all workflows/*.md). The new docs/host-adapter/contract.md "Host-Owned Fact Rollout" section, requiring named producer/verifier/provisioner/installer ownership plus clean-install acceptance before any future host-owned fact becomes a mandatory gate, is a sensible, concrete prevention control directly tied to the root cause.

Security implications

This removes a cryptographic verification layer, which is worth calling out explicitly even though it's the intended change: previously, "actual host/model/effort" claims required a signature verified against a locally-provisioned trust anchor; now they're purely advisory, honest-effort, self-reported metadata that can't be verified and never blocks anything. Per the postmortem, no supported host could ever produce a valid signature for this anchor, so in practice this control never provided real integrity guarantees in production — it only blocked otherwise-legitimate launches. Given that, replacing it with honest UNKNOWN-when-unavailable metadata is a reasonable trade, and the PR is explicit that this is an intentional, maintainer-approved scope reduction (closes #299) rather than an oversight. The controls it explicitly preserves (duplicate-launch prevention, single active assignment, replacement fencing with single-use proofs, exact-head CI, merge assurance, guarded merge submission, PR-security-preflight trust config for review input) are untouched by this diff.

Overall

This is a large but disciplined removal — the mechanical scope (script logic, tests, fixtures, and every doc/skill/workflow reference) is fully synchronized, the postmortem is a good-faith root-cause account, and I found no correctness bugs or leftover references to the removed signing contract.

@claude

claude Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review

Reviewed via gh pr diff 374 plus two focused deep-dives (dispatcher/batch-plan Ruby logic; docs/fixtures/postmortem consistency).

Overview

This PR rips out the previously-shipped "signed launch / signed lifecycle" cryptographic enforcement layer (RSA-signed launch confirmations, trust-anchor files, signed workflow-control lifecycle receipts) across skills/pr-batch/bin/dispatcher-capability-preflight and skills/plan-pr-batch/bin/batch-plan-preflight, replacing it with advisory, non-cryptographic observed_host/route-preference data and ordinary durable lane state (lane_lifecycle_states with a plain state_ref URI instead of a signed receipt_ref). The stated reason (docs/postmortems/2026-08-06-unsupported-signed-launch-enforcement.md) is that the signature scheme required a producer/provisioner/installer that was never actually built, so the enforcement was unsatisfiable by any real Codex/Claude host — i.e. it was dead security theater blocking legitimate workflows rather than a working control. Docs, SKILL.md files, fixtures, and the goal-prompt-size contract test are all updated in lockstep with the vocabulary change (route "requested"/"hard_route" → "preferred", "binding/attestation" → "observed_host").

Code quality / correctness

  • Traced the key behavioral changes in dispatcher-capability-preflight: requested_policy_equal? now compares only dispatcher (route is advisory), select_candidate's new tier-sort (requested-tuple → same-dispatcher → other), and fallback_authorized?/fallback_authority_sufficient?. A candidate with a different dispatcher still can only be selected with fallback_authorized: true and authority["dispatch"] == true — no path found where an unauthorized dispatcher substitution could be silently selected.
  • launch_partition in batch-plan-preflight correctly holds the entire serialization group (not just the individual lane) when any member is active or blocked, preventing two lanes in the same group from becoming eligible concurrently.
  • No leftover dead references to removed concepts (signature/binding/attestation/confirmation) found in either script; the retained stop_attestation/reconciliation_attestation fields and the self-computed trusted_plan_binding SHA256 are deliberately non-cryptographic and correctly distinguished from what was removed.
  • durable_state_ref? is now a plain URI-shape check with no caller/producer verification — a real trust-the-caller downgrade from the old signed receipt. This is coherent with the PR's stated intent (the old verification path could never actually be satisfied) and isn't relied on elsewhere as if it were still cryptographic, but worth calling out explicitly as accepted risk since it's a genuine reduction in tamper-resistance for lane lifecycle claims, not just a rename.

Test coverage

  • The large test suites (dispatcher-capability-preflight-test.rb, batch-plan-preflight-test.rb, model-routing-contract-test.rb, coordination-telemetry-contract-test.rb) do exercise the important new paths: route-preference-only changes replaying without fencing, dispatcher changes still forcing replacement fencing, the blocked lifecycle state, and the serialization-group-occupied-by-blocked-lane case.
  • Minor gap: the provenance_identity_replayable branch (replaying an active assignment whose selection_provenance is authorized-dispatcher-fallback) isn't exercised end-to-end by a dedicated test, so a regression in the fallback_authority_sufficient? re-check on replay (e.g. authority revocation not actually blocking replay) wouldn't be caught today.
  • Minor diagnostics-only gap: select_candidate silently drops unauthorized different-dispatcher candidates from rejections before unusable_reason runs, so they also won't show up with a specific rejection reason (they do still surface via viable_fallback_choices). Not a correctness issue, just slightly less debuggable output.

Docs / fixtures

Security implications

The core security-relevant change is intentional and well-justified: removing enforcement that couldn't be satisfied by any real host isn't a weakening of an effective control, it's removing a broken gate that was blocking legitimate dispatch. The one thing to be explicit about (and it sounds like this was a deliberate maintainer decision per the PR description) is that lane-lifecycle-state and observed-host data are now entirely caller-asserted with no cryptographic tamper-evidence — acceptable if nothing downstream currently treats these as trust boundaries, which matches what I found in the code.

Overall

Large, mechanically consistent refactor with good matching test/doc/fixture updates. No blocking bugs found. Two minor test-coverage suggestions above (not required for merge, but easy to add given how thorough the rest of the suite already is).

@justin808

Copy link
Copy Markdown
Member Author

head_sha: e2845cb
triggered_gates:

  • architectural-product-judgment
  • autonomous-merge-policy-change
  • changed-files-limit
  • changed-lines-limit
  • public-compatibility
  • security-auth-privacy
    rollback_disposition: Code-only rollback established.
    decision: approve
    approved_by: justin808
    source: direct-user-task
    evidence: Direct user approval in Codex task after the exact-diff PR walkthrough on 2026-08-07.
    ...

@justin808
justin808 added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 4d93a01 Aug 7, 2026
4 checks passed
@justin808
justin808 deleted the codex/remove-host-signing-299 branch August 7, 2026 23:36
@justin808

Copy link
Copy Markdown
Member Author

Completed-batch audit: replay evidence follows.

justin808 added a commit that referenced this pull request Aug 9, 2026
…/pr291-redesign-implementation

* commit '6239fd0afa5bb7d87cd3fb09cc22ae30bcf1e369':
  Fix locale-dependent test, surface policy-only CLAUDE.md follow-ups, add read-only seam-drift audit (#337)
  Add PR #377 changelog entry (#382)
  Make PR descriptions human-first (#377)
  Remove unsupported signed-launch enforcement (#374)
  Emit coordination telemetry and provenance at workflow checkpoints (#290)
  Add explicit multi-language lint CI (#313)
  Reconcile later-completed audit targets (#315)
  Report source lines in security preflight findings (#311)
  Gate completed-batch publication on terminal scope and QA (#308)
  Add guarded merge submission seam (#304)
  Fix exact-head readiness when status rows omit SHA (#307)
  fix: allow YAML timestamps in action scanner (#305)
  Pin workflow dependencies and define release trust boundary (#295)
  Support direct merges without merge queues (#297)
justin808 added a commit that referenced this pull request Aug 11, 2026
…8-batch-docs-status-skill

* origin/main:
  Default merge submission to direct (#407)
  Fix <PROJECT> digit ambiguity, anchor section extraction, ship coordination gate (#339)
  Enforce requested-versus-observed model route provenance (#348)
  Fix locale-dependent test, surface policy-only CLAUDE.md follow-ups, add read-only seam-drift audit (#337)
  Add PR #377 changelog entry (#382)
  Make PR descriptions human-first (#377)
  Remove unsupported signed-launch enforcement (#374)

# Conflicts:
#	bin/validate
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.

Remove unsupported signed-launch enforcement and restore advisory routing

1 participant