Commit Graph
10 Commits
Author SHA1 Message Date
wushenghua baeeb11356 fix: preserve deployed session fixes
Persist paged Codex history checkpoints and bounded, acknowledged delivery.
Keep usage sources and accounting across deleted or merged sessions.
Include native Goal controls, faster peer/session queries, and release guards.
Track the complete deployed source so isolated builds cannot omit local fixes.

Validation: all typechecks pass. The full suite reports 7,997 passing tests
and 46 existing failures, each reproduced against the prior commit.
2026-10-08 19:51:45 +08:00
wushenghua 8e1c4a80a1 docs(deploy): the keychain failure is session-scoped, not an ACL allow-list
Measured on this machine: from a Background session (a plain `ssh localhost` is
enough) `security show-keychain-info` already fails with "User interaction is
not allowed" (exit 36) and codesign returns errSecInternalComponent, while the
same command in Aqua reports the keychain unlocked and codesign succeeds. So the
key's ACL is not what blocks us - the session cannot reach the keychain at all -
and granting the key "allow all applications" would not help.

Correct the guidance in sign-build.sh and docs/local-deployment.md (both added
earlier today) accordingly: run the deploy from a Terminal window, or unlock the
keychain inside the Background session with the password
(`security unlock-keychain -p`, the CI-style recipe; the interactive form cannot
prompt there). Verified the failure path still prints the new text.
2026-09-18 01:55:29 +08:00
wushenghua f0ea0af94a docs(deploy): record the TCC cdhash trap and how to re-grant
A fixed path plus a pinned identity does not by itself keep TCC grants valid:
each grant stores a code requirement, and a grant created while the binary was
ad-hoc signed stays pinned to that build's cdhash. Replacing the binary at the
fixed path then matches nothing, and since a record exists macOS never prompts
again - it denies silently. Processes already running keep the cached allow
until macOS re-evaluates them, then lose ~/Documents mid-life; new processes are
unaffected. That is exactly how long-running sessions stopped answering with
"OpenCode service failure" / "getcwd: Operation not permitted" while fresh
sessions on the same machine worked.

AGENTS.md gets the short version; docs/local-deployment.md gets the csreq check
(identity-based vs cdhash), the normal re-grant through System Settings, and the
fallback used on mini on 2026-09-17 (delete the stale row, restart tccd, insert a
record copied from a machine with the same signing certificate), including the
row shape and the other two services that rot with it.
2026-09-18 01:51:01 +08:00
wushenghua 12193619d8 fix(deploy): correct the errSecInternalComponent advice
The previous revision told people to run 'security unlock-keychain' first, which
cannot work from launchd's Background domain: the command cannot prompt for the
passphrase there, and an unlocked keychain alone does not let a background
process read the private key. It also guessed the session up front from
`launchctl managername`, which flagged legitimate deploys (an SSH session that
unlocked first signs fine).

Detect nothing in advance: run codesign, and when it fails with
errSecInternalComponent / "User interaction is not allowed", print the two
remedies that actually work - run the deploy from a Terminal window on this
machine, or allow the signing key for all applications in Keychain Access.
Verified both paths with the pinned identity (real sign succeeds; a shim that
returns errSecInternalComponent prints the guidance and exits 1).

Also ignore .opencode/ (OpenCode's per-project scratch dir, ~60MB here).
2026-09-18 01:49:14 +08:00
wushenghua 66fa2d9a06 docs(deploy): warn when codesign runs outside a GUI session
codesign reads the private key from the login keychain, and only the Aqua
session can reach it: agents/daemons run in launchd's Background domain,
where codesign fails with errSecInternalComponent even while Keychain
Access shows the keychain unlocked. sign-build.sh now warns with the fix
(run from a Terminal window, or `security unlock-keychain` first), and
docs/local-deployment.md records the rule.
2026-09-18 01:45:43 +08:00
wushenghua bcfc69ed8c feat(deploy): install to the fixed path again (one TCC grant, verified rollback)
Versioned filenames fixed the per-path code-signature cache kill (exit 137)
but made macOS TCC treat every build as a new app: each deploy re-prompted for
Documents/media-library access, and while the prompt was unanswered every
process touching those folders (model probes, session startup) blocked -
visible as slow/timeout requests in the app.

Go back to the fixed path ~/.hapi/bin/hapi (a real file) so TCC asks once and
remembers it across deploys. Guard the signature-cache hazard with explicit
verification: back up the installed binary to ~/.hapi/bin/backups/, install
with a fresh mtime, prove it execs repeatedly (--version x3) plus
codesign --verify, restart the hub / kickstart the runner, and restore the
backup on any failure.

- deploy-local.sh / deploy-remote.sh: fixed-path install, verify, rollback
- prune-backups.sh replaces prune-versions.sh (keeps newest N backups, drops
  legacy versioned binaries)
- AGENTS.md, docs/local-deployment.md and the hapi-deploy skill updated
2026-09-17 09:38:08 +08:00
wushenghua 7221c8caed feat(deploy): add remote deploy over SSH with a shared signing step
- extract the pinned-identity signing into scripts/sign-build.sh so local and
  remote deploys ship the same stable signature (macOS TCC grants key on the
  signing identity, not the path)
- add scripts/deploy-remote.sh: signs locally, copies the binary to a new
  versioned file on the remote host, swaps the ~/.hapi/bin/hapi symlink,
  kicks the launchd job (default com.hapi.runner, override via
  HAPI_REMOTE_LAUNCHD_LABEL), and verifies the runner executes the new file;
  running sessions survive
- document the remote flow in AGENTS.md and docs/local-deployment.md
2026-09-16 18:29:42 +08:00
wushenghua d5bf8936a5 fix(deploy): refresh the runner on local deploys
The runner keeps its old machine RPC handlers and capability flags until
the process restarts: compiled binaries never self-update because the
heartbeat compares the mtime of the runner's own resolved exec path,
which is fixed for the life of the process.

- scripts/deploy-local.sh runs 'HAPI_CLI_EXECUTABLE=<stable symlink> hapi
  runner start' when a runner is running; skips when none; warns and
  exits 1 when the refresh fails (the hub deployment stays)
- AGENTS.md and docs/local-deployment.md document the runner refresh and
  the manual sequence step
2026-09-16 18:09:28 +08:00
wushenghua 80d7f04335 fix(deploy): pin a stable signing identity for local binary deploys
Ad-hoc signatures carry a cdhash-based TCC requirement that changes on
every build, so macOS treats each local binary as a new app and re-asks
protected permissions (Documents, Downloads, media library, ...) after
every deploy.

- add scripts/deploy-local.sh: pins one Apple Development identity
  (SHA-1 stored in ~/.hapi/signing-identity, override via
  HAPI_SIGN_IDENTITY), signs with identifier run.hapi.cli, copies to a
  new versioned file, repoints ~/.hapi/bin/hapi, restarts the hub, and
  rolls back when /health fails
- document the identity step and TCC rationale in AGENTS.md and
  docs/local-deployment.md; agent sessions must prune TCC-protected
  folders (~/Music, ~/Pictures, ~/Movies, ~/Library) from recursive
  $HOME sweeps
- drop the one-off scripts/deploy-local-capacity-retry.sh (ad-hoc)
2026-09-16 17:43:46 +08:00
wushenghua cb0dbd7d22 chore: rebase local deployment features onto hapi v0.30.3 2026-09-13 15:55:04 +08:00