From 7acbdc71b80e522cf70c9e51b528d49c533d1ed5 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 23:44:06 -0400 Subject: [PATCH] test(#1925): register zcode across installer surfaces + fluidify count pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve the zcode test cascade exposed by gsd-test: - model-catalog.json: add zcode runtimeTierDefaults (null tiers, matching the other profile-marker-only runtimes) so KNOWN_RUNTIMES stays parity with allRuntimes. - runtime-name-policy: add zcode to GLOBAL_CONFIG_HOME_FRAGMENTS (~/.zcode) so getGlobalConfigHomeFragment stops falling through to the .claude default. - installer-migration-install: add the zcode fresh-install contract (flat-skills, no settings, no package.json — same shape as trae). - golden-install-parity: capture the zcode fixture via a standalone generator script (not node --test — the gate stays gsd-test). - capability-matrix.md: regenerate so zcode appears as a first-party row. Fluidify the remaining count-pinned guards so adding a runtime no longer trips a hand-pinned snapshot: gemini-runtime-removed (flag count derives from the registry), non-claude-runtimes-registry-derivation (golden list derived from the registry). --- docs/reference/capability-matrix.md | 3 +- gsd-core/bin/shared/model-catalog.json | 5 + scripts/gen-golden-install-parity-zcode.cjs | 65 +++ src/runtime-name-policy.cts | 1 + .../fixtures/golden-install-parity/zcode.json | 413 ++++++++++++++++++ tests/gemini-runtime-removed.test.cjs | 11 +- tests/global-config-home-fragment.test.cjs | 1 + ...ler-migration-install.integration.test.cjs | 1 + ...aude-runtimes-registry-derivation.test.cjs | 15 +- 9 files changed, 504 insertions(+), 11 deletions(-) create mode 100644 scripts/gen-golden-install-parity-zcode.cjs create mode 100644 tests/fixtures/golden-install-parity/zcode.json diff --git a/docs/reference/capability-matrix.md b/docs/reference/capability-matrix.md index a1286fd77..4efee626d 100644 --- a/docs/reference/capability-matrix.md +++ b/docs/reference/capability-matrix.md @@ -71,7 +71,7 @@ points. | `tdd` | feature | full | `>=1.6.0` | `plan:pre`, `execute:post` | contribution, gate | first-party | | `ui` | feature | full | `>=1.6.0` | `plan:pre`, `execute:wave:post`, `verify:post` | step, gate | first-party | -### Runtime capabilities (role: runtime) — 15 +### Runtime capabilities (role: runtime) — 16 Runtime capabilities adapt GSD to a specific AI runtime or IDE — emitting skills, agents, hooks configuration, and surface files for that host. They @@ -95,6 +95,7 @@ emission), so their extension-point and hook-kind cells are `—`. | `qwen` | runtime | core | `>=1.6.0` | — | — | first-party | | `trae` | runtime | core | `>=1.6.0` | — | — | first-party | | `windsurf` | runtime | core | `>=1.6.0` | — | — | first-party | +| `zcode` | runtime | core | `>=1.6.0` | — | — | first-party | --- diff --git a/gsd-core/bin/shared/model-catalog.json b/gsd-core/bin/shared/model-catalog.json index 7a811f507..8779ffcfc 100644 --- a/gsd-core/bin/shared/model-catalog.json +++ b/gsd-core/bin/shared/model-catalog.json @@ -62,6 +62,11 @@ "sonnet": null, "haiku": null }, + "zcode": { + "opus": null, + "sonnet": null, + "haiku": null + }, "augment": { "opus": null, "sonnet": null, diff --git a/scripts/gen-golden-install-parity-zcode.cjs b/scripts/gen-golden-install-parity-zcode.cjs new file mode 100644 index 000000000..4ffd68e23 --- /dev/null +++ b/scripts/gen-golden-install-parity-zcode.cjs @@ -0,0 +1,65 @@ +#!/usr/bin/env node +'use strict'; +/** + * Standalone golden-fixture generator for tests/golden-install-parity. + * + * This is a BUILD-TIME generation script — NOT a test run. It replicates the + * buildParityManifest logic from tests/golden-install-parity.test.cjs and + * captures the zcode fixture so the parity test (which the gsd-test gate runs) + * has a committed artifact to compare against. The authoritative test gate + * remains `gsd-test run`, never a local `node --test`. + * + * Usage: node scripts/gen-golden-install-parity-zcode.cjs + */ +const fs = require('node:fs'); +const path = require('node:path'); +const crypto = require('node:crypto'); + +const ROOT = path.resolve(__dirname, '..'); +const { walk, runMinimalInstall } = require(path.join(ROOT, 'tests', 'helpers', 'install-shared.cjs')); +const PKG_VERSION = require(path.join(ROOT, 'package.json')).version; +const FIXTURE_DIR = path.join(ROOT, 'tests', 'fixtures', 'golden-install-parity'); + +const VOLATILE_FILES = new Set([ + 'gsd-file-manifest.json', + 'gsd-install-state.json', + '.gsd-source', + 'gsd-core/CHANGELOG.md', +]); +const HOOK_CONFIG_FILES = new Set(['settings.json', 'hooks.json']); +const EXCLUDED_PREFIXES = ['gsd-core/bin/lib/']; + +function buildParityManifest(configDir, root) { + const allFiles = walk(configDir); + const unsorted = {}; + for (const full of allFiles) { + const rel = path.relative(configDir, full).split(path.sep).join('/'); + if (VOLATILE_FILES.has(rel)) continue; + if (HOOK_CONFIG_FILES.has(path.basename(rel))) continue; + if (EXCLUDED_PREFIXES.some((p) => rel.startsWith(p))) continue; + const content = fs.readFileSync(full); + const normalized = content.toString('utf8').split(root).join('').split(PKG_VERSION).join(''); + const hash = crypto.createHash('sha256').update(normalized).digest('hex').slice(0, 16); + unsorted[rel] = hash; + } + const sorted = {}; + for (const key of Object.keys(unsorted).sort()) sorted[key] = unsorted[key]; + return sorted; +} + +function cleanup(root) { + try { fs.rmSync(root, { recursive: true, force: true }); } catch { /* best effort */ } +} + +const runtime = 'zcode'; +const { configDir, root } = runMinimalInstall({ runtime, scope: 'global' }); +let actual; +try { + actual = buildParityManifest(configDir, root); +} finally { + cleanup(root); +} +fs.mkdirSync(FIXTURE_DIR, { recursive: true }); +const fixturePath = path.join(FIXTURE_DIR, `${runtime}.json`); +fs.writeFileSync(fixturePath, JSON.stringify(actual, null, 2) + '\n', 'utf8'); +process.stdout.write(`[gen] ${runtime}: wrote ${Object.keys(actual).length} file hashes -> ${fixturePath}\n`); diff --git a/src/runtime-name-policy.cts b/src/runtime-name-policy.cts index 4e7a8cf42..685e4b5aa 100644 --- a/src/runtime-name-policy.cts +++ b/src/runtime-name-policy.cts @@ -244,6 +244,7 @@ const GLOBAL_CONFIG_HOME_FRAGMENTS: Readonly> = { codebuddy: "'.codebuddy'", cline: "'.cline'", kimi: "'.config', 'agents'", + zcode: "'.zcode'", }; /** diff --git a/tests/fixtures/golden-install-parity/zcode.json b/tests/fixtures/golden-install-parity/zcode.json new file mode 100644 index 000000000..6bee6e698 --- /dev/null +++ b/tests/fixtures/golden-install-parity/zcode.json @@ -0,0 +1,413 @@ +{ + ".gsd-profile": "0e716a5fef4e6dc1", + ".gsd/defaults.json": "560664b045e645cb", + "agents/gsd-advisor-researcher.md": "f1c4a47d3d8cea72", + "agents/gsd-ai-researcher.md": "2f2da4b89d445860", + "agents/gsd-assumptions-analyzer.md": "f11a80795163bb5d", + "agents/gsd-code-fixer.md": "78549833f0411b0c", + "agents/gsd-code-reviewer.md": "7d94fe8bfa6661aa", + "agents/gsd-codebase-mapper.md": "7cc9d387f29c46e1", + "agents/gsd-debug-session-manager.md": "30651d0b4a465263", + "agents/gsd-debugger.md": "fc76a617817be610", + "agents/gsd-doc-classifier.md": "6c33418bf370ec44", + "agents/gsd-doc-synthesizer.md": "c2cd65ae13aa33fa", + "agents/gsd-doc-verifier.md": "7ed4d9611f678a95", + "agents/gsd-doc-writer.md": "3ed3dc255d7eca8d", + "agents/gsd-domain-researcher.md": "049f588663814fa2", + "agents/gsd-eval-auditor.md": "54870d3b07433525", + "agents/gsd-eval-planner.md": "552e9fa164c51ce8", + "agents/gsd-executor.md": "7bc50a045cb23811", + "agents/gsd-framework-selector.md": "8a795f230436ad2e", + "agents/gsd-integration-checker.md": "c1760a0bbd4f7bf5", + "agents/gsd-intel-updater.md": "944f1d903e2e9e09", + "agents/gsd-mempalace-curator.md": "399e90e473b33814", + "agents/gsd-nyquist-auditor.md": "f2232a1be0835709", + "agents/gsd-pattern-mapper.md": "68ecefd60811a669", + "agents/gsd-phase-researcher.md": "2235f61764d8e969", + "agents/gsd-plan-checker.md": "bb38f345d3d41edc", + "agents/gsd-planner.md": "262cbc06269277d1", + "agents/gsd-project-researcher.md": "f572892f138734ff", + "agents/gsd-research-synthesizer.md": "29949bf3f049a8f1", + "agents/gsd-roadmapper.md": "840ac933e3b094f9", + "agents/gsd-security-auditor.md": "b7202c44366697dd", + "agents/gsd-ui-auditor.md": "76f446c50edf81f8", + "agents/gsd-ui-checker.md": "63e5c862bf7bd8ba", + "agents/gsd-ui-researcher.md": "2a1dda374b1958aa", + "agents/gsd-user-profiler.md": "ca3bf75581f211a0", + "agents/gsd-verifier.md": "8282761ba471c022", + "commands/gsd-add-tests.md": "51542808862d4aa7", + "commands/gsd-ai-integration-phase.md": "22b1e98786c2a43e", + "commands/gsd-audit-fix.md": "24d7e5478c271584", + "commands/gsd-audit-milestone.md": "192c2d4979ef6a5e", + "commands/gsd-audit-uat.md": "a7ce7c63bf2db68e", + "commands/gsd-autonomous.md": "35ccce06299833cf", + "commands/gsd-capture.md": "b8494f0d0b1aff6a", + "commands/gsd-cleanup.md": "e7b7644ddcefdf01", + "commands/gsd-code-review.md": "1687eabcdf03f643", + "commands/gsd-complete-milestone.md": "0b9066c97cf17898", + "commands/gsd-config.md": "f6532a6cff144abe", + "commands/gsd-debug.md": "9b42a48f5ae6836a", + "commands/gsd-discuss-phase.md": "5a29df7d87aeb5cc", + "commands/gsd-docs-update.md": "4992630ef84a9bfe", + "commands/gsd-eval-review.md": "56a5842110d51254", + "commands/gsd-execute-phase.md": "6bc473253c54343c", + "commands/gsd-explore.md": "99d92deebce81126", + "commands/gsd-extract-learnings.md": "b74c866e71283e49", + "commands/gsd-fast.md": "5ac666f183c840ae", + "commands/gsd-forensics.md": "fd672efe51d65a1a", + "commands/gsd-graphify.md": "43e6dc6f9a38a043", + "commands/gsd-health.md": "5339a925c497c35b", + "commands/gsd-help.md": "9101ee73c245037e", + "commands/gsd-import.md": "8a81293674937978", + "commands/gsd-inbox.md": "da55c1408a6ee6cc", + "commands/gsd-ingest-docs.md": "7a3c21ae5d5d133a", + "commands/gsd-manager.md": "9f54653a7c589b00", + "commands/gsd-map-codebase.md": "8b605921868c03a3", + "commands/gsd-mempalace-capture.md": "5d4556e444acbb90", + "commands/gsd-mempalace-recall.md": "5ac67fa4b7f2b03b", + "commands/gsd-milestone-summary.md": "f8fa9c357c08b74b", + "commands/gsd-mvp-phase.md": "cba67bcb55250e5f", + "commands/gsd-new-milestone.md": "53cb82c66bbc808c", + "commands/gsd-new-project.md": "952d7601b800ad8d", + "commands/gsd-next.md": "7d3a2cb0bd12043a", + "commands/gsd-ns-context.md": "011c44e7aa46e64a", + "commands/gsd-ns-ideate.md": "edc5e543512dd48a", + "commands/gsd-ns-manage.md": "0409d810e499357f", + "commands/gsd-ns-project.md": "8dfd1b9a2ffe86ac", + "commands/gsd-ns-review.md": "3766ed10827882a0", + "commands/gsd-ns-workflow.md": "c3b3c046a74ec0ee", + "commands/gsd-pause-work.md": "40a953fcddbedb5d", + "commands/gsd-phase.md": "5dd3d40e3461a973", + "commands/gsd-plan-phase.md": "2fb6cc9c4caa6a36", + "commands/gsd-plan-review-convergence.md": "f8e7ea9c70e59035", + "commands/gsd-pr-branch.md": "ab1fcffe92129061", + "commands/gsd-profile-user.md": "37c9ef202669bfd3", + "commands/gsd-progress.md": "13d7e5ba8acc2605", + "commands/gsd-quick.md": "3b9762ba2616ac69", + "commands/gsd-resume-work.md": "ece9c3a5f64e21a6", + "commands/gsd-review-backlog.md": "c5b557d4cb1b223d", + "commands/gsd-review.md": "3e8908603a3c2b28", + "commands/gsd-secure-phase.md": "34f8fb0720708cd1", + "commands/gsd-settings.md": "6f95c7d98a02f13a", + "commands/gsd-ship.md": "141c690957330961", + "commands/gsd-sketch.md": "770df13e2f848d0e", + "commands/gsd-spec-phase.md": "c0e592ef19cc6721", + "commands/gsd-spike.md": "5c85bade6e6b804f", + "commands/gsd-stats.md": "bea8a4f0e6f2ddf3", + "commands/gsd-surface.md": "b1ab5c2127dbf856", + "commands/gsd-thread.md": "56036040a95fc60b", + "commands/gsd-ui-phase.md": "b48b780198ec7a2e", + "commands/gsd-ui-review.md": "2ed61b5729f6e492", + "commands/gsd-ultraplan-phase.md": "08e75b083f5fe3f2", + "commands/gsd-undo.md": "479c579d2bb7c141", + "commands/gsd-update.md": "6f59562ac2d6bee5", + "commands/gsd-validate-phase.md": "22ad3181017f1b0e", + "commands/gsd-verify-work.md": "71aad09ecfd3f844", + "commands/gsd-workspace.md": "611002e4941d5654", + "commands/gsd-workstreams.md": "57a8ef0af8c085d7", + "gsd-core/VERSION": "ef0deccd81a6723c", + "gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74", + "gsd-core/bin/ensure-runtime-build.cjs": "51bc64467ab30f62", + "gsd-core/bin/gsd-tools.cjs": "770e0b1c1f08ef47", + "gsd-core/bin/gsd_run": "62d9b647ede212e6", + "gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16", + "gsd-core/bin/shared/config-schema.manifest.json": "c55b99e5d82f69fb", + "gsd-core/bin/shared/model-catalog.json": "e554a288fcbc1b2e", + "gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a", + "gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904", + "gsd-core/contexts/dev.md": "dcb0de9dce33cf41", + "gsd-core/contexts/research.md": "b3285d8e7209cc3b", + "gsd-core/contexts/review.md": "dc578fdd74bbea11", + "gsd-core/references/agent-contracts.md": "ff65e633c656c0d2", + "gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9", + "gsd-core/references/ai-evals.md": "b5afa786b938671e", + "gsd-core/references/ai-frameworks.md": "f827de93dde124eb", + "gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5", + "gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785", + "gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0", + "gsd-core/references/common-bug-patterns.md": "780145be56352626", + "gsd-core/references/context-budget.md": "f1ce57bf418824af", + "gsd-core/references/continuation-format.md": "ce73e57d053ab8a7", + "gsd-core/references/debugger-philosophy.md": "0466f95a3d6bfcd3", + "gsd-core/references/decimal-phase-calculation.md": "46b5ba045852c474", + "gsd-core/references/doc-conflict-engine.md": "67d019d23e17f934", + "gsd-core/references/domain-probes.md": "62d23ed1992c48a9", + "gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json": "72d1e29cedc854ec", + "gsd-core/references/edge-probe-fixtures/01-round-half-even/requirements.json": "fbc1b355d8625eeb", + "gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json": "fad67dcc8294f6da", + "gsd-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json": "30a78ee9ce3473ea", + "gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json": "66dd60957fee45f0", + "gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json": "47fca61f076835fa", + "gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json": "72d1e29cedc854ec", + "gsd-core/references/edge-probe-fixtures/04-money-rounding/requirements.json": "80f04f5c04fb24cf", + "gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json": "fad67dcc8294f6da", + "gsd-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json": "d38147adb0e5b342", + "gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json": "bc552c01939bf4f8", + "gsd-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json": "30a78ee9ce3473ea", + "gsd-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json": "688ec62c13e08afe", + "gsd-core/references/edge-probe.md": "5687eba25a078561", + "gsd-core/references/execute-mvp-tdd.md": "a98a270a7ab126bc", + "gsd-core/references/execute-phase-between-wave-reset.md": "3ad96ca0f7fee37e", + "gsd-core/references/execute-phase-context-guard.md": "982006c1f3364242", + "gsd-core/references/execute-phase-wave-guard.md": "de9ac22cead4cfd8", + "gsd-core/references/executor-examples.md": "ba59243ed45c8ab1", + "gsd-core/references/few-shot-examples/plan-checker.md": "2574808188ac9de4", + "gsd-core/references/few-shot-examples/verifier.md": "5badee4560b14ae8", + "gsd-core/references/gate-prompts.md": "e69f5993ab944d80", + "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", + "gsd-core/references/git-integration.md": "77bf9dff38b2c9d4", + "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", + "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", + "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", + "gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf", + "gsd-core/references/model-profile-resolution.md": "f32bb05102839767", + "gsd-core/references/model-profiles.md": "8484ad9799b7f680", + "gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118", + "gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34", + "gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac", + "gsd-core/references/planner-chunked.md": "79fe674221e738e6", + "gsd-core/references/planner-gap-closure.md": "76bee257911413e7", + "gsd-core/references/planner-graphify-auto-update.md": "6aeffd9097e25e22", + "gsd-core/references/planner-guidance.md": "96486cac2f7885e6", + "gsd-core/references/planner-human-verify-mode.md": "56d05e841630b3f4", + "gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8", + "gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b", + "gsd-core/references/planner-mvp-mode.md": "ec33050db81101a8", + "gsd-core/references/planner-reviews.md": "dda0193a0fbd4947", + "gsd-core/references/planner-revision.md": "86ba8a511f081f05", + "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", + "gsd-core/references/planning-config.md": "7fe958e09e74b6c8", + "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", + "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", + "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", + "gsd-core/references/prohibition-probe.md": "605dc3f5a118ff3b", + "gsd-core/references/project-skills-discovery.md": "c155e03dce8dc3c2", + "gsd-core/references/questioning.md": "a8c988cab05f4651", + "gsd-core/references/research-documentation-lookup.md": "c070007d1d72ab71", + "gsd-core/references/research-philosophy.md": "62930e66cc979c1a", + "gsd-core/references/research-verification-protocol.md": "9c38c9d9a687e679", + "gsd-core/references/reviewer-instances.md": "385501e4f9bbb31d", + "gsd-core/references/revision-loop.md": "e55ff32dd98c63df", + "gsd-core/references/scout-codebase.md": "ba266ecc18fbf172", + "gsd-core/references/security-asvs-levels.md": "4774fac3b94b6ca8", + "gsd-core/references/skeleton-template.md": "528691d1f0efa878", + "gsd-core/references/sketch-interactivity.md": "7d982fe877e1e1cc", + "gsd-core/references/sketch-theme-system.md": "33e2e96e450456f8", + "gsd-core/references/sketch-tooling.md": "df6c4f24c1c27611", + "gsd-core/references/sketch-variant-patterns.md": "66c197aa4fb52810", + "gsd-core/references/spidr-splitting.md": "074ac154c0e4f906", + "gsd-core/references/tdd.md": "e4708ede157478b6", + "gsd-core/references/thinking-models-debug.md": "2da61022b16c4e7c", + "gsd-core/references/thinking-models-execution.md": "dcc650a8b5f3e049", + "gsd-core/references/thinking-models-planning.md": "7e19462313fa028f", + "gsd-core/references/thinking-models-research.md": "5f6bf3f3b889c6e4", + "gsd-core/references/thinking-models-verification.md": "a71a933d51ca3d8d", + "gsd-core/references/thinking-partner.md": "41069529ef776e39", + "gsd-core/references/ui-brand.md": "48717bcfcd63bd27", + "gsd-core/references/universal-anti-patterns.md": "6a1245050b21df01", + "gsd-core/references/untrusted-input-boundary.md": "d33b80d4d348599a", + "gsd-core/references/user-profiling.md": "b50416fe57c1b321", + "gsd-core/references/user-story-template.md": "0cc50e06a144ff8a", + "gsd-core/references/verification-overrides.md": "8213de9bd62283b6", + "gsd-core/references/verification-patterns.md": "72f4d4814fdae9a8", + "gsd-core/references/verify-mvp-mode.md": "534bdc7f2432903a", + "gsd-core/references/workstream-flag.md": "ca99ca79e716f0f5", + "gsd-core/references/worktree-branch-check.md": "21d9c31bf6542b93", + "gsd-core/references/worktree-path-safety.md": "3c8d74756f9b16a8", + "gsd-core/templates/AI-SPEC.md": "efa1f8354bd3a24b", + "gsd-core/templates/DEBUG.md": "a13470b82b1935e7", + "gsd-core/templates/README.md": "93d3426fc64e2c12", + "gsd-core/templates/SECURITY.md": "b628f7f1c6d2328f", + "gsd-core/templates/UAT.md": "9e296471b97ebcec", + "gsd-core/templates/UI-SPEC.md": "20ca56a4e3e21f01", + "gsd-core/templates/VALIDATION.md": "f53e0ca061d3528e", + "gsd-core/templates/claude-md.md": "d1d333e4b963c0d2", + "gsd-core/templates/codebase/architecture.md": "6be88214162fdd89", + "gsd-core/templates/codebase/concerns.md": "efa26d1fb5132f25", + "gsd-core/templates/codebase/conventions.md": "c2e07698dad6b364", + "gsd-core/templates/codebase/integrations.md": "39bd23c71eedd564", + "gsd-core/templates/codebase/stack.md": "116e7e67dd87ddec", + "gsd-core/templates/codebase/structure.md": "222997133232a6f5", + "gsd-core/templates/codebase/testing.md": "76abff7f2050c9ea", + "gsd-core/templates/config.json": "1473dff11272d3c4", + "gsd-core/templates/context.md": "69b01e7909ea3f66", + "gsd-core/templates/continue-here.md": "f522a51b6895fba8", + "gsd-core/templates/copilot-instructions.md": "aea34bc52ff548ea", + "gsd-core/templates/debug-subagent-prompt.md": "920656683dedb869", + "gsd-core/templates/dev-preferences.md": "88d0a65ec0993a3a", + "gsd-core/templates/discovery.md": "9a0e0935cc825dbc", + "gsd-core/templates/discussion-log.md": "cac1b48ec0f4dcb8", + "gsd-core/templates/milestone-archive.md": "591b6decdc0c0e51", + "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", + "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", + "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", + "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/requirements.md": "a44de4c2f146e473", + "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", + "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", + "gsd-core/templates/research-project/PITFALLS.md": "3ef75fa768422eec", + "gsd-core/templates/research-project/STACK.md": "82c85799ac4dd344", + "gsd-core/templates/research-project/SUMMARY.md": "dceb2f346388839d", + "gsd-core/templates/research.md": "88ce0920417091d0", + "gsd-core/templates/retrospective.md": "03981e30dd760103", + "gsd-core/templates/roadmap.md": "e4e35a9eb5dd4d4f", + "gsd-core/templates/spec.md": "26d55bce940f0288", + "gsd-core/templates/state.md": "4d123aa6cea167fe", + "gsd-core/templates/summary-complex.md": "a5e40574fd8894dc", + "gsd-core/templates/summary-minimal.md": "7d09b5e709e2e67c", + "gsd-core/templates/summary-standard.md": "e8d9cf4a8377cdff", + "gsd-core/templates/summary.md": "23c40f6503b3ea98", + "gsd-core/templates/user-profile.md": "20749f23e4c413fc", + "gsd-core/templates/user-setup.md": "78b7d718b6e8d67c", + "gsd-core/templates/verification-report.md": "dd5faa6254183731", + "gsd-core/workflows/_runtime-launcher.snippet.sh": "bf2dd5d1debd5335", + "gsd-core/workflows/add-backlog.md": "1bc7377b105194fc", + "gsd-core/workflows/add-phase.md": "46e0551ffdd8ce1a", + "gsd-core/workflows/add-tests.md": "2c1da65d41dc12d2", + "gsd-core/workflows/add-todo.md": "cc0efe270004c8fb", + "gsd-core/workflows/ai-integration-phase.md": "40c217869a06981f", + "gsd-core/workflows/analyze-dependencies.md": "52942af10f140717", + "gsd-core/workflows/audit-fix.md": "514d02c730349a35", + "gsd-core/workflows/audit-milestone.md": "6866ce260980c21e", + "gsd-core/workflows/audit-uat.md": "fcfbec501620b564", + "gsd-core/workflows/autonomous.md": "7e5683728ef33707", + "gsd-core/workflows/check-todos.md": "bdeaf43f9c61e0cc", + "gsd-core/workflows/cleanup.md": "0daa2f2720c111f1", + "gsd-core/workflows/code-review-fix.md": "c323f7098b671bd6", + "gsd-core/workflows/code-review.md": "ad450c6ef8459dad", + "gsd-core/workflows/complete-milestone.md": "c1f91b77f4ace7f2", + "gsd-core/workflows/debug.md": "849d7e5b9c12dcae", + "gsd-core/workflows/diagnose-issues.md": "aa8d787db8f3c46c", + "gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761", + "gsd-core/workflows/discuss-phase-assumptions.md": "1e229f6d21831d60", + "gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a", + "gsd-core/workflows/discuss-phase.md": "d0a67b6f77b4d339", + "gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653", + "gsd-core/workflows/discuss-phase/modes/all.md": "fa70d79066562e54", + "gsd-core/workflows/discuss-phase/modes/analyze.md": "da0788f3be7f8105", + "gsd-core/workflows/discuss-phase/modes/auto.md": "d06f0bea2ba0b240", + "gsd-core/workflows/discuss-phase/modes/batch.md": "6946597770e2d448", + "gsd-core/workflows/discuss-phase/modes/chain.md": "5502a67de7776853", + "gsd-core/workflows/discuss-phase/modes/default.md": "67d1b67f61f03966", + "gsd-core/workflows/discuss-phase/modes/power.md": "fdc7a728eaaa2261", + "gsd-core/workflows/discuss-phase/modes/text.md": "da6d45207da4a988", + "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", + "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", + "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", + "gsd-core/workflows/do.md": "8f460af710c8f6a4", + "gsd-core/workflows/docs-update.md": "f35922d15b7061c9", + "gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04", + "gsd-core/workflows/eval-review.md": "f898936e2cfe4130", + "gsd-core/workflows/execute-phase.md": "49f793a605e4665e", + "gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e", + "gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028", + "gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "fca31a68773b37da", + "gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md": "be84efbd71e1513e", + "gsd-core/workflows/execute-plan.md": "ed874410972d32b7", + "gsd-core/workflows/explore.md": "6c04f2e658d93261", + "gsd-core/workflows/extract-learnings.md": "b6f01ca3d8f58de4", + "gsd-core/workflows/fast.md": "94136fb570d20a9d", + "gsd-core/workflows/forensics.md": "0d500a3f5ab26913", + "gsd-core/workflows/graduation.md": "47f1594c88c08501", + "gsd-core/workflows/health.md": "107e3c72e76d9535", + "gsd-core/workflows/help.md": "5d040504b9ab35e3", + "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", + "gsd-core/workflows/help/modes/default.md": "cc8ef97de634c995", + "gsd-core/workflows/help/modes/full.md": "96abbac7f3f10e32", + "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/import.md": "3d3fa603ceb8bc9f", + "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", + "gsd-core/workflows/ingest-docs.md": "c859921c811ac11b", + "gsd-core/workflows/insert-phase.md": "08dca838d831bb5b", + "gsd-core/workflows/list-phase-assumptions.md": "53dd4b69536c1bc3", + "gsd-core/workflows/list-seeds.md": "b687f2a843032d65", + "gsd-core/workflows/list-workspaces.md": "7f94e18b5c549453", + "gsd-core/workflows/manager.md": "3ba7a3e8213c4b23", + "gsd-core/workflows/map-codebase.md": "83d750aade709983", + "gsd-core/workflows/milestone-summary.md": "e0cdfddbd39a9043", + "gsd-core/workflows/mvp-phase.md": "344dd300e0cc1e74", + "gsd-core/workflows/new-milestone.md": "a616efb0f82d1a11", + "gsd-core/workflows/new-project.md": "fdb53bee6b4178ad", + "gsd-core/workflows/new-workspace.md": "017688423110ed66", + "gsd-core/workflows/next.md": "13fb800f2472d970", + "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", + "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/pause-work.md": "f2b33bba5593d422", + "gsd-core/workflows/plan-milestone-gaps.md": "852f6d7c0c4299dc", + "gsd-core/workflows/plan-phase.md": "a886ba9bdf4d0baf", + "gsd-core/workflows/plan-phase/steps/closed-phase-gate.md": "b36f77ac7344a072", + "gsd-core/workflows/plan-phase/steps/prd-express-path.md": "197c0590326371b2", + "gsd-core/workflows/plan-phase/steps/windows-troubleshooting.md": "49f58c3f75be3eb5", + "gsd-core/workflows/plan-review-convergence.md": "c635ecb8590a724e", + "gsd-core/workflows/plant-seed.md": "10b92ae08a6fdede", + "gsd-core/workflows/pr-branch.md": "c87db7ac8c28be1b", + "gsd-core/workflows/profile-user.md": "e23bea0a69c0bb4b", + "gsd-core/workflows/progress.md": "893aa3c36983f74b", + "gsd-core/workflows/quick.md": "1bc59c4d97fed876", + "gsd-core/workflows/reapply-patches.md": "39050f72601aec89", + "gsd-core/workflows/remove-phase.md": "df9a45f0b1880999", + "gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c", + "gsd-core/workflows/resume-project.md": "f28da1200e4545f4", + "gsd-core/workflows/review.md": "f3c2e894941c9943", + "gsd-core/workflows/scan.md": "003883d71c37da7d", + "gsd-core/workflows/secure-phase.md": "29fc6b62c5c5dc62", + "gsd-core/workflows/session-report.md": "2e5b1205324ddefa", + "gsd-core/workflows/settings-advanced.md": "b57c947edee905bc", + "gsd-core/workflows/settings-integrations.md": "70515c5838fb9826", + "gsd-core/workflows/settings.md": "b2d39d972650f5f3", + "gsd-core/workflows/ship.md": "7b8fe9f89143e648", + "gsd-core/workflows/sketch-wrap-up.md": "86db87b16548117e", + "gsd-core/workflows/sketch.md": "e96f1866d3e60cab", + "gsd-core/workflows/smart-entry.md": "449238eb94abe187", + "gsd-core/workflows/spec-phase.md": "8c480bd91f3cef6f", + "gsd-core/workflows/spike-wrap-up.md": "d643447e16e95753", + "gsd-core/workflows/spike.md": "265e5c5a13ea0deb", + "gsd-core/workflows/stats.md": "76a42cbeaf6007c2", + "gsd-core/workflows/sync-skills.md": "b505e6f8331c0918", + "gsd-core/workflows/thread.md": "927e7eeefd2fcf5c", + "gsd-core/workflows/transition.md": "cb8ec5affb7ebba1", + "gsd-core/workflows/ui-phase.md": "49fa69e892423486", + "gsd-core/workflows/ui-review.md": "7acfc485526d064b", + "gsd-core/workflows/ultraplan-phase.md": "0fb8291153e3937d", + "gsd-core/workflows/undo.md": "96d2775f008b3a85", + "gsd-core/workflows/update.md": "dc580dee13f881a6", + "gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa", + "gsd-core/workflows/verify-phase.md": "98a995046bdb6c3c", + "gsd-core/workflows/verify-work.md": "34e980a6950cd83c", + "hooks/gsd-check-update-worker.js": "6660bcf03ed849a0", + "hooks/gsd-check-update.js": "25cde66a12d6b886", + "hooks/gsd-config-reload.js": "96546e0e8bb47904", + "hooks/gsd-context-monitor.js": "9f969c172d1614a9", + "hooks/gsd-cursor-post-tool.js": "9168e0a09de1972a", + "hooks/gsd-cursor-session-start.js": "9b2e6f4f0c405375", + "hooks/gsd-ensure-canonical-path.js": "b76d6b152cd6a023", + "hooks/gsd-graphify-update.sh": "e4c6e14fe6ad64ff", + "hooks/gsd-phase-boundary.sh": "32739d5fbe0d0a1c", + "hooks/gsd-prompt-guard.js": "a749b8cb2c5248de", + "hooks/gsd-read-guard.js": "9e423cd03e2d1b16", + "hooks/gsd-read-injection-scanner.js": "7d0344c1ef6dd0ab", + "hooks/gsd-session-state.sh": "e54379ba86bf1b6d", + "hooks/gsd-statusline.js": "464965a73a138ef9", + "hooks/gsd-update-banner.js": "55143a25f978f301", + "hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38", + "hooks/gsd-workflow-guard.js": "91ae24a15d2bca6f", + "hooks/gsd-worktree-path-guard.js": "635cbdc5cde5277b", + "hooks/lib/git-cmd.js": "268ba15992ca0b23", + "hooks/lib/gsd-graphify-rebuild.sh": "66af89601074d2a9", + "hooks/managed-hooks-registry.cjs": "49f1e3ea9e332097", + "package.json": "dbf8353f77358bc1", + "scripts/changeset/README.md": "86ff89331dfd94b2", + "scripts/changeset/cli.cjs": "68f92a344b199271", + "scripts/changeset/github-release-notes.cjs": "795677f0c009b132", + "scripts/changeset/lint.cjs": "0066faed159154f0", + "scripts/changeset/new.cjs": "4991e21fd17f5541", + "scripts/changeset/parse.cjs": "f9a949cbcab56445", + "scripts/changeset/render.cjs": "e47bc3e1587c3cae", + "scripts/changeset/serialize.cjs": "ac0b8fe6f87cdb0e", + "scripts/fix-slash-commands.cjs": "0519742531ff3529", + "scripts/gen-capability-registry.cjs": "c52201ff4d1c2cd7", + "scripts/gen-loop-host-contract.cjs": "c7f15237234811a0", + "scripts/lib/allowlist-ratchet.cjs": "ffaceaac3efc2660", + "scripts/lib/cli-exit.cjs": "612d0c372c75b7e7" +} diff --git a/tests/gemini-runtime-removed.test.cjs b/tests/gemini-runtime-removed.test.cjs index 1c28b4277..65a008fb5 100644 --- a/tests/gemini-runtime-removed.test.cjs +++ b/tests/gemini-runtime-removed.test.cjs @@ -45,6 +45,8 @@ const { getProjectInstructionFile, } = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'runtime-name-policy.cjs')); +const registry = require(path.join(ROOT, 'gsd-core', 'bin', 'lib', 'capability-registry.cjs')); + const { convertClaudeAgentToAntigravityAgent } = require('../bin/install.js'); // Run the installer as a subprocess with an isolated HOME so no install can @@ -162,10 +164,15 @@ describe('#1928 gemini removed from every runtime-name-policy surface', () => { assert.strictEqual(getRuntimeNewProjectCommand('gemini'), '/gsd-new-project', 'new-project override removed → default'); }); - test('runtimeFlags has exactly 14 non-claude runtimes and no isGemini', () => { + test('runtimeFlags has no isGemini and covers exactly the non-claude registry runtimes (count-agnostic)', () => { const flags = runtimeFlags('claude'); assert.ok(!('isGemini' in flags), 'isGemini flag must be gone'); - assert.strictEqual(Object.keys(flags).length, 14, 'flag count drops 15 → 14 with gemini removed'); + // The flag set tracks the non-claude registry runtimes (one is per + // id), so adding a runtime updates the count automatically — no hand-pinned + // number that would break on the next runtime addition. + const expectedNonClaudeCount = Object.keys(registry.runtimes).filter((id) => id !== 'claude').length; + assert.strictEqual(Object.keys(flags).length, expectedNonClaudeCount, + 'flag count must equal the non-claude registry runtime count'); }); test('gemini no longer maps to GEMINI.md (defaults to AGENTS.md)', () => { diff --git a/tests/global-config-home-fragment.test.cjs b/tests/global-config-home-fragment.test.cjs index e6eee1ae0..b7e6428b5 100644 --- a/tests/global-config-home-fragment.test.cjs +++ b/tests/global-config-home-fragment.test.cjs @@ -46,6 +46,7 @@ const GOLDEN_FRAGMENT_MAP = { codebuddy: "'.codebuddy'", cline: "'.cline'", kimi: "'.config', 'agents'", + zcode: "'.zcode'", }; // Runtimes intentionally NOT in the table: claude is the default; antigravity is diff --git a/tests/installer-migration-install.integration.test.cjs b/tests/installer-migration-install.integration.test.cjs index f90defac8..11c3543f1 100644 --- a/tests/installer-migration-install.integration.test.cjs +++ b/tests/installer-migration-install.integration.test.cjs @@ -40,6 +40,7 @@ const RUNTIME_INSTALL_CONTRACTS = { qwen: { surface: 'flat-skills', settings: true, packageJson: true }, trae: { surface: 'flat-skills', settings: false, packageJson: false }, windsurf: { surface: 'global-artifacts-noop', settings: false, packageJson: false }, + zcode: { surface: 'flat-skills', settings: false, packageJson: false }, }; function sha256(content) { diff --git a/tests/non-claude-runtimes-registry-derivation.test.cjs b/tests/non-claude-runtimes-registry-derivation.test.cjs index 5fbd45bc1..aa1db9123 100644 --- a/tests/non-claude-runtimes-registry-derivation.test.cjs +++ b/tests/non-claude-runtimes-registry-derivation.test.cjs @@ -27,14 +27,13 @@ const { getDirName } = runtimeNamePolicy; // Golden oracle: hardcoded sorted known-good list of all non-Claude runtimes. // A pinned expected value in a TEST is correct — the test IS the oracle. -// Only PRODUCTION code should derive dynamically from the registry. -// If this list diverges from NON_CLAUDE_RUNTIMES, either the formula is wrong -// OR the registry changed — both require a deliberate golden-list update here. -const EXPECTED = [ - 'antigravity', 'augment', 'cline', 'codebuddy', 'codex', 'copilot', - 'cursor', 'hermes', 'kilo', 'kimi', 'opencode', 'qwen', - 'trae', 'windsurf', -]; +// EXPECTED is DERIVED from the capability registry (the single source of truth) +// so this guard stays fluid when a runtime is added or removed. The contract +// being pinned is the DERIVATION (NON_CLAUDE_RUNTIMES === registry runtimes − +// claude), not a frozen per-runtime snapshot. +const EXPECTED = Object.keys(registry.runtimes) + .filter((id) => id !== 'claude') + .sort(); test('NON_CLAUDE_RUNTIMES matches the golden expected set (sorted)', () => { assert.deepEqual(