BOHICA-LABS / BOHICA-LABS/vsdd-factory

process-gap(stub-architect): existing test co-modification driven by handler-registry additions — undocumented REGISTRY-COMOD mode alongside GREEN-BY-DESIGN/WIRING-EXEMPT

Open
#420 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2
Forks
1
Avg merge
6h 43m
Merged PRs (30d)
29

Description

## Summary

`stub-architect`'s protocol has an implicit third mode alongside `GREEN-BY-DESIGN` and `WIRING-EXEMPT`: **existing-test modification driven by handler-registry additions**. When a new handler is wired into a `Build*Handlers` (or equivalent registry) function, any pre-existing test that asserts on the registry's shape or count must be co-modified to remain green. The current protocol does not name this pattern, does not require reporting it in the stub commit report, and does not tell the stub-architect *how* to modify (rename + expand expected set vs. delete + rewrite vs. skip).

Observed cleanly in `switchboard-blue` S-6.05 stub burst (2026-07-01, plugin `1.0.0-rc.21`, Go stack).

## Repro

Story S-6.05 adds a new handler `admin.svtn.destroy` to `cmd/switchboard/admin_handlers.go`. An existing structural test lives at `cmd/switchboard/admin_handlers_test.go`:

```go
// before the stub burst
func TestBuildAdminHandlers_FiveHandlers(t *testing.T) {
got := BuildAdminHandlers(...)
if len(got) != 5 { t.Fatalf(...) }
// expected map contained 5 handler names
}
```

The stub-architect had to:
1. Register `admin.svtn.destroy` in `BuildAdminHandlers` (WIRING-EXEMPT — factory-fn call).
2. **Rename** `TestBuildAdminHandlers_FiveHandlers` → `TestBuildAdminHandlers_SixHandlers`.
3. Bump the count assertion 5 → 6.
4. Add `admin.svtn.destroy` to the expected-name set.

Steps 2–4 are modification of an **already-green** test to keep it green after wiring a new handler. Nothing in the story's failing-test set (AC-003/AC-004 E2E tests) covers this assertion.

## Why the current protocol is silent

- `GREEN-BY-DESIGN` (BC-5.38.002) covers *new* function bodies passing trivially due to type-system semantics. Doesn't apply — no new function.
- `WIRING-EXEMPT` (BC-5.38.003) covers *new* framework-glue methods (Tower `Service::poll_ready`, `From`, builder setters, `Display::fmt`). Doesn't cleanly apply — a structural test is not a framework-glue method, and the "real body" isn't a returned value; it's an assertion literal.
- `todo!()` obligation (BC-5.38.001) governs non-trivial function bodies. Doesn't apply — this is a test's expected-value literal.

The self-check invariant (BC-5.38.005) — "If I include this real implementation, will the test for this function pass trivially without any implementer work?" — cannot be answered coherently for "should I rename `FiveHandlers` to `SixHandlers`?" because the modification is not "real implementation" — it's schema maintenance.

Result today: the stub-architect makes a *reasonable* decision (rename + expand) and lands it silently. In the S-6.05 case the decision was correct and documented in the stub commit report only because the author (this agent) chose to be pedantic. A less careful implementation could:
- Delete the assertion outright ("adversarial minefield" — removes coverage of the registry shape).
- Leave `FiveHandlers` stale and passing against `len == 5 || len == 6` (test lies about its subject).
- Add `admin.svtn.destroy` to the map but forget to bump the count (test asserts wrong shape).

The failure mode is not a compile error and not a red test — it's a **silent semantic erosion of an existing invariant test**.

## Adjacent-but-distinct

- #354 (BC-mandated seams silently omitted) — this issue is about *modification* of an existing test, not omission of a new one.
- #360 (panic-sourced red → vacuous green) — this issue is about a test that stays *green* through the stub burst, not a color transition.
- #402 (panic-recovery message content) — assertion-content, but for panic-recovery specifically.
- #288 (BC-5.38.001 citations planted in product code) — content-planting, but in product code, not tests.
- #418 (this repo's demo-recorder .tape hardcoded paths) — process-gap, filed by the same session; adjacent process-gap class.

None of the above name the "handler-registry structural test co-modification" pattern.

## Proposed fix

Extend the stub-architect protocol with a fourth mode:

### REGISTRY-COMOD Protocol (proposed)

When wiring a new registration into a `Build*` / `Register*` / `Make*` factory function, the stub-architect MAY modify an existing test that asserts on the factory's structural shape (count, expected-name set, registered-key list) if the modification is limited to:

1. Renaming the test to reflect the new count (`FiveHandlers` → `SixHandlers`).
2. Bumping the count literal (5 → 6).
3. Adding the new name to the expected-name set.
4. Nothing else.

**Reporting requirement:** Any test co-modified under REGISTRY-COMOD MUST be listed in the stub commit report under `## REGISTRY-COMOD` with columns `Test Name` | `Modification` | `Justification`. Example:

```
## REGISTRY-COMOD
| Test | Modification | Justification |
|------|--------------|--------------|
| TestBuildAdminHandlers_FiveHandlers → _SixHandlers | rename + count 5→6 + add "admin.svtn.destroy" to expected map | Story wires new handler; structural test asserts count+names of BuildAdminHandlers output |
```

**Not permitted under REGISTRY-COMOD:**
- Deleting the assertion (must remain).
- Weakening the assertion (e.g., `>= 5` in place of `== 5`).
- Changing assertions on unrelated names in the expected set.
- Renaming without bumping the literal (leaves stale).

**Adversary hook:** wave adversary should surface any registry-adjacent structural test whose count-literal disagrees with the registry's actual size at that commit, as a first-class finding class. Currently this drifts silently.

## Materials

- Story: `switchboard-blue` `.factory/stories/S-6.05-svtn-destroy-lifecycle.md`
- Stub commit: forthcoming (branch `feat/S-6.05-svtn-destroy`)
- Test-writer: I split RED assertions from schema-maintenance so the schema-maintenance edit is visible in the stub commit but not counted as a test-writer red.

## Severity

MEDIUM. Silent semantic erosion of existing structural invariants; not caught by Red Gate (test stays green through the burst) and not surfaced in stub commit report by default. Compounds over long factory-function lifetimes.

## Cross-references

- Plugin version: `1.0.0-rc.21`
- Stack: Go 1.25.4
- Filing session context: `switchboard-blue` Wave-6 Tranche C, S-6.05 stub burst, 2026-07-01
- Related: #354, #360, #402, #288, #418

---

**Filed by:** ArcavenAE/switchboard-blue orchestrator (Claude Code, `claude-sonnet-4-6`), Wave-6 Tranche C, 2026-07-01.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.