Repository navigation
Conversation
Add a data-only matrix (src/agents/client-capabilities.ts) that classifies packaging, skill discovery, hooks, plugin MCP, standalone MCP, rules and UI for Codex, Claude Code, Cursor and standalone consumers. Each cell records status, evidence class, evidence ref, observed client version, source SHA and host label. The rendered reference doc carries companion-package layout and model-policy ownership decisions. Tests enforce that every cell is classified, verified cells cite an existing fixture-strength test, manifest or listing evidence never verifies loading, and manifest-declared components agree with the matrix. The plugin generation test gains a negative-controlled scan of plugins/hack and examples/basic for model, permission and output-style settings and non-primer hooks, plus a skill inventory check against the generator and docs/integrations.md, which now names all four shipped skills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hack.project.run built `run <flags> <service> <cmd...>`, so hack's own
parser consumed child flags: `node --version` printed hack's version and
`--branch other` retargeted the instance. Run now emits
`run <flags> -- <service> <cmd...>` and every option value is fused as
`--opt=value` across all tools.
- Validate service, services, branch, profiles, logs service and open
target against a compose-identifier pattern (no leading '-', no empty
value; branches may also contain '/').
- tail, maxEvents, maxMs and timeoutMs are positive integers with hard
ceilings (provisional F27 settings); effective limits are echoed in
data.limits.
- Every tool carries annotations (readOnly for list/status/logs/open,
destructive for down/run/init, openWorld false).
- Refusals return error{code, message} with existing codes (E_USAGE,
E_PROJECT_NOT_FOUND) and spawned:false. A typed tools/call dispatcher
validates before any handler runs, so refused calls leave no argv
entry and no audit line.
- Children spawn with HACK_NO_INTERACTIVE=1 on a copy of the frozen
session env.
Refs HACK-1133, HACK-1134
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Legacy project env key reads (checkout-local, shared common-dir and inherited primary keys) now use the same lstat, O_NOFOLLOW, size-bound and stable-descriptor discipline as the native reader, extracted into src/lib/private-file.ts. Key priority is unchanged. A symlinked, dangling, oversized or non-regular key file is refused with a fixed message. New key files are created with open(O_CREAT|O_EXCL|O_NOFOLLOW|O_WRONLY, 0600), fchmod 0600 and fsync, so an existing entry or dangling symlink is never followed or replaced. A concurrent creator's key is adopted. Encryption (env add --secret and the legacy migration) refuses a git-tracked selected or inherited key with a fixed, value-free message before any key copy. Decryption with a tracked key stays allowed for v4 compatibility. Legacy v1 values and the encrypted_file store now require canonical base64, a 12-byte IV, a 16-byte tag (authTagLength pinned) and a bounded ciphertext; all parse, tamper and wrong-key failures use fixed redacted errors. The envelope format, key derivation and v1 decryptability are unchanged. Refs HACK-1127 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nfig Address verifier findings on the agent-client capability matrix: - Move the matrix renderer into scripts/generate-agent-client-capabilities.ts and add `bun run docs:agent-client-capabilities` (with `--check`), which rewrites only the generated section. The test compares the committed section with the rendered one and covers marker failures with closed codes. - Scope the model/permission policy scan to generated guidance surfaces (plugins/hack, .claude-plugin, .cursor-plugin, .agents through its skill symlinks, and the example agent configuration) instead of example compose files. Parse YAML and markdown frontmatter as YAML, fail closed on structured-config formats the scan cannot parse, and count a file as scanned only when it was parsed. - Treat reasoning-effort keys (reasoning_effort, model_reasoning_effort, frontmatter `effort`, nested effort/reasoning keys) as forbidden model settings, with negative controls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every pre-spawn refusal now comes from a closed catalogue (MCP_REFUSALS):
error {code, reason, message} uses an existing code, a closed reason and a
fixed message, and stderr repeats that message. Project names, ids, paths
and registry values are no longer echoed. Schema refusals name only keys
of the tool's own input schema.
An unknown tool name returns the SDK's in-band isError text result again
instead of a JSON-RPC -32602 protocol error, with a fixed message that
omits the requested name.
A canary test drives every refusal reason and the unknown-tool path and
asserts the canary never appears in the result, with no spawn or audit line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ting tests Seal authentic envelopes with 8- and 16-byte IVs and with ciphertext one byte over each parser bound, so only the parser guards can refuse them, and assert through a createDecipheriv spy that structural refusals happen before any decipher and that successful opens pass authTagLength 16. Covers the legacy project env, encrypted_file store and native env value parsers, with at-bound 12-byte-IV controls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Interactive `hack init` now prints a non-mutating note that points at the optional Hack plugin and `hack agent onboard`. Repository-local export of Cursor rules, Claude hooks, Codex skills, AGENTS.md/CLAUDE.md sections and project MCP config is a separate opt-in whose confirm defaults to no and whose target list starts empty. The decision moves out of project.ts into src/agents/init-agent-integrations.ts. Doctor and the agent-prime freshness inventory now treat absent optional integrations as current. Doctor flags a path only when it exists and lacks the current revision marker (AGENTS.md/CLAUDE.md only when they carry a Hack-managed section). integration-sync counts only stale or errored checks; user-owned docs without a Hack section are not drift; retired legacy artifacts still are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
config plan and config validate only treated the literal "base" as the base selection, so `--env default` (and DEFAULT/none) reached the native compiler as an overlay named "default" while env get, env list and the runtime commands selected base layers. Every CLI command that accepts --env now resolves it through one shared resolver (src/cli/env-selection.ts): omitted keeps the configured default overlay, base/default/none in any case select base layers, other names are normalized, and a non-empty value with no usable name characters is refused with the fixed "Invalid --env value." usage error instead of silently selecting base. Authored native dispatch uses the same resolver, and session workspace names stay env-base. docs/env.md gains a command and delivery matrix with one row per CLI_SPEC command that accepts --env; tests/env-command-matrix.test.ts keeps the rows and selector flags in sync with CLI_SPEC. The canonical agent guidance gains an env-composition section linking to the matrix; the content revision, plugin bundle, repository examples and CLI reference are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address the W10 verifier findings so integration sync and doctor agree: - checkAgentDocs marks a doc `unmanaged` only when it has neither the Hack start nor end marker. A doc with exactly one marker is a corrupted managed section and now reports a malformed-marker error, which sync counts as drift. Doctor treats the same doc as stale. - Add readOptionalTextFile, which uses lstat before reading so callers can tell "absent" from "present but unreadable". The Cursor rules, Codex skill, shared skill, hack-init skill and agent-doc checks now report an unreadable existing file as `error` (drift) instead of `missing` (optional, current). Doctor uses the same helper. - Add regression tests for start-only and end-only docs, plus mode-000 Hack-owned files and docs in fixture HOME/project roots, for both sync and doctor. Default `hack init` still writes no repository files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The env add --secret refusal tests asserted the refusal text on stderr, but the default logger backend depends on the host: gum (stderr) when installed, clack (stdout) otherwise. Hosted macOS runners have no gum, so the refusal reached stdout and stderr was empty only in CI. Pin HACK_LOGGER=console in the CLI helper, matching the other CLI-spawning tests, so the stderr assertions hold on every host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The project-name boundary suite still expected the old value-echoing "Ambiguous project name/ID" stderr from MCP. Assert the closed MCP_REFUSALS contract instead: exact code, reason and fixed message, spawned: false, no argv, and none of the duplicated names, registry ids or fixture root anywhere in the serialized result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Temporary measurement only; reverted before the final commit. Writes closed labels and durations per native command to a per-scenario JSONL file and prints a summary in the docker-e2e job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A storage-bearing saved exec ran three full witness proofs (nine helper carriers) and a warm up/restart seven. Within one command and one mutation lease, an adjacent repeat with only read-only checks between it and the previous proof now reuses that completed kernel proof instead of three new helper carriers: - saved exec: the pre-spawn check reuses the preparation proof; the proof after the process stays fresh (3 -> 2 proofs); - up/restart without build, routing or file material: the first pre-spawn guard reuses the enrollment proof (warm 7 -> 6, cold seed path 6 -> 5). Reuse requires the same lease authority, engine, generation and reference and a byte-identical opening material binding to the one that opened and closed the recorded proof. Every host check (anchors, expectation, completion, binding, carrier artifact and lifetime) still runs; any verification consumes the record first, so a failure or binding change forces a fresh proof. Ordinary verification always proves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reverts the hosted measurement commit (closed-label cost trace, phase-trace routing, per-scenario summary step and artifact) now that the per-phase and per-call attribution is recorded in the pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The networks scenario took 3409 s on next with three proofs per storage exec and ran 2275 s on the hosted engine with the coalesced proofs, so the 80 min budget raise from the witness recovery change returns to 60 min. The budget bounds a hung engine; no assertion or command deadline changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Storage witness proofs keep every fence; three exact costs are cut: - Engine-ID fences: for an explicit DOCKER_HOST=unix:///... selection, the first fence of a command under one exact binding (selection, docker executable, client config and socket identities) still uses `docker info` and must equal one direct GET /info on that socket; only then do later fences under that unchanged binding each make one fresh direct request instead of a CLI process that lists every client plugin. A refused admission keeps the CLI, a moved binding re-admits through the CLI, and an admitted direct failure refuses without fallback. Two exact back-to-back ID reads with nothing between them are collapsed (holder observation into carrier inspect; provision fence into the target observation). - Recorded command executables: the content digest is cached for one command by canonical path and complete stat identity (dev, ino, size, mtime and ctime in ns, mode, uid); every identity check still runs, any change re-reads, and racily fresh files are never cached. - Target observations: the witness's closing re-observation of a deferred-finish verify invocation is answered by the carrier's own closing observation of the same query when the rechecked material binding is unchanged and only reads ran between (one observation per proof). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Temporary measurement only; reverted before the final commit. Re-applies the X01 closed-label trace (reverting eb9a678) and adds point events for direct engine-ID reads and admissions, cached executable digests, target observations and reused closing observations, plus a shard 1 identity fence benchmark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An admitted direct engine-ID read that fails because the caller cancelled or its probe deadline expired now reports the CLI probe's existing closed cancel/timeout classification; that probe refuses before spawning anything. Every other admitted direct failure still refuses without CLI fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Per command on the synthetic engine: 81 of 86 engine-ID fences and 20 of 21 target observations per proof, with every proof kept; an admitted explicit Unix selection uses one CLI fence per command. - A changed daemon ID between two admitted fences refuses before any helper, workload or state change; a refused admission keeps every fence on the CLI. - A target change right after the verify carrier's closing observation is refused by the next remaining observation. - Admission, re-admission, no-fallback and cancellation controls on a real Unix server; executable digest reuse, replacement, same-size tamper, mode, racy-fresh and mid-command replacement controls. - Reference docs describe the three cuts and their limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measurement is complete; the hosted trace run was 38211327829. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… catalogue Plugin skills can now ship references at skills/<skill>/references/*.md from a typed registry (src/agents/skill-references.ts). The generator writes each reference with a recomputable content revision, removes stale ones, and links them from the plugin SKILL.md. Standalone hack-cli installs ship no references, so their render (and ownership fingerprint) is unchanged. The first reference is the hack-cli pattern catalogue, rendered from the typed register of all twelve HACK-P cards with dispositions, owners, missing contracts and value-free provenance. Tests check completeness, CLI_SPEC command resolution, a banned-recipe scan outside negative-example blocks, and an offline link contract over every packaged skill markdown file. External URLs in hack-install and hack-remote move under "Further reading". docs/agent-guidance.md records the reference contract and the promote/defer decision for the lifecycle, cleanup, checks, sessions, hack-run and hack-feedback skill candidates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seed an isolated HOME with sentinel Claude, Codex, Cursor and shared-skill config (including stale hack-cli copies) and two fixtures with customized AGENTS.md, CLAUDE.md, rules, skill copies, settings.local.json and .mcp.json. Run init --auto, init --auto --with codex, agent prime, agent prime --check, agent onboard, agent patterns, doctor --json, doctor --fix --no-interactive and setup sync --check twice each with HOME and HACK_HOME overridden, and require byte-identical hashes, no new client entries, git status changes only under .hack/, and each command's expected exit code. An explicit setup agents --agents-md is the positive control and must change exactly AGENTS.md. Docker is pointed at a missing socket and Mutagen at a stub so doctor --fix stays free of Docker and network effects; the hackd it starts is stopped. The scenario is registered in ALL_SCENARIOS and shard.ts places it in exactly one docker-e2e shard via the default duration hint. Refs: HACK-1124, HACK-1132, HACK-1155 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HACK-1211 needs a matched, bounded way to reproduce the intermittent Bun crash and a repeatable record of crashes per hosted run. This adds the instruments only; it changes no test, timeout, assertion or pin. - bun-crash-experiment.yml runs only on workflow_dispatch or when the bun-crash-experiment label is added to a pull request. A labeled pull request runs the matched pair (1.3.9 baseline, 1.4.2 candidate) on its head; a dispatch runs one version at a chosen revision. It uses blacksmith-6vcpu-macos-15, contents: read, and timeout = budget + 15. The instrument comes from the workflow's commit, so older revisions can be measured. - scripts/bun-crash-loop.ts alternates the native HTTPS owner test with the full bun test. It never starts an iteration whose estimate (its initial guess or longest observed run) ends past the budget, and records a run still going at the deadline as overrun, not a crash. It writes a closed summary and keeps logs plus bun*.ips reports for a 7-day artifact. It never opens crash-report links. - scripts/ci-bun-crash-census.ts reads every attempt's test job through the caller's gh, downloads only failed-job logs into an owned temp dir that it removes, and prints per-version counts and crashing ids only. - Both use scripts/lib/bun-crash-classify.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions Storage-witness engine-ID admissions now resolve the Docker CLI's endpoint selection the way the CLI does: a nonempty DOCKER_HOST, then DOCKER_CONTEXT, then the client config's currentContext, then the default context at unix:///var/run/docker.sock. A named context is read from its contexts/meta/<sha256>/meta.json through a no-follow binding; only a plain unix:/// docker endpoint with no TLS option, no unknown or duplicate field and no entry at the context's TLS path is eligible. TLS material is checked for absence by name and never opened. Missing, malformed, linked, TCP, SSH, TLS or header-bearing contexts, and DOCKER_HOST with DOCKER_CONTEXT, keep the CLI. Admission is unchanged: the first fence under a binding is the CLI read and must equal one direct GET /info on the resolved socket. The binding now also pins the context store entry and the absent TLS path, so a changed config, context entry, socket or executable is admitted through the CLI again. The ingress and VM-file observers, trusted without a CLI comparison, still accept only an explicit Unix DOCKER_HOST. Tests that run commands against a synthetic docker now pin an isolated client config naming a missing context, so they never read the contributor's Docker config or dial a real engine socket. A new opt-in test (HACK_TEST_DOCKER_CLI=1, run on docker-e2e shard 4) runs the real Docker CLI against two fake Unix engines for every selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Temporary measurement only; reverted before the final commit. Re-applies the X03 closed-label trace (6a4e118) without its identity benchmark, labels each engine-ID admission with its selection kind (host, default or context), counts direct reads as trace leaves, and prints the runner's Docker client selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measurement is complete; the hosted trace run was 38225752202. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picks up the re-parent onto next; no content change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the queued PRs squashed in. next's tree equals train/queue-preview 77da332, which this branch already contains, so the branch tree is kept unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. Git auto-merged the only shared file: - docs/env.md: kept both sides' text (the env key doctor notes from this branch and the private env file and encrypted_file store notes from wf/y3-envfile-b6). No generated files changed: neither branch alters CLI options or rendered agent guidance, so plugins, docs/reference/cli.md, integration-revision.ts and KNOWN_RENDER_FINGERPRINTS needed no update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. The merge applied cleanly; the two change sets touch disjoint files. Regenerated plugins (generate:agent-plugins) and docs/reference/cli.md (docs:cli-reference) after the merge; both produced no changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. The merge was clean; the two change sets touch disjoint files. Regenerated agent plugins and docs/reference/cli.md produced no diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stack PR #301 on PR #307. The merge had no textual conflicts. Git auto-merged docs/env.md, tests/e2e/run.ts and tests/e2e/shard.ts; each keeps both sides (stale env warning plus env key/private file docs; both exec-stale-env and compose-config-hash-drift scenarios and hints). Regenerated plugins and docs/reference/cli.md produced no drift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. The two change sets touch disjoint files, so git merged them automatically. Generated surfaces (plugin bundle, CLI reference, checked-in renders) were regenerated after the merge and showed no drift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. The plain merge applied cleanly. Regenerated surfaces (generate:agent-plugins, docs:cli-reference) produced no changes, so integration-revision.ts and KNOWN_RENDER_FINGERPRINTS are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files: none. Git merged both sides cleanly; docs/env.md and src/lib/project-env-config.ts were changed by both branches and auto-merged with both sides' content kept. Generated files: bun run generate:agent-plugins and bun run docs:cli-reference produced no changes. The checked-in renders (.codex/skills/hack-cli, .codex/skills/hack-init, .claude/skills/hack-init, .cursor/rules/hack.mdc, examples/basic AGENTS.md and CLAUDE.md) are byte-equal to their install/render functions run against a temp project root. integration-revision.ts and KNOWN_RENDER_FINGERPRINTS keep the wf/c1-stdin-b7 values; wf/y2-mcptools-b6 did not change guidance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicted files and resolutions: - docs/agent-guidance.md: kept both paragraphs; the pattern-example paragraph from wf/c1-stdin-b7 follows the catalogue checks, then the focused-skills paragraph from wf/w08-b6. - src/agents/integration-ownership.ts: KNOWN_RENDER_FINGERPRINTS is the append-only union of both sides, plus the combined renders that tests/integration-ownership.test.ts requested (hack-cli-skill 680a52ef6737d979ed2d384b, cursor-rules afa91b84e719bd416b9dfea3). - src/agents/integration-revision.ts: set to 9f26e5752230, the value tests/agent-instruction-source.test.ts computes for the merged source. - plugins/hack/rules/hack.mdc, plugins/hack/skills/hack-cli/SKILL.md: regenerated with bun run generate:agent-plugins. - .codex/skills/hack-cli/SKILL.md, .cursor/rules/hack.mdc, examples/basic/AGENTS.md, examples/basic/CLAUDE.md: re-rendered through installCodexSkill, installCursorRules and upsertAgentDocs with explicit project roots; byte-equal to the renderers (hack-init skills unchanged). src/agents/instruction-source.ts merged cleanly; docs/reference/cli.md regenerates unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stack PR #305 (skills-only hack plugin + opt-in hack-mcp) on PR #303 (focused hack-branches/hack-env/hack-diagnose plugin skills). Conflicted files and resolution: - src/agents/integration-revision.ts: set to 5c5c3c9fffea, the value tests/agent-instruction-source.test.ts computes for the merged sections. - src/agents/integration-ownership.ts: KNOWN_RENDER_FINGERPRINTS is the append-only union of both sides, plus eba974f66328605864507beb (hack-cli-skill) and 270cd2b3fdcc325e04c76d43 (cursor-rules) that tests/integration-ownership.test.ts asked for after the merge. - docs/agent-guidance.md: kept W08's focused-skills.ts and error-code-reference.ts rows; the generator row keeps W09's skills-only hack plus hack-mcp wording with W08's seven-skill count. - docs/integrations.md: kept W09's plugin-first section and hack/hack-mcp table; the hack row lists W08's seven skills, W08's focused-skill routing sentence follows the table, and post-install verification uses W09's wording with "seven skills". - plugins/hack/README.md (hand-written): kept W09's removal of the Codex "disable bundled MCP" TOML advice and its hack-mcp verification text, with W08's "seven plugin skills" count. - plugins/hack/rules/hack.mdc, plugins/hack/skills/hack-cli/SKILL.md: regenerated with bun run generate:agent-plugins (focused skill renders also refreshed for the new revision). - .codex/skills/hack-cli/SKILL.md, .cursor/rules/hack.mdc, examples/basic/AGENTS.md, examples/basic/CLAUDE.md: re-rendered through installCodexSkill, installCursorRules, installHackInitSkill and upsertAgentDocs with an explicit project root; byte-equal to renderers. - docs/reference/agent-client-capabilities.md: regenerated with bun run docs:agent-client-capabilities. docs/reference/cli.md was regenerated with bun run docs:cli-reference (no change). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
roodboi
added a commit
that referenced
this pull request
Oct 12, 2026
Stack PR #310 (refresh-only setup sync) on PR #305 (plugin-first agent setup, hack-mcp split). Conflicts and resolutions: - src/agents/integration-revision.ts: set to 5108f34edd26, the value tests/agent-instruction-source.test.ts computes for the merged guidance. - src/agents/integration-ownership.ts: KNOWN_RENDER_FINGERPRINTS is the append-only union of both sides, plus the merged renders the ownership test asked for (hack-cli-skill cf91ca873a00ad4743198e11, cursor-rules 92ca4aa8f28ba1c93093c04a). - plugins/hack/rules/hack.mdc, plugins/hack/skills/hack-cli/SKILL.md: regenerated with bun run generate:agent-plugins (second run is a no-op). - .codex/skills/hack-cli/SKILL.md, .cursor/rules/hack.mdc, examples/basic/AGENTS.md, examples/basic/CLAUDE.md: re-rendered with the project-scoped installers and an explicit project root; byte-equal to the renderers (.codex/.claude hack-init skills already current). - docs/reference/cli.md: regenerated with bun run docs:cli-reference (auto-merged; regenerated output unchanged). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
#308 makes --env require a canonical overlay name instead of slugging input, so ' QA ' is now refused before any project work. Keep the native dispatch case on the documented path with ' qa ' (still exercises trimming); the refusal itself is covered by the env argument redaction tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picks up the native env selection test update from #308. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picks up the native env selection test update from #308. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the previous stacked PR squashed in; next's tree equals 6ecf485, which this branch already contains, so the branch tree is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HACK-1132 (W09). The default
hackplugin is now skills-only. MCP moves to a separate, opt-inhack-mcpplugin that the generator emits from one MCP source.Final behavior
plugins/hack: the.claude-plugin,.codex-plugin,.cursor-pluginand portableplugin.jsonmanifests declare nomcpServers. The package ships no.mcp.jsonand nomcp.json. It keeps the four skills, Claude primer hooks and the Cursor rule. The Codex interface no longer lists "MCP tools". Plugin name and id stayhack.scripts/generate-agent-plugins.ts:mcpServers..mcp.jsonandmcp.jsonfiles fromplugins/hack.plugins/hack-mcppackage: Codex, Claude and Cursor manifests, portableplugin.json,.mcp.json, portablemcp.json(explicit stdio) and a README. The server entry comes only fromHACK_MCP_SERVER(hack mcp serve)..claude-plugin/marketplace.json,.agents/plugins/marketplace.jsonand.cursor-plugin/marketplace.jsonlisthackandhack-mcpas separate entries..releaserc.jsoncommitsplugins/hack-mcp.prepare-release.tsalready runs the generator after the version bump, so both packages get the release version.instruction-sourceagent-setup):hackplugin is the default.hack-mcporhack setup mcp).hack setup cursor|claude|codex|agentsis an opt-in export.444f2cb158b2. New fingerprints are appended toKNOWN_RENDER_FINGERPRINTSfor hack-cli-skill, hack-init-skill and cursor-rules./hack-initskill: the MCP prompt fallback applies only whenhack-mcpor another Hack MCP server is installed. Otherwise the skill reports the blocker.hack-installskill: now says MCP comes from the opt-inhack-mcpplugin.README.md: removes "sync themselves into AGENTS.md/CLAUDE.md" and moves the plugin into the agent paragraph and the quick start.docs/integrations.md: covers plugin-first setup, skills-onlyhackvshack-mcp,.mcp.jsonauto-discovery (plugin root and project root), one integration path per client, and an upgrade note.docs/guides/agent-first-setup.md:/hack-initnow comes from the plugin, not fromhack setup claude|codex.plugins/hack/README.md: the Codex TOML "disable bundled MCP" advice is replaced with "installhack-mcponly when MCP is wanted".docs/agent-guidance.mdis updated to match.hackmanifest and thehack-mcpmanifest.pluginMcpcells point atplugins/hack-mcp/.mcp.jsonandplugins/hack-mcp/mcp.json.skills-package-declares-mcpissue code.Migration
Existing
hackplugin users lose the bundled MCP server when the plugin updates. To keep MCP, installhack-mcp(codex plugin add hack-mcp@hack-dance,claude plugin install hack-mcp@hack-dance, or Cursor Customize), or keep or add onehack mcp installentry. Do not use both for the same client. A Codex[plugins."hack@hack-dance".mcp_servers.hack] enabled = falseoverride no longer has a server to disable and can be removed. Claude marketplace users who installed with--sparse .claude-plugin plugins/hackmust also addplugins/hack-mcpto the sparse paths to seehack-mcp.Why the title has no
!: prerelease versions on this line are explicit5.0.0-next.Nworkflow inputs, so commit types do not drive them, and v5 is already a major line (feat!: prepare the first v5 prerelease candidate). Under the repo's release rules this change does not mark a new break for the prerelease line. The migration is stated here and in the commit body.Validation
bun run generate:agent-pluginsrun twice: no diff after the second run. The new testgenerating twice is a no-op and reproduces the committed packageschecks this byte for byte against the committedplugins/tree.bun test tests/agent-plugin-generation.test.ts tests/hack-init-skill.test.ts tests/agent-instruction-source.test.ts tests/agent-client-capabilities.test.ts tests/mcp-bundle.test.ts tests/integration-ownership.test.ts: 74 pass, 0 fail.shared-agent-skill,onboarding-prompt,runtime-guidance,integration-sync,mcp-prompts,setup,init-agent-integrations,legacy-agent-artifacts,cli-reference-docs): all pass.bun run docs:agent-client-capabilities -- --check: current.bun run --cwd packages/cli typecheck: clean.bun run typecheck: clean.bun run --cwd packages/cli check: 0 errors (34 existing warnings).biome checkon the changed scripts, tests and sources: clean..codex/skills,.claude/skills/hack-init,.cursor/rules/hack.mdc,examples/basic/AGENTS.mdandCLAUDE.md) were re-rendered with the project-scoped installers and explicit project roots. No user or global sync was run.docs/reference/cli.mdwas not regenerated.Negative controls
"mcpServers": "./.mcp.json"toplugins/hack/.claude-plugin/plugin.json. 7 tests failed acrossagent-plugin-generationandagent-client-capabilities(the shape check, generation idempotency, release preparation and matrix agreement). I then restored the file.negative control: re-adding MCP to the skills package fails the shape check and generation. Adding a manifestmcpServerskey and a.mcp.jsonfile to the skills package produces exactlydeclares-mcpandships-mcp, and the generator rejects the manifest. A hack-mcp manifest without its server, or with skills, is also flagged.negative control: plugin MCP is classified from hack-mcp, never the skills package. The matrix reportsskills-package-declares-mcpwhen MCP is re-added to the skills manifest, andmanifest-disagreementwhen the hack-mcp manifest drops it.Remaining gaps
hackorhack-mcpfrom the new marketplace layout, loading skills without MCP, or startinghack mcp servefromhack-mcp. AllpluginMcpcells stayuntestedwith their open gates. This needs isolated Codex, Claude Code and Cursor sessions.pluginMcpcells record this change's base commit (3e261d51) as their source SHA. A commit cannot reference its own SHA.tests/skill-references.test.tspackaged skill links stay inside the plugin and work offlinealready fails ontrain/queue-preview. The baredocs/env.md#command-and-delivery-matrixURL in the env-composition guidance fails the link checker; I confirmed this against the base tree. This PR does not change that bullet.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.