chore(#2932): emit a per-invocation section manifest from the init bundle (#2987)

* chore(#2932): emit a per-invocation section manifest from init

Extends the init bundle with a typed per-invocation section manifest so an
invocation loads only the branch guidance it will actually take.

The three flag/state-gated branches in execute-phase.md move into their own
step files; the parent keeps its gsd:section markers wrapping a one-line
on-demand reference, so each section's prose lives in exactly one file and
the parent shrinks 93369 -> 89507 bytes. A new drift-guarded generator
derives the shipped section manifest from those markers, and a new pure
evaluator maps invocation facts to applicable section ids.

The evaluator is a lookup over the frozen WHEN_VOCABULARY, never a parser
(Greenspun's Tenth Rule, ADR-1671:69); a parity test asserts the vocabulary
and the predicate map stay exhaustively in sync.

Closes #2932

* fix(#2932): fail closed on prototype-chain when values

An isolated adversarial review found WHEN_PREDICATES[section.when] was a
bracket lookup on a plain-prototype object, so inherited Object.prototype
members resolved as predicates: "constructor"/"toString"/"valueOf"/
"hasOwnProperty" returned truthy and SILENTLY INCLUDED the section, and
"__proto__" threw an untyped TypeError carrying no .reason. Both violate
the module's documented fail-closed contract, and the manifest is read from
disk at run time so it cannot be assumed trustworthy.

Builds the predicate map on a null prototype and guards the lookup with an
explicit Object.hasOwn check. Adds table-driven coverage for nine
Object.prototype-shaped keys asserting the TYPED reason (asserting only
that it throws would still pass while broken) plus a fast-check property
injecting a hostile value at an arbitrary document position.

* test(#2932): retarget execute-phase step assertions at extracted step files

* fix(#2932): emit typed reasons for generator lib-load and write failures

* fix(#2932): restore launcher preamble in extracted steps and refresh derived fixtures

* chore(#2932): backfill changeset pr number to 2987

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-08-02 12:34:41 -04:00
committed by GitHub
parent 33985c11a9
commit a987cf2731
46 changed files with 2680 additions and 179 deletions

View File

@@ -75,16 +75,31 @@ describe('execute-phase workflow: wave filtering', () => {
test('workflow has partial-wave completion guardrail', () => {
const content = fs.readFileSync(WORKFLOW_PATH, 'utf-8');
// handle_partial_wave_execution was extracted to
// gsd-core/workflows/execute-phase/steps/partial-wave.md. The parent now only
// references it via a <gsd:section> pointer, so assert the pointer is present here
// and then read the actual step body from the extracted file below.
assert.ok(
content.includes('<step name="handle_partial_wave_execution">'),
content.includes('gsd-core/workflows/execute-phase/steps/partial-wave.md'),
'workflow should reference the extracted partial-wave step file'
);
const PARTIAL_WAVE_STEP_PATH = path.join(
__dirname, '..', 'gsd-core', 'workflows', 'execute-phase', 'steps', 'partial-wave.md'
);
assert.ok(fs.existsSync(PARTIAL_WAVE_STEP_PATH), 'partial-wave step file should exist');
const stepContent = fs.readFileSync(PARTIAL_WAVE_STEP_PATH, 'utf-8');
assert.ok(
stepContent.includes('<step name="handle_partial_wave_execution">'),
'workflow should have a partial wave handling step'
);
assert.ok(
content.includes('Do NOT run phase verification'),
stepContent.includes('Do NOT run phase verification'),
'partial wave step should skip phase verification'
);
assert.ok(
content.includes('Do NOT mark the phase complete'),
stepContent.includes('Do NOT mark the phase complete'),
'partial wave step should skip phase completion'
);
});