BOHICA-LABS / BOHICA-LABS/vsdd-factory
[process-gap] body-prose ↔ impl-symbol drift persists across all POL-001/002/003 gates — POL-005-body-prose-impl-anchor-check
- Dominant language
- Rust
- Stars
- 2
- Forks
- 1
- Avg merge
- 6h 43m
- Merged PRs (30d)
- 29
Description
## Problem
POL-001 (changelog-completeness), POL-002 (index-row sync), and POL-003 (bidirectional-pin sync) collectively enforce version-citation coherence across frontmatter, index files, and cross-doc pointer cells. They do NOT enforce **narrative body prose ↔ impl behavior coherence**. Body sections that describe *what* the code does — AC bodies, invariant text, ruling rationale, task descriptions — can drift arbitrarily far from the impl reality without tripping any current gate.
## Concrete evidence (dual instance, one wave, one week)
### Instance 1: switchboard-blue S-6.05 F-P5L1-MED-1
- Story AC-003 body: "when omitted the command enters interactive mode prompting `Type SVTN- to confirm:`"
- Impl (`cmd/sbctl/admin.go:231-234`): static abort with error, no TTY read
- Test docstring: "no interactive TTY prompt"
- Story Confirm-Gate Semantics section: static syntactic check only
- Story Task 11: dead-letter "[TO IMPLEMENT] --confirm interactive prompt fallback" — impl never delivered
- Story frontmatter/index citations all sync-clean at story v1.7 through Pass-4
### Instance 2: switchboard-blue S-7.03 F-P4L3-MED-002
- BC-2.08.001 Inv-3 v1.2 body: "management-plane **Unix-socket** transport (ADR-006 / ADR-012)"
- Impl (`cmd/switchboard/mgmt_wire.go:143,153-158`): unconditional TCP loopback for console mode per BC-2.07.004 EC-013 / AC-014 Ruling D
- Story S-7.03 AC-001/002/003 body prose: propagates the same "mgmt-plane Unix socket" wording (3 locations)
- VP-050 Story Trace row: same wording
- RULING-W6TB-C decision text: same wording (6 locations)
- BC frontmatter/index citations all sync-clean at BC v1.3 / story v1.3 / VP v1.2 through Pass-3
In both instances, an implementer or reviewer reading the body text alone would form a false model of what the code does. In instance 2, this could lead a future implementer to break BC-2.07.004 EC-013.
## Proposed policy (POL-005-body-prose-impl-anchor-check)
Every AC body, invariant text, and ruling rationale that describes *observable code behavior* (as opposed to abstract contract shape) MUST include one of:
1. `→ impl at :` — direct impl anchor; adversary L2 lens verifies against the impl at the cited path.
2. `→ verified by test at ` — test anchor; adversary L2 verifies the test symbol exists and its assertions match the body claim.
3. `→ authoritative in ` — deferral to another spec artifact that carries an impl or test anchor.
4. `[UNVERIFIED impl anchor]` — explicit blind-write marker forcing next adversary Pass to close by verifying against impl.
### Enforcement candidates
- `spec-steward` gains a "body-prose anchor scan": for AC/invariant/ruling bodies containing text matching `/when (?:omitted|invoked|called|received|absent|present)/` OR `/transport (?:is|uses|binds)/` (imperative behavioral claims), require one of the four markers.
- `adversary` L1 lens (existing) plus a new L1 sub-axis "body-vs-impl": one AC per story per Pass gets a spot-check where the adversary greps the impl and verifies the AC body language matches.
- `pr-manager` gains a `body-prose-diff` sub-check at the final review: any hunks touching AC/invariant/ruling body prose require anchor-marker validity or a re-verification tag from an adversary run.
### Alternative (lighter)
Require every AC/invariant/ruling body to carry a `verified_by_test: ` YAML field in a frontmatter block. Adversary L2 (existing test-symbol existence check per F-P4L2-HIGH-1) then subsumes the anchor check with zero new grep logic.
## Sibling / cross-refs
- #382 (doc-comments asserting behavior not verified) — code-side sibling.
- #396 (spec-steward citation-corpus sweep on BC-bump) — sync-side sibling (index/citation drift).
- #428 (POL-001-verify-attestations) — same-cycle sibling (changelog-attestation drift).
- #429 (POL-003 governance_leaf cascade termination) — same-cycle sibling (governance loop).
## Severity: HIGH
Both concrete instances are MEDIUM-to-HIGH severity in their own right (spec-vs-impl contradiction on load-bearing anchors). The *class* is HIGH because:
- (a) it reproduces reliably across independent stories with unrelated content
- (b) it survives ALL current POL-{001,002,003} enforcement
- (c) the drift can be very large (multi-BC, multi-file propagation as in S-7.03)
- (d) late detection multiplies fix cost (S-7.03 F-P4L3-MED-002 requires ~10 file edits across BC/story/VP/ruling)
- (e) it can produce production-safety issues if an implementer defers to body-prose over impl comments
## Concrete data on gate porosity
Both instances passed:
- POL-001 (changelog-completeness) ✓
- POL-002 (story-index row sync) ✓
- POL-003 (bidirectional pins) ✓ (except the S-6.05 Pass-5 F-P5L3-MED-1 cascade lag, which #429 addresses)
- 3-lens adversary Pass 1..3 for S-6.05, Pass 1..2 for S-7.03 ✓
- Only fresh-context Pass-N adversary re-runs with impl-side grep caught them.
## Evidence paths (in-tree, switchboard-blue)
- `.factory/cycles/cycle-1/adversarial-reviews/S-6.05-adversary-pass-5.md` (F-P5L1-MED-1)
- `.factory/cycles/cycle-1/adversarial-reviews/S-7.03-adversary-pass-4.md` (F-P4L3-MED-002)
Contributor guide
Assessment
This issue has not been assessed yet.