fix(agent-hosts): adopt receiptless cataloged deploys on install/update - #574
Conversation
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e70ca76362
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
e70ca76 to
8c5f8f3
Compare
A live pre-receipt bundle (deployed before host-bundle receipts existed) could never converge: Update refused all receiptless artifacts and Install adopted only byte-identical ones, while cataloged artifacts restamp the product version and binary path on every release. On such installs `tracedecay install --agent cursor` (with or without --component core --yes --adopt) and `update-plugin` both failed with 'existing file is not owned by this component (observed ownership marker recorded by no receipt)'. Install, Update, and Repair now share the same adoption boundary: a receiptless observation at the component's own cataloged deploy path is adopted, backing divergent bytes up before replacing them. Receipt- claimed paths keep the unmodified marker-equality security boundary, foreign markers still conflict, and Uninstall stays fail-closed. The explicit --component route still demands --yes --adopt before claiming unrecorded files. Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
8c5f8f3 to
3ecb5a0
Compare
…lugin-restamp-adopt-d9a4
…lugin-restamp-adopt-d9a4
8c82f0d
into
codex/tracedecay-total-redesign-plan
Summary
tracedecay update-pluginrestamps a pre-receipt Cursor plugin bundle to the running binary/product version, andinstall --agent cursor/install --agent cursor --component core --yes --adopttake over a no-receipt bundle (expected ownertracedecay.cursor-desktop.core.v1) instead of failing therecorded by no receiptownership conflict.host-bundle-stagenamespace, the host adapter recognizes legacy first-party provenance in a durable anchor, or the operator passed--yes --adopt. A custom~/.config/opencode/plugins/tracedecay.tsis refused untouched with a typed conflict naming the--yes --adoptremedy.rules/tracedecay-memory.mdc,rules/tracedecay-memory-digest.mdc, retired skill dirs) is removed — content-gated and only from a bundle whose own manifest anchor proves tracedecay ownership — on install, update-plugin, and repair, so later updates and uninstall see a clean owned bundle.Motivation
The live Cursor bundle at
.cursor/plugins/local/tracedecay/predates host-bundle v2 receipts. The planner's old adoption boundary letRepairadopt any receiptless cataloged path,Installonly byte-identical ones, andUpdatenothing — and cataloged artifacts restamp versions/binary paths each release, so the live bundle could never converge: everyinstall/update-pluginhit the typedOwnershipConflictbefore the CLI--adoptgate could matter. Review then flagged the first fix attempt's inverse hazard:cataloged_ownership_markeris synthesized from the current manifest, so path-only adoption would silently replace an operator's own file at a cataloged path, and committed receipts drop their backups.Changes
crates/tracedecay-agent-hosts/src/agents/host_bundle_v2.rs—adopts_pre_receipt_artifactrequires the cataloged path AND an explicit authority (byte identity / first-party stage namespace / adapter-recognized legacy provenance / operator--yes --adopt), for Install, Update, and Repair alike; Uninstall never adopts.HostBundleLifecycleRequestV1.adopt_receiptlessandHostComponentSetLifecycleRequestV1.explicit_adoptioncarry the operator authority;HostComponentSetRegistrationV1::receiptless_component_provenance(default fail-closedfalse) carries the adapter's. Preview and confirmed execute resolve adoption through the same adapter so plans agree. The refusal message names the contested path and the--yes --adoptremedy.crates/tracedecay-agent-hosts/src/agents/cursor.rs—receiptless_component_provenancerecognizes exactly the durable first-party anchors (plugin-dir manifest namingtracedecay; the versioned native-extensionpackage.json);sweep_retired_cursor_plugin_artifactsperforms the bounded, ownership-gated retired-inventory cleanup after receipts commit.crates/tracedecay-agent-hosts/src/agents/host_component_registration.rs— the catalog registration authority delegates provenance to the Cursor recognizer; every other host stays on the fail-closed default.src/agent_cmd.rs,src/main.rs—--adoptthreads from the CLI throughinstall,update-plugin,reinstall, and the--componentroutes into the set request. The planner is the single adoption boundary: the CLI preview gate that re-litigated adoptions was deleted with itsadopted_relative_pathshelper (dry-run still labels unrecorded-path mutationsadopt). The Cursor retired-artifact sweep runs after every non-uninstall Cursor apply.Test plan
cargo test -p tracedecay-agent-hosts --lib— 720 passed, 0 failed. New/updated:receiptless_adoption_requires_provenance_or_explicit_authority(refusal matrix + staged-namespace and Uninstall boundaries),lifecycle_ops_converge_cataloged_pre_receipt_artifacts_only_with_adoption,cursor_transaction_refuses_unrecognized_receiptless_bytes_without_adoption(Install and Update refuse custom bytes untouched; explicit adopt takes over),cursor_component_transaction_takes_over_a_pre_receipt_bundle(provenance-driven restamp, receipts Doctor-Current),receiptless_provenance_requires_a_first_party_anchor,retired_artifact_sweep_is_bounded_and_ownership_gated, plus the fullagents::codex::auto-trust suite.cargo test --bin tracedecay -- agent_cmd::— all adoption/sweep tests pass:explicit_component_repair_refuses_adoption_without_the_adopt_flag,component_apply_refuses_receiptless_bytes_without_adoption_authority,default_component_apply_honors_explicit_adoption_authority,cursor_adoption_sweeps_retired_artifacts_and_preserves_user_files(now also covers the Update/update-pluginjourney),kimi_native_activated_retry_tracks_staged_source. The 6 remaining failures (codex_native_*,codex_core_rollback_*,kimi_canonical_*,opencode_core_*) fail identically on the unmodified base in this VM and are unrelated.cargo test --test host_bundle_acceptance— 18 passed.cargo check --workspace --all-features --profile testclean;cargo clippy -p tracedecay-agent-hosts --lib --all-featuresno new warnings.Checklist
.envfiles included