Skip to content

fix(daemon): treat only a named missing unit as absent; resolve the Hack home; run daemon tests on both hosts (HACK-2142) - #745

Merged
roodboi merged 14 commits into
nextfrom
claude/hack-2142-daemon-state-query
Nov 13, 2026
Merged

roodboi merged 14 commits into
nextfrom
claude/hack-2142-daemon-state-query

Conversation

@roodboi

@roodboi roodboi commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #709 (HACK-2052), from its fourth second-family review pass and a macOS run of its tests.

What changes

1. Only a diagnostic naming hackd.service means "no unit". The unit-state query reused the broad UNIT_MISSING match. "Failed to connect to bus: No such file or directory", or the runner's "systemctl not found" (exit 127), therefore read as "the unit does not exist", and with the unit file gone hack daemon stop and uninstall reported nothing to do.

  • A failed query now counts as absent only when every line of its output names hackd.service as absent ("Unit hackd.service could not be found.", optionally prefixed with "Failed to get properties:") and the exit code is not a runner timeout or launch failure (124, 126, 127).
  • Every other failure stays a stateError: bus, tool discovery, timeout and anything else. It is refused with the manual systemctl steps.

2. The Hack home is compared in resolved form. walkReplaceableChain follows symlinks, but secureDaemonDirectory passed the Hack home unresolved. Under a linked path such as macOS's /var/folders → /private/var/folders, nothing therefore counted as inside the Hack home, and a group-writable directory there was refused ("is writable by other users (mode 775)") instead of repaired. The walk now resolves the Hack home before comparing, which covers every caller. The two daemon-socket-permissions tests that failed on macOS take this path.

3. Daemon tests run on both CI hosts. In the pooled layout, a file that mentions process.platform is planned only in the macOS pool. The 105 Linux-only systemd tests in daemon-systemd.test.ts, plus the Linux-only tests in daemon-systemd-cli, daemon-process-proof and daemon-detach, therefore skipped in hosted CI; only local Linux runs exercised them. Meanwhile daemon-socket-permissions.test.ts ran only on Linux.

  • A new BOTH_POOL_FILES list (each entry with its reason) runs these five files on both hosts.
  • The coverage check still requires every other file to run exactly once.
  • bun scripts/test-shard.ts verify --count=8 --layout=pooled: 726 files; 184 in the macOS pool and 547 in the Linux pool.

Evidence (local, Linux)

  • New tests, each failing without its fix:
    • "only a diagnostic naming hackd.service counts as no unit (HACK-2142)": the bus-socket message, the missing-systemctl message (exit 127), and a valid line mixed with a bus error, for both stop and uninstall. The real missing-unit messages stay no-ops.
    • "a Hack home under a linked path is still repaired (HACK-2142)": reproduces the macOS error on Linux with a symlinked parent.
    • test-shard.test.ts: a both-pool fixture entry is planned in both pools, and the current checkout covers every file once, with the both-pool files on both hosts.
  • bun run typecheck, bun run check, bun run privacy:check and gitleaks are clean. The daemon, shard and selection tests pass 325 of 325.
  • Not run here: macOS. The fix for item 2 is reproduced and verified on Linux through a symlinked path; this PR's CI now runs the socket-permissions file on macOS.

🤖 Generated with Claude Code


Run Proof on this PR
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

roodboi and others added 2 commits November 12, 2026 21:45
… absent (HACK-2142)

The unit-state query reused the broad UNIT_MISSING match, so "Failed to
connect to bus: No such file or directory" or the runner's "systemctl not
found" (exit 127) read as "the unit does not exist", and with the unit
file gone stop and uninstall reported nothing to do. Only a failed query
whose every diagnostic line names hackd.service as absent now counts as
no unit; bus, tool-discovery, timeout and other failures stay stateError
and are refused with the manual systemctl steps.

Co-Authored-By: Claude <noreply@anthropic.com>
… CI hosts (HACK-2142)

The chain walk visits physical paths, but secureDaemonDirectory passed
the Hack home unresolved: under a linked path (macOS /var -> /private/var)
nothing counted as inside it, so a group-writable directory there was
refused instead of repaired. walkReplaceableChain now resolves the Hack
home before comparing.

The pooled CI layout ran the daemon systemd, process-proof and detach
files only in the macOS pool, where their Linux-only tests skip, and the
socket-permissions file only on Linux. BOTH_POOL_FILES runs these five on
both hosts; the coverage check still partitions the rest.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hack-docs Ready Ready Preview Nov 13, 2026 12:58am UTC

Request Review

