docs(voyage): S5 — formalize Handover 1 brief-schema as public contract (v5.4)

Elevate Handover 1 (brief.md → research) from an internal pipeline handover
to an explicit PUBLIC CONTRACT — the only public producer↔Voyage integration
boundary (Trinity asymmetry invariant: Voyage stays unaware of upstream tiers;
any compatible producer may feed it; no producer privileged).

Scope = freeze + document (operator-gated, option A). No schema change, no
plugin version bump (that is S10 RELEASE). Per S3, phase_signals stays optional
and brief_version 2.1 is the frozen public-contract baseline.

- docs/HANDOVER-CONTRACTS.md: PUBLIC CONTRACT label + callout on Handover 1
  (asymmetry, breaking-for-downstream, additive-vs-breaking, frozen 2.1 baseline);
  resolve the speculative "v5.4 may promote phase_signals to required → 3.0" line
  to the S3 freeze decision; fix stale schema-table baseline 2.0 → 2.1; annotate
  the Stability summary row (symmetric with Handover 3's "external" flag).
- CLAUDE.md: Trinity note now points at docs/HANDOVER-CONTRACTS.md §Handover 1.
- tests/lib/doc-consistency.test.mjs: +4 failing-first doc-truth pins (Iron Law)
  — PUBLIC CONTRACT label, callout + breaking-for-downstream guarantee, frozen
  2.1 baseline (no stale 2.0), freeze-not-promote. 586/584 pass/0 fail/2 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqBYc8Ltrk7LipyJmGxXiB
This commit is contained in:
Kjell Tore Guttormsen 2026-06-18 12:40:02 +02:00
commit fa23b16443
3 changed files with 43 additions and 5 deletions

View file

@ -620,3 +620,39 @@ test('v5.1.1 — commands/trekexecute.md contains ### High-effort behavior (v5.1
assert.match(t, /^### High-effort behavior \(v5\.1\.1\)$/m,
'trekexecute.md must contain ### High-effort behavior (v5.1.1) sub-section under Composition rule (gates_mode = closed)');
});
// --- v5.4 — brief.md formalized as PUBLIC CONTRACT (Handover 1) ---
// S5: the brief schema is the only public producer↔Voyage integration boundary
// (Trinity asymmetry invariant). These pin the formalization as enforced doc-truth,
// not prose — same pattern as the v5.1 Handover-1 pins above. Freeze, not promote:
// phase_signals stays optional; brief_version 2.1 is the frozen baseline (S3 decision).
test('v5.4 — HANDOVER-CONTRACTS.md Handover 1 heading is labeled (PUBLIC CONTRACT)', () => {
const t = read('docs/HANDOVER-CONTRACTS.md');
assert.match(t, /^## Handover 1 —.*\(PUBLIC CONTRACT\)\s*$/m,
'Handover 1 heading must carry the (PUBLIC CONTRACT) label — symmetric with Handover 3 (EXTERNAL CONTRACT)');
});
test('v5.4 — Handover 1 declares the PUBLIC CONTRACT callout + breaking-for-downstream guarantee', () => {
const t = read('docs/HANDOVER-CONTRACTS.md');
assert.ok(t.includes('Stability tier: PUBLIC CONTRACT'),
'Handover 1 must open with a "Stability tier: PUBLIC CONTRACT" callout');
assert.ok(t.includes('breaking change for every downstream consumer'),
'the callout must state that a brief-schema change is a breaking change for every downstream consumer');
});
test('v5.4 — brief_version 2.1 is the frozen public-contract baseline (no stale 2.0)', () => {
const t = read('docs/HANDOVER-CONTRACTS.md');
assert.ok(!t.includes('`"2.0"` (current)'),
'Handover 1 schema table must not still mark brief_version "2.0" as current (stale)');
assert.ok(t.includes('`"2.1"` (current)'),
'Handover 1 schema table must mark brief_version "2.1" as current');
});
test('v5.4 — phase_signals stays optional: v5.4 freezes, does not promote to required', () => {
const t = read('docs/HANDOVER-CONTRACTS.md');
assert.ok(!t.includes('v5.4 may promote'),
'the speculative "v5.4 may promote phase_signals to required" line must be resolved (S3 froze the shape)');
assert.ok(t.includes('freezes this schema as the public-contract baseline'),
'the Versioning note must record that v5.4 freezes the schema as the public-contract baseline');
});