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

Open
#430 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

## 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

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.