@linear-code

linear-code Bot commented Nov 12, 2026

Copy link
Copy Markdown

HACK-2142

@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T01:00:08.106853Z 2a5886a Manual request
🔒 Security Review ✅ Completed 2026-11-13T01:04:11.981235Z 2a5886a Manual request

Security findings

Advisory findings (2)

ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: f5460b9106

ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛡️ Codex Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: f5460b9106

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread src/lib/path-trust.ts Resolved
A daemon directory that others could write (repaired to 0700 at start,
now also under a linked Hack home) may already hold a planted hackd.log
link, which the log writer would append to or truncate. After the
repair, when nobody else can add entries, every entry must be this
user's, not a symlink, and not a regular file with other hard links;
otherwise hackd refuses to start and names the entry.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 7478e3cb5a

ℹ️ 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".

…sts (HACK-2142)

With the daemon test files now in the Linux pool, the hackd.service PATH
checks met GitHub's Ubuntu image, where /usr/local/bin and /opt (target
of some /usr/bin links) are mode 777, and refused install and start, as
they should on such a host. Make the two directories owner-writable on
Linux test shards, as on a stock Ubuntu install, so the tests check
Hack's logic rather than the runner's layout.

Co-Authored-By: Claude <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 7478e3cb5a

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…y/ owner-only (HACK-2142)

hackd also appends to gateway/audit.jsonl, which a top-level check did
not see: a link planted in a group-writable gateway/ was followed. Each
subdirectory is now opened without following a link, made owner-only,
and its entries get the same checks; anything nested deeper (Hack
creates nothing there) is refused. The gateway audit log and token
store create gateway/ with mode 0700.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: a0500ff82c

ℹ️ 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".

…K-2142)

Bun.write follows a symlink, so a link planted in a once group-writable
gateway/ had its target overwritten by the token JSON when a gateway
command wrote the store before hackd's next start check. The store now
refuses an existing link, hard-linked or foreign entry, and writes a new
owner-only file (exclusive create, 0600) renamed over it.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: ee795dc892

ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛡️ Codex Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: ee795dc892

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread src/daemon/socket-permissions.ts Resolved
…own files (HACK-2142)

A group member could rewrite a 0664 gateway/tokens.json in place (same
owner, one link) to plant a write token, and the start-time scan
accepted it. A group/other-writable regular file is now refused when
its contents decide who may use hackd (gateway/tokens.json); hackd's own
logs, pid file and markers, created with the process umask, get group
and other write removed through a handle that does not follow a link.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: c767558fae

ℹ️ 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".

…hackd start (HACK-2142)

Token stores written before 0600 stores are 0664 under umask 0002, the
Debian/Ubuntu default, so refusing them in the start-time scan stopped
hackd itself after an upgrade. The scan now leaves the store untouched
(a repair would bless its contents); readGatewayTokenStore refuses a
store that is not this user's plain, single-link, owner-writable file,
naming the recovery (rm the store, then hack x gateway token-create).
Authentication grants nothing from such a store; a static env token
still applies. The architecture docs carry the migration step.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: ffff28d7ba

ℹ️ 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".

…en (HACK-2142)

The store was checked with lstat and then read again by path, leaving a
window in which a group member could swap it in a still-writable
gateway/. It is now opened once (O_NOFOLLOW, O_NONBLOCK so a planted FIFO
cannot hang the read), checked on that open file and read through it.
The new test documents the no-follow and no-hang behavior; the race
itself is not reproducible in a test.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 09f35dc163

ℹ️ 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".

…d of failing (HACK-2142)

hack global status (JSON and interactive) reads the token store even
with the gateway disabled, so an upgraded 0664 store aborted a core
command. Status, remote status and doctor now use
listGatewayTokensForStatus: an untrusted store yields no tokens and a
warning with the recovery command. Authentication and token commands
keep refusing it.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 7ade500598

ℹ️ 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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 7ade500598

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

roodboi and others added 2 commits November 12, 2026 22:55
…nd /opt (HACK-2142)

The first runner hardening covered only /usr/local/bin and /opt. The
Linux shards then met /opt/microsoft (mode 777, reached from /usr/bin
links) and world-writable programs in /usr/local/bin (ccmake, mode 777).
Remove group/other write from every regular file and non-sticky
directory under /usr/local and /opt, and list what changed.

Co-Authored-By: Claude <noreply@anthropic.com>
…ner hardening (HACK-2142)

