Skip to content

fix(candidate): print commands for the launcher the user installed (HACK-2251) - #863

Merged
roodboi merged 11 commits into
nextfrom
fix/hack-2251-candidate-entrypoint
Nov 15, 2026
Merged

roodboi merged 11 commits into
nextfrom
fix/hack-2251-candidate-entrypoint

Conversation

@roodboi

@roodboi roodboi commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

What

With the prerelease installed the documented way, hack-next upgrade check printed candidate launcher: hack-v5 and told the user to run hack-v5 upgrade snapshot and so on. hack-v5 is a script inside the bundle and is not on PATH, so none of those commands ran when pasted.

Cause. On the native backend the channel manager runs the bundle's hack-v5 with HACK_CANDIDATE_ENTRYPOINT=hack-next (scripts/installer/channel.ts, environment()). scripts/hack-v5.sh then overwrote it with hack-v5 unconditionally. upgradeCommandPrefix would have mapped hack-next to ~/.hack-next/bin/hack-next, but it never saw that value. Compose runs bundle/hack-cli directly, so Compose output was already right.

flowchart LR
  U["user runs ~/.hack-next/bin/hack-next"] --> M["channel manager<br/>HACK_CANDIDATE_ENTRYPOINT=hack-next"]
  M -->|native| V["bundle/hack-v5<br/>keeps hack-next (was: overwrote with hack-v5)"]
  M -->|compose| C["bundle/hack-cli"]
  V --> C
  D["user runs a bundle's hack-v5 directly"] --> V2["bundle/hack-v5<br/>sets hack-v5"] --> C
  C --> R["printed commands name the launcher:<br/>hack-next path, or the bundle's hack-v5 path"]
Loading

Change

  • Entrypoint: scripts/hack-v5.sh keeps hack-next when the inherited value is exactly that, and sets hack-v5 otherwise. Only those two values reach the CLI.

  • One resolver: src/lib/candidate-launcher.ts gives the command for each install kind:

    Install kind Printed commands start with
    stable (no marker) hack
    hack-next ~/.hack-next/bin/hack-next as a full path; the selected bundle's hack-v5 only for a custom native home, which hack-next refuses
    a bundle's hack-v5 run directly that hack-v5 by full path, found next to the running hack-cli

    Paths are shell-quoted, and Compose runs keep the HACK_RUNTIME_BACKEND=compose prefix.

  • Every user-facing command text that was built from the entrypoint, or hard-coded hack, in these areas now uses it:

    • upgrade check: plan, next step, the "(apply)" line, "and N more", grouped steps, the env-layer refusal and the native-preflight hint;
    • upgrade apply: blocked-checkout, --project, unknown-project, rollback-overwrite and agent-migration texts;
    • native setup guidance and the setup-incomplete line;
    • the Compose-backend refusal and doctor hint, now "To run it there: HACK_RUNTIME_BACKEND=compose <launcher> up|restart";
    • the basic-build config import preview;
    • the self-update refusal, which names --manager upgrade for hack-next;
    • the manager's custom-home refusal, which names the selected bundle's hack-v5 by quoted path.
  • Unchanged on purpose:

    • src/daemon/client.ts isCandidateRun: any non-empty marker is still a candidate run.
    • The daemon autostart rule: hack-v5.sh still exports HACK_DAEMON_AUTOSTART_DISABLE=1.
    • The update refusal condition.
    • Help-text descriptions, code comments and lock-purpose labels that name an operation without telling the user to run it.
  • Docs:

    • candidate-install.md: new section "Printed commands name your launcher", and the custom-home path.
    • native-candidate.md: the setup blocker fix.
    • native/try-it.md (start page): the Compose refusal prints the runnable command.

Validation (Linux)

  • The new entrypoint test (each inherited value on both backends, autostart still 1) fails on next's hack-v5.sh: expected hack-next, received hack-v5.
  • The new upgrade-check tests run a native hack-next check, including a git checkout with an applicable step, a refused env layer and grouped steps. They assert that no bare hack (upgrade|native|doctor) command and no hack-v5 appears in the rendered text. They fail with next's renderer and with the old project hint.
  • tests/candidate-launcher.test.ts covers the resolver, prefixes, guidance, Compose and build hints, the update refusal and quoting. The installer test covers the quoted bundle path with a spaced root.
  • Affected files: 307 tests pass across 13 files, including tests/machine-output-contract.test.ts and tests/sync-spawn-bound.test.ts. No --json shape, CLI option or error code changed, so no generated reference needed regenerating.
  • Full suite at 1ea914e vs clean next 345dc0d on the same host: the failing-test sets are identical (803 unique host-environment failures, mostly native-compose state checks; none only on this branch), and this branch has 16 more passes.
  • Acceptance: the eight check:native-plan-cli scripts pass against dist/hack built at this head.
  • tsc -p packages/cli, bun run check, docs:check and biome pass.

