Skip to content

Harden runtime integrity and diagnostics#64

Merged
roodboi merged 6 commits into
mainfrom
fix/runtime-integrity-foundations
Jul 10, 2026
Merged

Harden runtime integrity and diagnostics#64
roodboi merged 6 commits into
mainfrom
fix/runtime-integrity-foundations

Conversation

@roodboi

@roodboi roodboi commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What changed

This PR hardens Hack's local runtime behavior across linked worktrees, lifecycle sessions, dependency bootstrap, targeted service operations, diagnostics, and generated agent guidance.

Runtime integrity

  • Resolve project env keys through the Git common directory so linked worktrees inherit the same encryption state.
  • Pass the selected overlay's resolved host view into lifecycle hooks and processes.
  • Preserve env precedence by source layer: base → named overlay → local base → local overlay, with host/service specificity inside each layer.
  • Warn when a worktree silently retargets from an already-running instance to a new auto-derived branch instance.
  • Bound detached Compose startup and state inspection; terminate the subprocess group and return E_STARTUP_TIMEOUT instead of hanging forever.
  • Treat running services and successful one-shot containers as success; return E_STARTUP_INCOMPLETE when Compose exits zero but services remain Created/failed or no services are reported.
  • Persist lifecycle ownership before mux-session creation so a SIGKILLed restart can be adopted or replaced safely by the next hack up.
  • Preserve the healthy runtime during full restart, force-recreate on the up phase, and attempt bounded repair after a failed recreation.
  • Add doctor --fix repair for exact containers stuck in Created without deleting them.

Generic dependency and service operations

  • Detect dependency bootstrap services from their command or hack.dependencies.bootstrap=true, without assuming a service named deps.
  • Preflight registry env references from npm/yarn/Bun configuration before mutating containers.
  • Add opt-in lockfile/runtime-keyed dependency volumes that compatible worktrees can share.
  • Add service-scoped hack up <service...> -d, hack restart <service...>, and hack env apply --service <service>; scoped operations skip project lifecycle and implicit dependency startup.
  • Add redacted hack env explain <KEY> --env ... --service ... --target host|compose output showing availability, source, precedence, scope, and delivery.

Doctor, global state, and agents

  • Make read-only config/status paths avoid the global project-registry lock.
  • Separate Doctor output into Dependencies, Global runtime & agents, Resolver & DNS, Project & env, and Sessions.
  • Hide missing optional tools and healthy macOS setup tips from the summary.
  • Name exact orphan/incomplete projects and emit a project-scoped cleanup command such as hack projects prune --project msp.
  • Add --project filtering to prune so cleanup cannot affect unrelated project families.
  • Audit and repair global agent guidance even outside a project, including when Docker is unavailable.
  • Add content-revision freshness markers, setup sync --all-scopes --check, shared ~/.ai/skills/hack-cli management, and explicit reload guidance for cached sessions.
  • Remove Hack Tickets from generated rules/skills and Doctor; retain deprecated compatibility commands with cleanup of recognized legacy artifacts.
  • Reject doctor --fix --json as a usage error instead of silently ignoring the mutating flag.

Why

The prior behavior could leave a command hanging at “Starting”, report success while no service was running, lose lifecycle ownership after interruption, reinstall dependencies unnecessarily, or target a new branch stack without enough warning. Agent sessions could also keep stale Hack rules indefinitely, while Doctor mixed optional setup tips with actual repair work and suggested machine-wide cleanup for project-local drift.

User impact

New worktrees should inherit usable env state, selected overlays now reach host lifecycle processes predictably, interrupted startup has a safe recovery path, targeted changes avoid full-stack churn, and Doctor now reports concise scope-aware actions. Global and project agent integrations expose content staleness up front and have a supported refresh path.

Verification

  • bun test — full suite passes.
  • bunx tsc -p packages/cli/tsconfig.json --noEmit.
  • bun run build.
  • Ultracite checks pass for every changed TypeScript file.
  • TLC model check for startup transaction invariants: 30 generated states, 22 distinct, no errors.
  • Isolated lifecycle-session-recovery E2E passes, including overlay propagation, branch isolation, compose failure, SIGTERM cleanup, deliberate SIGKILL, next-up recovery, and Doctor cleanup.
  • Live built-CLI verification against MSP:
    • global runtime/agent checks: ok
    • resolver/DNS: ok
    • sessions: ok
    • one existing MSP orphan is named with the scoped command hack projects prune --project msp
  • Current project/global integration sync check passes.

Follow-up / operator note

The existing orphan msp--feat-apple-pay-merchant-sessions-endpoint was intentionally not pruned while other sessions are active. This PR makes the repair command safely project-scoped; cleanup can be run deliberately after review.

@roodboi roodboi marked this pull request as ready for review July 10, 2026 02:08
@blacksmith-sh

This comment has been minimized.

@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: 284df182ac

ℹ️ 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/shell.ts
Comment thread src/lib/compose-startup-state.ts Outdated
Comment thread src/commands/project.ts Outdated

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

ℹ️ 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/commands/project.ts Outdated
Comment thread src/lib/project-env-config.ts Outdated
@roodboi roodboi merged commit 498e9c3 into main Jul 10, 2026
5 checks passed
@roodboi roodboi deleted the fix/runtime-integrity-foundations branch July 10, 2026 02:45

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

ℹ️ 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 on lines +294 to +295
removeTicketsSkill({ scope: "project", projectRoot: opts.projectRoot }),
removeTicketsSkill({ scope: "user" }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid deleting unrecognized hack-tickets skills

When a project or user already has a .codex/skills/hack-tickets directory whose SKILL.md is not the Hack-owned skill, checkDeprecatedTicketsSkill reports that as an error, but auto-sync still calls removeTicketsSkill; that remover deletes the directory without verifying the marker. In the default auto-sync mode this can be triggered by any normal Hack command after drift is detected, erasing an unrelated user skill instead of leaving the error for manual review.

Useful? React with 👍 / 👎.

Comment thread src/commands/env.ts
Comment on lines +1150 to +1155
const usesHost = opts.target === "host" && hostValue !== undefined;
let effectiveScope: string | null = null;
let storedValue: unknown;
if (usesHost) {
effectiveScope = "host";
storedValue = hostValue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use resolved env precedence in env explain

When --target host is used and a lower-priority host scope defines the key, this branch reports host as the effective source even if a later overlay/global or service value is what the runtime actually injects via hostTargetEnv/selectProjectEnvValuesForExecutionTarget. That makes hack env explain show the wrong source and secret status for layered overrides, so the explanation should be derived from the same resolved host/compose env map and precedence used for execution.

Useful? React with 👍 / 👎.

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