* refactor(#2368): extract capability arm to capability-command-router (ADR-2346 P2) Behavior-preserving relocation of the 706-line case 'capability': arm from gsd-tools.cjs into a new hand-authored bin/lib/capability-command-router.cjs (sibling of ensure-runtime-build.cjs). The 15 bin/-relative require paths are rewritten to sibling-relative (correct for bin/lib/). dispatchHostCommand is now async (capability's install/upgrade/consent ops await the lifecycle); sync routers (state/phase/…) pass through await unchanged. case 'capability': removed; capability dispatches via HOST_COMMAND_ROUTERS. Validated by the existing capability-lifecycle / -consent / -trust / -loader test suites (no logic changed). Golden install-parity fixtures regenerated. Closes #2368 (Slice 1 — relocation). Probe consolidation (capHostVersion→ readHostVersion, capReadStrict dedup) deferred to a follow-up slice. * fix(#2368): add capabilityState/capabilityWriter requires + INVENTORY row The relocated capability arm references capabilityState (cmdCapabilityState, resolveCapabilityRuntimeState) and capabilityWriter (cmdCapabilitySet) — both module-scope requires in gsd-tools.cjs (L288/289) that the initial closure-dep scan missed. Added as sibling requires to capability-command-router.cjs. Also adds the new cli module to docs/INVENTORY.md + regenerates the manifest. * fix(#2368): correct capHostVersion __dirname depth for bin/lib/ relocation capHostVersion's VERSION/package.json paths were bin/-relative ('..' and '..','..'); on relocation to bin/lib/ they resolved one level too deep, so capHostVersion returned 0.0.0 and capability install failed the engines.gsd gate (#1920). Added one more '..' to each (now resolves gsd-core/VERSION and repo-root package.json correctly). * test(#2368): drop capability from the invocation loop (async/FS vs /fake/cwd) capability is async and does FS/config reads, so invoking it against the unit test's /fake/cwd is fragile. The 6 sync Tier-1 routers stay in the invocation loop; capability is covered by the non-invoking registry- ownership assertion + the dedicated capability-* test suites. * chore: retrigger CI (no-changelog label now present)
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "ea841e2865248e74",
|
||||
"gsd-core/bin/gsd-tools.cjs": "15e42e7e6d7d8c84",
|
||||
"gsd-core/bin/gsd-tools.cjs": "e66d7561ef59d3ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "476aa24e8c4f03cf",
|
||||
"gsd-core/bin/gsd-tools.cjs": "8c4a564592742a98",
|
||||
"gsd-core/bin/gsd-tools.cjs": "a895ba31f85552b5",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "ea841e2865248e74",
|
||||
"gsd-core/bin/gsd-tools.cjs": "15e42e7e6d7d8c84",
|
||||
"gsd-core/bin/gsd-tools.cjs": "e66d7561ef59d3ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "2525f1ae8b086828",
|
||||
"gsd-core/bin/gsd-tools.cjs": "8f23cb9411d49aa6",
|
||||
"gsd-core/bin/gsd-tools.cjs": "39a7e60e50d3aba9",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "3a3409215044af9f",
|
||||
"gsd-core/bin/gsd-tools.cjs": "d7afff9ae7741fd6",
|
||||
"gsd-core/bin/gsd-tools.cjs": "826b3199cfbe2ea4",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
2
tests/fixtures/golden-install-parity/pi.json
vendored
2
tests/fixtures/golden-install-parity/pi.json
vendored
@@ -6,7 +6,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "6e98d76e955e35a2",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7cc25a154a7dfd6c",
|
||||
"gsd-core/bin/gsd-tools.cjs": "accb02bd8bdae4ff",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "de4627dff103d527",
|
||||
"gsd-core/bin/gsd-tools.cjs": "d928a772c8e30a5a",
|
||||
"gsd-core/bin/gsd-tools.cjs": "85318fd8778e85c0",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"gsd-core/VERSION": "ef0deccd81a6723c",
|
||||
"gsd-core/bin/check-latest-version.cjs": "e4a224058c8f4d74",
|
||||
"gsd-core/bin/ensure-runtime-build.cjs": "5636ca0b726871b2",
|
||||
"gsd-core/bin/gsd-tools.cjs": "0efc5ebda7f9b88d",
|
||||
"gsd-core/bin/gsd-tools.cjs": "fd0289f36085bf67",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"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": "49b882b68599fd19",
|
||||
"gsd-core/bin/gsd-tools.cjs": "7e1dab200b2bb6ec",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "0109a5a9866a24e0",
|
||||
|
||||
@@ -42,16 +42,16 @@ function makeErrorRecorder() {
|
||||
|
||||
// ─── 1. UNIT — dispatchHostCommand return values + pollution guard ───────────
|
||||
|
||||
describe('dispatchHostCommand: unit', () => {
|
||||
describe('dispatchHostCommand: unit', async () => {
|
||||
const CWD = '/fake/cwd';
|
||||
const RAW = false;
|
||||
|
||||
test('returns true for the migrated `state` command (consumed)', () => {
|
||||
test('returns true for the migrated `state` command (consumed)', async () => {
|
||||
// routeStateCommand will run against a fake cwd; it may call error() for a
|
||||
// missing subcommand — that is fine, we only assert the dispatch returned
|
||||
// true (consumed) rather than falling through to "Unknown command".
|
||||
const errFn = makeErrorRecorder();
|
||||
const consumed = dispatchHostCommand({
|
||||
const consumed = await dispatchHostCommand({
|
||||
command: 'state',
|
||||
args: ['state'],
|
||||
cwd: CWD,
|
||||
@@ -61,14 +61,18 @@ describe('dispatchHostCommand: unit', () => {
|
||||
assert.strictEqual(consumed, true, 'state must be consumed by the host table');
|
||||
});
|
||||
|
||||
test('all migrated Tier-1 host commands are consumed by the host table', () => {
|
||||
test('all migrated Tier-1 host commands are consumed by the host table', async () => {
|
||||
// Each migrated router receives its module-scope lib via the table entry;
|
||||
// against a fake cwd it may emit an error (missing subcommand), but the
|
||||
// dispatch itself must report consumed=true (no fall-through to the
|
||||
// unknown-command error).
|
||||
// NOTE: `capability` (P2) is omitted from this INVOCATION loop — it is async
|
||||
// and does FS/config reads, so invoking it against /fake/cwd is fragile.
|
||||
// It is covered by the registry-ownership assertion below (non-invoking)
|
||||
// and by the dedicated capability-lifecycle/consent/trust/state suites.
|
||||
for (const cmd of ['state', 'phase', 'init', 'roadmap', 'validate', 'verify']) {
|
||||
const errFn = makeErrorRecorder();
|
||||
const consumed = dispatchHostCommand({
|
||||
const consumed = await dispatchHostCommand({
|
||||
command: cmd,
|
||||
args: [cmd],
|
||||
cwd: CWD,
|
||||
@@ -79,9 +83,9 @@ describe('dispatchHostCommand: unit', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('returns false for an unknown command (fall through)', () => {
|
||||
test('returns false for an unknown command (fall through)', async () => {
|
||||
const errFn = makeErrorRecorder();
|
||||
const consumed = dispatchHostCommand({
|
||||
const consumed = await dispatchHostCommand({
|
||||
command: 'not-a-real-command',
|
||||
args: ['not-a-real-command'],
|
||||
cwd: CWD,
|
||||
@@ -92,10 +96,10 @@ describe('dispatchHostCommand: unit', () => {
|
||||
assert.strictEqual(errFn.calls.length, 0, 'error must not be called for a miss');
|
||||
});
|
||||
|
||||
test('prototype-pollution guard: __proto__/constructor/prototype fall through', () => {
|
||||
test('prototype-pollution guard: __proto__/constructor/prototype fall through', async () => {
|
||||
for (const bad of ['__proto__', 'constructor', 'prototype']) {
|
||||
const errFn = makeErrorRecorder();
|
||||
const consumed = dispatchHostCommand({
|
||||
const consumed = await dispatchHostCommand({
|
||||
command: bad,
|
||||
args: [bad],
|
||||
cwd: CWD,
|
||||
@@ -110,7 +114,7 @@ describe('dispatchHostCommand: unit', () => {
|
||||
|
||||
// ─── 2 + 3. DISPATCH + BEHAVIOR — end-to-end via runGsdTools ─────────────────
|
||||
|
||||
describe('state cutover: end-to-end dispatch via the host table', () => {
|
||||
describe('state cutover: end-to-end dispatch via the host table', async () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -121,7 +125,7 @@ describe('state cutover: end-to-end dispatch via the host table', () => {
|
||||
cleanup(tmpDir);
|
||||
});
|
||||
|
||||
test('`state load` succeeds end-to-end (dispatched via host table, not a case arm)', () => {
|
||||
test('`state load` succeeds end-to-end (dispatched via host table, not a case arm)', async () => {
|
||||
// Seed a minimal STATE.md so `state load` has something to read.
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'STATE.md'),
|
||||
@@ -136,7 +140,7 @@ describe('state cutover: end-to-end dispatch via the host table', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('unknown state subcommand surfaces the canonical unknown-subcommand error (non-zero exit)', () => {
|
||||
test('unknown state subcommand surfaces the canonical unknown-subcommand error (non-zero exit)', async () => {
|
||||
const result = runGsdTools(['--cwd=' + tmpDir, 'state', 'totally-not-a-subcommand'], process.cwd());
|
||||
assert.strictEqual(result.success, false, 'unknown subcommand must exit non-zero');
|
||||
assert.ok(
|
||||
@@ -148,9 +152,9 @@ describe('state cutover: end-to-end dispatch via the host table', () => {
|
||||
|
||||
// ─── 5. REGISTRY — HOST_COMMAND_ROUTERS owns `state` ────────────────────────
|
||||
|
||||
describe('HOST_COMMAND_ROUTERS registry', () => {
|
||||
test('owns all 6 migrated Tier-1 host commands as function entries', () => {
|
||||
for (const cmd of ['state', 'phase', 'init', 'roadmap', 'validate', 'verify']) {
|
||||
describe('HOST_COMMAND_ROUTERS registry', async () => {
|
||||
test('owns all 6 migrated Tier-1 host commands as function entries', async () => {
|
||||
for (const cmd of ['state', 'phase', 'init', 'roadmap', 'validate', 'verify', 'capability']) {
|
||||
assert.ok(
|
||||
Object.prototype.hasOwnProperty.call(HOST_COMMAND_ROUTERS, cmd),
|
||||
`HOST_COMMAND_ROUTERS must own \`${cmd}\``,
|
||||
@@ -159,7 +163,7 @@ describe('HOST_COMMAND_ROUTERS registry', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('does NOT own prototype-pollution keys', () => {
|
||||
test('does NOT own prototype-pollution keys', async () => {
|
||||
assert.ok(
|
||||
!Object.prototype.hasOwnProperty.call(HOST_COMMAND_ROUTERS, '__proto__'),
|
||||
'HOST_COMMAND_ROUTERS must not own __proto__',
|
||||
|
||||
Reference in New Issue
Block a user