Not verified

  • macOS and a real hack-next install: the lead checks on the Mac, with the next prerelease, that every command hack-next upgrade check prints runs when pasted.
  • The ninth acceptance script, check-release-config-compiler.ts, needs a locally built release compiler. This host has no C toolchain, so it was not run here; hosted CI's Config compiler job runs it. For the same reason, the full suite and acceptance scripts here used a config compiler built in another checkout with identical Rust inputs.
  • Linear HACK-2251 could not be read from this session (the connector is not authorized), so "tests as in the ticket" follows the lead's brief.

Release signal

fix: printed commands only. No change to candidate detection, autostart or the manager's upgrade behaviour.

Refs HACK-2251.

🤖 Generated with Claude Code


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

roodboi and others added 6 commits November 15, 2026 06:03
With the prerelease installed through hack-next, `hack-next upgrade check`
printed `hack-v5 ...` commands: the bundle entrypoint overwrote the
manager's HACK_CANDIDATE_ENTRYPOINT=hack-next with hack-v5, and hack-v5 is
not on PATH.

- scripts/hack-v5.sh keeps `hack-next` when the manager set exactly that
  and sets `hack-v5` otherwise.
- src/lib/candidate-launcher.ts resolves the runnable command per install
  kind: `hack`, ~/.hack-next/bin/hack-next, or the bundle's hack-v5 by
  path (next to the running hack-cli).
- upgrade check/apply, native setup guidance, the Compose-backend
  refusal and doctor hint, and the self-update refusal use it.

Candidate-run detection and the daemon autostart rule are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cs (HACK-2251)

- The bundle's resolved hack-v5 path rides on the hack-next launcher, so a
  fresh-native-home fix needs no second lookup.
- The channel manager's custom-home refusal names the selected bundle's
  hack-v5 by path.
- tests: the entrypoint keeps exactly hack-next and marks every other run
  hack-v5 (native and Compose, autostart still off); resolver, upgrade
  prefix, native setup guidance, Compose hint and update refusal per kind;
  the manager refusal names the bundle path.
- docs: candidate install gains "Printed commands name your launcher";
  native setup fixes and the start page say the printed command names
  the launcher.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…her (HACK-2251)