GitHub's Ubuntu image leaves world-writable trees all over (/opt/microsoft,
/usr/share, /usr/lib/jvm, programs in /usr/local/bin), and /usr/bin links
into them, so hardening the runner could not be complete. The in-process
systemd tests now use a PATH directory of their own: the fake's default
PATH is a temp sysbin, and install's system PATH directories come from a
new hook (systemPathDirectories, defaulting to the rendered /usr/local/bin,
/usr/bin, /bin). A probe that refuses any scan of /usr, /bin or /sbin
leaves all 104 unit tests passing. The CLI install flows, which run the
real binary, run only when the host's own system PATH passes Hack's check
and otherwise skip with the reason. The runner hardening step is removed.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1868628d51

ℹ️ 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".

…LI flows only on CI (HACK-2142)

With the in-process tests on their own PATH directory, the root-owned
system directory branch (system accounts' setuid helpers) had no test;
it is now checked through programFileProblem with fixed file details. The
CLI install flows skip only on GitHub Actions, so a refusal on any other
host fails them rather than hiding a regression in the check. The unit
renderer builds its PATH from RENDERED_SYSTEM_PATH_DIRECTORIES, the same
list install checks.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 157087f360

ℹ️ 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".

…ilure (HACK-2142)

A token store this user cannot open (another account's 0600 file) failed
with EACCES before the ownership check, and the raw error aborted
hack global status. Any open failure other than a missing store is now
an untrusted store: status output reports it as a warning, and
authentication and token commands refuse it.

Co-Authored-By: Claude <noreply@anthropic.com>
@roodboi

roodboi commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 2a5886af62

ℹ️ 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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 2a5886af62

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@roodboi

roodboi commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

Ready for lead: HACK-2142, the follow-up to #709. My persistent reviewer is CLEAN at this head, the Codex code and security reviews found no issues here, every bot thread is answered and resolved, and computer pr review-status reports CLEAR (next has moved only on unrelated files).

Hosted CI on this head: the whole run is green, 27 jobs with none pending. That includes macOS shards 1–3, docker-e2e 1–4, every compiler and candidate-core job, typecheck and lint.

  • tests/daemon-socket-permissions.test.ts passes on macos-15 (shard 3): the two tests that failed on your Mac and the new linked-path test.
  • The systemd unit tests run and pass on Linux (shard 4). Before this PR, pooled CI never ran them on Linux.
  • The three CLI install flows skip on GitHub's runner and print the reason ("/usr/local/bin is writable by other users (mode 777)"); see item 4.

What this PR does

  1. Missing-unit detection. A unit query counts as "unit absent" only when every line of its output names hackd.service as missing, and the exit code isn't 124, 126 or 127. Every other failure stays a stateError: a lost bus, a missing systemctl, a timeout. File-less stop and uninstall then refuse with the manual systemctl steps.
  2. Resolved Hack home (your macOS report). walkReplaceableChain resolves the Hack home before comparing paths, because the walk itself follows links (macOS /var → /private/var). Two more checks came out of the reviews of this change:
    • Daemon directory contents: once the directory is owner-only, it, and gateway/ one level down, must contain nothing hackd didn't create. Another account's entry, a symlink, a hard-linked file or a deeper directory is refused. hackd's own 0664 logs and pid file get group and other write removed.
    • Gateway token store: it's written 0600 through a new file renamed into place, and checked and read through a single open that doesn't follow links. The gateway won't use a store that is untrusted or can't be opened, and the error names the fix (rm <store> && hack x gateway token-create). hack global status, remote status and doctor report it as a warning and finish; hackd itself still starts. The migration step is in docs/architecture.md.
  3. Daemon tests on both hosts. BOTH_POOL_FILES runs daemon-systemd, daemon-systemd-cli, daemon-process-proof, daemon-detach and daemon-socket-permissions on macOS and Linux. Every other file still runs exactly once.
  4. Host-independent systemd tests. GitHub's Ubuntu image has world-writable trees that /usr/bin links into (/opt/microsoft, /usr/share, /usr/lib/jvm, programs in /usr/local/bin), so hardening the runner couldn't be complete, and I dropped it.
    • In-process tests: they use their own PATH directory. A test-only hook, systemPathDirectories, works like resolveExpected, and production behaviour is unchanged. A probe that refused any scan of /usr, /bin or /sbin left all 104 unit tests passing.
    • System-directory rule: it now has its own test with fixed file details, and that test fails when the rule is broken on purpose.
    • CLI flows: they skip only on GitHub Actions. On any other host, a refusal fails them.
    • ci.yml: the only change left is one comment line, which no longer says every file runs exactly once.

Follow-ups (not in this PR)

  • System-directory decision: the step that decides a directory is a protected system directory (checkPathDirectoryPrograms: root-owned, not writable by others) is covered only by the CLI flows, which skip on CI. A test with a fixed directory listing would cover it.
  • Temporary open errors: a temporary error opening the token store (EMFILE, EIO) is reported as an untrusted store with "remove and reissue" advice. Advice specific to the error code would be more accurate.
  • Gateway CLI listing: before hackd's first start it can still read a planted link through the old path; hackd itself is protected by its start-time scan.
  • Earlier follow-ups, still open: the dev shim's checkout isn't trust-checked, and the environment variables hackd's child tools read (GIT_CONFIG_*, GIT_SSH_COMMAND, DOCKER_CONFIG).

HACK-2070 (fresh-host qualification)

I can't run it on this host without sudo.

  • sudo -n asks for a password, so the resolver drop-in, the system CA trust store and a reboot are all out of reach.
  • This is a shared machine (Ubuntu 24.04, systemd 255, up since September) with an existing ~/.hack, the user's own systemd units, Docker shared with other workloads, and linger on. My rules forbid touching the real ~/.hack, hackd, systemd units, resolver, trust store or Docker here.
  • A reboot or re-login would interrupt other agents' sessions.

What the owner needs to provide: a disposable Ubuntu 24.04 VM (a paid action) with a non-root sudo user, a systemd user session, and Docker that nothing else uses. Then:

  • I do the clean install, hack daemon install, the daemon checks, and the parts of DNS and trust that don't need sudo.
  • You type sudo for the resolver drop-in, the system CA trust and the reboot, or give that VM's user passwordless sudo for those steps.
  • After the reboot and re-login, I verify that the service, DNS and trust all survived.

PR #745 head 2a5886a

@roodboi

roodboi commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

Second-family review (Codex gpt-6.1-sol; the author is a Claude session) at 2a5886af62d753bbf9bbf15df0b00c037bf76fc2, report only: 0 blockers, 1 should-fix that this PR does not address; nothing wrong found in what it changes.

Closed

  • A lost bus or a missing systemctl is no longer read as "unit not found": the diagnostic must name hackd.service, every stderr line must match, and runner exits 124, 126 and 127 are excluded (src/daemon/systemd.ts:803-834); stop and uninstall refuse with the manual steps. Twelve query inputs checked.
  • The Hack home is resolved before the repair comparison (src/lib/path-trust.ts:79,98); the full component walk, the ownership check before any repair (:217) and the final O_DIRECTORY|O_NOFOLLOW open (src/daemon/socket-permissions.ts:52-63) still hold. A parent link owned by another account is refused before any chmod. The lead's Mac run: tests/daemon-socket-permissions.test.ts 9 of 9.
  • Also reviewed and found sound: the scan that refuses planted links and foreign-owned entries before the logger opens them, and the gateway token-store reader and writer (type, owner, link count and mode checked on the same no-follow handle; exclusive 0600 temporary file, then rename).

Open (not in this diff): hack daemon stop still judges ownership from the loaded unit configuration (src/commands/daemon-systemd.ts:520,550; readSystemdUnitHackHome at src/daemon/systemd.ts:1055), not from the running process. After a drop-in that set another Hack home is removed and the manager reloaded without a restart, stop from the default home stops the daemon that still serves the other home.

Lead decision. This merges now: the open item is behaviour already on next, this PR does not make it worse, and it closes two real defects. The running-home proof becomes its own small PR from the same session (prove the unit's main process home from process evidence; refuse with the manual steps when it differs or cannot be read; same-home stop and cancelling a pending restart keep working; tests for drop-in removal with reload and no restart, unreadable evidence, and same-home success). The owner can overrule.

🤖 Review relayed by Claude Code

@roodboi
roodboi merged commit c89f4fd into next Nov 13, 2026
31 checks passed
@roodboi
roodboi deleted the claude/hack-2142-daemon-state-query branch November 13, 2026 05:00
roodboi added a commit that referenced this pull request Nov 13, 2026
…ess (HACK-2052) (#753)

Follow-up to #709/#745 (HACK-2052): `hack daemon stop` decides which
Hack home the running daemon serves from the process itself, not from
the loaded unit configuration, and leaves another home's daemon alone
only on positive evidence.

## Why
`stop` read the unit's Hack home from systemd's loaded configuration.
Suppose a drop-in that set another Hack home is removed and the manager
is reloaded without a restart. The configuration then says "this home"
while the running daemon still serves the other one, so `stop` from the
default home stopped the other home's daemon.

## What changes
```mermaid
flowchart TD
  A[hack daemon stop] --> Q{unit state and MainPID read?}
  Q -- query failed --> R[refuse with systemctl --user status / stop steps]
  Q -- yes --> B{live MainPID?}
  B -- no, e.g. pending restart --> D{loaded config's Hack home}
  B -- yes --> C[prove: hackd image holding a socket in this home's daemon dir, identity stable]
  C -- this home's --> H[recheck MainPID, then systemctl --user stop]
  C -- exited meanwhile --> D
  C -- unidentifiable or not hackd --> R
  C -- hackd without this home's socket --> F{config names another home H?}
  F -- no: this home or unreadable --> R
  F -- yes --> P[prove it holds a socket in H's daemon dir]
  P -- proven, or exited meanwhile --> N[leave the unit alone; stop this home's own hackd]
  P -- not proven: still starting or unreadable --> R
  D -- this home --> H
  D -- another home --> N
  D -- unreadable --> R
```
- **Failed queries refuse.** A unit-state or MainPID query that fails is
not "no process". It refuses with the manual commands, whether or not
the unit file is present. So does a final re-read that fails or finds
the manager unavailable, also during a pending restart with no main
process.
- **Live main process:** proven with `proveOwnedDaemonProcess`. The
image may come from another install or checkout (a Bun launcher, the dev
shim), because systemd names the process; the socket proves the home. A
launcher main process counts when this home's proven hackd is its direct
child in the unit's cgroup.
- **Another home's daemon** is left alone, and `hack daemon
stop`/`restart` still stop this home's own hackd, only on positive
evidence: the configuration names another home, and the process is
proven to hold a socket in that home's daemon directory (or exited while
being checked). A hackd holding neither home's socket is refused with
"may still be starting: run hack daemon stop again", or with the manual
steps if its sockets cannot be read.
- **No live process (a pending restart):** the configuration decides, so
`stop` still cancels the restart.
- **No unit file at the managed path:** another home's configuration is
left alone when nothing runs, the main process exited meanwhile, or the
process is proven another home's. Anything else is refused, because
without the file it cannot be checked.
- **Just before `systemctl --user stop`**, the unit's state is read
again, and a changed main pid or a failed read is refused. This narrows
the gap without closing it: a change after that read, or a reused pid,
is not detected.
- **Hosted Linux check of the CLI install flows:** the Linux-only
`linux-process-lifetime` job removes group/other write under the
runner's `/usr` and `/opt`, and gives root the files owned by other
regular accounts (uid at or above `UID_MIN`). It then runs
`tests/daemon-systemd-cli.test.ts` with
`HACK_TEST_REQUIRE_INSTALL_FLOWS=1`, so the real protected-directory
decision runs on hosted Linux and a refusal fails instead of skipping.
The job is not itself a required check, but whenever it is selected the
`test` fan-in job (from `next`) fails if it fails or is skipped
unexpectedly.

## Evidence (local, Linux)
- New tests, each failing without its fix:
- **The reload case:** a drop-in removed and reloaded without a restart,
with the daemon still serving the other home, is refused.
- Unreadable process evidence is refused, this home's daemon is stopped,
and a pending restart is cancelled.
- **A live daemon of another home is left alone, not refused:** this
holds for a drop-in, the manager environment, `UnsetEnvironment` and the
account's home, with and without the unit file. A hackd holding neither
home's socket is refused with the retry hint, and one that exits during
the proof is left to its home.
- **A failed state query, or a failed final re-read,** refuses even when
the configuration names this home.
  - **A main process that changes while it is checked** is refused.
- **Another install:** this home's daemon run by another install is
accepted through the real proof (a live child stands in as MainPID). A
non-hackd image is refused, and a hackd that has not bound its socket
gets the "may still be starting" message.
- The daemon, CLI-flow and process-proof tests pass. `bun run
typecheck`, `bun run check`, `bun run privacy:check` and gitleaks are
clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- codesmith:footer -->
---
<a
href="https://backend.blacksmith.sh/track/run-proof?expires=1797138818&installation_model_id=17053&pr_number=753&ref=codesmith_pr_footer&repository=hack-dance%2Fhack&return_to=https%3A%2F%2Fgithub.com%2Fhack-dance%2Fhack%2Fpull%2F753&variant=run_proof_on_this_pr&signature=171febd041ecee5b404652a33b2bf2bec0c74537f3578a96d5ed24993e087de9"><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/753?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>
Co-authored-by: Claude <noreply@anthropic.com>
roodboi added a commit that referenced this pull request Nov 14, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant