You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #12 proves a real end-to-end Radicle patch workflow: exact candidate inspection, Auths verification, required/executed configuration matching, a protected native signer, at-most-once execution, real Radicle publication, and observation from a second Radicle node.
The Auths verification kernel did not need to be weakened. The implementation did expose seven gaps at the proof-authoring, reusable-runtime, receipt, persistence, and Radicle automation boundaries. This issue tracks them as one coordinated production-hardening program.
Keep auths-radicle as one coherent vertical product package. Extract shared primitives only where the existing MCP/runtime implementation and the Radicle implementation have genuinely identical security semantics. Do not move network, filesystem, process, replay, receipt, or execution state into the offline core kernel.
Desired outcome
A person can inspect and sign one exact Radicle patch authorization with a key that never reaches the executor. The executor can verify, claim, publish, recover, and report the operation without parsing unstable display text. Decision, execution, and propagation claims are independently verifiable, and distributed-state completeness is an explicit derived fact rather than an assertion.
Workstreams
1. Replace the server-generated authorization fixture with a real human signing ceremony
The current live path derives the exact action and then generates transient human, workflow, and agent keys inside the executor process. This exercises real Auths authoring and verification, but it does not prove that an external human authorized the action while the executor lacked the human key.
Add a two-phase API: prepare an exact unsigned authorization request, then submit the externally completed proof.
Show the exact repository, issue, base commit, candidate commit, changed paths, patch metadata, verifier configuration, audience, expiry, and execution limit before signing.
Use the keyless auths-author signing-request APIs; never accept raw human private-key material.
Add a browser-capable signer path, preferably passkey/WebAuthn or another externally held did:key signer.
Ensure the executor receives only the signed result/proof.
Delete the live server-side human/workflow/agent seed generation path.
Add E2E tests proving signature mutation, action mutation, configuration drift, signer substitution, and replay all fail before the Radicle signer is contacted.
Acceptance criteria:
The live demo's human authorization is signed outside the executor trust domain.
An automated test can assert that no human signing key exists in executor configuration, process inputs, persisted state, or logs.
The UI does not claim that a human approved the patch until the external signature has completed successfully.
2. Replace Radicle display-output parsing with stable machine interfaces
The adapter currently parses human-facing output for identity history, issue status, and the Patch <id> opened diagnostic. Exact Radicle version pinning reduces drift but does not make display prose a suitable security interface.
Materialize issues using rad cob show --type xyz.radicle.issue --format json and parse a typed, deny-unknown-fields representation.
Canonicalize structured issue data before deriving issue_materialized_digest.
Obtain the identity revision from a structured or direct repository/ref interface instead of parsing rad inspect --history prose.
Use a machine-readable patch-create result if Radicle exposes one; otherwise isolate the version-specific parser behind a narrow adapter and lock it to golden CLI fixtures.
Keep post-write verification against the stored patch COB, exact candidate ref, signer, base, description, and unchanged canonical branch.
Add compatibility tests for every accepted Radicle CLI output shape.
Install Radicle from a release artifact pinned by digest/signature instead of executing an unpinned remote installer script during the container build.
Acceptance criteria:
No authorization or postcondition decision depends on localized or human-formatted CLI text where structured data is available.
A Radicle upgrade fails compatibility CI until its machine-output fixtures and adapter version are explicitly reviewed.
3. Reuse and generalize Auths execution leases, stores, and attested receipts
auths-runtime, auths-receipts, and auths-stores already contain execution leases, receipt attestation, and durable receipt storage, but the Radicle package had to define parallel vertical versions because the current runtime remains MCP-shaped and its receipts cannot express Radicle containment or multi-stage publication.
Define an application-neutral sealed execution boundary that can carry a typed verified command without importing MCP concepts.
Define the common execution-claim semantics once; preserve domain-specific identifiers and transitions as typed extensions rather than flattening them into strings.
Extend canonical receipts, or add linked typed companion receipts, for required/executed configuration, product containment, stored, announced, and replicated claims.
Use the existing ReceiptAttestor and canonical attested-receipt encoding.
Use existing auths-stores persistence where its semantics match; document and test any Radicle-specific state that must remain vertical.
Remove duplicated Radicle lease/receipt/store primitives once the shared contract proves the same invariants.
Keep dependency flow compliant with core <- exchange <- product; do not make the offline kernel own I/O or mutable execution state.
Acceptance criteria:
MCP and Radicle share generic execution/attestation primitives where semantics are identical.
Radicle-specific policy and stage data remain within the vertical product package.
Required and executed configuration remain separately present, digest-bound, and test-covered.
4. Make the independent observer receipt independently verifiable
The observer is a real separate Radicle node and independently fetches the patch, but its HTTP response is authenticated only by a shared bearer token. The executor currently constructs the propagation receipt from that response, so a third party cannot verify that the observer made the claim.
Give the observer an externally configured receipt-attestation capability bound to its did:key identity.
Have the observer sign a canonical propagation receipt containing the execution receipt ID, RID, patch ID, revision ID, candidate OID, observer node ID, and observation time.
Verify the observer signature and expected identity at the executor before recording Replicated.
Return the exact signed observer receipt to the browser.
Verify and display the receipt signature in the browser/WASM path.
Keep bearer authentication only as private channel authentication; it must not be treated as the observer attestation.
Acceptance criteria:
A third party can verify the propagation receipt offline without trusting the executor or observer HTTP channel.
Mutation of any publication or observation field invalidates the signature.
5. Derive evidence completeness and signed-ref security explicitly
The current adapter treats successful synchronization as sufficient to set issue_history_complete: true. minimum_successful_peers counts successful fetches, but does not itself prove peer agreement or causal completeness.
Commit the required Radicle signed-refs feature level into VerifierConfiguration and its digest.
Require the strongest supported signed-refs policy (parent) wherever the Radicle command/API supports it.
Record the exact signed refs/tips obtained from each configured peer.
Derive issue-history completeness from validated causal closure rather than assigning true after a successful command.
Distinguish "minimum successful fetches" from any stronger quorum/agreement claim in types, receipts, error codes, and UI copy.
Define deterministic handling for divergent but valid peer views and for missing dependencies.
Add denial/indeterminate tests for stale evidence, insufficient peers, missing causal history, signed-ref downgrade, replayed refs, and divergent views.
Acceptance criteria:
Every positive evidence-completeness field can be traced to validated inputs.
The verifier never labels fetch count as state agreement unless agreement was actually established.
Signed-ref downgrade cannot occur as an uncommitted CLI/default change.
6. Add crash reconciliation and transactional multi-writer execution state
Claim-before-effect correctly prevents duplicate execution, but a crash after Radicle stores the patch and before record_stored leaves the workflow permanently Claimed. The current persistent store is explicitly single-writer.
Add fault-injection tests before and after claim, Radicle write, execution receipt persistence, stored transition, announcement, and observer receipt persistence.
Define a reconciliation state machine for workflows left in Claimed, Stored, or Announced.
Reconcile a post-write crash by finding and validating the exact existing Radicle patch; never blindly retry the irreversible write.
Bind reconciliation to workflow ID, action digest, candidate OID, signer, base, and patch postconditions.
Provide a transactional compare-and-set store implementation suitable for multiple executor instances.
Preserve the single-writer filesystem store for bounded demos/tests only, with that limitation explicit in configuration.
Add operator-visible stuck/reconciled/conflict states and stable codes.
Acceptance criteria:
Every injected crash converges to a safe terminal or explicitly recoverable state.
Recovery cannot create a second patch for the same execution authorization.
Concurrent claims across processes/instances produce exactly one execution owner.
7. Replace prose-only Auths/Radicle linkage with structured metadata and idempotency
The current issue and workflow relationship is encoded in patch-description trailers (Radicle-Issue: and Auths-Workflow:). This is readable but not a typed or queryable Radicle contract.
Define a versioned canonical linkage object containing workflow ID, issue ID, Auths action/decision receipt ID, and candidate digest/OID.
Store or reference that linkage through a supported structured Radicle mechanism; retain prose trailers only as human-readable projection.
Make the linkage independently retrievable and verifiable from the published patch.
Use the structured workflow identifier as the reconciliation/idempotency lookup key.
If Radicle lacks the necessary mechanism, open an upstream Radicle proposal for machine-readable patch creation, typed external metadata/relations, and a client-supplied idempotency key.
Add tests proving duplicate submissions resolve to the existing exact patch and conflicting submissions fail closed.
Acceptance criteria:
Automation never needs to parse the patch description to recover Auths linkage.
The same workflow/action cannot create two distinct patches, including after a crash or retry.
A conflicting action using an existing workflow identifier is rejected.
Sequencing
Make the demo truthful: external signing and signed observer receipts.
Remove avoidable CLI parsing and make evidence semantics exact.
Generalize reusable Auths runtime/receipt/store primitives without breaking the vertical product boundary.
Add reconciliation and structured Radicle idempotency/linkage.
Upstream the missing Radicle automation capabilities that cannot be solved safely in the adapter.
Cross-cutting completion requirements
Preserve exact required/executed configuration reporting and mismatch denial.
Preserve the rule that the agent never receives the Radicle signing key.
Preserve bounded hostile Git inspection and sealed-command execution.
Add unit, property/regression, fault-injection, real pinned-Radicle CLI, and deployed E2E coverage appropriate to each change.
Update architecture/compliance inventories and generated dependency snapshots for intentional package-edge changes.
Pass cargo xtask ci, dependency policy, secret scanning, and the deployed browser/native/observer parity checks.
Update the live demo copy only when the corresponding guarantee is actually enforced and externally observable.
Context
PR #12 proves a real end-to-end Radicle patch workflow: exact candidate inspection, Auths verification, required/executed configuration matching, a protected native signer, at-most-once execution, real Radicle publication, and observation from a second Radicle node.
The Auths verification kernel did not need to be weakened. The implementation did expose seven gaps at the proof-authoring, reusable-runtime, receipt, persistence, and Radicle automation boundaries. This issue tracks them as one coordinated production-hardening program.
Keep
auths-radicleas one coherent vertical product package. Extract shared primitives only where the existing MCP/runtime implementation and the Radicle implementation have genuinely identical security semantics. Do not move network, filesystem, process, replay, receipt, or execution state into the offline core kernel.Desired outcome
A person can inspect and sign one exact Radicle patch authorization with a key that never reaches the executor. The executor can verify, claim, publish, recover, and report the operation without parsing unstable display text. Decision, execution, and propagation claims are independently verifiable, and distributed-state completeness is an explicit derived fact rather than an assertion.
Workstreams
1. Replace the server-generated authorization fixture with a real human signing ceremony
The current live path derives the exact action and then generates transient human, workflow, and agent keys inside the executor process. This exercises real Auths authoring and verification, but it does not prove that an external human authorized the action while the executor lacked the human key.
auths-authorsigning-request APIs; never accept raw human private-key material.did:keysigner.Acceptance criteria:
2. Replace Radicle display-output parsing with stable machine interfaces
The adapter currently parses human-facing output for identity history, issue status, and the
Patch <id> openeddiagnostic. Exact Radicle version pinning reduces drift but does not make display prose a suitable security interface.rad cob show --type xyz.radicle.issue --format jsonand parse a typed, deny-unknown-fields representation.issue_materialized_digest.rad inspect --historyprose.Acceptance criteria:
3. Reuse and generalize Auths execution leases, stores, and attested receipts
auths-runtime,auths-receipts, andauths-storesalready contain execution leases, receipt attestation, and durable receipt storage, but the Radicle package had to define parallel vertical versions because the current runtime remains MCP-shaped and its receipts cannot express Radicle containment or multi-stage publication.ReceiptAttestorand canonical attested-receipt encoding.auths-storespersistence where its semantics match; document and test any Radicle-specific state that must remain vertical.core <- exchange <- product; do not make the offline kernel own I/O or mutable execution state.Acceptance criteria:
4. Make the independent observer receipt independently verifiable
The observer is a real separate Radicle node and independently fetches the patch, but its HTTP response is authenticated only by a shared bearer token. The executor currently constructs the propagation receipt from that response, so a third party cannot verify that the observer made the claim.
did:keyidentity.Replicated.Acceptance criteria:
5. Derive evidence completeness and signed-ref security explicitly
The current adapter treats successful synchronization as sufficient to set
issue_history_complete: true.minimum_successful_peerscounts successful fetches, but does not itself prove peer agreement or causal completeness.VerifierConfigurationand its digest.parent) wherever the Radicle command/API supports it.trueafter a successful command.Acceptance criteria:
6. Add crash reconciliation and transactional multi-writer execution state
Claim-before-effect correctly prevents duplicate execution, but a crash after Radicle stores the patch and before
record_storedleaves the workflow permanentlyClaimed. The current persistent store is explicitly single-writer.Claimed,Stored, orAnnounced.Acceptance criteria:
7. Replace prose-only Auths/Radicle linkage with structured metadata and idempotency
The current issue and workflow relationship is encoded in patch-description trailers (
Radicle-Issue:andAuths-Workflow:). This is readable but not a typed or queryable Radicle contract.Acceptance criteria:
Sequencing
Cross-cutting completion requirements
cargo xtask ci, dependency policy, secret scanning, and the deployed browser/native/observer parity checks.