Review found suggestions that still sent candidate users to stable `hack`:
the upgrade check's "(apply)" line, the upgrade apply notes (`upgrade
check lists it`, `--only agent-integrations`, `upgrade rollback needs
--overwrite`), the project native-preflight hint, and the basic-build
`config import` preview. Each now renders through the report's
`cli.command` or the resolved launcher. The manager's custom-home refusal
quotes the bundle path as one shell word.

Tests: a native hack-next upgrade check prints no bare hack/hack-v5 command
in any hint (fails on the old renderer and project hint); apply notes and
the overwrite message carry the launcher; a spaced channel root is quoted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hints (HACK-2251)

Second review pass found bare `hack` suggestions in less common branches:
the "and N more" unchecked line, grouped manual plan steps, refused env
layer findings, the unknown-project apply refusal and the agent migration
outcome. Each renders through the report's launcher; the project checks
take a `CommandRenderer` (default `hack`). Hints that sit next to an
already-rendered doctor command now refer to it instead of repeating a
bare `hack doctor`.

Tests cover the env-layer refusal, the "and N more" line, a grouped manual
step and the unknown-project refusal with a hack-next launcher.

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

vercel Bot commented Nov 15, 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 15, 2026 9:25am UTC

Request Review

@linear-code

linear-code Bot commented Nov 15, 2026

Copy link
Copy Markdown

HACK-2251

@roodboi

roodboi commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 15, 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-15T09:27:06.898753Z d50c079 Manual request
🔒 Security Review ✅ Completed 2026-11-15T09:30:05.723288Z d50c079 Manual request
ℹ️ 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.

…te-entrypoint

# Conflicts:
#	src/commands/update.ts

@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: 1ea914ebd8

ℹ️ 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: 1ea914ebd8

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.

…mand (HACK-2251)

Codex review of #863: the printed `HACK_RUNTIME_BACKEND=compose <launcher>
up` dropped the project the refused command selected, so pasting it from
another directory found no project or the wrong one. The refusal now
prints `--path <project root>`, plus `--branch` when one was given, and
doctor's Compose and basic-build hints name the checked project's root.

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

roodboi commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: bd11385891

ℹ️ 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 (HACK-2251)

Review: `up --path /repos/app --env staging` printed a fallback without
`--env staging`, so pasting it would start the default overlay. The
fallback now carries the refused command's explicit --env next to --path
and --branch. A CLI regression covers `up --env dev`.

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

roodboi commented Nov 15, 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: e2bab57a2d

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

Comment thread src/lib/candidate-launcher.ts Resolved
The privacy check flags a home-shaped path in a test fixture string.

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

roodboi commented Nov 15, 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: 01bf2537b4

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

…t (HACK-2251)

Codex review of #863: a `--root` install lives outside ~/.hack-next, but
the resolver always printed $HOME/.hack-next/bin/hack-next. The manager
runs <root>/versions/<v>/bundle/hack-cli on both backends, so the root
now comes from the running executable: its bin/hack-next when that file
exists, the default root only otherwise (a source run).

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

roodboi commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: d50c0798ce

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

@roodboi

roodboi commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

Ready for lead: head d50c0798cef8cc453fe68d7dfd2f15e3a7bbecdb (contains next 34b5053 via a normal merge; the only conflict was the import block in src/commands/update.ts).

What it does

  • scripts/hack-v5.sh keeps the manager's hack-next marker and sets hack-v5 otherwise.
  • Every printed command in upgrade check/apply, native setup, the Compose fallback and doctor hints, the self-update refusal and the manager's custom-home refusal names a runnable launcher: hack, the channel's <root>/bin/hack-next (from the running bundle; ~/.hack-next by default), or the bundle's hack-v5 by path.
  • The Compose fallback keeps the refused command's --path <project root>, --branch and --env.
  • Candidate-run detection and the autostart rule are unchanged.
  • Side effect: feat(update): report available updates read-only for any install kind (HACK-2218 R14) #860's update --check --json --observe upgrade_command for candidates becomes reachable on native, because the marker now survives.

Ran (Linux)

  • Affected files at this head: 13 files, 323 tests pass, including tests/machine-output-contract.test.ts, tests/sync-spawn-bound.test.ts and tests/update-observe.test.ts.
  • Each fixed branch has a hack-next regression that fails on the old code; the entrypoint test fails on next's hack-v5.sh.
  • Full suite at 1ea914e vs clean next 345dc0d on this host: identical failing sets (803 unique host-environment failures, none only on this branch), plus 16 more passes. Not repeated at this head; the targeted files above cover every change since.
  • Acceptance: the eight check:native-plan-cli scripts pass against dist/hack built at this head.
  • Generated files: the CLI reference and the machine-output reference regenerate with no diff. No error codes or lifecycle state changed, so the error-code reference and the TLA coverage doc are not affected.
  • tsc -p packages/cli, bun run check (including privacy:check) and docs:check pass.
  • Session Codex reviewer (gpt-6.1-sol, same thread as earlier units): CLEAN at d50c079 after five finding rounds (bare-command branches, the --path/--env selector, quoting, custom root).
  • Codex bot: two findings, both fixed, replied to and resolved; no major issues at d50c079. computer pr review-status: CLEAR at d50c079.

Not waited for / not verified

  • Hosted CI run 43699137894 at this head was queued when this was posted (macOS and Linux jobs). Earlier heads passed the light checks, and 02c7be0's shard 8/8 failure was the privacy check, fixed in 01bf253.
  • The ninth acceptance script, check-release-config-compiler.ts, needs a locally built release compiler. This host has no C toolchain (cc/ld missing, owner install pending), so it is not run here; hosted Config compiler covers it. For the same reason, local runs used a config compiler built in another checkout with identical Rust inputs.
  • macOS and a real hack-next install: your Mac check that every command hack-next upgrade check prints runs when pasted.
  • Linear HACK-2251 was not readable from this session (the connector is not authorized), so the tests follow your brief.

@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: d50c0798ce

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 15, 2026

Copy link
Copy Markdown
Contributor Author

Update to the ready note: hosted CI run 43699137894 at d50c0798cef8cc453fe68d7dfd2f15e3a7bbecdb completed with success on every job that ran, including the macOS test shards, Candidate core and Config compiler (which covers the ninth acceptance script). No change to the head.

@roodboi
roodboi merged commit cad6568 into next Nov 15, 2026
30 checks passed
@roodboi
roodboi deleted the fix/hack-2251-candidate-entrypoint branch November 15, 2026 14:07
roodboi added a commit that referenced this pull request Nov 15, 2026
…econcile

Brings in next at 081a526 (#811 supervisor opt-in runner, #863 candidate launcher names HACK-2251, #808 desktop Logs tab). No conflicts. The CLI reference, machine-output table and error-code reference regenerate unchanged; E_DAEMON_SERVICE kept.

#863 changes which launcher printed commands name and the candidate update refusal; it does not change the executing-CLI identity, the service program checks, durability or the post-update binding, and a candidate install is still refused before any install or reconcile. #811's supervisor reads process identities through process-tree.ts and runs its own sibling binary; it does not use this PR's ps/lsof helpers, process-ancestry or the orphan sweep.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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