astp-docs-server 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. astp_docs_server/__init__.py +12 -0
  2. astp_docs_server/__main__.py +8 -0
  3. astp_docs_server/atlas_manifest.py +108 -0
  4. astp_docs_server/corpus/open/CHANGELOG.md +568 -0
  5. astp_docs_server/corpus/open/CONFORMANCE-BFM.md +430 -0
  6. astp_docs_server/corpus/open/CONFORMANCE-CONTEXT.md +332 -0
  7. astp_docs_server/corpus/open/CONFORMANCE-CROSS-EPISODE-LINKING.md +258 -0
  8. astp_docs_server/corpus/open/CONFORMANCE-LAYER3.md +272 -0
  9. astp_docs_server/corpus/open/CONFORMANCE-REPRODUCIBILITY.md +219 -0
  10. astp_docs_server/corpus/open/CONFORMANCE-TRUST.md +639 -0
  11. astp_docs_server/corpus/open/GLOSSARY.md +661 -0
  12. astp_docs_server/corpus/open/GOVERNANCE.md +43 -0
  13. astp_docs_server/corpus/open/IMPLEMENTATION-CONTEXT.md +121 -0
  14. astp_docs_server/corpus/open/IMPLEMENTATION-PHASE3.md +732 -0
  15. astp_docs_server/corpus/open/LICENSE.txt +202 -0
  16. astp_docs_server/corpus/open/NOTICE +60 -0
  17. astp_docs_server/corpus/open/PATENTS.md +325 -0
  18. astp_docs_server/corpus/open/PROTOCOL-CONFORMANCE.md +470 -0
  19. astp_docs_server/corpus/open/RATIFICATION-5.0.0.md +56 -0
  20. astp_docs_server/corpus/open/RATIFICATION-6.0.0.md +71 -0
  21. astp_docs_server/corpus/open/RATIFICATION-PATENTS-1.0.0.md +116 -0
  22. astp_docs_server/corpus/open/RATIFICATION-PROTOCOL-CONFORMANCE-1.0.0.md +145 -0
  23. astp_docs_server/corpus/open/RATIFICATION-SPEC-6.0.2.md +136 -0
  24. astp_docs_server/corpus/open/README.md +230 -0
  25. astp_docs_server/corpus/open/SPEC.md +3220 -0
  26. astp_docs_server/corpus/open/VERSIONING.md +105 -0
  27. astp_docs_server/corpus/open/vectors/5.0.0/seal-constructions.json +402 -0
  28. astp_docs_server/corpus/open/vectors/6.0.0/context-commitment.json +353 -0
  29. astp_docs_server/corpus/open/vendor_manifest.json +31 -0
  30. astp_docs_server/mcp_server.py +145 -0
  31. astp_docs_server/open_corpus.py +235 -0
  32. astp_docs_server/vendor_manifest.py +124 -0
  33. astp_docs_server/web/__init__.py +7 -0
  34. astp_docs_server/web/__main__.py +5 -0
  35. astp_docs_server/web/answerer.py +307 -0
  36. astp_docs_server/web/app.py +151 -0
  37. astp_docs_server-0.1.0.dist-info/METADATA +107 -0
  38. astp_docs_server-0.1.0.dist-info/RECORD +42 -0
  39. astp_docs_server-0.1.0.dist-info/WHEEL +4 -0
  40. astp_docs_server-0.1.0.dist-info/entry_points.txt +3 -0
  41. astp_docs_server-0.1.0.dist-info/licenses/LICENSE.txt +202 -0
  42. astp_docs_server-0.1.0.dist-info/licenses/NOTICE +72 -0
