allowed_actions is answered by kernel/domain/capabilities.py, and two test doubles transcribe
it by hand: frontend/ui-core/src/testing/wire.fixtures.ts and frontend/app/e2e/_wire.ts. The
script test tests/scripts/wire_rosters.test.mjs compares those two against each other, in
both directions, which is what the earlier report of the untyped duplicate roster (#358) was
closed with.
Comparing them to each other cannot see a mistake they share. The test's own source says so, and
names the two ways out that were considered and not taken — exposing a @visionset/ui-core/testing
subpath, or generating _wire.ts — with the reason: _wire.ts is TypeScript that node --test
cannot load. So the limitation is known and was accepted deliberately.
What is new is evidence of it costing something. The batch pre-labeling branch added a
BatchAction member and updated neither roster. Both doubles were wrong in the same way, so the
gate stayed green through the change that introduced the drift and through its review. Fixing only
wire.fixtures.ts is what finally made the gate fail — the failure reported the two doubles
disagreeing, which was true but was the second-order symptom, and it was the only reason the
second file was found at all. Had both been left alone, nothing would have reported anything.
An anchor outside the two doubles is what closes this. The kernel is the only thing that knows the
real answer, so the check has to reach it — either by generating one or both doubles from the
capability tables, or by having the test read the kernel's own answer for each batch state and
hold both transcriptions against it. The existing two-way comparison stays useful either way; it
just cannot be the only thing.
This is the same class of gap as a check table whose commands are a subset of the gate (#674): a
guard that reads less than it appears to, where the shortfall is invisible from the passing result.
allowed_actionsis answered bykernel/domain/capabilities.py, and two test doubles transcribeit by hand:
frontend/ui-core/src/testing/wire.fixtures.tsandfrontend/app/e2e/_wire.ts. Thescript test
tests/scripts/wire_rosters.test.mjscompares those two against each other, inboth directions, which is what the earlier report of the untyped duplicate roster (#358) was
closed with.
Comparing them to each other cannot see a mistake they share. The test's own source says so, and
names the two ways out that were considered and not taken — exposing a
@visionset/ui-core/testingsubpath, or generating
_wire.ts— with the reason:_wire.tsis TypeScript thatnode --testcannot load. So the limitation is known and was accepted deliberately.
What is new is evidence of it costing something. The batch pre-labeling branch added a
BatchActionmember and updated neither roster. Both doubles were wrong in the same way, so thegate stayed green through the change that introduced the drift and through its review. Fixing only
wire.fixtures.tsis what finally made the gate fail — the failure reported the two doublesdisagreeing, which was true but was the second-order symptom, and it was the only reason the
second file was found at all. Had both been left alone, nothing would have reported anything.
An anchor outside the two doubles is what closes this. The kernel is the only thing that knows the
real answer, so the check has to reach it — either by generating one or both doubles from the
capability tables, or by having the test read the kernel's own answer for each batch state and
hold both transcriptions against it. The existing two-way comparison stays useful either way; it
just cannot be the only thing.
This is the same class of gap as a check table whose commands are a subset of the gate (#674): a
guard that reads less than it appears to, where the shortfall is invisible from the passing result.