Repository navigation
fix(env): verify cleanup receipts and deletion outcomes (HACK-2171) - #768
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@codex review |
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Ready for lead: HACK-2171 implementation and persistent review are complete at 47f0deb. This PR targets
Pinned-Bun typecheck, lint, build and docs checks pass. Both env/worktree E2Es pass with no skips. The broad focused run passed 94 cases; the final cleanup/daemon/parser run passed 35 cases, and 12 relevant mocked doctor migration cases passed. The selector chooses 681 tests for this increment; full compiler-dependent local verification is unavailable here, so hosted Linux CI is still the wider gate. Pending hosted work: latest ready-state CI run 43387897032 is queued; its Linux shards and required hosted gates have not completed. Bot code/security reviews of this head have completed without findings; their full replies were read and the thread check reports Limits: noncooperative writers can race the last check and unlink; existing inherited primary layers are locked, but concurrent creation of previously absent inherited layers is not qualified. A partial cleanup error can leave earlier successful removals, which the fixed refusal reports. Other sessions retain at-rest, symlink, store/key and lifecycle-log ownership. The existing secret-downgrade and unsupported gateway observations are called out in #767's lead comment for scope decisions. No merge performed. Independent lead review and hosted gates remain before merge. |
|
Ready for lead: HACK-2171 is ready at b8ee9d5. This includes next 021b16b and updated #767 da5a62a. #769 and #756 are already merged. All four cleanup fixes remain: the legacy key uses its store mutation lock without creating a root .internal directory; recovery guidance uses stdin and preserves --local, secrecy and scope/overlay; partial failures retain confirmed removedPaths; automatic cleanup catches cleanup errors and warns so ordinary commands continue. Content/identity receipts, current scoped delivery, renewed Compose references, per-unlink guards, store-before-key order and live-input identity protection remain intact. Daemon deletion failures report HTTP 500 partial_failure with secretDeleted:null while retaining dotenvChanged. The squash conflicts in project-env-config.ts and the live-input test were resolved with the previously reviewed receipt implementation, retaining cleanupContext and the canonical fixture with unresolved alias coverage. The latest next merge was conflict-free and changes none of this cleanup code. The incoming threat-model entry now accurately marks HACK-2171 mitigated while retaining noncooperating-writer limits. Persistent review is clean at this exact head; the own cleanup delta is unchanged apart from that audit-status text. 46 cleanup/live-key/protection/daemon tests pass on the final tree, including unreadable store, YAML drift with unchanged store, real lock timeout, partial unlink and no root lock artifacts. Root typecheck/lint/build and docs checks pass. Inherited integration checks also pass: 19 argument/exposure cases, 21 daemon/dependency cases, 37 guidance/matrix cases, 51 scanner/background cases and the next.17 release-note tests. One inherited plugin release-preparation fixture remains unverified locally at a host toolchain trust gate; the exact blocker and requested prepared-host check are recorded in #767. No trust settings were changed. Thread audit: CLEAR at b8ee9d5, no unresolved bot findings or overlapping base changes. New-head bot review requested. At the current-head snapshot Change scope and secret-scan were pending; Linux shards and any selected wider checks/fan-ins had not yet reported. On #767, Linux/macOS compiler/core jobs, test shards, Docker shards, docs, models and runtime-images were queued/running. No current-head failures were reported. No Mac/Docker qualification or full compiler-dependent local-suite pass is claimed here. Next.17's actual release-note generator now includes the env breaking change and way forward, the HACK-2172 fix and daemon API migration. The upgrade guide distinguishes planned next.17 behavior from the published next.16 snapshot. No release or merge performed by this session. Full head SHA: b8ee9d5. Land #767 first; after its squash, reconcile next additively again if needed. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8ee9d5095
ℹ️ 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".
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
…K-2166) (#767) Env listings exposed migrated plaintext, legacy lifecycle commands received service values outside their scope, and secret writes accepted values in argv. Listings now show metadata by default, lifecycle delivery is scoped, and chosen plaintext entries can be encrypted in place without copying values through a terminal. - Text and JSON listings expose names, scope, source layer and set state. Revealing values requires an explicit flag and an interactive terminal. This reduces accidental output exposure; it is not access control against a local process. - `env add/set --secret` refuses positional values with stdin guidance before effects. Malformed add keys are validated before that guard, so pasted assignments receive a fixed, value-free refusal in either interactivity mode. - Legacy lifecycle hooks/processes receive only global values. Docker inspection/log/event helpers receive OS and transport settings, preserving Docker, Podman, SSH and XDG context variables without application values. - `env protect` lists plaintext names; `env protect KEY...` encrypts matching entries in their existing scopes, overlays and local layers. Existing ciphertext must decrypt before conversion; missing/wrong keys refuse before writes. Local-overlay overrides remain part of the local overlay. Doctor prints a names-only inventory and protection guidance after migration. - Daemon GET uses canonical YAML metadata without values; YAML-project legacy set/unset routes retain the parent's HTTP 409 refusal. Agent source, generated plugin, repository examples, ownership fingerprints, security model and diagram agree with these boundaries. Breaking change: scripts must replace `env list --json --show-secrets` with explicit `hack env get KEY` reads for only the keys needed; never log those plaintext reads. Use `has_value` for availability checks. Pipe secret input with `--value-stdin`. Update text parsers for modern key/scope/set/layer columns (value only on reveal) and legacy set/layer columns 7/8. Review legacy hooks that depended on service values and move only their required values to global scope. Use `env protect` to inventory and encrypt chosen plaintext entries while keeping existing key backups. Next.17's generated release notes carry this breaking change, the migration commands, daemon API changes and HACK-2172's live-key preservation fix. The upgrade guide distinguishes planned next.17 behavior from the published next.16 snapshot. Publish next.17 only after this PR is included; no release is performed here. Existing secret-to-plaintext downgrade without `--secret` remains HACK-2173. Validation on pinned Bun 1.4.4: root typecheck/lint/build, docs generation/checks, 19 argument/exposure cases, 21 daemon/dependency cases, 37 guidance/matrix cases, 51 scanner/background-process cases, release-note tests and ownership tests pass. Additional original listing/protection/worktree regressions remain in the branch. One plugin release-preparation fixture cannot complete locally because a managed runtime refuses an untrusted host toolchain config; no trust approval is bypassed. Prepared-host verification or hosted CI is still needed for that fixture. The selector chooses 742/full; the compiler-dependent full local suite remains unavailable. Local checks do not qualify Mac VM or real Docker behavior. Targets `next` and includes next 021b16b. #756 and #769 have landed; their squash history is reconciled additively. The merge-only comparison tree for the lead's earlier verification is 814fbd1; later deliberate changes are the refusal ordering, release notes, current-base integration and guidance/audit reconciliation. HACK-2171/#768 follows with cleanup receipts and truthful deletion failures. Other sessions retain ownership of at-rest, store/key and lifecycle-log findings. --------- Co-authored-by: Kit <344842+roodboi@users.noreply.github.com>
…ne key (HACK-2169) (#766) Fixes HACK-2169 (env/secret audit items F7, F8, F9 and S3) and HACK-2036 (key file hygiene), and adds a `hack doctor` migration path for setups those bugs already damaged. ## What changes **Encrypted secret store (`encrypted_file`, and the `cloud` shim)** - **F7:** a store that exists but cannot be read is never treated as empty. Every reader classifies the store through one no-follow read: a symlinked, non-regular or oversized store is refused, and any other read failure raises `SecretStoreUnreadableError`. So a `set` can never replace an unreadable store. - **F9:** the process-wide key cache holds only keychain material. A key read from one store's key file, or from the environment, never stands in for another store's key. - **HACK-2036:** the key file is read without following a link. It is refused when group or other users can read or write it (mode `0600` is required), or when git tracks it. - The tracking check runs `git ls-files --literal-pathspecs --error-unmatch` with a 5 s bound, and only when the key's real directory (symlinks resolved, as git does) is inside a work tree. - Inside a work tree where git cannot answer, the key is refused rather than guessed untracked. - **S3, explicit provisioning** (`hack env backend --provision-key` with `HACK_SECRETS_FILE_KEY`): - It **never replaces a different existing key**, or one it cannot read. A key path can serve more than one store (the default one is shared), and a key that does not open one store may be the only key for another. Changing a key is a rotation, which re-encrypts; the refusal says to move a key file aside yourself, keeping a copy, only once no store needs it. - With no key file, it writes the key only when the configured store is absent or empty, or opens under that key. An unreadable or symlinked store is refused, because a new key file could shadow the key that opens it today. - **Every key writer** (explicit provisioning, keychain persistence and the first-use key) holds the key file's own `<key>.lock`, and each write checks the file again just before it lands. A concurrent writer's key is kept, never overwritten. **Project env layers** - **F8:** `hack env add --secret` and `hack env set --secret` refuse, before writing anything, in two cases: - `HACK_ENV_SECRET_KEY` is set but no `.hack.secret.key` exists (a new key file would shadow the environment key); - a secret already in the layer does not open under the key readers use. Replacing the one entry being set is allowed. Legacy env migration refuses the same way instead of creating a shadowing key. **`hack doctor`: new `secret integrity` check** - It reports, without values: - a store that is unreadable or refused; - a store key that is missing or refused; - a key that does not open its store; - an env layer with no available key, or the wrong key; - a layer with secrets under more than one key. - It inspects every layer runtime can read, each read the way runtime reads it: committed and machine-local layers, local-only overlays, in-project symlinked layers, and, in a linked worktree, the primary checkout's inherited local layers. - For a mixed layer it names the secrets that do not open, with the `--service`, `--env` and `--local` options needed to address them. Recovery: read those values with the old key, `hack env unset` each one (unset needs no key), then `hack env set --secret` again. For inherited layers it says to run those steps in the primary checkout, and to fix a divergent key first (the "worktree keys" check). - Anything it cannot inspect is an **error, never success**: a layer that exists but cannot be read or parsed, a directory that cannot be listed, inheritance that cannot be resolved, or an inspection that throws. ## Behavior changes to note in the release - An `encrypted_file` key file that group or other users can read is now refused until someone runs `chmod 600`. Hack has always written `0600`, so this affects only key files made or changed by hand. - `--provision-key` with a different `HACK_SECRETS_FILE_KEY` no longer overwrites an existing key file; it refuses. - A key file inside a git work tree whose git cannot report tracking (git fails, is missing, or takes more than 5 s) is refused. ## Shared files - `src/lib/project-env-config.ts`. All of these are outside #756's areas and HACK-2165's local-layer writes: - the secret branch of `setProjectEnvValue`, which now uses the hydration key rules; - the new read-only inspector and its helpers; - a pre-write check in `migrateLegacyProjectEnv`. - `src/commands/doctor.ts`: one new check (`secret integrity`), not in the hygiene section. - `shell.ts`, the env parse errors and the ignore list are untouched. - HACK-2172 (#768): this PR adds no key-deletion path, so it has no "can this key still decrypt something" predicate to share. If #768 needs one, the read-only store listing here (`listFileSecretStoreEntries`, with its new `reason`) is the building block. ## Follow-up (not in this PR) - The project env key's own git-tracking check (the `.hack.secret.key` helper in `project-env-config.ts`) still passes the file name without `--literal-pathspecs`. The name is fixed, so the risk is low, but it should match the store key check. ## Validation - An independent persistent reviewer was clean after 9 rounds. The lead's second-family review then ran three rounds and found the issues fixed in the last four commits; its final round is clean on the code at `9fc9e26f`. - Every Codex finding (5) is fixed with a regression test, replied to and resolved. - Tests: - `tests/secret-store.test.ts`: - F7, F9, HACK-2036 (mode, symlink, tracked, a key reached through a symlinked directory, a git that cannot answer); - provisioning refusals, including a different key shared with another store, and unreadable or refused stores; - three concurrent provisions writing exactly one key; - a first-use bootstrap that waits for the key lock and adopts the key written meanwhile. - `tests/project-env-secret-key-integrity.test.ts`: F8. - `tests/doctor-secret-integrity.test.ts`, isolated from the real home and global config: - every finding is value-free; - mixed-key recovery runs end to end, with the old values read under the old key; - local-only, symlinked, legacy and inherited layers; - unreadable, unparseable and unlistable layers reported as errors. - `tests/env-migration-safety.test.ts`: the migration refusal. - Local gates (Bun 1.4.4): `bun run typecheck`; `bun run check` at the 39-warning baseline; `privacy:check`; gitleaks over `origin/next..HEAD`. 574 tests across the related env, secret, doctor, inheritance, migration, hermeticity and CI-selection suites pass. ```mermaid stateDiagram-v2 [*] --> Locked: --provision-key with HACK_SECRETS_FILE_KEY (holds <key>.lock) Locked --> Refused: key file unreadable Locked --> Refused: a different key is there Locked --> CheckStore: no key file, or an empty one Locked --> Write: the same key (0600 rewrite) CheckStore --> Refused: store unreadable or refused CheckStore --> Refused: store has entries the key does not open CheckStore --> Write: store absent or empty, or opens under the key Write --> Written: file unchanged just before the write lands Write --> Refused: another key landed meanwhile ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Kit <344842+roodboi@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
|
@codex review |
|
Review update: the approved trust step cleared the plugin fixture, and the integration checks pass at b02309e. The final thread audit has one unresolved store/key confirmation-batching finding (discussion_r4562560267), which I am fixing now. The previous CLEAR/readiness statement was premature; do not merge this head until the batching fix and exact-head review are posted. |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Ready for lead: All four requested cleanup fixes are present: key locking creates no repository-root Validation for this final delta: 19 legacy-cleanup tests/117 assertions, two doctor store-batching cases/19 assertions, typecheck, root and changed-file lint, build and docs checks pass. Both the key-lock and batching regressions fail without their fixes. The formerly blocked plugin release-preparation fixture passes (13 assertions) after the approved trust step in an isolated test home; global trust was unchanged. Persistent reviewer: clean at this exact head. Audit: @codex review |
|
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Ready for lead: CI run 43457786974 completed successfully at that exact head: all five planned Linux test shards, the required test gate, secret scan and docs checks passed. The earlier red test gate belongs to the superseded canceled run; it reported incomplete shard evidence, not an assertion failure. Persistent exact-head review is clean, and Codex code review completed without findings at this head. Bot audit: All four lead-requested cleanup fixes, the key-owner lock integration and tracked-store/untracked-key batching fix are included. Local regression, typecheck, lint, build, docs and approved isolated-home plugin-fixture evidence remain as recorded above. Mac/VM and real Docker qualification remain with the lead's integration checks. Scratch is cleaned, the pushed checkout is clean, and no merge or publication was performed. Stopping this watch for lead handoff. |
Conflict in docs/security/env-secrets-threat-model.md gaps 16-19 only: next's wording for gaps 17 (#766) and 19 (#768, HACK-2171) is kept; gap 18 takes next's #762 text plus this branch's mode tightening, read warning, ACL/umask limits and markerless-work-tree note; gap 16 keeps the doctor reference, and the two table rows that pointed at gaps 17/18 say "narrowed". #768's cleanup receipts merge cleanly with this branch's strictGit live-input collector (its new caller keeps the non-strict path). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add next.17 “what changed and what to do” notes to the release summary, both upgrade guides and the env guide. Users get concrete script migrations for hidden env values and native followed logs, the next.16 key-backup warning, and recovery guidance for partial cleanup. These describe merged source changes intended for next.17; they do not claim a release is published. The docs site remains pinned to next.16. #764 and #779 remain explicitly pending, and the recorded next.16 trials keep their original limits. | Subject | Merged contract checked at base `0a0bfdb8` | | --- | --- | | #747: native plain followed logs, streams, timestamps and structured session results | [native-log-follow.ts](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/backends/native-log-follow.ts), [followed-service-log contract](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/docs/reference/native-authored-commands.md#followed-service-logs) | | #767: metadata/`has_value`, scoped plaintext reads, terminal-only reveal, stdin secret writes, `env protect`, global-only lifecycle hooks/processes and YAML daemon API | [canonical prerelease wording](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/scripts/prerelease-plan.ts#L158), [env command](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/commands/env.ts), [env routes](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/daemon/routes/env.ts), [env contract](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/docs/env.md) | | #769 / HACK-2172 and #768/#783: protect live keys/config/YAML including filesystem aliases; cleanup receipts, partial removal and config-pointer reconciliation | [project-env-config.ts](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/lib/project-env-config.ts), [Doctor cleanup](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/commands/doctor.ts), [canonical cleanup note](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/scripts/prerelease-plan.ts#L164) | | #766: Doctor refuses unusable env layers | [doctor-secret-integrity.ts](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/lib/doctor-secret-integrity.ts) | | #773: loopback proxy ports, diagnosis without automatic repair | [proxy-loopback.ts](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/lib/proxy-loopback.ts), [Doctor](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/commands/doctor.ts) | | #770: inferred route readiness, 240-second grace, HTTP 200–499 limits and `service_healthy` exclusion | [http_probe.rs](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/packages/runtime-core/src/provider/http_probe.rs), [probe contract](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/docs/guides/native-candidate.md#native-http-readiness-probe) | | #778: bridge connection readiness after pool restart | [bridge.rs](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/packages/runtime-core/src/provider/bridge.rs) | | #758 and #776: merged startup fix and newer optional-daemon behavior, kept separate from next.16 | [project command](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/commands/project.ts), [Doctor](https://github.com/hack-dance/hack/blob/0a0bfdb8d1ee818d89bb49a2109bd88b0a9fea1b/src/commands/doctor.ts) | Validation at `f1d0d72fede5db6ce46f56039ba22a47911aa308`: - Persistent reviewer: clean after round 2. - Pinned Bun 1.4.4: docs prepare/check/typecheck and production site build pass. - Production-mode HTTP smoke: 95 docs, isolated searches/exports, redirects/refusals, 37 diagram blocks / 74 SVGs and 183 recipe links/anchors pass. The rendered upgrade guide returns 200 and contains the new guidance. - Privacy check, diff check and full-history Gitleaks pass (1,295 commits, no leaks). - Source citations and documented command forms checked against the merged base. Documentation only: no runtime, workflow, site pin, snapshot or global client changes. No live migration, keys, daemon, Docker or native VM tests were run. Lead owns batch integration and deployment. <!-- codesmith:footer --> --- <a href="https://backend.blacksmith.sh/track/run-proof?expires=1797183263&installation_model_id=17053&pr_number=785&ref=codesmith_pr_footer&repository=hack-dance%2Fhack&return_to=https%3A%2F%2Fgithub.com%2Fhack-dance%2Fhack%2Fpull%2F785&variant=run_proof_on_this_pr&signature=b04dd421a08341f70e804e671fd68678f102d1c4152146bdea18adf6de909981"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-run-proof-on-this-pr-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-run-proof-on-this-pr-light.svg"><img alt="Run Proof on this PR" src="https://pr-comments-assets.blacksmith.sh/codesmith/proof-run-proof-on-this-pr-dark-3x.png" width="168" height="28"></picture></a> <sup><a href="https://app.blacksmith.sh/hack-dance/codesmith/hack/pr/785?autoLogin=true&ref=codesmith_pr_footer">Open in [code]smith</a> · Need help on this PR? Tag <code>@codesmith-bot</code> with what you need.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer --> --------- Co-authored-by: Kit <344842+roodboi@users.noreply.github.com>
The next.17 section omitted the tmux breaking-change warning that already existed at the page tail. Move it into the release section and put its v4 stop procedure before the v5 trial. The env breaking entry was already correct; keep its scoped single-key/terminal/stdin migration guidance. Audit all **71 commits** from `v5.0.0-next.16` (`b21c3b1898`) through candidate **`5002cf87bb50686b17ceae8a4c835f524ee1b3a5`** against merged code and PR text. Add missing upgrade-assistant, activity, observe/plan/version, interactive exec, recovery, background-command and host/secret-custody notes. Preserve the complete native env-file behavior table and mark the four new JSON contracts **shape may change before 5.0.0**, with the planned HACK-2238 envelope migration. Correct stale native interactive-exec/network/metadata/Ctrl-C claims and the short upgrade assistant wording. Credit the publisher-shutdown fix to #719, already in next.16; keep next.17 lifecycle-command retirement separate. Retake a private stopped-state backup after v4 stops zellij, keeping the first copy too. Keep next.16 warnings scoped to that bundle. Keep original-key backups before older Doctor migrations and distinguish file rollback from runtime/data recovery. Only eight Markdown files change. Runtime, tests, workflows, generated CLI reference, diagrams, immutable snapshots and the site pin are unchanged. No diagram changed, so a new visual would add nothing. The site re-pin remains a separate release follow-up. Merge timing: respect the lead's candidate freeze; intended for the batch immediately after next.17 publication and the site re-pin. The moved tmux breaking-change notice is called out for the lead's pre-cut decision. This PR does not merge or publish anything. Validation at **`d95cfc554fabc4a0d70e3ba6caeb6746f63a198c`**: - Bun 1.4.4, frozen dependencies. Docs prepare/check/typecheck/build and site tests (2 passed, 25 assertions) pass. Production-mode HTTP smoke: 97 docs, 82 SVGs, 217 local links/anchors; task server stopped. - All 50 Hack commands named anywhere in the notes exist in the current generated CLI reference; 19 option contracts checked. CLI-reference regeneration has no diff. - All 71 commits have one row below, including the test commit and merge for #786. All 70 source evidence paths exist at the fixed candidate. Source release-note local links/anchors pass. - Privacy and complete reachable-history Gitleaks pass (1,330 commits, no findings). Persistent Claude Opus second-family review is CLEAN at this exact head. Hosted run 43585059152 passed docs site, secret scan and every planned Linux unit shard (4–8), plus the required test fan-in. Typecheck/privacy/quality ran on shard 8. Focus had no selected tests. Compiler, native core, runtime images/models, process-lifetime and Docker execution were out of scope; a green Docker fan-in is not Docker execution evidence. All bot comments were read; CLEAR at d95cfc5, zero unresolved threads/change requests. Codex code/security reviews found no issues. - No real install, migration, daemon/DNS/trust change, Docker or native VM run was performed for this documentation audit. Native acceptance and the candidate's hosted release qualification remain separate. ## Candidate commit coverage `entry present` means the behavior already had an entry within the next.17 section (some now have fuller detail). `added` means missing behavior or migration guidance was added there; #824 moves the existing warning into that section. `not user-visible` means no shipped CLI/runtime change: documentation, test/CI/repository housekeeping or the internal desktop preview. Source links pin the candidate, rather than a moving branch. | Commit / PR | Coverage | Entry or reason | Audited source | | --- | --- | --- | --- | | [70d328e](70d328e) [#743](#743) | added | Host setup: privileged/NSS safeguards | [src/lib/linux-trust-setup.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/linux-trust-setup.ts) | | [51f15c8](51f15c8) [#746](#746) | not user-visible | Docs-only upgrade checklist and site generation; no installed behavior | [scripts/docs/prepare.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/docs/prepare.ts) | | [c14f3f5](c14f3f5) [#744](#744) | added | Native setup JSON accounting | [packages/runtime-core/src/provider/setup.rs](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/packages/runtime-core/src/provider/setup.rs) | | [b0c6bcd](b0c6bcd) [#705](#705) | added | Retained background exec/run and cursor tools | [src/commands/background-command-start.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/background-command-start.ts) | | [c89f4fd](c89f4fd) [#745](#745) | added | Linux daemon query/home refusals | [src/commands/daemon-systemd.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/daemon-systemd.ts) | | [cce4b59](cce4b59) [#752](#752) | not user-visible | Site pin/snapshots and editorial pages only | [scripts/docs/versions.json](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/docs/versions.json) | | [56676fc](56676fc) [#754](#754) | added | Setup reuse/offline accounting; pin-watch changes are internal | [packages/runtime-core/src/provider/setup.rs](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/packages/runtime-core/src/provider/setup.rs) | | [7a496f1](7a496f1) [#755](#755) | added | MCP registered selectors and background tool guidance | [src/mcp/server.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/mcp/server.ts) | | [e7a7039](e7a7039) [#747](#747) | entry present | Native follow text shape; added session ends/restart recovery | [src/backends/native-log-follow.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/backends/native-log-follow.ts) | | [87a6df5](87a6df5) [#758](#758) | added | Compose short one-shot startup | [src/lib/compose-startup-state.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/compose-startup-state.ts) | | [2afb5c4](2afb5c4) [#761](#761) | added | Native Hack networks and inert generated labels | [src/lib/native-hack-compose-conventions.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/native-hack-compose-conventions.ts) | | [342a585](342a585) [#771](#771) | not user-visible | Docs-only next.16 trial record | [docs/versions/v5/guides/upgrade-from-v4.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/versions/v5/guides/upgrade-from-v4.md) | | [6f0acf1](6f0acf1) [#769](#769) | entry present | Migration live-key/alias preservation | [src/lib/project-env-config.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/project-env-config.ts) | | [c96c444](c96c444) [#756](#756) | added | Child key filtering, fixed diagnostics, legacy ignore/YAML API refusals | [src/lib/child-environment.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/child-environment.ts) | | [e2c73c6](e2c73c6) [#748](#748) | not user-visible | Contributor CI selection/coalescing, outside product release notes | [scripts/ci-change-scope.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/ci-change-scope.ts) | | [ebf794e](ebf794e) [#760](#760) | added | Agent/output custody warning; runtime unchanged | [src/agents/instruction-source.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/agents/instruction-source.ts) | | [021b16b](021b16b) [#763](#763) | added | One-pass background redaction scan; no public benchmark claim | [src/lib/background-command/output-scanner.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/background-command/output-scanner.ts) | | [8564ec4](8564ec4) [#765](#765) | added | Shared preflight/start admission and detached failure reporting | [src/backends/native-project-review.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/backends/native-project-review.ts) | | [0c0fba2](0c0fba2) [#767](#767) | entry present | Breaking env exposure/protect/stdin/scope/API guidance | [src/commands/env.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/env.ts) | | [9435da9](9435da9) [#762](#762) | added | Local Git/link refusals and no-follow dotenv | [src/lib/project-env-config.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/project-env-config.ts) | | [edf23ae](edf23ae) [#753](#753) | added | Daemon stop proves the live Hack home | [src/commands/daemon-systemd.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/daemon-systemd.ts) | | [573ceec](573ceec) [#766](#766) | entry present | Doctor layer/integrity error; added store/key write refusals | [src/lib/secret-store.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/secret-store.ts) | | [a0e9760](a0e9760) [#757](#757) | added | Orphan output truncation and final-sync evidence | [src/lib/background-command/recovery.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/background-command/recovery.ts) | | [10e1958](10e1958) [#759](#759) | added | Private lifecycle logs/FIFO and expiring mux payloads | [src/lib/private-file.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/private-file.ts) | | [bd899ee](bd899ee) [#775](#775) | not user-visible | Portable test fixtures only | [tests/single-file-tar.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/single-file-tar.test.ts) | | [80dae3d](80dae3d) [#776](#776) | added | Candidate missing-daemon diagnosis is optional/healthy | [src/commands/doctor.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/doctor.ts) | | [5b2a2d0](5b2a2d0) [#772](#772) | added | Bounded attaching-network retry; strict saved reads remain | [src/lib/native-compose-ownership.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/native-compose-ownership.ts) | | [ab29d49](ab29d49) [#777](#777) | not user-visible | CI scheduling only | [docs/reference/ci-test-selection.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/reference/ci-test-selection.md) | | [31339c7](31339c7) [#770](#770) | entry present | Native inferred readiness, 240 s, HTTP/service_healthy limits | [packages/runtime-core/src/project/compose/service.rs](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/packages/runtime-core/src/project/compose/service.rs) | | [156ee7f](156ee7f) [#773](#773) | entry present | Loopback proxy port/Doctor/open checks | [src/lib/proxy-loopback.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/proxy-loopback.ts) | | [a7ec3c7](a7ec3c7) [#768](#768) | entry present | Cleanup receipts/partial outcomes and tracked-file wording | [src/lib/project-env-config.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/project-env-config.ts) | | [ceb3e23](ceb3e23) [#778](#778) | entry present | Native bridge socket readiness | [packages/runtime-core/src/provider/bridge.rs](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/packages/runtime-core/src/provider/bridge.rs) | | [af91049](af91049) [#783](#783) | entry present | Pointer reconciliation after partial cleanup | [src/commands/doctor.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/doctor.ts) | | [0a0bfdb](0a0bfdb) [#780](#780) | not user-visible | Site-only Linux guide publication; no CLI behavior | [scripts/docs/versions.json](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/docs/versions.json) | | [d0cf767](d0cf767) [#786](#786) | not user-visible | Consent test wording only (both commits) | [tests/env-migration-tracked-consent.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/env-migration-tracked-consent.test.ts) | | [7e2e630](7e2e630) [#786](#786) | not user-visible | Consent test wording only (both commits) | [tests/env-migration-tracked-consent.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/env-migration-tracked-consent.test.ts) | | [91c311e](91c311e) [#779](#779) | entry present | Restore or reversible retire; missing store keys scoped to readers | [src/lib/secret-store-retire.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/secret-store-retire.ts) | | [6ab1ace](6ab1ace) [#785](#785) | not user-visible | Docs-only release/upgrade/env notes | [docs/guides/v5-release-notes.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/guides/v5-release-notes.md) | | [25bd63c](25bd63c) [#764](#764) | entry present | Doctor hygiene, local modes, ignored staging and live-input protection | [src/lib/secrets-hygiene.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/secrets-hygiene.ts) | | [d9df57c](d9df57c) [#784](#784) | not user-visible | Resolver/proxy and consent test corrections only | [tests/project-open-loopback.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/project-open-loopback.test.ts) | | [2c1f665](2c1f665) [#791](#791) | added | Detached failure names, open DNS hint, init placeholder; prune guidance | [src/commands/project.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/project.ts) | | [f6fe55f](f6fe55f) [#787](#787) | not user-visible | Docs-only retirement/hygiene follow-up | [docs/guides/v5-release-notes.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/guides/v5-release-notes.md) | | [7f9548c](7f9548c) [#792](#792) | not user-visible | Start-here docs, navigation and contributor rule only | [docs/versions/v5/install.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/versions/v5/install.md) | | [a0cfc73](a0cfc73) [#793](#793) | added | Verified updater publication, backups and reversible candidate removal | [src/lib/self-update.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/self-update.ts) | | [292d312](292d312) [#782](#782) | added | Lock-free native ps and proved failed-start down | [src/backends/native-project-observe.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/backends/native-project-observe.ts) | | [b1e123b](b1e123b) [#796](#796) | added | Doctor reader count/worktree grouping in store recovery | [src/lib/doctor-secret-integrity.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/doctor-secret-integrity.ts) | | [286d00f](286d00f) [#789](#789) | added | Foreground command-before-wrapper retirement | [src/lib/project-lifecycle-processes.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/project-lifecycle-processes.ts) | | [bb6a7d1](bb6a7d1) [#788](#788) | not user-visible | Linux qualification runbook only | [docs/guides/linux-host-qualification.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/docs/guides/linux-host-qualification.md) | | [a262d42](a262d42) [#800](#800) | not user-visible | Internal desktop design; outside supported CLI release scope | [apps/desktop/DESIGN.md](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/apps/desktop/DESIGN.md) | | [6b161ba](6b161ba) [#774](#774) | added | Native interactive exec, finite fallback and receipt recovery | [src/backends/native-project-exec.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/backends/native-project-exec.ts) | | [1249272](1249272) [#799](#799) | not user-visible | Portable output-contract CI selection only | [scripts/test-shard-plan.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/test-shard-plan.ts) | | [fa3f03d](fa3f03d) [#790](#790) | added | Read-only upgrade check, snapshot and rollback | [src/commands/upgrade.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/upgrade.ts) | | [c3b79bc](c3b79bc) [#807](#807) | added | Observe-only global status and unknown evidence | [src/commands/global-status-observe.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/global-status-observe.ts) | | [29be043](29be043) [#812](#812) | added | Read-only local CA trust diagnosis | [src/lib/ca-trust-status.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/ca-trust-status.ts) | | [f0102fd](f0102fd) [#814](#814) | not user-visible | Prepared-base verifier test fixture only | [tests/qualify-provider-pin.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/qualify-provider-pin.test.ts) | | [b4ebfec](b4ebfec) [#815](#815) | added | Compact upgrade plan, snapshot-backed apply/resume | [src/lib/upgrade-apply.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/upgrade-apply.ts) | | [c44b266](c44b266) [#801](#801) | not user-visible | Internal optional desktop preview; not shipped CLI behavior | [apps/desktop/Cargo.toml](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/apps/desktop/Cargo.toml) | | [56d1d0f](56d1d0f) [#804](#804) | added | Automatic mux sweep preserves live/retired config inputs | [src/lib/live-inputs.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/live-inputs.ts) | | [1958363](1958363) [#805](#805) | added | MCP timedOut result and Codex installer timeout | [src/mcp/server.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/mcp/server.ts) | | [e6207e8](e6207e8) [#810](#810) | added | Lifecycle activity writes including handler refusals; activity JSON | [src/commands/lifecycle-activity.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/lifecycle-activity.ts) | | [23fe08f](23fe08f) [#825](#825) | added | Read-only batch review and permission-only key repair | [src/lib/upgrade-review.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/upgrade-review.ts) | | [cab596c](cab596c) [#781](#781) | entry present | Full native env-file behavior table; added support/precedence summary | [src/backends/native-compose-environment.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/backends/native-compose-environment.ts) | | [1e84684](1e84684) [#798](#798) | not user-visible | Rust test process isolation/nextest; internal qualification only | [scripts/test-runtime-core.sh](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/scripts/test-runtime-core.sh) | | [518af29](518af29) [#817](#817) | not user-visible | Remove accidental empty checkout files; no installed CLI change | [.gitignore](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/.gitignore) | | [07192f7](07192f7) [#824](#824) | added | BREAKING warning moved from page tail into next.17; v4 stop procedure retained | [src/mux/mux-config.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/mux/mux-config.ts) | | [fe09a5b](fe09a5b) [#816](#816) | added | Read-only install/trust admin plans and exits | [src/commands/global.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/global.ts) | | [8977676](8977676) [#827](#827) | added | Registry-preserving project observe, runtime opt-in | [src/commands/projects.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/commands/projects.ts) | | [5965b23](5965b23) [#828](#828) | added | Running CLI version identity JSON | [src/lib/version-report.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/version-report.ts) | | [2922210](2922210) [#830](#830) | added | Upgrade safe/admin/manual action kinds | [src/lib/upgrade-action-kind.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/upgrade-action-kind.ts) | | [51b55c0](51b55c0) [#820](#820) | not user-visible | Archive/plan/shared-helper verification fixtures only | [tests/python-free-download.test.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/tests/python-free-download.test.ts) | | [5002cf8](5002cf8) [#809](#809) | added | Retirement read retry, second Ctrl-C and native cancellation cleanup | [src/lib/project-lifecycle-processes.ts](https://github.com/hack-dance/hack/blob/5002cf87bb50686b17ceae8a4c835f524ee1b3a5/src/lib/project-lifecycle-processes.ts) | --------- Co-authored-by: Kit <344842+roodboi@users.noreply.github.com>
Migration cleanup could delete a newer legacy env file after an earlier confirmation decision. It now carries bounded content and file-identity receipts from before migration, rechecks current scoped delivery and Compose references under writer locks after consent, and checks each target again before unlinking.
.internal/for a key.--local, secrecy, scopes and overlays and uses stdin rather than promising a migration rerun imports changed values into existing YAML.partial_failure, fixedsecret_delete_unconfirmedtext andsecretDeleted: null, preserving the completeddotenvChangedresult. It does not claim backend absence or rollback.This addresses audit F10 and S5. S6's value-free legacy JSON diagnostics arrived in merged #756. HACK-2172/#769 already preserves live project/shared keys, config and YAML inputs, including aliases; this PR keeps those guards before/under locks and immediately before unlink.
The integration includes next
ab29d491and the landed parent fixes. A held-key-writer regression fails without adopting the new HACK-2169 key-owner lock and passes with it. A real temporary Git regression reproduces the tracked-store/untracked-key batching refusal without the fix and passes afterward.Pinned Bun validation: 39 cleanup/live-key/daemon cases, 56 store/integrity cases and 14 selected doctor migration cases passed before the final batching change. For the batching change, 19 legacy cleanup cases (117 assertions), both doctor store batches (19 assertions), typecheck, root and changed-file lint, build and docs checks pass. The plugin release-preparation fixture also passes (13 assertions) after an owner-approved trust step scoped to an isolated test home; no global trust setting changed. Persistent review is clean at exact head
6cf07d3801ba00c6f4399b4eadc6ae8e85fa051f. Hosted checks and the refreshed GitHub review remain pending. The full compiler-dependent suite remains a hosted gate; no new Mac VM or real Docker qualification is claimed locally.Noncooperating writers can still race the last unlink. The reverse consent case (untracked store, tracked key, initial cleanup declined) retains its existing safe refusal. Opposing future lock nesting can time out safely; normal key writers hold only the key lock and normal store writers resolve the key before taking the store lock. No cipher-format or rotation change is made.
Targets
next; all parent PRs have landed and their squash ancestry is reconciled by additive merge. No history rewrite, merge to next or publication is performed here. The lead arranges independent review before merge.