@@ -0,0 +1,430 @@
1
+ # ASTP — BFM Conformance Test Vectors
2
+
3
+ **Version:** 1.3.0
4
+ **Status:** Stable
5
+ **Authors:** Scorched Earth Labs
6
+ **Date:** 2026-09-19
7
+ **Applies To:** SPEC.md §19 (Branch / Fork / Merge / **Departure Fork** / Aside / Soliloquy / CoherenceFingerprint + Orphan Recovery), 5.1.0 (SPEC §19 as of 5.1.0; see the note in §1)
8
+
9
+ ---
10
+
11
+ ## 1. Overview
12
+
13
+ > **SPEC 5.0.0 / 5.1.0 note.** Two things changed above this document and are stated here so it is not read as current on them. (1) **Seals commit structural nodes.** Under `spine_algorithm_version` 2 a BranchPoint, BranchTerminus, ForkPoint, DepartureForkPoint, ForkReturn, MergePoint and every concluded HITL event is a *structural-manifest member* (SPEC §5.7.1), hashed from its **stored fields** under its own `:v2:` prefix by the canonical field encoding of §5.1.1 — provenance and commentary fields (`initiated_by`, `initiator`, `returned_by`, labels, summaries) are out of those preimages, `spine_merkle_snapshot` and `merge_type` are in, and `GENESIS` is NULL. Those member hashes are pinned in [`vectors/5.0.0/seal-constructions.json`](./vectors/5.0.0/seal-constructions.json) and computed by `astp/core/seal_v2.py`; the reference deployment's adapter supplies the reader. The 4.x `content_hash` values this document describes are still what the reference writers stamp on the nodes; they are not what a version 2 seal commits. (2) **Asides and soliloquies.** SPEC §19.4 now defines their content hashes as `ASIDE:v2:`, `ASIDE_TERMINUS:v2:`, `SOLILOQUY:v2:`, `DELIBERATION_CHAIN:v2:` (over the deliberation Segments' content hashes, in order) and `SOLILOQUY_CONCLUSION:v2:`, with the 4.x forms — including the two-policy `SoliloquyContentHashPolicy` — retained only as the definitions of nodes already written. The reference writers (`create_aside`, `close_aside`, `create_soliloquy`, `conclude_soliloquy`) stamp the 5.0.0 forms from `astp` 0.5.0; nodes written before that carry the 4.x forms this document describes. The `FINGERPRINT:` prefix is retired: a coherence fingerprint has no content hash (§19.5.1).
14
+
15
+ This document specifies the conformance test vectors for the Branch/Fork/Merge (BFM) feature family of ASTP (the AI State Tree Protocol). A conforming implementation MUST pass all vectors marked **REQUIRED**. Vectors marked **RECOMMENDED** test behaviors that conforming implementations SHOULD support.
16
+
17
+ BFM is organized into the following phases (the reference deployment's adapter guide, `IMPLEMENTATION-BFM.md`, which lives with that adapter, follows the same order):
18
+
19
+ | Phase | Scope | Vector Prefix |
20
+ |-------|-------|---------------|
21
+ | 1 | Branch lifecycle (linear deviation) | `BR-` |
22
+ | 2 | Fork / merge / common ancestor | `FM-` |
23
+ | D | Departure-fork lifecycle (single directional departure; origin continues) + orphan recovery | `DF-` / `FO-` |
24
+ | 3 | Aside / Soliloquy (social & internal primitives) | `AS-` / `SL-` |
25
+ | 4 | Coherence fingerprint write-time branch detection | `CF-` |
26
+
27
+ Vector format matches `CONFORMANCE-TRUST.md` (Phase 3 Trust Infrastructure §16): ID, spec reference, class, description, inputs, expected output, failure condition. All hex values lowercase. All string fields UTF-8.
28
+
29
+ > **v1.1.0 reconciliation note.** This vector set was realigned to SPEC v3.2.1: §19 subsection references and governance rule numbers were corrected to the consolidated §19 / G-19–G-29 numbering (the v1.0.0-draft predated it), and the Phase D `DF-` set was added. Branch-phase governance (depth limit, access policy, abandonment reason) is enforced at the implementation layer — it has no numbered SPEC §19 governance rule — so those vectors cite the `IMPLEMENTATION-BFM.md` enforcement function rather than a G-number.
30
+ >
31
+ > **v1.2.0 note.** Added the orphan-recovery `FO-` set (§4.5, SPEC §19.3.7). These are state-integrity vectors (they test the shape of a conformant *recovery*), not new governance rules — and FO-008 makes explicit that running detection is **not** a conformance requirement.
32
+
33
+ ---
34
+
35
+ ## 2. Phase 1 — Branch Lifecycle Vectors (§19.2)
36
+
37
+ ### 2.1 Hash Canonicalization
38
+
39
+ **BR-001** — `BranchPointNode` commitment hash
40
+ - **Class:** REQUIRED
41
+ - **Spec Reference:** §19.2.1, §19.2.3 (Dual Hash Chain)
42
+ - **Description:** `compute_branch_point_hash()` MUST produce identical bytes across implementations given identical inputs. The canonical byte layout covers: `parent_episode_id`, `branch_id`, `declaration_type`, `parent_sequence_index`, `branch_root_content_hash`, `authored_by`, `created_at`.
43
+ - **Verification Protocol:** Cross-implementation consistency check (pattern matches KH-001). Two conforming implementations MUST produce identical `branch_point_hash` bytes for the same input tuple.
44
+ - **Failure Condition:** Divergent bytes indicate a canonicalization error (wrong field order, wrong integer encoding, missing field).
45
+
46
+ **BR-002** — `BranchTerminusNode` commitment hash
47
+ - **Class:** REQUIRED
48
+ - **Spec Reference:** §19.2.2, §19.2.3
49
+ - **Description:** `compute_branch_terminus_hash()` canonicalizes `branch_id`, `terminus_type`, `final_sequence_index`, `terminus_content_hash`, `abandonment_reason` (optional), `authored_by`, `closed_at`.
50
+
51
+ **BR-003** — `AuditRecord` commitment hash
52
+ - **Class:** REQUIRED
53
+ - **Spec Reference:** §19.2.4 (Derived Lifecycle State)
54
+ - **Description:** `compute_audit_record_hash()` forms a content-addressed chain where `prior_audit_hash` binds each record to its predecessor. Implementations MUST NOT allow silent tampering; recomputing the hash over stored fields MUST match the stored `audit_hash`.
55
+ - **Failure Condition:** Any stored `AuditRecord` whose recomputed hash diverges from its stored value.
56
+
57
+ **BR-004** — `IntentRecord` idempotency key
58
+ - **Class:** REQUIRED
59
+ - **Spec Reference:** §19.2.4
60
+ - **Description:** `compute_intent_idempotency_key()` MUST collapse retried writes with the same `(agent_id, intent_type, resource_id, request_sequence)` tuple to the same key. A second `create_branch` call with the same idempotency key MUST return the original `BranchResult` without creating a new `BranchPointNode`.
61
+
62
+ ### 2.2 Governance Enforcement
63
+
64
+ > Branch-phase governance below is enforced at the implementation layer (the reference adapter's guide, `IMPLEMENTATION-BFM.md` §3.2, shipped with that adapter); the current SPEC §19 defines no numbered branch-phase governance rule. Numbered SPEC governance begins at G-19 (fork).
65
+
66
+ **BR-005** — Branch depth limit
67
+ - **Class:** REQUIRED
68
+ - **Spec Reference:** §19.2, IMPLEMENTATION-BFM §3.2 (`enforce_branch_depth_limit`)
69
+ - **Description:** `enforce_branch_depth_limit()` MUST reject (or log-on-override) any `create_branch` whose resulting lineage depth exceeds the soft maximum (default 4). Depth is counted from the root episode, inclusive.
70
+ - **Failure Condition:** A lineage past the soft max is created with no audit record of the override.
71
+
72
+ **BR-006** — Access policy gate
73
+ - **Class:** RECOMMENDED
74
+ - **Spec Reference:** §19.2, IMPLEMENTATION-BFM §3.2
75
+ - **Description:** Where an implementation records an `AccessPolicy`, branch creation whose policy denies the requester's `AccessLevel` for the requested `AccessResourceType` MUST be rejected before any write.
76
+
77
+ **BR-007** — Abandonment reason required
78
+ - **Class:** REQUIRED
79
+ - **Spec Reference:** §19.2.2, IMPLEMENTATION-BFM §3.2 (`enforce_abandonment_reason_required`)
80
+ - **Description:** `enforce_abandonment_reason_required()` MUST reject `abandon_branch()` calls whose `reason` is `None` or the empty string. A branch with `terminus_type=ABANDONED` MUST have a non-empty reason recorded.
81
+
82
+ ---
83
+
84
+ ## 3. Phase 2 — Fork / Merge Vectors (§19.3)
85
+
86
+ ### 3.1 Hash Canonicalization
87
+
88
+ **FM-001** — `ForkPointNode` commitment hash
89
+ - **Class:** REQUIRED
90
+ - **Spec Reference:** §19.3.1
91
+ - **Description:** `compute_fork_point_hash()` canonicalizes `parent_episode_id`, `fork_id`, `objective_hash`, `sibling_branch_ids` (sorted), `parent_sequence_index`, `authored_by`, `created_at`.
92
+
93
+ **FM-002** — `MergePointNode` commitment hash
94
+ - **Class:** REQUIRED
95
+ - **Spec Reference:** §19.3.2
96
+ - **Description:** `compute_merge_point_hash()` canonicalizes all three integrity roots (`source_merkle_root`, `target_merkle_root_pre`, `target_merkle_root_post`) plus `merge_id`, `source_episode_id`, `target_episode_id`, `common_ancestor_id`, `timestamp`, `parent_hash`. Domain prefix `MERGE_POINT:`.
97
+
98
+ **FM-003** — `ConflictManifest` commitment hash
99
+ - **Class:** REQUIRED
100
+ - **Spec Reference:** §19.3.2 (G-23 Conflict Surface Invariant)
101
+ - **Description:** `compute_conflict_manifest_hash()` canonicalizes an ordered list of `ConflictSegment`+`ConflictResolution` pairs. Order-independence is a non-goal; reordering changes the hash. Domain prefix `CONFLICT_MANIFEST:`.
102
+
103
+ ### 3.2 Governance Enforcement
104
+
105
+ **FM-004** — Fork objective required (G-19)
106
+ - **Class:** REQUIRED
107
+ - **Spec Reference:** §19.3.1, G-19
108
+ - **Description:** `create_fork()` with a missing or empty `fork_objective` MUST be rejected. A fork without an objective is indistinguishable from a branch.
109
+
110
+ **FM-005** — Fork alternatives ≥ 2 (G-20)
111
+ - **Class:** REQUIRED
112
+ - **Spec Reference:** §19.3.1, G-20
113
+ - **Description:** A fork creating fewer than 2 sibling alternatives MUST be rejected. Single-path divergence is a branch, not a fork.
114
+
115
+ **FM-006** — Merge summary required (G-22)
116
+ - **Class:** REQUIRED
117
+ - **Spec Reference:** §19.3.2, G-22
118
+ - **Description:** `execute_merge()` calls without a non-empty `merge_summary` MUST be rejected. Every merge records why the convergence happened.
119
+
120
+ **FM-007** — Three-root conflict-surface integrity (G-23)
121
+ - **Class:** REQUIRED
122
+ - **Spec Reference:** §19.3.2, G-23, IMPLEMENTATION-BFM §4.3
123
+ - **Description:** On conflicts without matching resolutions — or `merge_strategy == AUTO` with any conflicts — `execute_merge()` MUST write NO merge records and return a `ConflictManifest` carrying `source_merkle_root`, `target_merkle_root_pre`, the common ancestor, and all conflict segments. Every manifest-referenced segment MUST be reachable from at least one of the three recorded roots.
124
+ - **Failure Condition:** A merge silently commits a conflicted resolution, or a manifest entry references a segment not present under any of the three roots.
125
+
126
+ **FM-008** — `find_common_ancestor()` determinism
127
+ - **Class:** REQUIRED
128
+ - **Spec Reference:** §19.3.2
129
+ - **Description:** `find_common_ancestor(branch_id, target_episode_id)` MUST return the same `CommonAncestorResult` across repeated invocations on stable graph state, preferring the most-recent shared ancestor (LCA semantics) when multiple common ancestors exist.
130
+
131
+ **FM-009** — Merge integrity verification (G-24)
132
+ - **Class:** REQUIRED
133
+ - **Spec Reference:** §19.3.3, G-24
134
+ - **Description:** `verify_merge_integrity()` MUST re-verify all three Merkle roots against stored `MergePointNode` fields (`source_valid ∧ target_pre_valid ∧ target_post_valid`). Any field-level mutation MUST produce `integrity_holds = false`.
135
+
136
+ ---
137
+
138
+ ## 4. Phase D — Departure-Fork Vectors (§19.3.5–19.3.6)
139
+
140
+ A departure fork is a single directional departure (`create_departure_fork()`) into a new Episode while the origin *continues* — distinct from the speculative fork of §3. (The reference adapter's guide, `IMPLEMENTATION-BFM.md` §5, describes one storage layout.)
141
+
142
+ ### 4.1 Hash Canonicalization
143
+
144
+ **DF-001** — `DepartureForkPointNode` commitment hash
145
+ - **Class:** REQUIRED
146
+ - **Spec Reference:** §19.3.5
147
+ - **Description:** `compute_departure_fork_point_hash()` canonicalizes, in order, `fork_point_id`, `fork_id`, `fork_episode_id`, `origin_episode_id`, `origin_segment_id`, `fork_objective`, `fork_creation_trigger`, `spine_tip_hash_at_departure`, `initiator`, `timestamp`, `parent_hash`. Domain prefix `DEPARTURE_FORK_POINT:` (SHA3-256).
148
+ - **Verification Protocol:** Cross-implementation consistency check. Two conforming implementations MUST produce identical bytes for the same input tuple.
149
+ - **Failure Condition:** The `DEPARTURE_FORK_POINT:` prefix collides with `FORK_POINT:` (a departure fork point and a speculative fork point with otherwise-identical fields MUST hash differently), or any field-order divergence.
150
+
151
+ **DF-002** — `ForkReturnNode` commitment hash
152
+ - **Class:** REQUIRED
153
+ - **Spec Reference:** §19.3.5
154
+ - **Description:** `compute_fork_return_hash()` canonicalizes, in order, `fork_return_id`, `fork_id`, `fork_episode_id`, `origin_episode_id`, `return_type`, `synthesis_summary`, `fork_final_spine_tip_hash`, `returned_by`, `timestamp`, `parent_hash`. Domain prefix `FORK_RETURN:` (SHA3-256).
155
+
156
+ ### 4.2 The Backdating Integrity Invariant
157
+
158
+ **DF-003** — Backdating integrity (G-30)
159
+ - **Class:** REQUIRED
160
+ - **Spec Reference:** §19.3.5, G-30
161
+ - **Description:** `create_departure_fork()` MUST make `DepartureForkPointNode.spine_tip_hash_at_departure` equal to the fork Episode's `fork_origin_spine_tip_hash` — both derived from a single read of the origin spine tip at the departure moment. Cross-verifiable across the two independent spines.
162
+ - **Failure Condition:** The fork point's `spine_tip_hash_at_departure` and the fork Episode's `fork_origin_spine_tip_hash` differ. This MUST be a fatal error at creation, never a runtime reconciliation.
163
+
164
+ ### 4.3 Governance Enforcement
165
+
166
+ **DF-004** — Fork objective required (G-31)
167
+ - **Class:** REQUIRED
168
+ - **Spec Reference:** §19.3.5, G-31
169
+ - **Description:** `create_departure_fork()` with an empty `fork_objective` MUST be rejected (mirrors G-19 for the speculative fork).
170
+
171
+ **DF-005** — Trigger whitelist (G-32)
172
+ - **Class:** REQUIRED
173
+ - **Spec Reference:** §19.3.5, G-32
174
+ - **Description:** `fork_creation_trigger` MUST be one of `{TOPIC_SHIFT, PARALLEL_THREAD, EXPLICIT_FORK, AGENT_ESCALATION}`. `EXPLORATORY_THREAD` MUST be rejected here — it routes to the speculative `create_fork()`.
175
+
176
+ **DF-006** — Escalation requires trigger segment (G-33)
177
+ - **Class:** REQUIRED
178
+ - **Spec Reference:** §19.3.5, G-33
179
+ - **Description:** When `fork_creation_trigger == AGENT_ESCALATION`, `fork_trigger_segment_id` MUST be present. Escalations must point at the segment that provoked them.
180
+
181
+ ### 4.4 Lifecycle FSM
182
+
183
+ **DF-007** — State transitions
184
+ - **Class:** REQUIRED
185
+ - **Spec Reference:** §19.3.5
186
+ - **Description:** The lifecycle FSM is `ACTIVE → COMPLETED | ABANDONED`. `complete_departure_fork()` (`ACTIVE → COMPLETED`) and `abandon_departure_fork()` (`ACTIVE → ABANDONED`, terminal) MUST reject transitions from any non-`ACTIVE` state. A `COMPLETED` fork MUST NOT be abandoned.
187
+ - **Verification Protocol:** Given a state and an operation, the resulting state MUST match the FSM; illegal transitions MUST raise, not silently no-op.
188
+ - **Failure Condition:** A `COMPLETED` or `ABANDONED` fork accepts a further transition; resumption (re-entering the origin while the fork stays `ACTIVE`) writes any node or declaration (it MUST be a non-event).
189
+
190
+ **DF-008** — Return requires COMPLETED (G-34)
191
+ - **Class:** REQUIRED
192
+ - **Spec Reference:** §19.3.5, G-34
193
+ - **Description:** `declare_fork_return()` MUST reject any fork whose `fork_status` is not `COMPLETED`.
194
+
195
+ **DF-009** — At most one return per fork (G-35)
196
+ - **Class:** REQUIRED
197
+ - **Spec Reference:** §19.3.5, G-35
198
+ - **Description:** A second `declare_fork_return()` for a `fork_id` that already has a `ForkReturnNode` MUST be rejected. `return_type ∈ {INCORPORATED, ACKNOWLEDGED, SUPERSEDED}`; the return is declarative (origin-spine assertion across two spines), never a structural merge.
199
+
200
+ ### 4.5 Orphan Recovery (§19.3.7)
201
+
202
+ These vectors test the *shape of a conformant recovery*, not that an implementation runs detection — **detection cadence is explicitly non-normative** (FO-008).
203
+
204
+ **FO-001** — `ForkOrphanMarker` self-hash determinism
205
+ - **Class:** REQUIRED
206
+ - **Spec Reference:** §19.3.7
207
+ - **Description:** `compute_fork_orphan_marker_hash()` (domain `FORK_ORPHAN_MARKER:`) canonicalizes `fork_orphan_marker_id`, `fork_id`, `origin_episode_id`, `orphan_class`, `sequence_index`, `detection_run_id`, `recovery_action`, `requires_operator_review`, `detected_at`. Two conforming implementations MUST produce identical bytes for the same input tuple.
208
+
209
+ **FO-002** — Marker is a non-chained satellite (Spine isolation)
210
+ - **Class:** REQUIRED
211
+ - **Spec Reference:** §19.3.7
212
+ - **Description:** A `ForkOrphanMarker` is self-hashed (`content_hash`) but MUST NOT participate in the origin spine's Merkle chain — it carries no `parent_hash`, and writing it MUST NOT change the origin Episode's spine root/tip.
213
+ - **Verification Protocol:** Capture the origin Episode's spine root; write a marker; the root MUST be unchanged.
214
+ - **Failure Condition:** Writing a marker alters the origin Episode's integrity fingerprint (a diagnostic write mutating the cryptographic record).
215
+
216
+ **FO-003** — Marker dedup (one per orphaned fork)
217
+ - **Class:** REQUIRED
218
+ - **Spec Reference:** §19.3.7
219
+ - **Description:** Markers are deduplicated on `fork_id` — a re-detection sweep that re-finds the same orphan MUST NOT create a duplicate marker.
220
+ - **Failure Condition:** Two detection passes over the same unresolved orphan yield two marker nodes.
221
+
222
+ **FO-004** — Marker excluded from departure registry
223
+ - **Class:** REQUIRED
224
+ - **Spec Reference:** §19.3.7
225
+ - **Description:** Departure-registry queries match `DepartureForkPointNode` / `ForkReturnNode` only. A `ForkOrphanMarker` MUST NOT appear in departure-registry results.
226
+
227
+ **FO-005** — Class-B retroactive write: append + backdated anchor + byte-identical
228
+ - **Class:** REQUIRED
229
+ - **Spec Reference:** §19.3.7
230
+ - **Description:** The Class-B retroactive `DepartureForkPointNode` write MUST (a) use the fork Episode's stored `fork_origin_spine_tip_hash` as the point's `spine_tip_hash_at_departure` so the cross-verifiable invariant holds, (b) produce a `content_hash` **byte-identical** to an on-time write (the `retroactive` / `orphan_recovery_timestamp` flags are outside the preimage), and (c) create ONLY the missing point — no existing spine node or chain hash is recomputed.
231
+ - **Failure Condition:** The recovered point's `content_hash` differs from an on-time write, OR any pre-existing spine hash changes.
232
+
233
+ **FO-006** — Class-B hash-mismatch gate
234
+ - **Class:** REQUIRED
235
+ - **Spec Reference:** §19.3.7
236
+ - **Description:** When the fork provenance is inconsistent with the origin spine at `fork_anchor_index`, recovery MUST escalate to an operator and MUST NOT write the retroactive point.
237
+
238
+ **FO-007** — Append-only recovery
239
+ - **Class:** REQUIRED
240
+ - **Spec Reference:** §19.3.7
241
+ - **Description:** Orphan recovery MUST NOT delete spine nodes. A dangling point (Class A) is flagged `orphaned=true` and marked, never removed.
242
+
243
+ **FO-008** — Detection cadence is non-normative
244
+ - **Class:** RECOMMENDED
245
+ - **Spec Reference:** §19.3.7
246
+ - **Description:** Conformance does NOT require an implementation to run orphan detection, nor at any particular cadence. Only the node schema, the field mutations, and the retroactive-write discipline (FO-001…007) are normative. An implementation that never orphans (or resolves orphans by other means) is conformant provided it never violates the invariants.
247
+
248
+ ---
249
+
250
+ ## 5. Phase 3 — Aside / Soliloquy Vectors (§19.4)
251
+
252
+ ### 5.1 Aside Hash Canonicalization
253
+
254
+ **AS-001** — `AsideSegmentNode` commitment hash
255
+ - **Class:** REQUIRED
256
+ - **Spec Reference:** §19.4.1
257
+ - **Description:** `compute_aside_hash()` canonicalizes `aside_id`, `parent_segment_id`, `initiated_by_human`, `target_agent_id`, `content_hash`, `opened_at`.
258
+
259
+ ### 5.2 Aside Governance
260
+
261
+ **AS-002** — Aside human-initiated (G-25)
262
+ - **Class:** REQUIRED
263
+ - **Spec Reference:** §19.4.1, G-25
264
+ - **Description:** An aside whose `initiated_by_human` is missing or does not identify a human user MUST be rejected. Asides are strictly human-initiated — agent-initiated diversions use soliloquy.
265
+
266
+ **AS-003** — Aside target agent required
267
+ - **Class:** REQUIRED
268
+ - **Spec Reference:** §19.4.1
269
+ - **Description:** An aside without a `target_agent_id` MUST be rejected. Every aside pairs one human with one agent; multi-agent asides are modeled as nested asides.
270
+
271
+ **AS-004** — Aside close reason required
272
+ - **Class:** REQUIRED
273
+ - **Spec Reference:** §19.4.1
274
+ - **Description:** `close_aside()` without a non-empty `reason` MUST be rejected. The close reason distinguishes `AsideTerminationStatus` values (`resolved`, `abandoned`, `superseded`, etc).
275
+
276
+ **AS-005** — Aside return obligation at episode seal (G-26)
277
+ - **Class:** REQUIRED
278
+ - **Spec Reference:** §19.4.1, G-26
279
+ - **Description:** `check_aside_return_obligation(aside_open=True, episode_sealing=True)` MUST raise. An episode MUST NOT seal while an aside is open; all asides must close or be explicitly abandoned first.
280
+
281
+ **AS-006** — Aside external reference scan
282
+ - **Class:** RECOMMENDED
283
+ - **Spec Reference:** IMPLEMENTATION-BFM §6.2
284
+ - **Description:** On aside close, implementations SHOULD scan for segments outside the aside subgraph that reference the aside's segments and flag them for review. Advisory (not governance) but valuable for downstream audit.
285
+
286
+ ### 5.3 Soliloquy Hash Canonicalization
287
+
288
+ **SL-001** — `SoliloquySegmentNode` content hash
289
+ - **Class:** REQUIRED
290
+ - **Spec Reference:** §19.4.3 (Soliloquy Content Hash Policy)
291
+ - **Description:** `compute_soliloquy_content_hash()` is policy-dependent on `SoliloquyContentHashPolicy`:
292
+ - `HASH_PLACEHOLDER` (default) — preimage `{id}:{ep}:{seg}:{agent}:{ts}`; content NOT recoverable from the hash, chain integrity preserved.
293
+ - `FULL_CONTENT` — preimage `{id}:{ep}:{seg}:{agent}:{ts}:{chain}`; allows direct hash verification of the chain.
294
+ - **Verification Protocol:** Given a fixed policy, implementations MUST match byte-for-byte. Switching policy across implementations expectedly produces different hashes.
295
+
296
+ **SL-002** — Deliberation chain hash
297
+ - **Class:** REQUIRED
298
+ - **Spec Reference:** §19.4.2
299
+ - **Description:** *4.x form — retained for nodes written before astp 0.5.0; the 5.0.0 construction is `DELIBERATION_CHAIN:v2:` over the deliberation Segments' content hashes in order (SPEC §19.4).* `compute_deliberation_chain_hash()` (domain `DELIBERATION_CHAIN:`) binds each soliloquy segment to its predecessor via a rolling hash chain. Tampering with any intermediate segment MUST be detectable by recomputing the chain and comparing to the stored conclusion's chain hash.
300
+
301
+ **SL-003** — `SoliloquyConclusionNode` hash
302
+ - **Class:** REQUIRED
303
+ - **Spec Reference:** §19.4.2
304
+ - **Description:** *4.x form — retained for nodes written before astp 0.5.0; the 5.0.0 construction is `SOLILOQUY_CONCLUSION:v2:` (SPEC §19.4).* `compute_soliloquy_conclusion_hash()` (domain `SOLILOQUY_CONCLUSION:`) canonicalizes `soliloquy_id`, `conclusion_content_hash`, `deliberation_chain_hash`, `merged_into_segment_id`, `concluded_at`.
305
+
306
+ ### 5.4 Soliloquy Governance
307
+
308
+ **SL-004** — Soliloquy purpose required
309
+ - **Class:** REQUIRED
310
+ - **Spec Reference:** §19.4.2
311
+ - **Description:** `create_soliloquy()` without a non-empty `purpose` MUST be rejected. A soliloquy without a purpose is indistinguishable from a branch.
312
+
313
+ **SL-005** — Human-accessible visibility policy (G-27)
314
+ - **Class:** REQUIRED
315
+ - **Spec Reference:** §19.4.2, G-27
316
+ - **Description:** Every soliloquy's `SoliloquyVisibilityPolicy` MUST allow at least one identified human user to view the conclusion. Agent-only soliloquies (no human visibility ever) are forbidden.
317
+
318
+ **SL-006** — Conclusion summary required
319
+ - **Class:** REQUIRED
320
+ - **Spec Reference:** §19.4.2
321
+ - **Description:** `conclude_soliloquy()` without a non-empty `summary` MUST be rejected. The summary is the only content guaranteed visible to humans under all visibility policies.
322
+
323
+ **SL-007** — Soliloquy return obligation (G-28)
324
+ - **Class:** REQUIRED
325
+ - **Spec Reference:** §19.4.2, G-28
326
+ - **Description:** `check_soliloquy_return_obligation()` MUST raise when an episode attempts to seal with an open soliloquy. Mirror of AS-005 for agent-initiated deliberation.
327
+
328
+ ---
329
+
330
+ ## 6. Phase 4 — Coherence Fingerprint Vectors (§19.5)
331
+
332
+ ### 6.1 Hash Canonicalization
333
+
334
+ **CF-001** — `CoherenceFingerprint` hash
335
+ - **Class:** REQUIRED
336
+ - **Spec Reference:** §19.5.1
337
+ - **Description:** `compute_fingerprint_hash()` canonicalizes `fingerprint_id`, `agent_id`, `session_id`, `computed_at`, `components` (a fixed-order dict of signal→score), `version`. Field order and component ordering are part of canonicalization.
338
+
339
+ **CF-002** — Objective hash
340
+ - **Class:** REQUIRED
341
+ - **Spec Reference:** §19.5.3
342
+ - **Description:** `compute_objective_hash()` (domain `OBJECTIVE:`) MUST be a stable function of the objective text. Two semantically-equivalent objectives with different wording MUST produce different hashes — the hash is syntactic, not semantic.
343
+
344
+ ### 6.2 Detection State Machine
345
+
346
+ **CF-003** — State machine transitions
347
+ - **Class:** REQUIRED
348
+ - **Spec Reference:** §19.5.2, IMPLEMENTATION-BFM §7.2
349
+ - **Description:** `advance_detection_state()` MUST implement the canonical state machine (`NOMINAL → WATCHING → CANDIDATE → MATERIALIZED`), with drift-below-threshold resetting toward `NOMINAL`, and the overrides that force `CANDIDATE` (objective_hash change between consecutive observations; `intent_class == INTRODUCE`). Direct `NOMINAL → MATERIALIZED` MUST NOT occur.
350
+ - **Verification Protocol:** Given a sequence of `(drift, intent_class, objective_hash, thresholds)` inputs, the output state sequence MUST match the canonical execution.
351
+
352
+ **CF-004** — Materialized recommendation
353
+ - **Class:** REQUIRED
354
+ - **Spec Reference:** §19.5.3
355
+ - **Description:** The materialized recommendation MUST be deterministic given the same `DetectionResult`, and MUST anchor at the last NOMINAL segment (before drift began) so a retroactive branch covers the full drift window. Non-determinism (e.g., model-sampling-based suggestions) violates conformance.
356
+
357
+ ### 6.3 Write-Time Enforcement
358
+
359
+ **CF-005** — Write-time fingerprint gate (G-29)
360
+ - **Class:** REQUIRED
361
+ - **Spec Reference:** §19.5.3, G-29
362
+ - **Description:** `enforce_write_time_fingerprint()` MUST reject segment writes whose `fingerprint` is `None` in episodes where fingerprint enforcement is enabled. Segments written without fingerprints cannot be retroactively analyzed for branch candidacy.
363
+
364
+ **CF-006** — Intercept sequence ordering
365
+ - **Class:** REQUIRED
366
+ - **Spec Reference:** §19.5.3, IMPLEMENTATION-BFM §7.3
367
+ - **Description:** `intercept_segment_write()` MUST execute in the order: (1) compute objective hash, (2) `detect_branch_candidate()` against the last fingerprint, (3) `advance_detection_state()`, (4) build + write-time-gate the fingerprint, (5) persist, (6) return a decision. A different ordering may produce inconsistent results.
368
+
369
+ ### 6.4 Confirmation Cache Idempotency
370
+
371
+ **CF-007** — `ConfirmationCache` idempotency
372
+ - **Class:** REQUIRED
373
+ - **Spec Reference:** §19.5.4, IMPLEMENTATION-BFM §7.4
374
+ - **Description:** Given the same canonicalized `(action_description, confirming_party)` within its `valid_for_turns` window, `ConfirmationCache` MUST report the action confirmed across repeated lookups. Re-confirming a prior decision is a no-op, not a new decision.
375
+ - **Failure Condition:** Two lookups with identical keys inside the window produce different confirmation results.
376
+
377
+ **CF-008** — Cache expiry at read time
378
+ - **Class:** REQUIRED
379
+ - **Spec Reference:** §19.5.4
380
+ - **Description:** Expiry MUST be checked at read time; an entry past its turn window MUST be treated as absent (discarded, not merely filtered). A confirmation MUST NOT apply past its `valid_for_turns` horizon.
381
+
382
+ ---
383
+
384
+ ## 7. Governance Rule Enforcement Matrix
385
+
386
+ Summary of governance rules enforced across BFM, cross-referenced with SPEC §19's rule catalog (G-19–G-35). Branch-phase checks are implementation-enforced (no numbered SPEC rule) and omitted here.
387
+
388
+ | Rule | Scope | Vector(s) |
389
+ |------|-------|-----------|
390
+ | G-19 | Fork objective non-empty | FM-004 |
391
+ | G-20 | Fork alternatives ≥ 2 | FM-005 |
392
+ | G-22 | Merge summary non-empty | FM-006 |
393
+ | G-23 | Conflict surface invariant | FM-007 |
394
+ | G-24 | Merge integrity assertions | FM-009 |
395
+ | G-25 | Aside human-initiated | AS-002 |
396
+ | G-26 | Aside return obligation | AS-005 |
397
+ | G-27 | Soliloquy human accessibility | SL-005 |
398
+ | G-28 | Soliloquy return obligation | SL-007 |
399
+ | G-29 | Write-time fingerprint | CF-005 |
400
+ | G-30 | Departure-fork backdating integrity | DF-003 |
401
+ | G-31 | Departure-fork objective non-empty | DF-004 |
402
+ | G-32 | Departure-fork trigger whitelist | DF-005 |
403
+ | G-33 | Departure-fork escalation trigger segment | DF-006 |
404
+ | G-34 | Return requires COMPLETED | DF-008 |
405
+ | G-35 | One return per fork | DF-009 |
406
+
407
+ ---
408
+
409
+ ## 8. Conformance Levels
410
+
411
+ ### Level 1: Protocol Conformance
412
+
413
+ Implementation passes all **REQUIRED** vectors in sections 2–6 and the governance matrix in section 7. No claim is made about storage layout or performance.
414
+
415
+ ### Level 2: Full Conformance
416
+
417
+ Level 1 plus all **RECOMMENDED** vectors and the advisory checks in IMPLEMENTATION-BFM §6.2 (aside external reference scan) and §9 (test coverage matrix).
418
+
419
+ ---
420
+
421
+ ## 9. Cross-Reference
422
+
423
+ - **SPEC.md §19** — normative protocol surface (v3.3.0)
424
+ - **IMPLEMENTATION-BFM.md** — the reference deployment's adapter guide (non-normative; shipped with that adapter, not with the protocol)
425
+ - **CONFORMANCE-TRUST.md** — Phase 3 Trust Infrastructure vectors (§16)
426
+
427
+ ---
428
+
429
+ *ASTP BFM Conformance Test Vectors are maintained by Scorched Earth Labs.*
430
+ *Vector set version: 1.2.0 | Applies to SPEC.md: v3.3.0 §19*