DOC73_Artifact2_R0.4.md
Current Specs/DOC73/DOC73_Artifact2_R0.4.md
# DOC73 V1.6 — Artifact 2: Legal & Corpus Surfaces (R0.4)
**Status:** R0.4 — CSA extraction applied; pending red-team Round 1. The prior "R1.0 freeze candidate" claim from R0.3 is RESCINDED. Group N legal-corpus-aware consumer surfaces now reference RecentActivityRollup entries directly (CSA framing removed); consumer-side runtime orchestration deferred to DOC72.
**R0.4 changes from R0.3:**
Per architect-issued CSA extraction prompt 2026-05-04 (see `DOC73_V1_6_CSA_EXTRACTION_PRE_REPORT.md` and `DOC73_V1_6_CSA_EXTRACTION_REPORT.md`):
| Change | Action | Section |
|---|---|---|
| §2.4 Group N consumer surfaces header | Rewritten from "legal-corpus-aware CSA consumer surfaces" to "legal-corpus-aware RecentActivityRollup entries" | §2.4 |
| §25 Group N section | "CSA injection" / "CSAInjectionTierPolicy consumer" / "orientation context" framing rewritten to "RecentActivityRollup consumer (orchestration deferred to DOC72)"; cross-references to OrientationContextEntry replaced with direct references to activity entry arrays; helper functions updated to consume activity entry arrays directly | §25 |
| Cross-references | "Consumed via Artifact 4 §18 CSAInjectionTierPolicy" → "Consumed via DOC72-side runtime orchestration (deferred from V1.6)" | (multiple) |
| Landing Matrix | Removed CSA R2 absorption tracked entries; Group N framing updated | (Landing Matrix) |
| OP-A rows referenced | Removed OBL-D72-CSA-R2-DOC73-ALIGN-01; Group N's own OBL rows preserved | (multiple) |
| V3-N-3 "CSA continuity log resolution" | Framing rewritten — underlying invariant about RecentActivityRollup receipt wrapping stays; CSA framing removed | (where present) |
| Build Questions §3 Q-3-A2-3 about CSA R2 file availability | Marked as moot post-extraction in original BUILD_QUESTIONS historical record (BUILD_QUESTIONS file annotated separately) | — |
| Status header | Updated to R0.4; removed "R1.0 freeze candidate" language | (header) |
**No V3.7-or-earlier obligation rows added or removed in DOC73 itself.** R0.4 is a surgical extraction of CSA scaffolding from DOC73 V1.6 Artifact 2. OPA V3.10 → next-revision flags tracked in `DOC73_V1_6_CSA_EXTRACTION_REPORT.md`.
---
**R0.3 changes from R0.2:**
Per `AUDIT_CROSS_ARTIFACT_R0.1.md` Step 9 cross-artifact audit + architect Path B-minus decision 2026-05-03:
| Audit finding | R0.3 action | R0.3 section |
|---|---|---|
| **XHIGH-2** — Ref types previously declared inline in §0.7 should consolidate to canonical Artifact 1 §A appendix per V4-§0.1-1 OwnerDocAdapterMapping | §0.7 inline declarations replaced with cross-reference pointer to Artifact 1 R0.4 §A.12 (canonical home). Per Q-3-A2-5 architect decision deferred to Step 9. | §0.7 |
| **XHIGH-4** — `compute_engagement_rate` formula deferred from MED-A4-9 not yet specified | Added formula spec at §23.4 INV-K-HEALTH-1 (canonical home). Helper-home appendix `DOC73_V1_6_HELPER_HOMES_R0.1.md` §6.F.2 cross-references back here. | §23.4 |
**No V3.7-or-earlier obligation rows added or removed.** R0.3 is a cross-artifact harmonization pass: discharges 2 of the 3 Step 9 cross-artifact schema patches identified by `AUDIT_CROSS_ARTIFACT_R0.1.md` (XHIGH-3 ECFHeaderParserOutput.ecf_annotations is the third; lives in Artifact 5 R0.3 §4.2).
---
**R0.2 changes from R0.1:**
Per `AUDIT_DOC73_Artifact2_R0.1.md` findings + architect Path B-minus decision:
| Audit finding | R0.2 action | R0.2 section |
|---|---|---|
| **CRIT-A2-1** — Phantom Ref types (PartyRef, ClaimRef, CaseRef, MotionChainRef, FilingChainRef, SourceKindRef, SourceSelector) | Declared inline in §0.7 NEW | §0.7 (NEW) |
| **CRIT-A2-2** — ~28 phantom helper functions | DEFERRED to Step 9 per Path B-minus (cross-artifact consolidation across Artifacts 2/4/5 ~70+ helpers); inline note added | (deferred) |
| **CRIT-A2-3** — MetadataFieldDef.field_kind enum vs §7.3 J.5 FilterCriteria mismatch | Reconciliation note added in §3.1 + §7.3 clarifying field_kind = universe of fields; FilterCriteria = V1.6 J.5 minimum subset | §3.1 + §7.3 |
| **HIGH-A2-1** — INV-O-FILING-PART-VIS-1 referenced but not canonically declared | Added canonical declaration with runtime check pseudocode | §11.4 |
| **HIGH-A2-2** — Worked example §26.1 segment IDs SE-2 through SE-7 inconsistent with Artifact 5 §14.4 (8 total segments) | Added cross-artifact reconciliation note | §26.1 |
| **HIGH-A2-3** — §26.3 FilingUnitVersion supersession decision tree incomplete | Expanded decision tree with 6 scenarios in §11.5 | §11.5 |
| **HIGH-A2-4** — Group N consumer surface lacks consumer behavior contract | Added §25.2 NEW with domain detection + producer/consumer split semantics | §25.2 (NEW) |
| **HIGH-A2-5** — INV-K-MANIFEST-DURABLE-1 cross-reference incomplete in §22.1 | Added cross-reference note | §22.1 |
| **MED-A2-1** — FilingChain.chain_significance V1.6.1 tracking row | Added OBL-D73-V161-FILING-CHAIN-AGGREGATION-01 reference | §15.2 |
| **MED-A2-3** — FilingUnitResolutionCandidate listed but not declared | Inlined minimal V2 O.14 schema + V1.6.1 expansion note | §15.X (NEW) |
| **MED-A2-4** — INV-J-PROFILE-1 phantom KernelEffect.target_node_kind field | Moved runtime check to envelope-validation layer using lookup_target_node_kind helper | §3.2 |
| **MED-A2-7** — TopicAssignment.confidence range comment | Added [0, 1] range comment | §5.1 |
| **MED-A2-8** — ResolvedCaseIdentity histories optional vs populated | Added comment clarifying absence semantics | §11.3 |
| **MED-A2-9** — MetadataFieldDef.schema_version missing | Added schema_version: 1 field | §3.1 |
| LOW + DRAFTING NOTES | Tracked in `DOC73_V1_6_BUILD_QUESTIONS.md` for Step 9 architect review | (deferred) |
**Deferred to Step 9 (cross-artifact patches):**
- CRIT-A2-2 (~28 phantom helpers + ~32 from Artifact 4 + ~13 from Artifact 5): cross-artifact helper-home appendix consolidation.
- MED-A2-2 (ECFHeaderParserOutput.ecf_annotations field): pairs with Artifact 5 R0.3 amendment.
- MED-A2-4 (KernelEffect.target_node_kind field on Artifact 1): R0.2 moves check to envelope-validation layer; cross-artifact patch tracked for Step 9.
- MED-A2-6 (BindingPermissionPolicy + PropA reconciliation): cross-doc PropA contract.
**No V3.7-or-earlier obligation rows added or removed.** R0.2 is a tightening pass.
---
**Status:** R0.2 (Step 7 output → Step 8 audit revision).
**Scope:** Group J (Brief Bank surfaces) + Group K (Corpus Source Bindings semantic specs) + Group O (Legal Filing Artifact Normalization). Per V4 §0.4 Artifact 2: brief-bank-specific deliverables; legal-filing entity schemas; binding entity semantics (kernel runtime in Artifact 3; routing runtime in Artifact 4).
**Owner:** DOC73 V1.6 Legal & Corpus Surfaces. Per V4 §2.2.1 Group O ownership split: DOC73 owns FilingUnit + legal-relationship semantics; DOC25 owns SourceArtifact / ArtifactSegment mechanics (Artifact 5); DOC72 owns governed taxonomy projection.
**Position in V1.6 release wave:** Artifact 2 of 5 (per V4 §0.4: Artifact 1 Core / **Artifact 2 Legal & Corpus Surfaces** / Artifact 3 EC + DOC73 Transaction Kernel / Artifact 4 DOC24 + EC Session & Search Runtime / Artifact 5 DOC25 Legal Artifact & Materialization).
**Consumes from Artifact 1:** canonical schemas (PBEOperationEnvelope, KernelEffect, ContentHashRef, RecordedModelOutput, ConsolidatedUnderstanding, VersionedClaim, AccessOverlay, PromptInjectionRiskFlags, RecentActivityRollup, activity entry types — WorkPhaseEntry/CorpusActivityEntry/CaseActivityEntry/ArtifactEntry/UnresolvedThreadEntry per Artifact 1 §A.5); V16 cross-cutting INVs. [R0.4 PATCH per CSA extraction 2026-05-04: OrientationContextEntry removed from consumes list — type was deleted in Artifact 1 R0.5 §A.4.] **Consumes from Artifact 3:** kernel envelope construction, KernelEffect runtime per effect_kind (filing_unit_write, filing_unit_version_write, filing_unit_text_version_write, court_disposition_observation_write, ruling_disposition_write, filing_relationship_write, topic_assignment_write, anchor_node_promotion, membership_state_transition, binding_generation_advance, case_resolution_event_write); INV-A-TAINT-INFECTIOUS-1; INV-MVC-CU-1; INV-MVC-3. **Consumes from Artifact 5:** SourceArtifact / ArtifactSegment (Artifact 5 §2-§3); ECF header parser output (Artifact 5 §4); MaterializationState V4-O-7 (Artifact 5 §5). **Consumes from Artifact 4:** SearchScope + RetrievalPosture (Artifact 4 §12); SharedCorpusView (Artifact 4 §4). **This artifact does NOT redefine those schemas.**
---
## §0. About this artifact
### §0.1 Position in the V1.6 Release Wave
Artifact 2 specifies **the legal-domain entity layer**:
- Group J (Brief Bank surfaces): CorpusProfile, LegalMetadataFieldValue, TopicVisibilityPolicy, PatternLibraryVisibility, J.5 minimum filter UI, ForkRelationshipEdge, INV-J-* invariants.
- Group K (Source Bindings semantic specs): binding entity schema, BindingResourcePolicy, BindingTargetKind / BindingOutcomeRecord, FilingUnitKind / FilingRole / RelatedMotionType orthogonal axes (V4-K-1), StructuralSelectorList per V4-K-2, ContentHashRef typed schema (V4-K-4), BindingGenerationSnapshot (V4-K-7), INV-K-DEDUP-3 same_as edge lifecycle, INV-K-OUTCOME-1, SemanticConflictPolicy default resolution per conflict class.
- Group O (Legal Filing Artifact Normalization): FilingUnit (world_entity), FilingUnitVersion + FilingUnitTextVersion split (V4-O-2), ResolvedCaseIdentity (V4-O-3), RulingDisposition with mandatory scope_targets (V4-O-4) + RulingDispositionPolarity (V4-O-5), CourtDispositionObservation lifecycle (V4-O-8), MotionChain / FilingChain / FilingRelationship / FilingRelationshipCandidate, LegalEvidencePosture, MaterializationState consumer (V4-O-7).
Group K runtime (binding evaluation, fan-out, capacity governance) lives in Artifact 3. Search router consumption lives in Artifact 4. DOC25 ingestion mechanics live in Artifact 5. Mechanism 4 RecentActivityRollup canonical schema lives in Artifact 1 (Group N consumer surfaces here only).
### §0.2 What Artifact 2 covers
```text
Artifact 2 normative scope:
§1 Cross-doc framing (DOC73 + DOC72 + DOC25 owner split per V4 §2.2.1)
§2 Group J — Brief bank framing + INV-13.6 9-tab compliance (carry from
V1.5.1)
§3 Group J — CorpusProfile (V3-J-1 fix; world_entity payload, NOT new
node_kind) + INV-J-PROFILE-1
§4 Group J — LegalMetadataFieldValue + field_lock (V3-J-2) +
INV-J-METADATA-LOCK-1
§5 Group J — TopicVisibilityPolicy (V3-J-3 + V4-J-1 strengthened
defaults) + INV-J-TOPIC-VIS-1 + Anchor Nodes + INV-J-TOPIC-MERGE-1
+ INV-J-TOPIC-DEDUP-1 (V4-J-4)
§6 Group J — PatternLibraryVisibility (V4-J-3) + INV-J-PATTERN-LIB-VIS-1
§7 Group J — J.5 minimum filter UI (V3-J-4 promoted V1.6) +
V4-J-2 provenance/review_state/source_visibility filters
§8 Group J — topic_dedup_threshold (V3-J-5) + source_span_unavailable
rename (V3-J-6)
§9 Group J — CorpusProfileFork + ForkRelationshipEdge (V4-J-FORK) +
INV-J-FORK-1
§10 Group O — Owner split (DOC73 + DOC25 + DOC72 per V3-O-1 +
V4-O-1 entity_subtype split) + INV-O-TAXONOMY-1
§11 Group O — FilingUnit + FilingUnitIdentity (V3-O-2 + V4-O-3
ResolvedCaseIdentity)
§12 Group O — FilingUnitVersion + FilingUnitTextVersion split
(V3-O-6 + V4-O-2) + INV-O-VERSION-1
§13 Group O — RulingDisposition with mandatory scope_targets (V4-O-4)
+ CourtOrderDisposition + RulingDispositionPolarity (V4-O-5) +
INV-O-DISPOSITION-1
§14 Group O — CourtDispositionObservation lifecycle (V3-O-8 + V4-O-8)
+ INV-O-OBSERVATION-LIFECYCLE-1
§15 Group O — MotionChain + FilingChain + FilingRelationshipCandidate
+ UnmatchedDocumentRelationshipCandidate (V3-O-10) +
FilingRelationship typed edges
§16 Group O — Citation display rule (V4-O-6 INV-O-CITATION-1) +
LegalEvidencePosture (V3-O-13) + INV-O-CAPTION-1 +
INV-O-DEDUP-1 / INV-O-DEDUP-2 + StructuredExtractionStrategy
(V3-O-4)
§17 Group K semantic — binding entity schema (world_entity subtype) +
BindingResourcePolicy + BindingTargetKind / BindingOutcomeRecord
(V3-K-3) + INV-K-TARGET-1
§18 Group K semantic — FilingUnitKind / FilingRole / RelatedMotionType
orthogonal axes (V4-K-1) + LegalProfileKind unified canonical
enum (V4-J-3.5-K-3.6) + ContentTypeClassification 3-field split
(V3-K-2)
§19 Group K semantic — StructuralSelectorList (V3-K-1) +
selector_phase_available (V4-K-2) + INV-K-SELECTOR-1
§20 Group K semantic — CorpusMembershipRecord (V3-K-4 + V4-K-3 state
machine) + ContentHashRef (V4-K-4) +
INV-K-MEMBERSHIP-EXTRACTION-1
§21 Group K semantic — same_as / canonical_entity edges (V3-K-7 +
V4-K-INV-DEDUP-3) + INV-K-DEDUP-1/2/3 + INV-K-OUTCOME-1
(V4-K-5) + SemanticConflictPolicy default resolution (V4-K-MISC)
§22 Group K semantic — BindingGenerationSnapshot (V4-K-7) +
BindingBackfillPolicy (V3-K-6) + INV-K-BACKFILL-1 + binding
lifecycle states + BindingMutationKind
§23 Group K semantic — BoundSourceIngestionBatch (V3-K-9) +
BatchReviewOperation (V3-K-8) + INV-K-BATCH-1 +
CorpusBindingContribution + INV-K-EVICTION-1 + INV-K-HEALTH-1
§24 Group K semantic — CorpusSourceBindingHealth + binding UI command
matrix + BindingPermissionPolicy (share-link gating)
§25 Group N consumer surfaces — legal-corpus-aware rollup entries
(consume Artifact 1 §16.2 RecentActivityRollup canonical;
NOT redefined here)
§26 Worked Examples Appendix
§27 Landing Matrix entries authored by Artifact 2
Drafting Summary
```
### §0.3 What Artifact 2 does NOT cover
```text
Out of scope:
- §6.4 Mechanism 4 canonical schema (Artifact 1 §16; consumer surfaces
here in §25)
- Group K runtime (binding evaluation runtime, fan-out, capacity
governance, BindingEvaluationManifest emission, partial-failure
batch handling) → Artifact 3 §13-§15
- Search router consumption of legal surfaces → Artifact 4 §10-§15
- SourceArtifact / ArtifactSegment schemas (DOC25-owned) →
Artifact 5 §2-§3
- ECF header parser specification (DOC25-owned) → Artifact 5 §4
- MaterializationState V4-O-7 enum schema (DOC25-owned) →
Artifact 5 §5
- Pattern library extraction pipeline (DOC25 V2.0 §10) → Artifact 5
- Group K runtime / extraction pipeline integration → Artifact 5 §6
- DOC72 governed taxonomy registry → DOC72 R5.74+ (consumed via
OwnerDocAdapterMapping; not redefined per INV-V16-NO-LOCAL-SCHEMA-1)
```
### §0.4 [V1.6 DRAFTING NOTE] markers in this artifact
Per the standing build process: ambiguities not resolvable from V4 / V1.5.1 / OPA V3.8 sources are documented inline as `[V1.6 DRAFTING NOTE]` and tracked in `DOC73_V1_6_BUILD_QUESTIONS.md`. Tracked items (Q-3-A2-*) appear in §9 of that file after this artifact's self-audit.
### §0.5 Per-Artifact Gating Contract for Artifact 2 (per V4 §0.2.1)
Artifact 2 ships only when the following gates pass:
```text
G2.1 Group J Brief Bank surfaces complete:
- CorpusProfile schema (V3-J-1 fix; world_entity payload)
- INV-J-PROFILE-1 enforcement
- LegalMetadataFieldValue + field_lock (V3-J-2) +
INV-J-METADATA-LOCK-1
- TopicVisibilityPolicy (V3-J-3 + V4-J-1 strengthened) +
INV-J-TOPIC-VIS-1
- INV-J-TOPIC-MERGE-1 + INV-J-TOPIC-DEDUP-1 (V4-J-4 legal ≥0.93)
- PatternLibraryVisibility (V4-J-3) + INV-J-PATTERN-LIB-VIS-1
- J.5 minimum 12 filter axes (9 original + 3 V4-J-2)
- topic_dedup_threshold defaults + override capability (V3-J-5)
- source_span_unavailable framing (V3-J-6)
- CorpusProfileFork + ForkRelationshipEdge (V4-J-FORK) +
INV-J-FORK-1
G2.2 Group K semantic specifications complete:
- Binding entity schema (world_entity subtype)
- BindingTargetKind / BindingOutcomeRecord (V3-K-3) +
INV-K-TARGET-1
- FilingUnitKind / FilingRole / RelatedMotionType orthogonal
axes (V4-K-1)
- 8-value LegalProfileKind unified canonical enum
(V4-J-3.5-K-3.6)
- ContentTypeClassification 3-field split (V3-K-2)
- StructuralSelectorList + selector_phase_available
(V3-K-1 + V4-K-2) + INV-K-SELECTOR-1
- CorpusMembershipRecord + state machine (V3-K-4 + V4-K-3) +
ContentHashRef (V4-K-4) + INV-K-MEMBERSHIP-EXTRACTION-1
- same_as / canonical_entity edges (V3-K-7) + INV-K-DEDUP-1/2/3
(V4-K-INV-DEDUP-3 lifecycle)
- INV-K-OUTCOME-1 (V4-K-5)
- SemanticConflictPolicy default resolution (V4-K-MISC)
- BindingGenerationSnapshot (V4-K-7)
- BindingBackfillPolicy (V3-K-6) + INV-K-BACKFILL-1
- BoundSourceIngestionBatch (V3-K-9) + BatchReviewOperation
(V3-K-8)
- CorpusBindingContribution + INV-K-EVICTION-1 + INV-K-HEALTH-1
G2.3 Group O Legal Filing Artifact Normalization complete:
- Owner split per V3-O-1 + V4-O-1 entity_subtype split
- FilingUnit + FilingUnitIdentity (V3-O-2 + V4-O-3
ResolvedCaseIdentity)
- FilingUnitVersion + FilingUnitTextVersion split (V4-O-2) +
INV-O-VERSION-1
- RulingDisposition with mandatory scope_targets (V4-O-4) +
RulingDispositionPolarity (V4-O-5)
- CourtDispositionObservation lifecycle (V4-O-8) +
INV-O-OBSERVATION-LIFECYCLE-1
- MotionChain + FilingChain + FilingRelationshipCandidate +
UnmatchedDocumentRelationshipCandidate (V3-O-10)
- Citation display rule per V4-O-6 + INV-O-CITATION-1
- LegalEvidencePosture (V3-O-13)
- StructuredExtractionStrategy (V3-O-4)
- INV-O-DISPOSITION-1
- INV-O-CAPTION-1
- INV-O-DEDUP-1 / INV-O-DEDUP-2
- INV-O-IDENTITY-1 + INV-O-CASE-RESOLUTION-1 (V4-O-3)
- INV-O-EXTRACTION-FILING-UNIT-SCOPED-1 (cross-Artifact 5)
G2.4 [R0.4 PATCH per CSA extraction 2026-05-04: prior gate G2.4 tracked
CSA R2 absorption via OBL-D72-CSA-R2-DOC73-ALIGN-01 dependency.
After extraction, DOC73 V1.6 no longer absorbs CSA; CSA stays in
DOC72. Gate G2.4 is RESCINDED. §25 consumer surfaces now consume
Artifact 1 §16 Mechanism 4 RecentActivityRollup directly without
CSA framing. New OBL row: OBL-D73-RECENT-ACTIVITY-ROLLUP-CONSUMER-
CONTRACT-01.]
G2.5 Cross-artifact dependencies declared in Landing Matrix:
- Consumed schemas listed (Artifact 1, 3, 4, 5)
- V4 patches covered enumerated
- OP-A rows authored
All gates required before Artifact 2 ships to coding agents.
```
### §0.6 Drafting discipline reminders
Per Artifact 1 §1 standing rules:
- **Anti-summarization mandate**: every normative rule stated explicitly.
- **No-invention rule**: ambiguities not resolvable from sources flagged with `[V1.6 DRAFTING NOTE]`.
- **State machine fidelity**: CorpusMembershipState transitions + binding lifecycle + CourtDispositionObservation lifecycle enumerated.
- **INVs are executable**: runtime check pseudocode for each INV-J-* / INV-K-* / INV-O-*.
- **Cross-spec contracts consumed, not redefined** (INV-V16-NO-LOCAL-SCHEMA-1).
### §0.7 Cross-doc Ref Type Declarations (R0.3 PATCH per AUDIT_CROSS_ARTIFACT_R0.1.md XHIGH-2)
**[R0.3 PATCH:XHIGH-2 — inline Ref type declarations consolidated to canonical Artifact 1 R0.4 §A.12 per V4-§0.1-1 OwnerDocAdapterMapping pattern. R0.2 inline declarations REMOVED in R0.3; cross-reference pointer retained for backward-compat documentation.]**
Per Step 9 cross-artifact audit XHIGH-2 + Q-3-A2-5 architect decision: the 14 V1.6 Ref types previously declared inline in this section (CaseRef, PartyRef, ClaimRef, FilingUnitRef, FilingUnitVersionRef, FilingUnitTextVersionRef, MotionChainRef, FilingChainRef, CorpusRef, SourceArtifactRef, SourceKindRef, ActorRef, EdgeRef, NodeRef + SourceSelector typed object) have moved to **canonical home Artifact 1 R0.4 §A.12** ("Cross-Artifact Ref Type Declarations").
Consumers in this artifact (Artifact 2 R0.3) reference the types by name; resolution is to Artifact 1 §A.12. Per INV-V16-NO-LOCAL-SCHEMA-1 (Artifact 1 §19.2): only ONE canonical home per type.
```text
Cross-reference pointer (R0.3 PATCH per XHIGH-2):
V1.6 Ref types canonically declared at:
DOC73_Artifact1_R0.4.md §A.12
Consumer artifacts (this section + downstream):
- Artifact 2 R0.3 (this artifact): all Group O / Group J / Group K
sections that reference Ref types resolve to Artifact 1 §A.12.
- Artifact 3 R0.2 / Artifact 4 R0.2 / Artifact 5 R0.2: same.
Helper-home cross-reference:
DOC73_V1_6_HELPER_HOMES_R0.1.md §1 (DB-layer lookup helpers)
— function signatures consume these types.
R0.2 → R0.3 migration:
R0.2 §0.7 contained inline declarations of CaseRef / PartyRef /
ClaimRef / FilingUnitRef / FilingUnitVersionRef /
FilingUnitTextVersionRef / MotionChainRef / FilingChainRef /
CorpusRef / SourceArtifactRef / SourceKindRef / ActorRef /
EdgeRef / NodeRef + SourceSelector typed object. R0.3 REMOVES
those inline declarations; coding agents reading this artifact
MUST resolve Ref-type references to Artifact 1 R0.4 §A.12.
```
OP-A row: implicit (canonical type registry; covered by V4-§4.X-TYPE-DEFINITIONS in Artifact 1 §A appendix umbrella; no separate OBL row required).
---
## §1. Cross-doc framing
### §1.1 Owner split per V4 §2.2.1 Group O
**[V4 PATCH:V3-O-1 per R-EX §2.2 BUG + R-V22 §7]**
Per V4 §2.2.1: Group O entities split across DOC25 (artifact mechanics), DOC73 (legal-semantics layer), DOC72 (governed taxonomy projection):
```text
DOC25 owns (Artifact 5):
- SourceArtifact schema (Artifact 5 §2)
- ArtifactSegment schema (Artifact 5 §3)
- Acquisition_shape enum + segmentation state machine (Artifact 5 §3.3)
- ECF header parser (Artifact 5 §4)
- Materialization tri-state V4-O-7 (Artifact 5 §5)
- DocumentArtifactVersionChanged event emission (Artifact 5 §13)
- File/package normalization mechanics (Artifact 5 §6)
DOC73 owns (Artifact 2 — THIS ARTIFACT):
- FilingUnit schema (legal identity at court_id + case_number +
ecf_document_no level) — §11
- FilingUnitVersion + FilingUnitTextVersion split per V4-O-2 — §12
- FilingPartVisibility (per V2 patch L9 / V4-O-FILING-PART-VIS) — §11.4
- MotionChain + FilingChain entities — §15
- CourtDispositionObservation per V3-O-8 + V4-O-8 lifecycle — §14
- CourtOrderDisposition with RulingDisposition array per V3-O-5 +
V4-O-4 mandatory scope_targets + V4-O-5 polarity — §13
- Typed FilingRelationship edges — §15
- LegalEvidencePosture per V3-O-13 — §16
- 4-profile model: legal_brief_filing / court_order / pleading /
evidentiary_filing — §16
- 8-value LegalProfileKind unified canonical enum per V4-J-3.5-K-3.6 —
§18
- StructuredExtractionStrategy enum per V3-O-4 — §16
DOC72 owns (DOC72 R5.74+):
- Filing relationship edge type registry — referenced via
EdgeTypeRef (Artifact 1 §A.7)
- Governed node-kind projection per V4-O-1:
FilingUnit → world_entity subtype (external court filing fact)
MotionChain / FilingChain / CorpusProfile → work_product subtype
RulingDisposition → world_entity payload
CourtDispositionObservation → world_entity (observation of real
docket event)
- Cross-doc taxonomy compliance (per INV-O-TAXONOMY-1)
```
OP-A rows: `OBL-D25-O-SOURCEARTIFACT-01` (Artifact 5; DOC25 ownership) + `OBL-D73-O-FILINGUNIT-01` (this artifact; DOC73 ownership) per V4 §0.3.2 explicit owner split.
### §1.2 INV-O-TAXONOMY-1 — no new DOC72 top-level node kinds
**[V3 PATCH:V3-O-11 per R-EX §7 — INV-O-TAXONOMY-1]**
Per V4 §2.2.10:
```text
INV-O-TAXONOMY-1 (V3 NEW; canonical home Artifact 2 §1.2):
Group O does NOT introduce DOC72 top-level node kinds. FilingUnit,
MotionChain, FilingChain, CourtOrderDisposition,
CourtDispositionObservation, RulingDisposition, FilingUnitVersion,
and FilingUnitTextVersion are all expressed as world_entity subtypes
(or as payload fields on existing node kinds). Cross-doc taxonomy
compliance is owned by DOC72.
Per V4-O-1 entity_subtype assignment (canonical):
FilingUnit: world_entity (entity_subtype: "filing_unit")
— external court filing fact (real-world
filing identity, NOT host work product)
FilingUnitVersion: world_entity (entity_subtype:
"filing_unit_version") payload of FilingUnit
FilingUnitTextVersion: world_entity (entity_subtype:
"filing_unit_text_version") payload
MotionChain: work_product (entity_subtype: "motion_chain")
— host's analytical labeling
FilingChain: work_product (entity_subtype: "filing_chain")
— host's analytical labeling
CorpusProfile: work_product (entity_subtype:
"corpus_profile") — host's analytical
configuration; payload on knowledge_corpus
world_entity per V3-J-1 fix
RulingDisposition: world_entity payload (court's actual
disposition; world fact recorded by host)
CourtDispositionObservation: world_entity (entity_subtype:
"court_disposition_observation") —
observation of real docket event
CourtOrderDisposition: world_entity payload (parent of
RulingDisposition[] array)
DOC73 V1.6 ships these schemas as payloads on existing world_entity /
work_product node-kinds; DOC72 R5.74+ registry adds the entity_subtype
values. No new top-level node-kinds.
Runtime check: any V1.6 implementation attempting to introduce a new
DOC72 node_kind for Group O entities is non-conformant. Storage uses
world_entity / work_product table with entity_subtype + payload JSONB
field.
```
OP-A row: implicit (covered by OBL-D73-O-FILINGUNIT-01 + DOC72 governed
taxonomy projection); per Tier B Q-3-A2-INV-O-TAXONOMY-OP-A may need
dedicated row.
### §1.3 Consumed schemas (verbatim from sibling artifacts)
```text
From Artifact 1 (Core):
ConsolidatedUnderstanding Artifact 1 §8.2 (consumed at
§13 RulingDisposition cited
source_spans)
VersionedClaim trait Artifact 1 §10 (consumed at
§11 FilingUnit when claim
carve-outs apply)
AccessOverlay Artifact 1 §A (consumed for
per-filing-unit access overlay)
ContentHashRef Artifact 1 §A.9 (consumed at
§20 multi-hash discipline)
PromptInjectionRiskFlags Artifact 1 §A.8 (consumed at §16
extraction strategy)
RecentActivityRollup Artifact 1 §16.2 (consumed at
§25 Group N legal-corpus-aware
rollup entries)
CapabilityRef / EdgeTypeRef Artifact 1 §A.7 (consumed at §15
FilingRelationship edge types)
PartyRef / ClaimRef / CaseRef (forward-declared in §11
FilingUnitIdentity; not yet
in Artifact 1 §A; tracked as
new types — see §11.X for
inline declarations)
V16 cross-cutting INVs:
INV-V16-TIMEZONE-1 Artifact 1 §19.1 (consumed for
filing_date / docket_entry_date
/ order_date fields)
INV-V16-NO-LOCAL-SCHEMA-1 Artifact 1 §19.2 (followed
throughout)
INV-V16-RETENTION-DURABLE-1 Artifact 1 §19.4 (consumed for
legal-evidence durable receipts
+ audit log)
INV-V16-STORAGE-GRANULARITY-1 Artifact 1 §19.6
From Artifact 3 (EC + DOC73 Transaction Kernel):
KernelEffect runtime per effect_kind Artifact 3 §4.3 (effect_kinds
consumed: filing_unit_write,
filing_unit_version_write,
filing_unit_text_version_write,
court_disposition_observation_write,
ruling_disposition_write,
filing_relationship_write,
topic_assignment_write,
anchor_node_promotion,
membership_state_transition,
binding_generation_advance,
case_resolution_event_write)
PBEOperationEnvelope construction Artifact 3 §2 (consumed at every
legal-entity write)
INV-A-TAINT-INFECTIOUS-1 Artifact 3 §7 (consumed at §15
FilingRelationship visibility
inference)
INV-MVC-CU-1 Artifact 3 §9 (consumed at §13
RulingDisposition citation
source_spans)
INV-MVC-3 Artifact 3 §10 (consumed at §16
extraction strategy +
INV-D25-PROMPTINJ-1 cross-ref)
INV-K-OUTCOME-1 Artifact 3 §13.6 (canonical
home; cited at §21)
AccessOverlay write-time enforcement Artifact 3 §12 (companion to
read-time enforcement Artifact 4)
Three-tier rollback Artifact 3 §5 (consumed for
legal entity rollback semantics)
From Artifact 4 (DOC24 + EC Session & Search Runtime):
SearchScope + RetrievalPosture Artifact 4 §12
SharedCorpusView Artifact 4 §4
DocumentRef = SourceArtifactRef alias Artifact 4 §2.0
[R0.4 PATCH per CSA extraction 2026-05-04: CSAInjectionTierPolicy
Artifact 4 §18 removed from consumes list — CSAInjectionTierPolicy
was deleted in Artifact 4 R0.4 §18 CSA extraction; consumer-side
session-orientation orchestration deferred to DOC72.]
From Artifact 5 (DOC25):
SourceArtifact Artifact 5 §2
ArtifactSegment Artifact 5 §3
ECFHeaderParserOutput Artifact 5 §4.2
MaterializationState (V4-O-7) Artifact 5 §5.1
DocumentArtifactVersionChangedEvent Artifact 5 §13.1
StructuredExtractionStrategy Artifact 5 §6.1 (consumer side
here in §16; Artifact 5 owns
runtime)
INV-K-METADATA-AUTHORITY-1 Artifact 5 §4.1
From Source Bindings V1.1 (proposal; V4 §3.6 consolidation):
Source Bindings V1.1 redraft has been folded into V4 §3.6 Stage 5
[INSERT] consolidation; this artifact §17-§24 is the canonical
Group K semantic specification consuming the V4 consolidation.
```
Group J / Group K / Group O invariants whose canonical home is **this** artifact (Artifact 2):
```text
Group J:
INV-J-PROFILE-1 §3
INV-J-METADATA-LOCK-1 §4
INV-J-TOPIC-VIS-1 §5
INV-J-TOPIC-MERGE-1 §5 (V4-J-4)
INV-J-TOPIC-DEDUP-1 §5 (V4-J-4 legal ≥0.93)
INV-J-PATTERN-LIB-VIS-1 §6 (V4-J-3)
INV-J-FORK-1 §9 (V4-J-FORK)
Group K:
INV-K-SELECTOR-1 §19 (V3-K-1; runtime in Artifact 3
§13.8)
INV-K-TARGET-1 §17 (V3-K-3)
INV-K-MEMBERSHIP-EXTRACTION-1 §20 (V3-K-4 / V3-K-5)
INV-K-BACKFILL-1 §22 (V3-K-6)
INV-K-DEDUP-1 §21 (V3-K-7 refined)
INV-K-DEDUP-2 §21 (V2 carry-forward)
INV-K-DEDUP-3 §21 (V4-K-INV-DEDUP-3 lifecycle)
INV-K-BATCH-1 §23 (V3-K-8; runtime Artifact 3
§14.6)
INV-K-EVICTION-1 §23 (V3-K-10)
INV-K-HEALTH-1 §23 (V2 patch L5)
INV-K-FILTER-1 §19 (V2 carry-forward)
INV-K-SUGGEST-1 §22 (V2 carry-forward)
INV-K-OUTCOME-1 (canonical home Artifact 3 §13.6;
cited here §21)
Group O:
INV-O-ARTIFACT-IDENTITY-1 (canonical home Artifact 5 §2.6;
cited here §10)
INV-O-FILING-UNIT-CANONICAL-1 §11
INV-O-COMPOSITE-NORMALIZATION-1 §16
INV-O-ATOMIC-NORMALIZATION-1 §16
INV-O-IDENTITY-1 §11 (V3-O-2)
INV-O-CASE-RESOLUTION-1 §11 (V4-O-3)
INV-O-EXTRACTION-FILING-UNIT-SCOPED-1 (canonical home Artifact 5 §3.5;
cited here §16)
INV-O-CAPTION-1 §16
INV-O-DEDUP-1 §16
INV-O-DEDUP-2 §16
INV-O-VERSION-1 §12 (V3-O-7 + V4-O-2)
INV-O-DISPOSITION-1 §13 (V3-O-5 + V4-O-4)
INV-O-OBSERVATION-LIFECYCLE-1 §14 (V4-O-8)
INV-O-FILING-PART-VIS-1 §11.4
INV-O-TAXONOMY-1 §1.2
INV-O-CITATION-1 §16 (V3-O-12 + V4-O-6 display rule)
INV-O-UNMATCHED-1 §15 (V3-O-10)
```
### §1.4 Section conventions
- `[V4 PATCH:V4-X-Y]` markers preserve V4 provenance.
- TypeScript-style schemas with explicit type annotations.
- Section numbers stable; cross-references use "§N.M" (this artifact), "Artifact X §N.M" (cross-artifact), "V1.5.1 §N.M", "V4 §N.M".
- INV blocks restate the invariant in full at point of use; runtime check pseudocode follows.
---
## §2. Group J — Brief bank framing + INV-13.6 9-tab compliance
### §2.1 V1.5.1 INV-13.6 9-tab structure carry-forward
Per V4 §3.5.1 (carry from V2 patch H2):
```text
INV-13.6 (V1.5.1 carry-forward; canonical home V1.5.1 §13.6; consumer
side Artifact 2 §2.1):
DOC73 V1.6 Group J UI changes fit within V1.5.1 INV-13.6 9-tab
structure. NO new tabs added in V1.6. Filter UI changes (§7 J.5
expansion) fit within Members tab sub-views.
The 9 tabs (V1.5.1 §13.6 canonical):
1. Overview — corpus-level summary
2. Topics — topic governance + Anchor Nodes UI
3. Members — filing list with §7 J.5 minimum filter UI
4. Themes — cross-corpus synthesis surfaces
5. Authority — cu_authority audit surface
6. History — corpus mutation log
7. Bindings — source-binding configuration UI
8. Permissions — share-link + access policy UI
9. Settings — corpus-level configuration
V1.6 changes fit within these tabs without adding new tab IDs.
V4 confirmed (no V1.6.1 SAFE list addition for new tabs).
```
OP-A row: `OBL-J-INV-13.6-RESOLVE-01` (V4-NEW per V4 §6 — Group J UI fits within INV-13.6 9-tab structure lock).
### §2.2 Group J as forcing function (V2 framing carry-forward)
Per V4 §3.5.9 + V2 framing:
```text
Group J Brief Bank surfaces are the V1.6 forcing function for
multi-document litigation work. Without J.5 minimum filters + topic
governance + metadata field locks + pattern library visibility, brief
bank ships as "feature checkbox" rather than usable litigation tool.
V1.6 ships J.5 minimum + INV-J-* governance INVs as MUST-HAVE; V1.6.1
expands with PSLRA/9(b) + CW count + theme + citation pattern + exhibit
dependency + judge + counsel + hearing metadata filters per V4 §3.5.5
V1.6.1 candidate list.
```
OP-A row: implicit (covered by Group J row family).
### §2.3 V4 §6 Group J recommended scope summary
Per V4 §3.5.8 Stage 5 [INSERT] + V4 §6.J.X V1.6 status:
```text
V1.6 Group J ships:
J.1 CorpusProfile (V3-J-1 fix; world_entity payload) §3
J.2 ExtractionSpec (consumed at §16 StructuredExtractionStrategy)
J.3 TopicVisibilityPolicy + Anchor Nodes governance §5
J.4 metadata_schema_ref (consumed at §4 LegalMetadataFieldValue) §4
J.5 Minimum 12-filter UI (9 V3 + 3 V4-J-2) §7
J.6 topic_extraction_directive (consumed via CorpusProfile)
J.7 Deliver document affordance — depends on Artifact 5 §5
MaterializationState V4-O-7
J.8 PatternLibraryVisibility (V4-J-3) §6
J.9 CorpusProfileFork (V4-J-FORK) §9
J.10 ForkRelationshipEdge (V4-J-FORK) §9
J.11 source_span_unavailable framing rename (V3-J-6) §8
Deferred to V1.6.1:
Hierarchical topic organization (V4 NOT SAFE list per V4 §0.5.1)
Full Suggested Bindings (V4 NOT SAFE list)
TF-IDF / mean-vector hubness mitigation (V4-J-4 implementation
optimization; OBL-J-V161-LEGAL-HUBNESS-MITIGATION-01)
Deferred to V1.7+:
Generic predicate/filter UI (per V4 §0.5.1 NOT SAFE — would
resurrect predicate DSL)
Anchor Nodes interaction polish (V4 moved from V1.6.1 to V1.7
per V4-§0.5-1)
```
---
## §3. Group J — CorpusProfile (V3-J-1 fix)
### §3.1 CorpusProfile canonical schema
**[V4 PATCH:V3-J-1 per R-EX §3.5 BUG]**
Per V4 §3.5.2: V2 introduced `CorpusProfile` as ACCEPT_MOD — refinement of §3.1 knowledge_corpus, NOT new node_kind. R-EX §3.5 caught a schema-conformance bug: V2 wrote `node_kind: "knowledge_corpus"` which is incorrect — DOC73's actual graph representation per DOC72 taxonomy is `node_kind: "world_entity"` with `entity_subtype: "knowledge_corpus"`.
V3 corrected schema (canonical home Artifact 2 §3.1):
```typescript
type CorpusProfile = { // V3-J-1 fix
// Graph identity (V3 FIX per V3-J-1):
// Node is node_kind: "world_entity", entity_subtype: "knowledge_corpus".
// CorpusProfile is a payload field on the world_entity node.
// CorpusProfile is NOT a node_kind itself.
corpus_id: string; // refers to world_entity
// node ID
extraction_spec: ExtractionSpec; // J.2 — consumed at
// §16 strategy
metadata_schema_ref: string; // J.4 — consumed at
// §4 LegalMetadataFieldValue
topic_extraction_directive: TopicDirective; // J.6 — consumed at
// §5 TopicVisibilityPolicy
// + §8 topic_dedup
// thresholds
relationship_edge_types: EdgeTypeRef[]; // Group O FilingRelationship
// — consumed at §15
pattern_library_ref?: string; // Group O O.10/O.17
// — consumed at §16
// StructuredExtractionStrategy
legal_citation_normalization_profile?: LegalCitationNormalizationProfile;
// V1.5.1 carry-forward
// — DOC18 FTS5
// tokenizer per
// OBL-D18-LEGAL-SEARCH-01
forkable_template_id?: string; // domain-pack leverage
// — consumed at §9
// CorpusProfileFork
template_version: string;
schema_version: 1;
};
```
**Storage:** `world_entity` table (DOC72) with `entity_subtype = "knowledge_corpus"`; `payload` JSONB column carries `corpus_profile: CorpusProfile`. NOT a separate node-kinds table entry.
`ExtractionSpec` schema:
```typescript
type ExtractionSpec = { // V1.5.1 carry-forward
spec_id: string;
domain_profile: "legal" | "general" | "technical" | "medical" | "custom";
// governs topic_dedup
// thresholds per §8
required_fields: MetadataFieldDef[]; // per metadata_schema_ref
optional_fields: MetadataFieldDef[];
extraction_strategy_ref: string; // StructuredExtractionStrategy
// ref (per §16)
schema_version: 1;
};
type MetadataFieldDef = { // R0.2 PATCH per
// AUDIT_DOC73_Artifact2_R0.1.md
// CRIT-A2-3 +
// MED-A2-9
field_id: string;
field_kind:
// V1.6 J.5 minimum filter axes (9 V3-J-4):
| "case_number"
| "court_id"
| "filing_kind"
| "procedural_posture"
| "filing_date"
| "motion_type"
| "filing_side"
| "outcome"
| "docket_status"
// V1.6.1 candidate filter axes (V4 §3.5.5; declared here as field_kind
// for forward-compat; FilterCriteria UI ships V1.6.1 per V4 §0.5.1
// SAFE list):
| "judge"
| "counsel"
| "hearing_metadata"
// V1.6 metadata provenance / state (NOT FilterCriteria-driven; these
// are LegalMetadataFieldValue.source_kind / state derivatives that
// §7.3 FilterCriteria translates):
| "custom";
required: boolean;
default_field_lock: LegalMetadataFieldValue<any>["field_lock"];
// per §4
// default_field_lock
// often
// "source_authoritative"
// for ECF metadata
schema_version: 1;
};
```
**[R0.2 RECONCILIATION NOTE per AUDIT_DOC73_Artifact2_R0.1.md CRIT-A2-3]** — `MetadataFieldDef.field_kind` enum vs §7.3 J.5 `FilterCriteria` relationship:
```text
MetadataFieldDef.field_kind = the universe of fields that CAN exist
on a FilingUnit (per CorpusProfile.
extraction_spec.required_fields /
optional_fields). Schema-level enumeration.
FilterCriteria (per §7.3) = the subset of fields that V1.6 J.5 filter
UI exposes. UI-level enumeration.
Different concerns:
- MetadataFieldDef.field_kind enumerates ALL fields including
judge / counsel / hearing_metadata (V1.6.1 candidate filters
per V4 §3.5.5).
- FilterCriteria includes 9 V1.6 minimum + 3 V4-J-2 axes
(field_provenance, review_state, source_visibility).
The 3 V4-J-2 axes (field_provenance, review_state, source_visibility)
are NOT MetadataFieldDef.field_kind values — they are derivatives of
LegalMetadataFieldValue.source_kind, ReviewState, and VisibilityClass:
- field_provenance: derives from
LegalMetadataFieldValue.source_kind enum (per §4.1)
- review_state: separate Member-tab state per §7.4 ReviewState enum
- source_visibility: derives from FilingUnit.visibility_class +
AccessOverlay (per Artifact 1 §13)
V1.6.1 candidate filters (judge / counsel / hearing_metadata):
MetadataFieldDef declared in V1.6 schema but FilterCriteria UI ships
V1.6.1 per V4 §3.5.5 V1.6.1 candidate list.
Step 9 cross-artifact audit verifies FilterCriteria UI consumer side
(Artifact 4 + DOC20/DOC7) consistently translates field_kind enum
values to filter UI controls.
```
### §3.2 INV-J-PROFILE-1
Per V4 §3.5.2 + V2 base:
```text
INV-J-PROFILE-1 (V2 base; canonical home Artifact 2 §3.2):
CorpusProfile is the canonical configuration source for brief-bank-
specific behavior. J.2, J.3, J.4, J.6 specifications consume from
CorpusProfile (a payload field on the knowledge_corpus world_entity
node), NOT from corpus-type-specific scattered config.
CorpusProfile is NOT a new DOC72 node_kind (per INV-O-TAXONOMY-1 §1.2).
Runtime check (envelope construction time):
// [R0.2 PATCH per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-4] —
// Original R0.1 referenced KernelEffect.target_node_kind which
// is NOT declared on Artifact 1 §17.3 KernelEffect schema (phantom
// field). R0.2 moves runtime check to envelope-validation layer
// using lookup_target_node_kind helper (DOC72 graph lookup via
// write_set_refs).
function validate_corpus_profile_storage(
envelope: PBEOperationEnvelope,
profile: CorpusProfile
): ValidationResult {
// Per Artifact 3 §4.3 effect_kind: CorpusProfile creation/update
// emits effect_kind = "node_write" on world_entity table with
// entity_subtype = "knowledge_corpus". NOT a separate node-kind
// write.
//
// Verify by walking write_set_refs and checking DOC72 node_kind
// for each target. lookup_target_node_kind is a Step 9 helper-home
// (per CRIT-A2-2 deferred consolidation); per V1.6 implementation
// handoff, lookup_target_node_kind queries DOC72 world_entity /
// work_product / knowledge_corpus tables for the target node ref
// and returns the canonical node_kind.
for (const write_ref of envelope.write_set_refs) {
const target_kind = lookup_target_node_kind(write_ref);
// INVALID: any write where target node_kind = "corpus_profile"
// (V1.6 ships CorpusProfile as PAYLOAD on world_entity
// entity_subtype=knowledge_corpus; no "corpus_profile" node_kind
// exists in DOC72 V1.6 governed taxonomy).
if (target_kind === "corpus_profile") {
return reject(
"invalid_corpus_profile_node_kind",
"CorpusProfile is NOT a DOC72 node_kind; per INV-J-PROFILE-1 " +
"+ INV-O-TAXONOMY-1, store as payload on world_entity " +
"entity_subtype=knowledge_corpus"
);
}
}
return accept();
}
// Helper: lookup_target_node_kind(node_ref) returns the canonical
// DOC72 node_kind for the given node_ref. Per CRIT-A2-2 helper-home
// deferral: full implementation contract specified in Step 9
// helper-home appendix.
OP-A row: OBL-J-CORPUSPROFILE-01 (V2 candidate; V3 fixes node_kind
classification per V3-J-1).
```
Acceptance test: V4-AT-40 (INV-V16-NO-LOCAL-SCHEMA-1 conformance — covers CorpusProfile placement).
### §3.3 CorpusProfile create envelope
Per Artifact 3 §3.3 SemanticVerb taxonomy + §4.3 effect_kind:
```text
CorpusProfile creation flow:
1. PrimaryPBEOrchestrator constructs PBEOperationEnvelope with:
- operation_kind: "create"
- semantic_intent: "create"
- primitive_effects: [
{ effect_kind: "node_write",
reversibility: "fully_reversible",
target_node_kind: "world_entity",
target_entity_subtype: "knowledge_corpus",
payload_field: "corpus_profile",
inverse_operation_kind: "node_retract" },
{ effect_kind: "index_update",
reversibility: "fully_reversible",
inverse_operation_kind: "index_revert" }
]
- semantic_intent verb produces effect_kind = "node_write";
Group K semantic verb mapping per Artifact 3 §3.3.
2. INV-J-PROFILE-1 + INV-O-TAXONOMY-1 enforced at envelope V3 +
V12 validation (Artifact 3 §2.2): kernel rejects envelope if
target_node_kind is "corpus_profile" or any non-world_entity
kind for CorpusProfile creation.
3. Kernel writes per §2.3 Artifact 3 sequence + effect application.
```
---
## §4. Group J — LegalMetadataFieldValue + field_lock
### §4.1 LegalMetadataFieldValue canonical schema
**[V4 PATCH:V3-J-2 per R-V22 §22]**
Per V4 §3.5.3:
```typescript
type LegalMetadataFieldValue<T> = { // V3-J-2
field_id: string;
value: T;
// Provenance (V2 base)
source_kind:
| "ecf_metadata"
| "extraction"
| "user_corrected"
| "user_locked"
| "third_party_provider";
source_ref: string;
confidence: number; // [0, 1]
extraction_method?: string; // e.g.,
// "hybrid_deterministic_schema_llm"
// (per Artifact 5 §6 +
// Artifact 2 §16)
user_confirmed: boolean;
// V3 NEW per V3-J-2 — field_lock:
field_lock:
| "unlocked" // re-extraction may
// overwrite
| "user_locked" // user explicitly
// locked; re-extraction
// surfaces conflict
| "policy_locked" // policy (e.g.,
// regulatory) prevents
// change
| "source_authoritative"; // source provides
// authoritative value
// (e.g., ECF metadata
// per Artifact 5 §4
// INV-K-METADATA-AUTHORITY-1)
field_lock_reason?: string; // free-text reason
field_lock_set_by?: ActorRef; // who set the lock
field_lock_set_at?: ISO8601;
schema_version: 1;
};
type ActorRef = string; // user_id / system /
// migration / agent
// (forward-declared
// per Artifact 1 §A;
// inline reference
// here)
```
### §4.2 INV-J-METADATA-LOCK-1
Per V4 §3.5.3:
```text
INV-J-METADATA-LOCK-1 (V3 NEW; canonical home Artifact 2 §4.2):
A LegalMetadataFieldValue with field_lock != "unlocked" is preserved
across re-extraction runs. Re-extraction that produces a different
value for a locked field surfaces a `field_extraction_conflict`
candidate for user review; the lock is not silently overwritten.
Lock semantics:
unlocked: re-extraction may overwrite value with new extraction
output without surfacing conflict.
user_locked: user explicitly set; re-extraction blocked from
overwrite. New extraction output that conflicts surfaces a
field_extraction_conflict candidate for user review. User
decides: accept new value (clear lock + apply update) OR retain
locked value.
policy_locked: policy prevents change. Even user override requires
policy approval (e.g., regulatory pinning). Triggers different
UI flow than user_locked: surfaces "policy approval required"
rather than user-decision affordance.
source_authoritative: source provides authoritative value. Per
Artifact 5 §4.1 INV-K-METADATA-AUTHORITY-1: ECF header parser
output is authoritative for ECF metadata. Re-extraction does
NOT overwrite; new ECF metadata read CAN update if provenance
shows newer authoritative source (e.g., court issues corrected
ECF stamping).
User locks persist until explicitly cleared by user. Re-extraction
proposing a conflicting value emits a field_extraction_conflict
candidate (queueable for user review per Triage UI surface in §7.X
J.5 review_state filter).
Runtime check (re-extraction time):
function reconcile_extraction_value(
candidate_value: any,
existing_field: LegalMetadataFieldValue<any>
): ReconciliationOutcome {
if (existing_field.field_lock === "unlocked") {
return { action: "overwrite", new_value: candidate_value };
}
if (existing_field.value === candidate_value) {
return { action: "no_change" }; // same value; no conflict
}
// Conflict detected.
switch (existing_field.field_lock) {
case "user_locked":
return {
action: "emit_field_extraction_conflict",
conflict_kind: "user_locked_field_conflict",
existing_value: existing_field.value,
candidate_value,
locked_by: existing_field.field_lock_set_by,
locked_at: existing_field.field_lock_set_at,
};
case "policy_locked":
return {
action: "emit_field_extraction_conflict",
conflict_kind: "policy_locked_field_conflict",
existing_value: existing_field.value,
candidate_value,
policy_reason: existing_field.field_lock_reason,
};
case "source_authoritative":
// Per INV-K-METADATA-AUTHORITY-1: parser output wins ONLY if
// new ECF metadata read with confidence >= existing.
if (candidate_source_kind === "ecf_metadata" &&
candidate_confidence >= existing_field.confidence) {
return { action: "overwrite_with_audit",
new_value: candidate_value };
}
return { action: "preserve_existing" };
}
}
OP-A row: implicit (covered by Group J row family).
```
Acceptance test: V3-AT-21 (LegalMetadataFieldValue field_lock preserved across re-extraction).
### §4.3 field_lock UI affordance contract
```text
Q Dashboard rendering rules for field_lock state (Artifact 4 owns
rendering; data contract here):
unlocked:
- Editable inline; pencil icon visible.
- "Auto-extracted; re-extraction may update."
user_locked:
- Editable inline (clears lock on edit).
- Lock icon + "User-locked" badge.
- Tooltip: "Locked by <actor> on <date>."
- Re-extraction conflict resolution UI: "Re-extraction proposed
different value. Accept new value, retain locked value, or
defer."
policy_locked:
- NOT editable inline.
- Policy badge + reason text.
- "Locked by policy: <reason>."
source_authoritative:
- NOT editable inline (use ECF re-read instead).
- Source badge + confidence.
- "From ECF metadata; updated when court issues corrected
stamping."
```
OP-A row: implicit (Q Dashboard layer per DOC20/DOC7).
---
## §5. Group J — TopicVisibilityPolicy + Anchor Nodes + INV-J-TOPIC-MERGE-1 + INV-J-TOPIC-DEDUP-1
### §5.1 TopicVisibilityPolicy canonical schema
**[V4 PATCH:V3-J-3 per R-V22 §19]**
Per V4 §3.5.4:
```typescript
type TopicVisibilityPolicy = { // V3-J-3
policy_id: string;
topic_visibility:
| "neutral_classifier" // domain ontology /
// system-generated;
// shareable by default
| "host_authored_neutral" // host added but
// content-neutral;
// V4 CHANGED to
// NOT shareable
// default
| "host_strategy" // host work product
// strategy; defaults
// to host-only
| "user_marked_shareable" // host explicitly
// marked shareable
| "user_marked_private"; // host explicitly
// marked private
default_share_link_visibility: "include" | "exclude";
schema_version: 1;
};
type TopicAssignment = { // V3 expanded per V3-J-3
topic_id: string;
document_or_filing_unit_ref: string; // target of assignment
visibility_policy_ref: string; // V3 NEW per V3-J-3
// — points to
// TopicVisibilityPolicy
confidence: number; // [0, 1]; V2 base;
// R0.2 PATCH per
// MED-A2-7
// range comment
extraction_method?: string;
user_confirmed: boolean;
schema_version: 1;
};
```
### §5.2 INV-J-TOPIC-VIS-1 (V3 NEW + V4 STRENGTHENED)
**[V4 PATCH:V4-J-1 per R-CG #21 + R-G55 #25 — host_authored_neutral default NOT shareable]**
Per V4 §3.5.4:
```text
INV-J-TOPIC-VIS-1 (V3 + V4 STRENGTHENED; canonical home Artifact 2 §5.2):
Topic labels carry TopicVisibilityPolicy. Share-link sessions render
topics matching the SharedCorpusView's topic exposure rules
(per Artifact 4 §4 SharedCorpusView).
V4 STRENGTHENED default behavior (per V4-J-1 / R-CG #21 + R-G55 #25):
neutral_classifier topics:
shareable by default
→ SharedCorpusView "neutral_topics" exposure permits.
host_authored_neutral:
NOT shareable by default (V4 CHANGED from V3 which defaulted
shareable). Rationale: even "host_authored_neutral" topics carry
host's organizational thinking; default to private with explicit
opt-in to share via user_marked_shareable promotion.
host_strategy:
NOT shareable by default (host work product).
user_marked_shareable:
shareable.
user_marked_private:
NOT shareable.
A share-link rendering a document does NOT show host_strategy or
host_authored_neutral topic labels unless the SharedCorpusView
explicitly includes them via "host_topics" exposure surface. Topic
labels are work product when authored by host; the system defaults
to privacy-conservative.
Anchor Nodes (system-generated topics that become permanent on user
interaction; per V2 patch GEM Bug 4): on anchoring, the topic
inherits `host_authored_neutral` visibility (per V4: NOT shareable
by default) unless the user explicitly upgrades to
`user_marked_shareable`.
Runtime check (share-link search retrieval):
function filter_topics_by_share_link_visibility(
topics: TopicAssignment[],
session: SessionProfile,
shared_view: SharedCorpusView
): TopicAssignment[] {
if (session.session_kind !== "share_link_session") {
return topics; // host session sees everything
}
return topics.filter(t => {
const policy = lookup_topic_visibility_policy(t.visibility_policy_ref);
// V4 strengthened: host_authored_neutral defaults to NOT shareable.
if (policy.topic_visibility === "user_marked_private") return false;
if (policy.topic_visibility === "user_marked_shareable") return true;
if (policy.topic_visibility === "neutral_classifier") {
return shared_view.exposed_surfaces.includes("neutral_topics");
}
if (policy.topic_visibility === "host_authored_neutral" ||
policy.topic_visibility === "host_strategy") {
// NOT shareable by default (V4-J-1 + V3-J-3).
// Recipient sees ONLY if shared_view explicitly includes
// "host_topics" exposure surface.
return shared_view.exposed_surfaces.includes("host_topics");
}
return false; // safe fallback
});
}
```
OP-A row: implicit (covered by OBL-J-CORPUSPROFILE-01 + Artifact 4 SharedCorpusView).
Acceptance test: V3-AT-13 + V4-AT-29 (deny-wins precedence in
SharedCorpusView; covers topic visibility consumer side).
### §5.3 INV-J-TOPIC-MERGE-1 — Anchor Node anti-auto-merge
**[V4 PATCH:V4-J-4 per R-GEM #4 — INV-J-TOPIC-MERGE-1]**
Per V4 §3.5.4:
```text
INV-J-TOPIC-MERGE-1 (V4 NEW per V4-J-4; canonical home Artifact 2 §5.3):
Anchor Nodes (system topics that drift freely until user interaction;
then permanent) MUST NOT be auto-merged once anchored. The system MAY
suggest merges via the Triage UI; user MUST approve before any merge
operation executes.
Implementation: when topic_dedup pipeline detects an Anchor Node as a
candidate for merge with another topic:
1. Generate a merge_candidate event in Triage UI (Q Dashboard
surface; data contract via FieldResolution-like envelope).
2. Display both topic labels, content samples, and divergence /
convergence signals (term overlap, embedding distance,
cluster centroid distance).
3. Require explicit user approval before executing merge operation.
4. Approval kernel-records the merge_decision with operator_ref
and merge_basis ("user_approved_merge"); emits topic_assignment_write
effect_kind (per Artifact 3 §4.3.15) for the merged result.
Auto-merge of non-Anchor topics is permitted under topic_dedup_threshold
rules (V3-J-5 + §8). Anchor Nodes are exempt from auto-merge regardless
of similarity score.
Anchor Node lifecycle:
- System generates topic via topic_extraction (per CorpusProfile.
topic_extraction_directive).
- Topic enters "drifting" state; can be auto-merged or auto-renamed.
- On user interaction (any of: opening the topic, marking as
relevant, including in a brief, manually editing label):
→ topic transitions to "anchored" state via
anchor_node_promotion effect_kind (per Artifact 3 §4.3.16).
- Anchored topic MUST NOT be auto-merged or auto-renamed
thereafter; user-approved actions only.
Runtime check (topic_dedup pipeline):
function evaluate_topic_for_dedup(
candidate_a: Topic,
candidate_b: Topic,
similarity_score: number
): DedupOutcome {
const a_anchored = (candidate_a.lifecycle_state === "anchored");
const b_anchored = (candidate_b.lifecycle_state === "anchored");
if (a_anchored || b_anchored) {
// Per INV-J-TOPIC-MERGE-1: anchored topics not auto-merged.
if (similarity_score >= AUTO_MERGE_THRESHOLD) {
return {
action: "emit_merge_candidate_for_user_review",
reason: "anchor_node_anti_auto_merge",
anchored: a_anchored ? candidate_a.id :
b_anchored ? candidate_b.id : null,
};
}
return { action: "no_merge" };
}
// Both non-anchored: standard auto-merge rules apply.
if (similarity_score >= AUTO_MERGE_THRESHOLD) {
return { action: "auto_merge" };
}
if (similarity_score >= EMBEDDING_SIMILARITY_CANDIDATE) {
return { action: "llm_validation_required" };
}
return { action: "no_merge" };
}
```
OP-A row: `OBL-D73-V16-TOPIC-DOMAIN-CONCEPT-01` (V3.7 base; consumed here for Anchor Node lifecycle invariant).
Acceptance test: V4-AT-39 (Anchor Node anti-auto-merge; covered by V1.6.1 Safe Patch Audit if relevant).
### §5.4 INV-J-TOPIC-DEDUP-1 — Legal domain dedup threshold ≥ 0.93
**[V4 PATCH:V4-J-4 per R-GEM #14 — INV-J-TOPIC-DEDUP-1]**
Per V4 §3.5.4:
```text
INV-J-TOPIC-DEDUP-1 (V4 NEW per V4-J-4; canonical home Artifact 2 §5.4):
For domain_profile = legal, topic embedding deduplication threshold
MUST be ≥ 0.93 (raised from V3 default 0.82-0.90 band per
topic_dedup_threshold). Lower thresholds in legal domain trigger
hubness collapse where boilerplate chunks ("plaintiff", "scienter",
"motion", "prejudice") cluster with nearly everything, forcing
expensive LLM validation on every ingestion and destroying the API
budget.
Implementation: TopicExtractionStrategy carries domain_profile field;
deduplication thresholds vary by profile. CorpusProfile.topic_extraction_directive
overrides defaults.
Default thresholds by domain_profile:
legal:
embedding_similarity_candidate ≥ 0.93
auto_merge_threshold ≥ 0.95
llm_validation_band [0.93, 0.95]
general: (V3 carried)
embedding_similarity_candidate ≥ 0.82
auto_merge_threshold ≥ 0.90
llm_validation_band [0.82, 0.90]
technical:
embedding_similarity_candidate ≥ 0.88
auto_merge_threshold ≥ 0.92
llm_validation_band [0.88, 0.92]
medical:
embedding_similarity_candidate ≥ 0.90
auto_merge_threshold ≥ 0.93
llm_validation_band [0.90, 0.93]
Recommended optimization (V1.6.1 candidate, NOT V1.6 must-have):
TF-IDF weighted embeddings OR mean-vector subtraction for legal corpora
to dramatically reduce boilerplate hubness. Tracked as
OBL-J-V161-LEGAL-HUBNESS-MITIGATION-01.
Runtime check (topic_dedup pipeline; called before §5.3
evaluate_topic_for_dedup):
function get_dedup_thresholds(
corpus_profile: CorpusProfile
): DedupThresholds {
const profile = corpus_profile.extraction_spec.domain_profile;
const default_thresholds = DOMAIN_DEDUP_DEFAULTS[profile];
// Apply override from CorpusProfile.topic_extraction_directive
// if present (per V3-J-5 / §8).
const directive_override = corpus_profile.topic_extraction_directive
?.topic_dedup_threshold_override;
if (directive_override) {
return {
embedding_similarity_candidate:
directive_override.embedding_similarity_candidate ??
default_thresholds.embedding_similarity_candidate,
auto_merge_threshold:
directive_override.auto_merge_threshold ??
default_thresholds.auto_merge_threshold,
llm_validation_band:
directive_override.llm_validation_band ??
default_thresholds.llm_validation_band,
};
}
return default_thresholds;
}
function validate_threshold_floor(
domain_profile: string,
proposed_thresholds: DedupThresholds
): ValidationResult {
// INV-J-TOPIC-DEDUP-1 enforcement: legal domain ≥ 0.93 floor.
if (domain_profile === "legal" &&
proposed_thresholds.embedding_similarity_candidate < 0.93) {
return reject("topic_dedup_threshold_below_legal_floor",
"INV-J-TOPIC-DEDUP-1 requires legal domain " +
"embedding_similarity_candidate >= 0.93");
}
return accept();
}
```
OP-A rows: implicit (covered by Group J family) + `OBL-J-V161-LEGAL-HUBNESS-MITIGATION-01` (V1.6.1 candidate per V4 §0.5.1).
Acceptance test: V4-AT-39 (legal domain dedup threshold ≥ 0.93 enforcement).
---
## §6. Group J — PatternLibraryVisibility
### §6.1 PatternLibraryVisibility canonical schema
**[V4 PATCH:V4-J-3 per R-G55S §28 — PatternLibraryVisibility]**
Per V4 §3.5.4.5: pattern_library entries authored by host (e.g., `legal_caption_patterns_v1` extended with host-specific patterns) are work product. They become hidden work product if shared without visibility marking.
```typescript
type PatternLibraryVisibility = { // V4 NEW per V4-J-3
policy_id: string;
pattern_library_visibility:
| "system_starter" // shipped with V1.6
// starter library;
// shareable by default
| "host_authored_neutral" // host-added but
// content-neutral;
// NOT shareable by
// default (mirrors
// topic policy)
| "host_strategy" // host work product
// strategy; NOT
// shareable by default
| "user_marked_shareable" // host explicitly
// marked shareable
| "user_marked_private"; // host explicitly
// marked private
default_share_link_visibility: "include" | "exclude";
schema_version: 1;
};
type PatternLibraryEntry = { // V4 NEW
entry_id: string;
library_ref: string; // pattern_library_ref
// from CorpusProfile
// (per §3.1)
pattern_kind:
| "regex"
| "structural_grammar"
| "schema_llm_prompt_template"
| "validation_rule"
| "cross_field_consistency_rule";
pattern_content: string; // pattern definition
// (regex / template /
// etc.)
visibility_policy_ref: string; // PatternLibraryVisibility
// ref
authored_by: ActorRef;
authored_at: ISO8601;
schema_version: 1;
};
```
### §6.2 INV-J-PATTERN-LIB-VIS-1
Per V4 §3.5.4.5:
```text
INV-J-PATTERN-LIB-VIS-1 (V4 NEW; canonical home Artifact 2 §6.2):
Pattern library entries carry PatternLibraryVisibility mirroring
TopicVisibilityPolicy. Default for host-authored pattern entries:
NOT shareable. System-shipped starter library entries: shareable.
Share-link sessions consuming pattern libraries (e.g., for reference
extraction within share-link scope) see only system_starter +
user_marked_shareable patterns; host-authored entries are filtered
out.
Default visibility per pattern_library_visibility:
system_starter: shareable by default
host_authored_neutral: NOT shareable by default
host_strategy: NOT shareable by default
user_marked_shareable: shareable
user_marked_private: NOT shareable
Runtime check (pattern library consumption at extraction time):
function filter_pattern_library_for_session(
library: PatternLibraryEntry[],
session: SessionProfile,
shared_view?: SharedCorpusView
): PatternLibraryEntry[] {
if (session.session_kind !== "share_link_session") {
return library; // host session sees everything
}
return library.filter(entry => {
const policy = lookup_pattern_library_visibility(
entry.visibility_policy_ref
);
if (policy.pattern_library_visibility === "user_marked_private") {
return false;
}
if (policy.pattern_library_visibility === "user_marked_shareable" ||
policy.pattern_library_visibility === "system_starter") {
return true;
}
// host_authored_neutral / host_strategy:
// NOT shareable by default.
return false;
});
}
```
OP-A row: `OBL-J-PATTERN-LIB-VIS-V16-01` (V4 NEW per V4-J-3).
### §6.3 Pattern library lifecycle
```text
Pattern library lifecycle:
Creation:
- System ships starter library at V1.6 release time:
pattern_library_visibility = "system_starter"
Per Artifact 2 §3.1 CorpusProfile.pattern_library_ref points to
starter library by default.
Host extension:
- Host adds patterns (e.g., new ECF court variant); created with
pattern_library_visibility = "host_authored_neutral" by default.
- Host can mark as "host_strategy" if pattern is strategy-bearing.
- Host can promote individual entries to "user_marked_shareable" via
Q Dashboard (per Artifact 4 affordance).
Share-link consumption:
- Per INV-J-PATTERN-LIB-VIS-1: filter applied at extraction time.
- Recipient session consuming pattern library for reference
extraction sees only system_starter + user_marked_shareable
entries; host_authored entries filtered out.
Anchoring (V1.6.1 candidate):
- Pattern entry usage tracking; high-usage entries can be promoted
to "anchored" state similar to Anchor Nodes for topics.
- V1.6 ships without anchor lifecycle for patterns; V1.7+ adds.
```
[V1.6 DRAFTING NOTE: Pattern library anchoring lifecycle deferred to V1.7+. Current V1.6 schema does not include "anchored" state for patterns. Tracked Tier B Q-3-A2-PATTERN-ANCHOR.]
---
## §7. Group J — J.5 minimum filter UI
### §7.1 V1.6 minimum filter UI promoted (V3-J-4)
**[V4 PATCH:V3-J-4 per R-EX §3.5 MODIFY]**
Per V4 §3.5.5: V2 had J.5 (filter UI) as ACCEPT_MOD: "V1.6 ships filter on core 16 fields; V1.6.1 expands." R-EX correctly noted brief bank without minimum filtering is not actually usable for litigation work — case/court/filing_type/date/motion_type/side/outcome are core-required filters, not stretch.
V3 promotes J.5 minimum to V1.6 must-have:
```text
J.5 V1.6 minimum filter UI (PROMOTED to V1.6 must-have per V3-J-4):
Required filters (V1.6 — 9 original):
1. case_number_normalized (text + selector)
2. court_id (selector)
3. filing_kind (selector: motion / opposition / reply / order /
pleading / declaration / exhibit / proposed_order /
stipulation / rjn / non_filing — per FilingUnitKind
§11.2)
4. procedural_posture (selector: pleadings / discovery / dispositive /
trial / post_trial / appellate)
5. filing_date (date range — per INV-V16-TIMEZONE-1)
6. motion_type (selector: MTD / MSJ / MTC / MTS / MIL / MTC_protective /
MTC_class_cert / discovery_motion_other /
trial_motion_other / post_trial_motion /
appellate_motion / other — per RelatedMotionType
§18.3)
7. filing_side (selector: plaintiff / defendant / third_party / amicus /
court — per FilingRole §18.2)
8. outcome (selector: pending / granted / denied / mooted / withdrawn /
stricken / deferred / reserved / terminated / vacated /
reversed / remanded / other — per RulingDisposition.disposition
§13.2)
9. docket_status (selector: active / closed / stayed / consolidated /
severed)
Filter UI rendering: Members tab sub-view per INV-13.6 §2.1.
```
### §7.2 V4-J-2 additional filters (provenance + review_state + source_visibility)
**[V4 PATCH:V4-J-2 per R-CG #22 + R-G55 #26 + R-G55X §28 + R-G55S #29]**
Per V4 §3.5.5:
```text
V4-J-2 additional filter axes (V1.6 minimum expanded to 12 total):
Required additional filters (V1.6 — V4 NEW):
10. field_provenance (selector):
auto / user_corrected / source_authoritative / locked
11. review_state (selector):
unreviewed / partially_reviewed / fully_reviewed / contested
12. source_visibility (selector):
public_open / work_product_internal / firewalled / sealed
(only values present in user's accessible corpora; host tier
sees full list)
Total V1.6 minimum filter axes: 12 (9 original V3-J-4 + 3 V4-J-2 additions).
These three axes are useful for litigation:
field_provenance:
Filter "show me only filings where I corrected case_number"
(user_corrected) or "auto-extracted only" (auto). Useful for
triage queue review.
Maps to LegalMetadataFieldValue.source_kind (per §4.1).
review_state:
Triage queue shows "unreviewed" or "contested"; verified-work-product
shows "fully_reviewed". Useful for distinguishing audit-ready
work from in-progress work.
source_visibility:
Scope queries to specific visibility classes. Per Artifact 4
INV-M-COVERAGE-VISIBILITY-1: share-link sessions see filtered
list (only values present in their permitted corpora).
V1.6.1 candidates (full filter UI per V4 §3.5.5):
- PSLRA / 9(b) status filter
- CW count filter
- argument-level theme filter
- citation pattern filter
- exhibit dependency filter
- judge filter (with temporal validity)
- counsel filter (CounselAppearance — V1.6.1 schema)
- hearing metadata filter
These extend the 12 V1.6 minimums; not blockers for V1.6 ship.
```
### §7.3 J.5 filter UI data contract
```typescript
type FilterCriteria = { // V1.6 J.5 minimum
case_number_normalized?: string; // text or pattern
court_id?: string[]; // selector (multi)
filing_kind?: FilingUnitKind[]; // per §11.2
procedural_posture?: ProceduralPosture[]; // per §7.4 enum
filing_date_range?: { // per INV-V16-TIMEZONE-1
start?: ISO8601;
end?: ISO8601;
inclusive_endpoints: boolean;
timezone_basis: "originating" | "utc" | "host_user_local";
};
motion_type?: RelatedMotionType[]; // per §18.3
filing_side?: FilingRole[]; // per §18.2
outcome?: RulingDispositionEnum[]; // per §13.2
docket_status?: DocketStatus[]; // per §7.4 enum
// V4-J-2 additions:
field_provenance?: LegalMetadataFieldValue<any>["source_kind"][];
review_state?: ReviewState[]; // per §7.4 enum
source_visibility?: VisibilityClass[]; // per Artifact 1 §13
schema_version: 1;
};
```
### §7.4 Supporting enums (ProceduralPosture / DocketStatus / ReviewState)
```typescript
type ProceduralPosture =
| "pleadings"
| "discovery"
| "dispositive"
| "trial"
| "post_trial"
| "appellate";
type DocketStatus =
| "active"
| "closed"
| "stayed"
| "consolidated"
| "severed"
| "transferred";
type ReviewState =
| "unreviewed"
| "partially_reviewed"
| "fully_reviewed"
| "contested";
```
OP-A rows: implicit (covered by Group J family) + Q Dashboard rendering layer per DOC20/DOC7.
---
## §8. Group J — topic_dedup_threshold + source_span_unavailable rename
### §8.1 topic_dedup_threshold defaults vs override (V3-J-5)
**[V4 PATCH:V3-J-5 per R-EX §3.5 MODIFY]**
Per V4 §3.5.6:
```typescript
type TopicDedupThresholdConfig = { // V3-J-5
config_id: string;
topic_dedup_threshold_defaults: {
embedding_similarity_candidate: number; // default 0.82
// (general); 0.93
// (legal per
// INV-J-TOPIC-DEDUP-1
// §5.4)
auto_merge_threshold: number; // default 0.90
// (general); 0.95
// (legal)
llm_validation_band: [number, number]; // default [0.82, 0.90]
// (general); [0.93,
// 0.95] (legal)
};
topic_dedup_threshold_override?: { // per-corpus override
embedding_similarity_candidate?: number;
auto_merge_threshold?: number;
llm_validation_band?: [number, number];
};
override_set_by?: ActorRef;
override_reason?: string;
schema_version: 1;
};
```
V1.6 default config ships with the V2 thresholds. Override capability is per-corpus; CorpusProfile.topic_extraction_directive carries the optional override.
Per INV-J-TOPIC-DEDUP-1 §5.4: legal domain has FLOOR (≥ 0.93) — overrides BELOW the floor are rejected at policy construction.
### §8.2 source_span_unavailable framing rename (V3-J-6)
**[V4 PATCH:V3-J-6 per R-EX §3.5 MODIFY]**
Per V4 §3.5.7: V2 had `Synthetic_Synthesis` UI flag for memories without source spans. R-EX correctly noted the name is jargon-laden and unclear at the UI surface.
```text
V3 rename:
V2 name: Synthetic_Synthesis
V3 name: synthesis_summary_no_spans
Rationale: user-facing framing must be clear ("system synthesis;
source spans unavailable") rather than technical jargon.
This V1.6 framing rename appears in:
- CU.display_kind enum (Artifact 1 §8.2; per V4-A-INV-CU + V3-J-6)
value: "synthesis_summary_no_spans" (NOT "synthetic_synthesis")
- source_span_unavailable receipt (Artifact 3 §9.3)
- Q Dashboard rendering (Artifact 4 §19.1 CURenderingDataContract)
Per V4-A-INV-CU + INV-MVC-CU-1 (Artifact 3 §9): CUs with
display_kind = "synthesis_summary_no_spans" render with explicit
"system synthesis; source spans unavailable" framing and NO
"Jump to Source" affordance; NOT cited as authority for legal
work-product purposes.
```
OP-A row: implicit (consumed by Group J + cross-Artifact 3 §9 + Artifact 4 §19.1).
---
## §9. Group J — CorpusProfileFork + ForkRelationshipEdge
### §9.1 CorpusProfileFork canonical schema
**[V4 PATCH:V4-J-FORK per R-CL4 #34 — CorpusProfile fork semantics]**
Per V4 §3.5.2: V3 had `forkable_template_id` field but didn't specify fork behavior when source corpus updates. V4 adds explicit fork semantics:
```typescript
type CorpusProfileFork = { // V4 NEW per V4-J-FORK
fork_id: string;
forked_from_template_id: string; // source CorpusProfile
// template
forked_from_template_version: string; // version at fork
// time (snapshot
// semantics)
forked_at: ISO8601;
forked_by_actor_ref: ActorRef;
// Schema deviation: which fields the fork has changed from source
field_overrides: string[]; // field paths e.g.,
// "extraction_spec.required_fields",
// "metadata_schema_ref"
schema_version: 1;
};
```
### §9.2 ForkRelationshipEdge canonical schema
```typescript
type ForkRelationshipEdge = { // V4 NEW per V4-J-FORK
edge_id: string;
source_template_ref: string; // origin CorpusProfile
// template
forked_corpus_ref: CorpusRef; // forked corpus
fork_id: string; // CorpusProfileFork ref
edge_type: "forked_from"; // edge_type registered
// in DOC72 R5.74+
// FilingRelationship
// edge type registry
schema_version: 1;
};
```
### §9.3 INV-J-FORK-1
Per V4 §3.5.2:
```text
INV-J-FORK-1 (V4 NEW per V4-J-FORK; canonical home Artifact 2 §9.3):
Forks are template-snapshots, not template-references. Forking creates
a new CorpusProfile with template_version = source_template_version_at_fork.
Source-template subsequent updates do NOT auto-propagate to forks.
User options to update a fork:
(a) Re-fork:
Discard current fork, fork from current source. Incurs migration
of any field_overrides; user reviews diff before re-forking.
(b) Pull-update specific fields:
User opts in to specific field updates from source template;
conflicts with field_overrides surface as candidates for review.
(c) Continue without update:
Fork remains pinned to source_template_version at fork time;
user accepts that source template has evolved.
ForkRelationshipEdge tracks fork lineage for audit. Multiple forks
of same source template are independent (no cross-fork update
propagation).
V1.6 default behavior on source template update: surface notification
to fork owner ("Source template <id> updated to <version>; fork
pinned to <your_fork_version>; review available at <url>").
Runtime flow:
function fork_corpus_profile(
source_template_id: string,
forking_actor: ActorRef,
field_overrides: string[] = []
): { forked_corpus: CorpusProfile;
fork: CorpusProfileFork;
edge: ForkRelationshipEdge } {
const source = lookup_corpus_profile(source_template_id);
// Snapshot semantics: deep-copy source CorpusProfile.
const forked_corpus_id = new_id();
const forked_corpus: CorpusProfile = {
...deep_copy(source),
corpus_id: forked_corpus_id,
template_version: source.template_version, // pinned
forkable_template_id: undefined, // forked corpus is
// NOT itself a
// forkable template
schema_version: 1,
};
const fork: CorpusProfileFork = {
fork_id: new_id(),
forked_from_template_id: source_template_id,
forked_from_template_version: source.template_version,
forked_at: NOW(),
forked_by_actor_ref: forking_actor,
field_overrides,
schema_version: 1,
};
const edge: ForkRelationshipEdge = {
edge_id: new_id(),
source_template_ref: source_template_id,
forked_corpus_ref: forked_corpus_id,
fork_id: fork.fork_id,
edge_type: "forked_from",
schema_version: 1,
};
// Persist via kernel envelope; effect_kinds: node_write +
// edge_create + index_update (per Artifact 3 §3.3 semantic verb).
return { forked_corpus, fork, edge };
}
OP-A row: OBL-D73-J-FORK-LINEAGE-V16-01 (V4 NEW per V4-J-FORK).
```
Acceptance test: V4-AT-FORK (CorpusProfile fork update isolation; covered by V1.6 fork lineage tests).
### §9.4 Source template update notification flow
```text
Source template update lifecycle:
T-1: Source template author publishes new template_version.
T-2: System detects version change in source template.
T-3: System enumerates active forks of source template.
T-4: For each fork: emit notification to fork owner ("Source
template <id> updated; fork pinned to <fork_version>; review
available").
T-5: Fork owner makes decision per §9.3 (a/b/c).
T-6: Decision applied via kernel envelope (effect_kind: node_write
on forked CorpusProfile if updates applied; receipt_only if
no-change).
OP-A row: implicit (notification layer per Q Dashboard).
```
---
## §10. Group O — Owner split
### §10.1 V4-O-1 entity_subtype split (canonical home cross-reference)
**[V4 PATCH:V4-O-1 per R-CG #8 + R-G55 #10 + R-G55X §13 + R-G55S §11]**
Per V4 §2.2.1 + V4-O-1 (already declared at §1.2 INV-O-TAXONOMY-1):
```text
Group O entity_subtype assignments per V4-O-1:
FilingUnit: world_entity (entity_subtype:
"filing_unit") — external court filing
fact (real-world filing identity, NOT
host work product)
FilingUnitVersion: world_entity (entity_subtype:
"filing_unit_version") — payload of
FilingUnit
FilingUnitTextVersion: world_entity (entity_subtype:
"filing_unit_text_version") — payload
MotionChain: work_product (entity_subtype:
"motion_chain") — host's analytical
labeling
FilingChain: work_product (entity_subtype:
"filing_chain") — host's analytical
labeling
CorpusProfile: work_product (entity_subtype:
"corpus_profile") — payload on
knowledge_corpus world_entity per V3-J-1
RulingDisposition: world_entity payload (court's actual
disposition; world fact recorded by host)
CourtDispositionObservation: world_entity (entity_subtype:
"court_disposition_observation") —
observation of real docket event
CourtOrderDisposition: world_entity payload (parent of
RulingDisposition[] array)
V4-O-1 rationale: ChatGPT proposed full FilingUnit-as-work_product. V4
disposition splits more cleanly: FilingUnit identifies an external
court filing (world fact); MotionChain/FilingChain/CorpusProfile are
host's analytical structures (work product). DOC72 entity_subtype
distinction captures this without over-classifying.
```
### §10.2 INV-O-ARTIFACT-IDENTITY-1 cross-reference
Per V4 §2.2.3 (renamed from INV-J.11-1):
```text
INV-O-ARTIFACT-IDENTITY-1 (V3 carry-forward; canonical home Artifact 5
§2.6; cross-reference here):
A SourceArtifact is NOT a FilingUnit. SourceArtifact is the file-level
identity (one PDF blob, one DOCX file, one image); FilingUnit is the
legal-semantics identity (court + case + docket entry + attachment +
subdocument).
Mapping:
- One SourceArtifact may contain multiple FilingUnits (composite
PACER bundle: one PDF with brief + 5 exhibits → 1 SourceArtifact,
6 FilingUnits).
- One FilingUnit may have multiple SourceArtifacts across versions
(FilingUnitVersion legal-version sequence; FilingUnitTextVersion
text-version sequence).
- The link is via SegmentToFilingUnit binding (per Artifact 5 §3.3
segmentation).
Kernel-side: SourceArtifact creation emits document_artifact_write
effect_kind (Artifact 3 §4.3.4); FilingUnit creation emits
filing_unit_write effect_kind (Artifact 3 §4.3.8). The two are
distinct kernel operations; the binding between them is a third
operation (filing_relationship_write per Artifact 3 §4.3.14).
This artifact §11 specifies the FilingUnit canonical schema; Artifact 5
§2 specifies SourceArtifact. Both are required for V1.6 release.
```
OP-A rows: `OBL-D73-O-FILINGUNIT-01` (this artifact; FilingUnit) + `OBL-D25-O-SOURCEARTIFACT-01` (Artifact 5; SourceArtifact).
---
## §11. Group O — FilingUnit + FilingUnitIdentity
### §11.1 FilingUnit canonical schema
**[V4 PATCH:V3-O-2 per R-V22 §9 + V4-O-3 ResolvedCaseIdentity]**
Per V4 §2.2.2:
```typescript
type FilingUnit = { // canonical V1.6 schema
// Graph identity per V4-O-1:
// node_kind: world_entity, entity_subtype: filing_unit
// FilingUnit is a payload field on the world_entity node.
filing_unit_id: string; // refers to
// world_entity
// node ID
// Identity (V3-O-2 + V4-O-3)
filing_unit_identity: FilingUnitIdentity; // per §11.2
// Legal classification (per V4-J-3.5-K-3.6 unified canonical enum)
legal_profile_kind?: LegalProfileKind; // per §18.4
// V4-K-1 orthogonal axes (per §18):
filing_unit_kind?: FilingUnitKind; // physical filing
// shape
filing_role?: FilingRole; // relationship
// to motion
related_motion_type?: RelatedMotionType; // specific motion
// type when
// applicable
// Filing date (per INV-V16-TIMEZONE-1)
filing_date_utc?: ISO8601;
filing_date_originating_tz?: string; // IANA tz name
filing_date_originating_calendar_date?: string; // YYYY-MM-DD
// FilingUnit metadata fields (LegalMetadataFieldValue per §4.1)
metadata_fields: Map<string, LegalMetadataFieldValue<any>>;
// Versions (per §12 FilingUnitVersion + FilingUnitTextVersion)
current_legal_version_ref?: string; // FilingUnitVersionRef
legal_version_history: string[]; // FilingUnitVersionRef[]
// (chronological)
// Visibility / policy
visibility_class: VisibilityClass; // per Artifact 1 §13
policy_generation_id: string; // per V4-§0.4-1
// Filing parts (per §11.4 FilingPartVisibility)
filing_parts?: FilingPart[]; // per V2 patch L9 +
// V4-O-FILING-PART-VIS
// Lineage
superseded_by_filing_unit_id?: string; // when filing
// superseded
superseding_basis?: string; // basis for
// supersession
// Audit
created_at: ISO8601;
schema_version: 1;
};
```
### §11.2 FilingUnitIdentity canonical schema (V3-O-2 + V4-O-3)
Per V4 §2.2.2:
```typescript
type FilingUnitIdentity = { // V3-O-2 expanded +
// V4-O-3
// Core docket identity
court_id?: string; // canonical court
// ID (DOC72
// governed)
case_number_normalized?: string; // matches against
// jurisdictional
// pattern
case_number_raw?: string;
docket_entry_no?: string; // ECF main entry
ecf_attachment_no?: number; // attachment index
// (0 = main, 1+ =
// attachments)
subdocument_no?: string; // for filings split
// into sub-documents
// V4 NEW per V4-O-3:
resolved_case_ref?: ResolvedCaseIdentityRef; // canonical case
// identity (per
// §11.3)
// Source identity (when docket identity unavailable)
source_system?:
| "pacer"
| "recap"
| "court_efile"
| "user_upload"
| "email_attachment"
| "free_web_pdf"
| "third_party_provider"
| "unknown";
// Confidence
identity_confidence: number; // [0, 1]
identity_evidence:
| "ecf_metadata" // structured metadata
// available (per
// Artifact 5 §4.1
// INV-K-METADATA-AUTHORITY-1
// authoritative)
| "filing_caption_extraction" // caption parsed;
// verified
| "filename_inference" // weak inference
// from filename
| "user_assigned" // user labeled
| "unknown_artifact"; // identity unknown
schema_version: 1;
};
type ResolvedCaseIdentityRef = string; // pointer to
// ResolvedCaseIdentity
// (§11.3)
```
### §11.3 ResolvedCaseIdentity canonical schema (V4-O-3)
**[V4 PATCH:V4-O-3 per R-CG #10 + R-G55 #12 + R-G55X §14 — ResolvedCaseIdentity]**
Per V4 §2.2.2: same case can be filed under multiple case numbers (consolidated cases, severed cases, transferred cases). Real legal-litigation reality.
```typescript
type ResolvedCaseIdentity = { // V4 NEW per V4-O-3
resolved_case_id: string; // canonical case
// identity across
// renumbering
alternate_case_numbers: string[]; // historical /
// parallel case
// numbers
// R0.2 PATCH per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-8:
// Histories are optional; absence indicates "no known history" rather
// than "no history exists". Legacy data or incomplete ECF parses may
// yield ResolvedCaseIdentity with histories undefined even when case
// has been consolidated/transferred/severed. Queries should fall back
// to canonical case_number_normalized only and surface
// "history-unknown" framing when histories absent for cross-case
// queries.
consolidation_history?: ConsolidationEvent[];
transfer_history?: TransferEvent[];
severance_history?: SeveranceEvent[];
schema_version: 1;
};
type ConsolidationEvent = { // per V4-O-3
consolidation_date: ISO8601;
consolidating_court: string;
consolidated_into_case_number: string;
source_case_numbers: string[];
};
type TransferEvent = { // per V4-O-3
transfer_date: ISO8601;
source_court: string;
destination_court: string;
destination_case_number: string;
};
type SeveranceEvent = { // per V4-O-3
severance_date: ISO8601;
parent_case_number: string;
severed_case_numbers: string[];
};
```
FilingUnitIdentity carries optional `resolved_case_ref` pointing to ResolvedCaseIdentity. Queries searching across "the case" follow ResolvedCaseIdentity to find all FilingUnits historically associated with that case.
### §11.4 FilingPart + FilingPartVisibility
Per V2 patch L9 + V4-O-FILING-PART-VIS + INV-O-FILING-PART-VIS-1:
```typescript
type FilingPart = { // V2 patch L9 +
// V4-O-FILING-PART-VIS
part_id: string;
filing_unit_ref: FilingUnitRef;
part_kind:
| "caption" // case caption page
| "main_body" // main argument /
// pleading body
| "exhibit" // exhibit attached
| "declaration" // sworn declaration
| "proposed_order" // proposed order
| "certificate_of_service"
| "table_of_contents"
| "table_of_authorities"
| "signature_block";
part_path: string; // hierarchical
// path (e.g.,
// "/main/exhibit/A")
page_range?: { start: number; end: number };
artifact_segment_ref?: string; // pointer to
// ArtifactSegment
// (Artifact 5 §3)
visibility_class: VisibilityClass; // per-part visibility
// (e.g., sealed
// exhibit within
// public filing)
schema_version: 1;
};
type FilingPartVisibility = { // V2 + V4
policy_id: string;
filing_unit_ref: FilingUnitRef;
part_visibilities: Map<string, VisibilityClass>; // keyed by part_path
schema_version: 1;
};
```
#### §11.4.X INV-O-FILING-PART-VIS-1 (R0.2 NEW per AUDIT_DOC73_Artifact2_R0.1.md HIGH-A2-1)
**[V4 PATCH:V2 patch L9 + V3-O-3 (renamed from INV-J.11-VIS-1) — INV-O-FILING-PART-VIS-1]**
Per V4 §2.2.3 (line 2575): `INV-J.11-VIS-1 → INV-O-FILING-PART-VIS-1`. Audit HIGH-A2-1: R0.1 listed in cross-references table but missing canonical declaration.
```text
INV-O-FILING-PART-VIS-1 (V3 renamed from INV-J.11-VIS-1; canonical
home Artifact 2 §11.4.X):
FilingParts within a FilingUnit can have distinct visibility classes
(e.g., sealed exhibit within public filing). FilingPartVisibility
schema captures per-part visibility; queries operating on filing-part
granularity respect per-part visibility class.
Resolution rules:
- artifact.visibility_class = max_visibility_class across
filing_parts (most restrictive wins per V4 INV-A-TAINT-INFECTIOUS-1
lattice — Artifact 3 §7.2 canonical home).
- Search retrieval at filing-part granularity (per Artifact 4 §15.4
INV-M-ACCESS-RANK-1) honors FilingPartVisibility.
- AccessOverlay at target_kind = "filing_part" granularity (per
Artifact 3 §12.1 + V3-B2-1) overrides FilingPartVisibility when
overlay deny-wins (per Artifact 3 §12.3 INV-B2-OVERLAY-RESOLUTION-1).
Runtime check (filing-part-scoped retrieval):
function check_filing_part_visibility(
part: FilingPart,
session: SessionProfile
): boolean {
// Step 1: AccessOverlay check (most-specific-wins per
// INV-B2-OVERLAY-RESOLUTION-1; Artifact 3 §12.3).
const overlays = lookup_overlays_at_part_granularity(part);
if (overlays.length > 0) {
const winning = resolve_overlays_per_inv_b2(overlays, part);
if (winning.access_restriction === "blocked") return false;
}
// Step 2: FilingPartVisibility class check.
return check_visibility_permits(part.visibility_class, session);
}
function compute_filing_unit_visibility_rollup(
filing_unit: FilingUnit
): VisibilityClass {
if (!filing_unit.filing_parts || filing_unit.filing_parts.length === 0) {
return filing_unit.visibility_class;
}
const part_classes = filing_unit.filing_parts.map(p => p.visibility_class);
return max_visibility_class(part_classes); // per
// INV-A-TAINT-INFECTIOUS-1
// lattice
// (Artifact 3 §7.2)
}
OP-A row: OBL-O-FILING-PART-VIS-01 (per OPA V3.8 §6.26.O).
```
### §11.5 INV-O-FILING-UNIT-CANONICAL-1 (renamed from J.11-2)
Per V4 §2.2.3:
```text
INV-O-FILING-UNIT-CANONICAL-1 (V3 renamed from V2 INV-J.11-2; canonical
home Artifact 2 §11.5):
FilingUnit canonical key = court_id + case_number + ecf_document_no +
ecf_attachment_no + subdocument_no.
Two SourceArtifacts referencing the same canonical key MUST resolve
to the same FilingUnit (dedup at FilingUnit layer per V2 INV-J.11-2 +
V4 INV-O-DEDUP-1/2).
When canonical key components are missing (identity_evidence !=
"ecf_metadata"): use heuristic with identity_confidence; if confidence
< 0.6, render with "identity_uncertain" badge per INV-O-IDENTITY-1
(§11.6).
Runtime check:
function lookup_or_create_filing_unit(
candidate_identity: FilingUnitIdentity
): FilingUnit {
if (canonical_key_complete(candidate_identity)) {
const existing = lookup_by_canonical_key(candidate_identity);
if (existing) return existing;
}
return create_new_filing_unit(candidate_identity);
}
function canonical_key_complete(id: FilingUnitIdentity): boolean {
return id.court_id !== undefined &&
id.case_number_normalized !== undefined &&
id.docket_entry_no !== undefined;
}
```
#### §11.5.X Canonical key resolution decision tree (R0.2 NEW per AUDIT_DOC73_Artifact2_R0.1.md HIGH-A2-3)
Per audit HIGH-A2-3: §26.3 worked example identified two scenarios (different docket_entry_no vs amended same docket_entry_no) but didn't cover edge cases. R0.2 adds explicit 6-scenario decision tree:
```text
Canonical key resolution decision tree (R0.2 NEW per HIGH-A2-3):
Scenario A — Different docket_entry_no (court issues new entry):
Example: "ECF #145 supersedes ECF #142"
Resolution: NEW FilingUnit + FilingRelationship edge_type =
"supersedes_filing"
Worked example: §26.3 Scenario A.
Scenario B — Same docket_entry_no, court "amended" annotation:
Example: "Amended brief filed at ECF #142 per Local Rule 7-3"
Resolution: SAME FilingUnit, NEW FilingUnitVersion
(legal_version_kind = "amended")
Worked example: §26.3 Scenario B.
Scenario C — Same docket_entry_no, court "corrected" annotation:
Example: "Court issues clerical correction at ECF #142"
Resolution: SAME FilingUnit, NEW FilingUnitVersion
(legal_version_kind = "corrected")
Per V4-O-2: corrected = clerical fix by court; distinct from
amended (substantive update by filer).
Scenario D — Same docket_entry_no, different SourceArtifact, no
court annotation:
Example: User re-uploads version they received externally
Resolution: SAME FilingUnit; check FilingUnitTextVersion
(NOT FilingUnitVersion). Per V4-O-2: re-OCR or
user-correction creates new FilingUnitTextVersion
without legal version advance. If user is asserting
corrected content, flag for review (manual
FilingUnitVersion advance is a user-initiated workflow,
not auto-derived).
Scenario E — Different SourceArtifact ID but identical content_hash:
Example: Same PDF uploaded twice from different paths
Resolution: dedup at SourceArtifact layer per Artifact 5 §10
(multi-hash collision detection). FilingUnit unchanged.
Per INV-O-DEDUP-1 / INV-O-DEDUP-2 (§16.4).
Scenario F — User uploads service copy from external party:
Example: Service copy from opposing counsel email
Resolution: depends on user intent. Default: treat as alternate
SourceArtifact mapping to existing FilingUnit; user
affordance to confirm/upgrade.
Decision logic:
function resolve_filing_unit_for_new_artifact(
artifact_identity: FilingUnitIdentity,
artifact_metadata: ArtifactMetadata
): { resolution: ResolutionKind; filing_unit_id: string;
new_version_kind?: FilingUnitVersion["legal_version_kind"] } {
const existing = lookup_by_canonical_key(artifact_identity);
if (!existing) {
return { resolution: "create_new_filing_unit",
filing_unit_id: new_id() };
}
const has_amendment_annotation = artifact_metadata.ecf_annotations
?.some(a => a.kind === "amended");
const has_correction_annotation = artifact_metadata.ecf_annotations
?.some(a => a.kind === "corrected");
if (has_amendment_annotation || has_correction_annotation) {
return {
resolution: "create_new_filing_unit_version",
filing_unit_id: existing.filing_unit_id,
new_version_kind: has_amendment_annotation ? "amended" : "corrected"
};
}
// Same canonical key, no court annotation.
return {
resolution: "create_new_filing_unit_text_version",
filing_unit_id: existing.filing_unit_id
};
}
// ArtifactMetadata.ecf_annotations is a forecast Artifact 5 R0.3
// field per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-2; cross-artifact
// patch tracked for Step 9.
type ResolutionKind = // R0.2 NEW
| "create_new_filing_unit"
| "create_new_filing_unit_version"
| "create_new_filing_unit_text_version"
| "dedup_to_existing_artifact_layer" // Scenario E
| "user_review_required"; // Scenario F
// default
```
### §11.6 INV-O-IDENTITY-1 (V3-O-2 + V4-O-3)
Per V4 §2.2.2:
```text
INV-O-IDENTITY-1 (V3 renamed; canonical home Artifact 2 §11.6):
A FilingUnit with `identity_confidence < 0.6` is rendered as
`identity_uncertain` and excluded from default cross-brief synthesis
until user confirms identity. Identity uncertainty does not block
ingestion or extraction; it gates downstream cross-brief reasoning.
Rendering: Q Dashboard surfaces "identity uncertain" badge per
FilingUnit; user affordance "confirm identity" promotes confidence
to user_assigned with confidence = 1.0.
Cross-brief synthesis exclusion:
- Search retrieval (per Artifact 4 §15.5 INV-M-VERSION-AWARE-1
consumer side) excludes identity_uncertain FilingUnits from
default scope; user can opt-in via filter.
- cross_source_synthesis posture (per Artifact 4 §12.4) flags
identity_uncertain inclusions with explicit framing.
Per V4-O-3 INV-O-CASE-RESOLUTION-1: when ResolvedCaseIdentity exists,
queries scoped to "case X" follow the ResolvedCaseIdentity graph to
include all FilingUnits historically associated with X.
```
### §11.7 INV-O-CASE-RESOLUTION-1 (V4-O-3)
Per V4 §2.2.2:
```text
INV-O-CASE-RESOLUTION-1 (V4 NEW per V4-O-3; canonical home Artifact 2
§11.7):
When ResolvedCaseIdentity exists for a FilingUnit, queries scoped to
"case X" follow the ResolvedCaseIdentity graph to include all
FilingUnits historically associated with X (consolidated, transferred,
severed branches). User can opt out per-query with explicit
`case_resolution_scope: strict` flag.
Default behavior:
- Query "show all filings in 2:23-cv-04567" returns FilingUnits with:
(a) filing_unit_identity.case_number_normalized == "2:23-cv-04567", AND
(b) filing_unit_identity.resolved_case_ref points to a
ResolvedCaseIdentity whose alternate_case_numbers include
"2:23-cv-04567".
- Includes FilingUnits with different case numbers that share
resolved_case_ref (e.g., post-consolidation filings under new
case number).
User opt-out:
- SearchScope.case_scope flag `case_resolution_scope: strict` returns
only exact case_number matches; does NOT follow ResolvedCaseIdentity
graph.
Runtime resolution:
function resolve_case_scope(
case_ref: CaseRef,
strict: boolean = false
): FilingUnitRef[] {
if (strict) {
return lookup_filing_units_by_exact_case_number(case_ref);
}
const resolved = lookup_resolved_case_identity(case_ref);
if (!resolved) {
return lookup_filing_units_by_exact_case_number(case_ref);
}
const all_case_numbers = [
case_ref,
...resolved.alternate_case_numbers
];
return lookup_filing_units_by_any_case_number(all_case_numbers);
}
```
OP-A row: `OBL-D73-O-FILINGUNIT-01` (covers FilingUnit + ResolvedCaseIdentity).
---
## §12. Group O — FilingUnitVersion + FilingUnitTextVersion (V4-O-2)
### §12.1 FilingUnitVersion canonical schema (V4-O-2 split)
**[V4 PATCH:V4-O-2 per R-CG #9 + R-G55 #11 + R-G55X §12 + R-G55S §10 — split legal version vs text/OCR version]**
Per V4 §2.2.6: V3 conflated legal versioning (court-driven: amended, corrected, reissued, redacted) with text versioning (system-driven: re-OCR, OCR correction, redaction overlay, user correction). V4 separates:
```typescript
type FilingUnitVersion = { // V4 RENAMED per V4-O-2
version_id: string;
filing_unit_ref: FilingUnitRef;
// V4 RENAMED from version_kind:
legal_version_kind:
| "original_as_filed"
| "sealed_unredacted"
| "public_redacted"
| "amended"
| "corrected"
| "reissued"
| "stricken_record"
| "vacated";
// V4 NEW per V4-O-2 (R-CG #9):
version_sequence_number: number; // monotonic per
// FilingUnit
supersedes_version_id?: string; // explicit pointer
// in addition to
// superseded_by
superseded_by_version_ref?: string;
// V4 distinction:
// "corrected" = clerical fix by court
// "amended" = substantive update by filer
// "reissued" = court re-issuance for procedural reasons
// "stricken_record" = court order striking the filing
// "vacated" = court order vacating the filing's effect
source_artifact_ref: string; // pointer to specific
// DOC25 SourceArtifact
// (Artifact 5 §2)
text_version_ref?: string; // V4 NEW: points to
// FilingUnitTextVersion
// (per §12.2)
visibility_class: VisibilityClass;
version_provenance:
| "filing_caption_metadata"
| "redaction_log_entry"
| "court_order_referencing_version"
| "user_assigned";
effective_date: ISO8601; // per
// INV-V16-TIMEZONE-1
effective_date_originating_tz?: string;
effective_date_originating_calendar_date?: string;
schema_version: 1;
};
```
### §12.2 FilingUnitTextVersion canonical schema (V4-O-2 NEW)
```typescript
type FilingUnitTextVersion = { // V4 NEW per V4-O-2
text_version_id: string;
filing_unit_version_ref: string; // FilingUnitVersionRef
text_version_kind:
| "as_extracted_initial" // initial OCR/extraction
| "ocr_corrected" // OCR re-run with
// improved engine
| "redaction_applied" // redaction overlay
// applied
| "user_correction_applied"; // user-edited text
source_artifact_ref: string; // SourceArtifactRef
text_hash: string; // SHA-256 of text
// content (per
// ContentHashRef
// normalized_text
// kind)
extraction_run_ref?: string; // pointer to
// ExtractionRunRecord
// (Artifact 5 §6.3)
schema_version: 1;
};
```
Legal version (court-driven) and text version (system-driven) are separate. Re-OCR creates new `FilingUnitTextVersion` without new `FilingUnitVersion`. Court correction creates new `FilingUnitVersion`; text version inherits or gets re-extracted.
### §12.3 Version_kind precedence (V4)
Per V4 §2.2.6:
```text
For query selection in absence of explicit version request, version_kind
precedence (per R-CG #9):
amended > corrected > reissued > public_redacted > original_as_filed
(stricken_record / vacated EXPLICITLY EXCLUDED from query results
unless requested with `version_filter: include_terminated`)
This precedence is consumed by Artifact 4 §15.5 INV-M-VERSION-AWARE-1
search merge.
```
### §12.4 INV-O-VERSION-1
**[V4 PATCH:V3-O-7 + V4 STRENGTHENED — INV-O-VERSION-1]**
Per V4 §2.2.6:
```text
INV-O-VERSION-1 (V3 + V4; canonical home Artifact 2 §12.4):
Extraction, search, retrieval, and quote production bind to
FilingUnitVersion (legal version) AND FilingUnitTextVersion (text
version), not FilingUnit.
A query like "show me what defendants argued in Grocery Outlet MTD"
resolves to:
1. Most-authoritative FilingUnitVersion permitted by session profile
(per V4 precedence: amended > corrected > reissued >
public_redacted > original_as_filed)
2. Within that legal version, the most-recent FilingUnitTextVersion
(typically ocr_corrected over as_extracted_initial)
A share-link with public_redacted-only access cannot retrieve content
from sealed_unredacted versions or cite spans within them, even when
the FilingUnit is the same.
Cross-version content overlap (e.g., 95% identical text between
original_as_filed and corrected) does NOT permit substitution. The
legal version with permission is the legal version that is rendered.
Cross-text-version content stability does NOT propagate quote anchors:
quotes anchored to as_extracted_initial coordinates may have drifted
in ocr_corrected; system MUST re-anchor on text-version change.
V4-O-VERSION-COST implementation note (per Artifact 5 §6.5): cross-
version sharing of deterministic-stage extraction outputs is permitted
under hash-identical-at-filing-part-granularity rule; LLM stages
always run per-version (per INV-O-VERSION-1 strict reading).
Runtime check at search merge:
function select_filing_unit_version(
filing_unit_id: string,
candidates: FilingUnitVersion[],
session: SessionProfile
): FilingUnitVersion {
// Filter by visibility per session profile.
const accessible = candidates.filter(v =>
check_visibility_permits(v.visibility_class, session)
);
if (accessible.length === 0) {
throw new Error("filing_unit_no_accessible_version");
}
// Apply precedence.
const order = ["amended", "corrected", "reissued",
"public_redacted", "original_as_filed"];
const filtered = accessible.filter(v =>
v.legal_version_kind !== "stricken_record" &&
v.legal_version_kind !== "vacated"
);
if (filtered.length === 0) {
throw new Error("filing_unit_only_terminated_versions");
}
return filtered.sort((a, b) =>
order.indexOf(a.legal_version_kind) -
order.indexOf(b.legal_version_kind)
)[0];
}
```
OP-A rows: `OBL-D73-O-FILING-UNIT-VERSION-01` (V4 NEW per V4-O-2) + `OBL-D72-V16-DOCREL-01` (DOC72 R5.74+ filing-relationship edge types — supersedes_filing edge consumed at version supersession).
Acceptance test: V3-AT-17 + V4-AT-32 (FilingUnitVersion supersession + version_sequence_number monotonic).
---
## §13. Group O — RulingDisposition + CourtOrderDisposition
### §13.1 CourtOrderDisposition canonical schema
**[V4 PATCH:V3-O-5 per R-EX §2.2 + V4-O-4 mandatory scope_targets + V4-O-5 polarity]**
Per V4 §2.2.5: V2 had `RulingDisposition` as a single object on Court Order profile. Real orders dispose multiple motions/defendants/claims. V3 changed to array; V4 adds mandatory scope_targets + polarity.
```typescript
type CourtOrderDisposition = { // V3-O-5 array form
order_id: string;
source_filing_unit_ref: FilingUnitRef; // pointer to Court
// Order FilingUnit
source_filing_unit_version_ref: string; // FilingUnitVersionRef
order_date: ISO8601; // per
// INV-V16-TIMEZONE-1
order_date_originating_tz?: string;
order_date_originating_calendar_date?: string;
disposition_events: RulingDisposition[]; // ARRAY (V3-O-5
// change from
// single object)
schema_version: 1;
};
```
### §13.2 RulingDisposition canonical schema (V4-O-4 + V4-O-5)
**[V4 PATCH:V4-O-4 per R-G55 #13 + R-G55X §15 + R-G55S §12 — mandatory scope_targets]**
**[V4 PATCH:V4-O-5 per R-G55S §2 — RulingDispositionPolarity]**
```typescript
type RulingDisposition = { // V3 base + V4 expansion
disposition_event_id: string;
// What this disposition resolves (V3 base + V4 mandatory enforcement):
motion_chain_ref?: string; // MotionChainRef
filing_chain_ref?: string; // FilingChainRef
defendant_ref?: string; // PartyRef — V3 NEW;
// V4 deprecated
// → defendant_refs[]
// in scope_targets
claim_ref?: string; // ClaimRef — V3 NEW;
// V4 deprecated
// → claim_refs[]
// in scope_targets
party_role?: string;
// V4 NEW per V4-O-4 — mandatory scope:
scope_targets: {
motion_chain_ref?: string;
filing_chain_ref?: string;
defendant_refs?: string[]; // V4 array (was
// single)
claim_refs?: string[]; // V4 array (was
// single)
party_role?: string;
};
scope_basis: ScopeBasis; // V4 NEW required
// Disposition
disposition: RulingDispositionEnum; // per §13.3
leave_to_amend?:
| "with_leave"
| "without_leave"
| "not_applicable"
| "unknown";
prejudice?:
| "with_prejudice"
| "without_prejudice"
| "not_applicable"
| "unknown";
// V4 NEW per V4-O-5 — legal-polarity semantics:
polarity?: RulingDispositionPolarity;
normalized_label: string; // canonical short
// form
raw_court_language?: string; // verbatim
// disposition
// language (per
// INV-MVC-3 wrapped
// on extraction)
schema_version: 1;
};
type ScopeBasis = // V4 NEW per V4-O-4
| "explicit_court_language" // order's text
// scopes the
// disposition
| "inferred_from_motion_target" // inferred from
// motion's named
// targets
| "ambiguous_user_review_required"; // scope unclear;
// user adjudicates
type RulingDispositionPolarity = { // V4 NEW per V4-O-5
for_moving_party: PolarityValue;
for_non_moving_party: PolarityValue;
polarity_basis:
| "granted_disposition" // disposition =
// granted ⇒ moving
// wins
| "denied_disposition" // disposition =
// denied ⇒ moving
// loses
| "explicit_court_language" // court text
// directly indicates
// polarity
| "inferred_from_relief"; // relief inferred
// from order body
};
type PolarityValue =
| "win"
| "loss"
| "partial_win"
| "partial_loss"
| "ambiguous";
```
### §13.3 RulingDispositionEnum
```typescript
type RulingDispositionEnum = // V3-O-5 enum
| "granted"
| "denied"
| "granted_in_part"
| "denied_in_part"
| "moot"
| "withdrawn"
| "stricken"
| "deferred"
| "reserved"
| "terminated"
| "vacated"
| "reversed"
| "remanded"
| "other";
```
### §13.4 INV-O-DISPOSITION-1 (V3 REVISED + V4 STRENGTHENED)
Per V4 §2.2.5:
```text
INV-O-DISPOSITION-1 (V3 + V4; canonical home Artifact 2 §13.4):
A CourtOrderDisposition contains an array of RulingDisposition events.
An order disposing N motions/defendants/claims produces N
RulingDisposition entries. Each RulingDisposition.normalized_label is
required; raw_court_language preserved when available.
A single order with multiple dispositions MUST NOT be flattened to a
single RulingDisposition.
V4 ADDITION per V4-O-4:
scope_targets is MANDATORY when the disposition applies to a subset
of motion/defendants/claims. An order disposing "all defendants"
with no qualifier may use empty scope_targets with scope_basis =
"explicit_court_language" indicating universal scope.
But an order disposing "Granted as to defendant A; Denied as to
defendants B-D" MUST produce two RulingDisposition entries with
populated scope_targets each. Flattening to a single disposition
with ambiguous scope is non-conformant.
V4 ADDITION per V4-O-5:
polarity is OPTIONAL but recommended for queries that ask "did
defendants win" or "did plaintiff prevail." When disposition is
unambiguous (granted ⇒ moving party wins; denied ⇒ moving party
loses), polarity can be auto-derived. When ambiguous (granted_in_part
/ mixed relief), polarity = ambiguous unless explicit_court_language
present.
Runtime check (RulingDisposition creation):
function validate_ruling_disposition(
disposition: RulingDisposition
): ValidationResult {
// Required fields per V3-O-5 + V4-O-4.
if (!disposition.normalized_label) {
return reject("ruling_disposition_normalized_label_required");
}
if (!disposition.scope_basis) {
return reject("ruling_disposition_scope_basis_required");
}
// V4-O-4 enforcement: scope_targets mandatory when applicable.
if (disposition_applies_to_subset(disposition) &&
is_scope_targets_empty(disposition.scope_targets) &&
disposition.scope_basis !== "explicit_court_language") {
return reject(
"ruling_disposition_scope_targets_required",
"V4-O-4: subset disposition requires populated scope_targets"
);
}
return accept();
}
function disposition_applies_to_subset(d: RulingDisposition): boolean {
// Heuristic: dispositions like "granted_in_part", "denied_in_part",
// "deferred", or with named parties suggest subset application.
return d.disposition.includes("_in_part") ||
d.scope_targets.defendant_refs?.length > 0 ||
d.scope_targets.claim_refs?.length > 0;
}
function is_scope_targets_empty(targets: any): boolean {
return !targets ||
(!targets.motion_chain_ref &&
!targets.filing_chain_ref &&
(!targets.defendant_refs || targets.defendant_refs.length === 0) &&
(!targets.claim_refs || targets.claim_refs.length === 0));
}
```
OP-A row: `OBL-O-RULING-DISPOSITION-01` (V2 candidate; V4 strengthens with mandatory scope_targets per V4-O-4).
Acceptance test: V4-AT-31 (mandatory scope_targets enforcement — order disposing multiple defendants produces per-defendant RulingDisposition with scope_targets populated; flattening rejected).
### §13.5 Polarity auto-derivation rules
Per V4-O-5:
```text
Polarity auto-derivation (when polarity_basis = "granted_disposition"
or "denied_disposition"):
disposition = "granted":
polarity.for_moving_party = "win"
polarity.for_non_moving_party = "loss"
polarity_basis = "granted_disposition"
disposition = "denied":
polarity.for_moving_party = "loss"
polarity.for_non_moving_party = "win"
polarity_basis = "denied_disposition"
disposition = "granted_in_part":
polarity.for_moving_party = "partial_win"
polarity.for_non_moving_party = "partial_loss"
polarity_basis = "granted_disposition" (partial)
disposition = "denied_in_part":
polarity.for_moving_party = "partial_loss"
polarity.for_non_moving_party = "partial_win"
polarity_basis = "denied_disposition" (partial)
disposition = "moot" / "withdrawn" / "stricken" / "deferred" /
"reserved" / "terminated":
polarity = ambiguous (no clear win/loss)
disposition = "vacated" / "reversed" / "remanded":
polarity_basis = "explicit_court_language" required (court action
is procedural; not direct merits)
When user manually sets polarity (overriding auto-derivation):
polarity_basis = "explicit_court_language" (user determination)
Runtime helper:
function auto_derive_polarity(
disposition: RulingDisposition
): RulingDispositionPolarity | undefined {
switch (disposition.disposition) {
case "granted":
return { for_moving_party: "win",
for_non_moving_party: "loss",
polarity_basis: "granted_disposition" };
case "denied":
return { for_moving_party: "loss",
for_non_moving_party: "win",
polarity_basis: "denied_disposition" };
case "granted_in_part":
return { for_moving_party: "partial_win",
for_non_moving_party: "partial_loss",
polarity_basis: "granted_disposition" };
case "denied_in_part":
return { for_moving_party: "partial_loss",
for_non_moving_party: "partial_win",
polarity_basis: "denied_disposition" };
default:
return undefined; // requires explicit_court_language
}
}
```
### §13.6 Worked query example: "Did defendants win the MTD?"
Per V4 §2.2.5:
```text
Query: "Did defendants win the MTD in case X?"
Resolution flow (read-time per Artifact 4 §15):
1. Find MotionChain matching MTD in case X
(filter: motion_type = "motion_to_dismiss",
case_scope = case X via INV-O-CASE-RESOLUTION-1).
2. Find CourtOrderDisposition referencing that MotionChain via
RulingDisposition.scope_targets.motion_chain_ref.
3. Find RulingDisposition entries where defendants are non_moving_party
(typical MTD framing: defendants are moving_party because they
filed the MTD; defendants WIN if disposition = granted).
Per scope_targets.defendant_refs filtering + party_role
classification.
4. Read polarity.for_moving_party for direct answer:
- "win" → defendants won (MTD granted)
- "loss" → defendants lost (MTD denied)
- "partial_win" → mixed (MTD granted in part)
5. Render with framing:
"MTD in case X: granted (defendants won, plaintiff lost) [citation
to court order disposition + raw_court_language quote]"
Per INV-O-CITATION-1 (§16.X): "citation match (does not validate
authority)" framing required on every cited authority.
```
OP-A row: `OBL-O-RULING-DISPOSITION-01` + `OBL-D15-CITATION-DISPLAY-V16-01` (V4 NEW per V4-O-6).
---
## §14. Group O — CourtDispositionObservation lifecycle (V3-O-8 + V4-O-8)
### §14.1 CourtDispositionObservation canonical schema
**[V4 PATCH:V3-O-8 per R-V22 §7 + V4-O-8 per R-G55S §27 — lifecycle + supersession]**
Per V4 §2.2.7: not every disposition has a SourceArtifact. Minute orders, docket text orders, vacatur entries, and oral rulings recorded only in docket may have no PDF.
```typescript
type CourtDispositionObservation = { // V3-O-8 + V4-O-8
observation_id: string;
court_id: string;
case_number_normalized: string;
observation_kind:
| "minute_order"
| "docket_text_order"
| "oral_ruling_docket_only"
| "vacatur_entry"
| "stipulated_order_text_only";
// What it disposes
motion_chain_ref?: string; // MotionChainRef
ruling_dispositions: RulingDisposition[]; // per §13.2
// Source (no SourceArtifact required for observation)
docket_text_extract?: string; // raw docket text
// (per INV-MVC-3
// wrapped on
// extraction)
docket_entry_date: ISO8601; // per
// INV-V16-TIMEZONE-1
docket_entry_date_originating_tz?: string;
docket_entry_date_originating_calendar_date?: string;
observation_provenance:
| "pacer_docket_entry"
| "recap_docket_text"
| "user_recorded"
| "third_party_observation";
identity_confidence: number; // [0, 1]
// V4 NEW per V4-O-8 — lifecycle + supersession:
lifecycle_state:
| "active"
| "superseded" // a later observation
// replaces this one
| "vacated" // court vacated the
// underlying disposition
| "stricken" // court struck the
// underlying
// disposition
| "user_corrected"; // user identified
// an error
superseded_by_observation_id?: string;
supersession_basis?:
| "court_correction" // court issued
// correction
| "court_clarification" // court clarified
// ambiguous earlier
// observation
| "court_vacatur" // court vacated
// underlying ruling
| "user_correction"; // user-identified
// error in observation
schema_version: 1;
};
```
### §14.2 INV-O-OBSERVATION-LIFECYCLE-1
**[V4 PATCH:V4-O-8 per R-G55S §27 — observation lifecycle]**
Per V4 §2.2.7: observations get superseded (initial minute order corrected; vacated; clarified). V3 didn't model lifecycle. V4 adds explicit lifecycle_state + supersession_basis.
```text
INV-O-OBSERVATION-LIFECYCLE-1 (V4 NEW; canonical home Artifact 2 §14.2):
Queries returning CourtDispositionObservations default to
lifecycle_state == "active". Queries scoped to "all dispositions ever"
(e.g., audit / history) include all states. Superseded observations
remain queryable; not deleted.
A CourtDispositionObservation in lifecycle_state != "active" MUST NOT
be cited as authoritative current disposition. Citation rendering MUST
display state + supersession info ("Note: this disposition was vacated
on <vacatur_date> by <vacating_observation_id>").
Runtime check (citation render):
function format_disposition_citation(
obs: CourtDispositionObservation
): CitationRendering {
const base_citation = format_base_citation(obs);
if (obs.lifecycle_state === "active") {
return base_citation;
}
// Per INV-O-OBSERVATION-LIFECYCLE-1: render with state info.
const successor = obs.superseded_by_observation_id
? lookup_observation(obs.superseded_by_observation_id)
: null;
const supersession_note = formatSupersessionNote(
obs.lifecycle_state,
obs.supersession_basis,
successor
);
return {
...base_citation,
lifecycle_warning: supersession_note,
not_authoritative_current: true,
};
}
function formatSupersessionNote(
state: CourtDispositionObservation["lifecycle_state"],
basis: CourtDispositionObservation["supersession_basis"],
successor: CourtDispositionObservation | null
): string {
switch (state) {
case "superseded":
return `Note: this disposition was superseded by ` +
`<${successor?.observation_id}> per ${basis}.`;
case "vacated":
return `Note: this disposition was vacated by court order.`;
case "stricken":
return `Note: this disposition was stricken from the record.`;
case "user_corrected":
return `Note: this disposition was corrected by user; ` +
`original observation retained for audit.`;
default:
return "";
}
}
```
OP-A rows: `OBL-OBSERVATION-LIFECYCLE-01` (general pattern per V4-O-8) + `OBL-D24-OBSERVATION-LIFECYCLE-V16-01` (DOC24-side consumer per V4-O-8) + `OBL-D73-O-COURT-DISPOSITION-OBS-01` (DOC73-side ownership; pairs with OBL-O-RULING-DISPOSITION-01).
Acceptance test: V3-AT-18 + V4 lifecycle handling test.
### §14.3 Supersession lifecycle
```text
CourtDispositionObservation supersession lifecycle:
T-1: Initial observation created.
lifecycle_state: "active"
superseded_by_observation_id: undefined
T-2: Court issues correction / clarification.
New observation created with lifecycle_state: "active".
Original observation transitions:
lifecycle_state: "superseded"
superseded_by_observation_id: <new_observation_id>
supersession_basis: "court_correction" | "court_clarification"
Both observations remain queryable; only "active" returned in
default scope.
T-3: Court vacates underlying disposition.
New observation created (vacatur_entry kind) with
lifecycle_state: "active".
Original observation transitions:
lifecycle_state: "vacated"
supersession_basis: "court_vacatur"
T-4: User identifies error in original observation.
User corrects via Q Dashboard.
Original observation transitions:
lifecycle_state: "user_corrected"
supersession_basis: "user_correction"
Corrected observation created with lifecycle_state: "active".
Lifecycle transitions emit court_disposition_observation_write
effect_kind (Artifact 3 §4.3.13) + receipt_only for the supersession
event. Audit chain reconstructs via superseded_by_observation_id walk.
```
---
## §15. Group O — MotionChain + FilingChain + FilingRelationship
### §15.1 MotionChain canonical schema
Per V4 §2.2 + V4-O-1 (work_product entity_subtype):
```typescript
type MotionChain = { // V4-O-1 work_product
// entity_subtype:
// motion_chain
motion_chain_id: string; // refers to
// work_product node ID
case_ref: string; // CaseRef per
// ResolvedCaseIdentity
// §11.3
motion_type: RelatedMotionType; // per §18.3
// Constituent filings (FilingUnits in chain)
motion_filing_unit_refs: FilingUnitRef[]; // initial motion +
// responses + reply
// + surreply
filing_role_assignments: Map<FilingUnitRef, FilingRole>; // per §18.2 enum
// Lifecycle
chain_state:
| "open" // motion in progress
| "ruled" // CourtOrderDisposition
// exists
| "withdrawn"
| "moot";
ruling_disposition_ref?: string; // CourtOrderDisposition
// pointer when ruled
// Audit
created_at: ISO8601;
schema_version: 1;
};
```
### §15.2 FilingChain canonical schema
Per V4 §2.2 + V4-O-1:
```typescript
type FilingChain = { // V4-O-1 work_product
// entity_subtype:
// filing_chain
filing_chain_id: string;
case_ref: string;
chain_kind:
| "motion_chain" // subset of
// FilingChain;
// see MotionChain
// §15.1
| "discovery_chain" // discovery dispute
// chain
| "appellate_chain" // appellate
// filing chain
| "trial_chain" // trial-related
// filings
| "post_trial_chain"
| "general_chain"; // other
filing_unit_refs: FilingUnitRef[]; // chronologically
// ordered
filing_role_assignments: Map<FilingUnitRef, FilingRole>;
chain_state:
| "open"
| "complete"
| "withdrawn"
| "stayed";
// V1.6.1 candidate (per V4 §3.5.5):
// chain_significance / chain_outcome aggregation deferred per
// OBL-D73-V161-FILING-CHAIN-AGGREGATION-01 (V1.6.1 candidate;
// R0.2 PATCH per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-1 — tracking
// row added; not yet in OPA V3.8 §1; Step 9 backfill).
// Audit
created_at: ISO8601;
schema_version: 1;
};
```
### §15.3 FilingRelationship canonical schema
Per V4 §2.2 + DOC72 R5.74+ filing-relationship edge type registry:
```typescript
type FilingRelationship = { // typed edge
edge_id: string;
source_filing_unit_ref: FilingUnitRef;
target_filing_unit_ref: FilingUnitRef;
edge_type: // DOC72 R5.74+
// registered types:
| "amends"
| "supersedes_filing" // used at
// FilingUnitVersion
// supersession §12
| "attaches_to" // exhibit attaches
// to main filing
| "responds_to" // opposition
// responds to motion
| "severs_from" // case severance
| "cites"; // citation edge
// (V1.6.1 expansion
// candidate per
// citation matching)
// Provenance
edge_basis:
| "ecf_metadata_extracted"
| "filing_caption_inference"
| "user_marked"
| "structured_extraction" // hybrid_deterministic_schema_llm
// per §16
| "third_party_provider";
confidence: number; // [0, 1]
visibility_class: VisibilityClass; // inherits from
// source +
// target per
// INV-A-TAINT-INFECTIOUS-1
policy_generation_id: string; // per V4-§0.4-1
// Audit
created_at: ISO8601;
schema_version: 1;
};
```
OP-A row: `OBL-D72-V16-DOCREL-01` (DOC72 R5.74+ filing-relationship edge types).
### §15.4 FilingRelationshipCandidate + UnmatchedDocumentRelationshipCandidate
Per V3-O-10 + V2 §O.16:
```typescript
type FilingRelationshipCandidate = { // V3 spec
candidate_id: string;
source_filing_unit_ref: FilingUnitRef; // resolved
target_filing_unit_ref?: FilingUnitRef; // optional;
// may be unresolved
candidate_target_kind?: "filing_unit" | "case_metadata" |
"external_authority";
edge_type: FilingRelationship["edge_type"];
candidate_basis:
| "ecf_metadata_extracted"
| "filing_caption_inference"
| "structured_extraction";
confidence: number;
state:
| "pending"
| "user_confirmed" // → FilingRelationship
| "user_rejected"
| "auto_confirmed_high_confidence" // identity_confidence
// >= 0.95 +
// no_contested_signals
// per V4-K-5
// INV-K-OUTCOME-1
| "stale_unresolved"; // V3-O-10 renamed
// from "expired"
schema_version: 1;
};
type UnmatchedDocumentRelationshipCandidate = { // V2 §O.16 + V3-O-10
candidate_id: string;
source_filing_unit_ref: FilingUnitRef;
target_pattern: string; // pattern
// describing
// target (e.g.,
// "opposition to
// MTD filed before
// 2024-04-01")
state:
| "waiting"
| "matched"
| "ambiguous"
| "stale_unresolved" // V3 RENAMED from
// "expired"
| "user_resolved";
default_stale_after_days: number; // V3: 365 default
// OR case-close
// + 90 grace
stale_evaluation_basis:
| "calendar_days_since_creation"
| "case_status_close_plus_grace";
schema_version: 1;
};
```
### §15.5 INV-O-UNMATCHED-1 (V3-O-10)
**[V4 PATCH:V3-O-10 per R-EX §2.2 — Unmatched relationship expiration]**
Per V4 §2.2.9: V2 had 90-day expiration which was too short for litigation timelines.
```text
INV-O-UNMATCHED-1 (V3 RENAMED + EXTENDED; canonical home Artifact 2 §15.5):
UnmatchedDocumentRelationshipCandidate state transitions:
"waiting" → "matched":
Pattern matches a newly ingested FilingUnit; relationship promoted
to FilingRelationship.
"waiting" → "ambiguous":
Pattern matches multiple candidates; user must adjudicate.
"waiting" → "stale_unresolved":
Per default_stale_after_days (V3 default: 365 days; OR case-close
+ 90 grace per stale_evaluation_basis).
"ambiguous" → "user_resolved":
User picks one; promoted to FilingRelationship.
"stale_unresolved":
Archived but queryable for retrospective reconciliation; not
deleted.
V3 rename from "expired" to "stale_unresolved" reflects litigation
timeline reality: relationships may resolve months later (counsel
files tardy responses; courts issue late orders). Stale candidates
are NOT silently deleted — they remain queryable with explicit
"stale" framing.
V1.6 default: 365 days OR case_status_close + 90 grace, whichever
is longer.
```
OP-A row: implicit (covered by Group O family).
### §15.6 FilingRelationship from candidate promotion
Per V4-K-5 INV-K-OUTCOME-1 (Artifact 3 §13.6 canonical home):
```text
Per Artifact 3 §13.6 INV-K-OUTCOME-1: a binding fire produces evidence
(FilingRelationshipCandidate, etc.). Evidence is NOT adjudicated
outcome.
Adjudicated outcome (FilingRelationship) requires:
(a) Primary source citation:
- For relationships: matched primary filing
(b) Explicit user confirmation OR auto-confirmation when
identity_confidence >= 0.95 AND no contested signals
(c) FilingRelationship with normalized_label and source provenance
Bindings that fire on docket entries do NOT auto-create
FilingRelationship; they create FilingRelationshipCandidate that the
user adjudicates.
Auto-confirmation safe path: identity_confidence >= 0.95 + signed
source artifact + no_contested_signals → auto-confirm. Below threshold
→ user adjudication path.
```
OP-A row: `OBL-D73-V16-K-BINDING-NORMALIZATION-01` (cross-reference Group K) + `OBL-D72-V16-DOCREL-01` (DOC72 R5.74+ edge types).
### §15.7 FilingUnitResolutionCandidate (R0.2 NEW per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-3)
Per V4 §2.2.11 Stage 5 [INSERT] line 6072: V1.6 ships "O.20 FilingUnitResolutionCandidate per V2 O.14" as a Group O sub-deliverable. R0.1 listed in §0.4 scope but did NOT declare canonical schema. R0.2 declares minimal schema (full resolution workflow per V1.6.1 candidate per V4 §0.5.1):
```typescript
type FilingUnitResolutionCandidate = { // V2 O.14 minimal
// declaration; V1.6
// ships base; V1.6.1
// expands resolution
// workflow per V4
// §0.5.1 SAFE list
candidate_id: string;
ambiguous_filing_unit_refs: FilingUnitRef[]; // when canonical
// key produces
// multiple
// candidates (e.g.,
// identity_confidence
// < 0.6 + multiple
// matches per
// §11.6 INV-O-IDENTITY-1)
resolution_state:
| "pending"
| "user_resolved" // user picked
// canonical from
// ambiguous_filing_unit_refs
| "auto_resolved"; // auto-resolved
// when one candidate
// meets
// identity_confidence
// >= 0.95 +
// no_contested_signals
// per V4-K-5
// INV-K-OUTCOME-1
resolution_basis?: string; // when
// user_resolved or
// auto_resolved:
// reason for
// resolution
resolved_filing_unit_ref?: FilingUnitRef; // canonical
// FilingUnit picked
// from candidates
schema_version: 1;
};
```
**[V1.6 DRAFTING NOTE per AUDIT_DOC73_Artifact2_R0.1.md MED-A2-3]** — Minimal V2 O.14 schema; full resolution workflow (e.g., user-presented diff between candidates, auto-merge across candidates) per V1.6.1 candidate. Tracked Tier B Q-3-A2-FILING-UNIT-RESOLUTION-CANDIDATE.
OP-A row: implicit (covered by `OBL-D73-O-FILINGUNIT-01` group row) + V1.6.1 expansion candidate `OBL-D73-V161-FILING-UNIT-RESOLUTION-01` (not yet in OPA V3.8 §1; Step 9 backfill).
---
## §16. Group O — Citation display + LegalEvidencePosture + Caption + Dedup + StructuredExtractionStrategy
### §16.1 INV-O-CITATION-1 (V3-O-12 + V4-O-6 display rule)
**[V4 PATCH:V3-O-12 per R-EX §27 + R-V22 §20 + V4-O-6 per R-G55X §38]**
Per V4 §2.2.10:
```text
INV-O-CITATION-1 (V3 + V4; canonical home Artifact 2 §16.1):
Legal citation normalization (FTS5 tokenizer per OP-A V3.7 row
OBL-D18-LEGAL-SEARCH-01) is for retrieval, not authority validation.
The system normalizes case citations for search/match purposes; it
does NOT certify whether a cited case is good law, whether a cited
statute is current, or whether a precedent has been overruled.
Authority validity is a downstream V1.7+ feature with explicit
dependency declaration.
V4 ADDITION (display rule per V4-O-6):
DOC15/KDA rendering of citation results MUST display "citation match
(does not validate authority)" framing on every cited case/statute.
Prevents users from inferring system has validated the citation.
Examples of compliant rendering:
- "Found 3 briefs citing Janus Capital Grp., Inc. v. First Derivative
Traders [citation match — authority validity not verified]"
- "Defendants cite Tellabs in support of scienter argument [citation
match; authority status unverified]"
Examples of non-compliant rendering:
- "Defendants cite valid authority Janus..." (asserts validity)
- "Tellabs supports the argument..." (asserts current authority)
Runtime check (citation rendering):
function render_citation(
cited_case: CitedCase,
context: "search_result" | "synthesis" | "summary"
): string {
const base = format_canonical_citation(cited_case);
// Per INV-O-CITATION-1 + V4-O-6: ALWAYS append validity disclaimer.
return `${base} [citation match — authority validity not verified]`;
}
OP-A row: OBL-D15-CITATION-DISPLAY-V16-01 (V4 NEW per V4-O-6) +
OBL-D18-LEGAL-SEARCH-01 (V3.7 base — DOC18 FTS5 tokenizer).
```
### §16.2 LegalEvidencePosture (V3-O-13)
**[V4 PATCH:V3-O-13 per R-V22 §20 — LegalEvidencePosture]**
Per V4 §2.2.10:
```typescript
type LegalEvidencePosture = { // V3-O-13
posture:
| "argument_presence" // "did defendants
// argue X" —
// verifiable from
// filing text
| "argument_summary" // "summarize
// defendants'
// argument on X"
// — synthesis with
// spans
| "outcome_linked" // "did this argument
// win" — requires
// CourtOrderDisposition
// per §13
| "authority_validity_check"; // "is this case still
// good law" —
// V1.7+ feature
v17_only_postures: ["authority_validity_check"]; // explicitly gated
schema_version: 1;
};
```
```text
V1.6 default for legal queries:
argument_presence OR argument_summary
outcome_linked requires:
- CourtOrderDisposition (per §13) OR
- CourtDispositionObservation (per §14)
linked via RulingDisposition.scope_targets to the argument's
MotionChain.
authority_validity_check is V1.7+ ONLY.
Runtime check (search posture resolution per Artifact 4 §15):
function resolve_legal_evidence_posture(
query: string,
requested: LegalEvidencePosture["posture"]
): LegalEvidencePosture["posture"] {
if (requested === "authority_validity_check") {
throw new Error(
"legal_evidence_posture_v17_only: authority_validity_check " +
"is V1.7+ feature; not available in V1.6"
);
}
// outcome_linked verification deferred to query execution; falls
// back to argument_summary if no CourtOrderDisposition found.
return requested;
}
```
OP-A row: implicit (covered by OBL-O-RULING-DISPOSITION-01 + Artifact 4 §15 search posture).
### §16.3 INV-O-CAPTION-1 (V2 carry-forward + filing-part scope)
```text
INV-O-CAPTION-1 (V2 carry-forward; canonical home Artifact 2 §16.3):
Caption / signature page extraction is filing-part scoped (per
INV-O-EXTRACTION-FILING-UNIT-SCOPED-1 in Artifact 5 §3.5).
Caption extraction operates on FilingPart with part_kind = "caption"
(per §11.4 FilingPart schema).
Cross-FilingUnit caption inheritance: signature blocks in exhibits
DO NOT inherit caption from main brief; each FilingPart with
part_kind = "caption" is independent.
Implementation per StructuredExtractionStrategy (§16.5): caption
extraction uses pattern_library entries (legal_caption_patterns_v1)
per CorpusProfile.pattern_library_ref.
```
### §16.4 INV-O-DEDUP-1 + INV-O-DEDUP-2 (V2 carry-forward)
```text
INV-O-DEDUP-1 (V2 + V3-K-7 cross-reference; canonical home Artifact 2 §16.4):
Cross-source dedup happens at FilingUnit layer (NOT SourceArtifact
layer). Two SourceArtifacts referencing the same canonical
FilingUnitIdentity (per INV-O-FILING-UNIT-CANONICAL-1 §11.5) resolve
to the same FilingUnit.
Visibility-class scope (per V3-K-7 + INV-K-DEDUP-1 §21): cross-source
dedup respects visibility class. Two FilingUnits from different
visibility-class corpora MAY have same canonical key but DO NOT
auto-merge unless cross-corpus same_as edge is established under
appropriate visibility scope.
INV-O-DEDUP-2 (V2 carry-forward; canonical home Artifact 2 §16.4):
Cross-corpus search results dedup AFTER access-overlay filtering
(per Artifact 4 §15.4 INV-M-ACCESS-RANK-1 + §15.5
INV-M-VERSION-AWARE-1 + §16.1 access set computation), NOT before.
Two visible same_as endpoints render as one result; one visible +
one firewalled endpoint renders only the visible one with no signal
that the other exists.
Runtime check (search merge per Artifact 4):
function dedup_filing_units_post_access(
candidates: SearchResult[],
session: SessionProfile
): SearchResult[] {
// Per INV-O-DEDUP-2: dedup happens AFTER access filtering.
const access_filtered = candidates.filter(c =>
check_access_overlay_permits(c, session)
);
return dedup_by_filing_unit_id(access_filtered);
}
```
### §16.5 StructuredExtractionStrategy (V3-O-4)
**[V4 PATCH:V3-O-4 per R-EX §2.2 MODIFY + R-V22 §10]**
Per V4 §2.2.4: V2 framed NuExtract hybrid pipeline as the "default V1.6 strategy across all domains." Both R-EX and R-V22 §10 correctly noted this overreached — NuExtract is one implementation of a class of strategies; the architectural primitive is the strategy class.
V3 introduces `StructuredExtractionStrategy` as the architectural primitive (canonical home Artifact 2 §16.5):
```typescript
type StructuredExtractionStrategy = { // V3-O-4
strategy_id: string;
strategy_class:
| "pure_deterministic" // regex/rule-based
// only
| "hybrid_deterministic_schema_llm" // regex → validate
// → schema-LLM
// gap-fill →
// cross-field
// check (V1.6
// default per
// Artifact 5 §6)
| "schema_llm_only" // schema-LLM
// extraction
// without
// deterministic
// pre-pass
| "agent_extraction" // model agent with
// tool access
| "user_only"; // user manual entry
// only
// For hybrid_deterministic_schema_llm strategy class:
deterministic_pattern_library_ref?: string; // per CorpusProfile
// .pattern_library_ref
validation_rules_ref?: string;
schema_llm_model_ref?: string; // V1.6 preferred:
// "nuextract_0.5b_local"
cross_field_consistency_rules_ref?: string;
fallback_strategy?:
| "user_review"
| "agent_extraction"
| "skip_field";
// R0.2 add per AUDIT_DOC73_Artifact5_R0.1.md MED-A5-9 (cross-artifact
// consistency):
stage_3_fallback_confidence_threshold?: number; // default 0.85;
// per-strategy
// override
strategy_version: number;
schema_version: 1;
};
```
V3 framing (per V4 §2.2.4):
```text
"V1.6 commits the `hybrid_deterministic_schema_llm` strategy class as
the default for structured-document corpora. NuExtract is the V1.6
preferred implementation of the schema-LLM gap-fill stage in this
strategy class for the legal_caption profile. Other implementations
of the same strategy class (different schema-LLM models, different
gap-fill mechanisms) are equivalent under the strategy class contract.
The architectural primitive is the strategy class; NuExtract is a
specific implementation choice."
V1.7+ candidate: alternative hybrid implementations (e.g., constrained-grammar
LLM, structured-output APIs).
```
Runtime: Artifact 5 §6 specifies the runtime pipeline (4-stage hybrid_deterministic_schema_llm). This artifact §16.5 specifies the strategy class schema; Artifact 5 §6.1 consumes via reference.
OP-A row: implicit (consumed by Artifact 5 §6 OBL-D25-V16-LEGAL-ARTIFACT-NORMALIZATION-01 + DOC73-side via Group O OP-A rows).
### §16.6 INV-O-COMPOSITE-NORMALIZATION-1 + INV-O-ATOMIC-NORMALIZATION-1
```text
INV-O-COMPOSITE-NORMALIZATION-1 (V3 renamed; canonical home Artifact 2 §16.6):
Composite SourceArtifacts (e.g., 382-page PACER bundle with brief +
exhibits) MUST be normalized into per-FilingUnit ArtifactSegments
(per Artifact 5 §3.3 segmentation state machine) before extraction.
Composite handling:
- SourceArtifact ingested (Artifact 5 §2.2).
- ArtifactSegment created per ECF stamping boundary (Artifact 5
§3.3); each segment maps to a candidate FilingUnit.
- Per-FilingUnit FilingUnitVersion + FilingUnitTextVersion created.
- Extraction runs per-FilingUnit (per
INV-O-EXTRACTION-FILING-UNIT-SCOPED-1 Artifact 5 §3.5).
INV-O-ATOMIC-NORMALIZATION-1 (V3 renamed; canonical home Artifact 2
§16.6):
Atomic SourceArtifacts (single filing; no composite decomposition
needed) STILL pass through normalization pipeline (FilingUnit creation
+ FilingUnitVersion + FilingUnitTextVersion + ECF header parsing).
The pipeline is uniform across composite vs atomic; segmentation is
a no-op for atomic artifacts (single ArtifactSegment with
segment_type = "unsegmented_full_artifact" per Artifact 5 §3.2).
Rationale: uniform normalization pipeline simplifies downstream
consumers (search, retrieval, citation) — every FilingUnit has the
same shape regardless of source SourceArtifact composite/atomic
nature.
```
OP-A rows: `OBL-D73-V16-J11-FILING-NORMALIZATION-01` + `OBL-D25-V16-LEGAL-ARTIFACT-NORMALIZATION-01` (Artifact 5).
---
## §17. Group K — Binding entity + BindingResourcePolicy + BindingTargetKind / BindingOutcomeRecord
### §17.1 Binding entity canonical schema
Per V4 §3.6 Group K + V4 §3.6.11 Stage 5 [INSERT]:
```typescript
type SourceBinding = { // V4-O-1 work_product
// entity_subtype:
// source_binding
binding_id: string; // refers to
// work_product node
// ID
// Source identity (per V3-K-2 + V4-J-3.5-K-3.6 unified)
source_kind: SourceKindRef; // DOC72 R5.74+
// source-kind
// registry per
// OBL-D72-V16-K-SOURCE-REGISTRY-01
source_selector: SourceSelector; // typed identity
// per V3-K-2 +
// relink_policy
// What this binding watches and produces
target_kind: BindingTargetKind; // per §17.3
corpus_ref: CorpusRef; // target corpus
// Selectors (per V3-K-1 + V4-K-2; full canonical at §19)
selector_list: StructuralSelectorList; // per §19.1
content_type_filter?: ContentTypeFilter; // per §18.5
// Lifecycle (per K.7-K.8)
lifecycle_state: BindingLifecycleState; // per §22.4
// Resource policy
resource_policy: BindingResourcePolicy; // per §17.2
// Backfill (per V3-K-6)
backfill_policy?: BindingBackfillPolicy; // per §22.2
// Permission (per K.25 share-link gating)
permission_policy?: BindingPermissionPolicy; // per §24.3
// Generation tracking (per V4-K-7)
binding_generation_id: string; // monotonic per
// binding revision
// Audit
created_at: ISO8601;
schema_version: 1;
};
```
### §17.2 BindingResourcePolicy + capacity_priority (V4-K-CAPACITY)
**[V4 PATCH:V4-K-CAPACITY per R-CL4 #19 — Group K capacity governance integration]**
Per V4 §3.6.6:
```typescript
type BindingResourcePolicy = { // V3 base + V4-K-CAPACITY
policy_id: string;
max_estimated_cost_usd?: number; // cost cap per
// evaluation
on_cost_exceeded:
| "halt_with_alert"
| "user_confirm_required"
| "auto_throttle";
on_limit_exceeded: // for K.30 fan-out
// per Artifact 3
// §14.1
| "log_warning_and_defer"
| "halt_with_alert";
// V4 NEW per V4-K-CAPACITY:
capacity_priority:
| "background" // (default) suspend
// under capacity
// pressure
| "user_initiated" // continue with
// throttle
| "critical"; // continue without
// throttle (rare;
// requires explicit
// binding configuration)
schema_version: 1;
};
```
V1.6 default `capacity_priority`:
- Binding-author-created bindings: `"background"`
- System-suggested bindings (V1.6.1 candidate per V4 §0.5.1 SAFE list per OBL-D73-V16-K-LIFECYCLE-01): `"background"`
- `"critical"` tier requires explicit user/architect approval at binding creation time and audit-records the elevation.
Runtime: capacity governance enforcement per Artifact 3 §14.3 (kernel-side runtime). This artifact §17.2 specifies the schema and defaults; Artifact 3 §14 specifies the runtime enforcement.
OP-A rows: `OBL-K-CAPACITY-GOVERNANCE-V16-01` (joint EC + DOC73 per V4-K-CAPACITY).
### §17.3 BindingTargetKind enum (V3-K-3)
**[V4 PATCH:V3-K-3 per R-V22 §11 — BindingTargetKind / BindingOutcomeRecord]**
Per V4 §3.6.3:
```typescript
type BindingTargetKind = // V3-K-3
| "corpus_document_membership" // V2 default: source
// event creates
// corpus member
| "case_metadata_update" // updates case-level
// metadata only
| "relationship_candidate" // creates
// FilingRelationshipCandidate
// (per §15.4)
| "court_disposition_observation" // creates
// CourtDispositionObservation
// (per §14)
| "extraction_task"; // queues extraction
// without membership
```
### §17.4 BindingOutcomeRecord canonical schema
Per V4 §3.6.3:
```typescript
type BindingOutcomeRecord = { // V3-K-3
outcome_id: string;
source_event_id: string; // event that
// triggered binding
binding_id: string;
target_kind: BindingTargetKind;
outcome_state:
| "pending"
| "succeeded"
| "deduplicated"
| "policy_blocked"
| "user_review_required"
| "extraction_failed"
| "abandoned";
outcome_target_ref?: string; // membership_id /
// case_metadata_id /
// filing_relationship_candidate_id
// / etc.
outcome_reason_code: string; // namespaced per
// §0.7.2 (registry
// canonical;
// consumer here)
// Linkage to extraction (per V3-K-4 + Artifact 5 §6.6)
extraction_run_ref?: string; // pointer to
// ExtractionRunRecord
// when target_kind =
// "extraction_task"
// or membership
// triggers extraction
schema_version: 1;
};
```
### §17.5 INV-K-TARGET-1
Per V4 §3.6.3:
```text
INV-K-TARGET-1 (V3 NEW; canonical home Artifact 2 §17.5):
Source bindings declare target_kind. Bindings with
target_kind != corpus_document_membership do NOT create corpus member
documents unless explicitly registered to do so. A binding watching
a docket for new minute orders (target_kind = "court_disposition_observation")
creates disposition observations without creating corpus document
members, and BindingOutcomeRecord captures the outcome.
REJECTED V2 implicit assumption: every binding fire produces a
document. V3 explicit: target_kind enum determines outcome shape.
Per Artifact 3 §13.5 BindingTargetKind dispatch (kernel-side runtime):
each target_kind maps to specific primitive_effects[] composition.
Runtime check (binding evaluation per Artifact 3 §13):
function dispatch_binding_fire_per_target_kind(
binding: SourceBinding,
source_event: SourceEvent
): BindingOutcomeRecord {
switch (binding.target_kind) {
case "corpus_document_membership":
return fire_with_membership_creation(binding, source_event);
case "case_metadata_update":
return fire_with_metadata_update(binding, source_event);
case "relationship_candidate":
return fire_with_relationship_candidate(binding, source_event);
case "court_disposition_observation":
return fire_with_disposition_observation(binding, source_event);
case "extraction_task":
return fire_with_extraction_task_only(binding, source_event);
}
}
```
OP-A row: `OBL-EC-V16-K-ROUTING-OUTBOX-01` (kernel runtime; this artifact specifies the schema layer).
Acceptance test: V3-AT-19 (binding evaluation lifecycle).
---
## §18. Group K — FilingUnitKind / FilingRole / RelatedMotionType orthogonal axes + 8-value LegalProfileKind
### §18.1 V4-K-1 orthogonal axes split
**[V4 PATCH:V4-K-1 per R-CG #11 + R-G55 #14 + R-G55X §18 + R-G55S §15 + R-CL4 #16 — filing_unit_kind orthogonal axes]**
Per V4 §3.6.1: V3 had `filing_unit_kind` with 16 values mixing different axes (physical filing shape vs relationship to motion). V4 splits into 3 orthogonal enums.
### §18.2 FilingUnitKind enum (physical filing shape)
```typescript
type FilingUnitKind = // V4 narrowed:
// physical filing
// shape only
| "brief" // a brief
// (motion / opposition
// / reply
// distinguished by
// filing_role)
| "order" // a court order
| "pleading" // complaint / answer
// / counterclaim
| "exhibit" // exhibit attached
// to a filing
| "declaration" // sworn declaration
| "proposed_order" // proposed court
// order
| "stipulation" // stipulation
// between parties
| "rjn" // request for
// judicial notice
| "non_filing"; // non-litigation
// document
```
### §18.3 FilingRole enum (relationship to motion)
```typescript
type FilingRole = // V4 NEW:
// relationship to
// motion
| "motion" // initiating filing
| "opposition" // opposition response
| "reply" // moving party reply
// to opposition
| "surreply" // additional reply
| "sua_sponte" // court-initiated
| "not_applicable";
```
### §18.4 RelatedMotionType enum (specific motion type when applicable)
```typescript
type RelatedMotionType = // V4 NEW:
// specific motion
// type when
// applicable
| "motion_to_dismiss"
| "motion_for_summary_judgment"
| "motion_to_strike"
| "motion_in_limine"
| "motion_to_compel"
| "motion_for_protective_order"
| "motion_for_class_certification"
| "discovery_motion_other"
| "trial_motion_other"
| "post_trial_motion"
| "appellate_motion"
| "other";
```
### §18.5 8-value LegalProfileKind canonical enum (V4-J-3.5-K-3.6)
**[V4 PATCH:V4-J-3.5-K-3.6 per R-CG #11 + R-G55 #14 + R-CL4 #3 — legal_profile_kind enum unified]**
Per V4 §3.6.2: V3 had inconsistency where `legal_profile_kind` differed between Group J (4 profiles) and Group K (8 profiles). V4 unifies to 8-value canonical enum:
```typescript
type LegalProfileKind = // V4 UNIFIED canonical
// enum
// V1.6 ships these (Group J 4-profile model + Group K extensions):
| "legal_brief_filing" // motion / opposition
// / reply briefs
| "court_order" // court orders
| "pleading" // complaints / answers
// / counterclaims
| "evidentiary_filing" // declarations /
// exhibits /
// depositions
// V1.6 ships these (resolves V3 §3.5/§3.6 split):
| "discovery_request" // discovery propounded
| "discovery_response" // discovery responses
| "deposition_transcript" // deposition transcript
| "non_legal"; // catch-all for
// non-litigation
// content
```
### §18.6 ContentTypeClassification 3-field split (V3-K-2)
**[V4 PATCH:V3-K-2 per R-EX §12 + R-V22 §9 — Content-type ownership 3-field split]**
Per V4 §3.6.2: V2 had `IntakeContentTypeRegistration` with single `content_type` field. V3 splits into three orthogonal fields.
```typescript
type ContentTypeClassification = { // V3-K-2 + V4
// unification
// DOC25 owns: file mechanics
source_artifact_kind:
| "pdf"
| "docx"
| "rtf"
| "txt"
| "md"
| "html"
| "xlsx"
| "csv"
| "image_jpg"
| "image_png"
| "email_message"
| "calendar_event"
| "audio_recording";
// DOC25 owns: low-level content type observations
doc25_content_type:
| "structured_text"
| "scanned_pdf"
| "form_pdf"
| "tabular_data"
| "transcript"
| "metadata_only"
| "binary_attachment_unknown";
// DOC73 owns: legal semantics — V4 UNIFIED enum:
legal_profile_kind?: LegalProfileKind; // per §18.5
// DOC73 owns: filing-unit-level kind — V4 SPLIT into orthogonal axes:
filing_unit_kind?: FilingUnitKind; // physical
// filing shape
// only
filing_role?: FilingRole; // V4 NEW:
// relationship to
// motion
related_motion_type?: RelatedMotionType; // V4 NEW:
// specific motion
// type
schema_version: 1;
};
```
Owner-split rule:
```text
DOC25 owns: source_artifact_kind, doc25_content_type
(and registration of new values for these fields)
DOC73 owns: legal_profile_kind (unified enum), filing_unit_kind
(physical shape), filing_role (relationship to motion),
related_motion_type (specific motion)
(and registration of new values for these fields per
Group O 4-profile model + V4 orthogonal axes split)
```
OP-A row: `OBL-D72-V16-K-SOURCE-REGISTRY-01` (DOC72 R5.74+ source registry; consumed at intake) + `OBL-D73-O-FILINGUNIT-01` (DOC73 filing-semantics ownership).
### §18.7 ContentTypeFilter (V2 patch L8)
```typescript
type ContentTypeFilter = { // V2 patch L8
filter_id: string;
required_source_artifact_kinds?: ContentTypeClassification["source_artifact_kind"][];
required_doc25_content_types?: ContentTypeClassification["doc25_content_type"][];
required_legal_profile_kinds?: LegalProfileKind[];
required_filing_unit_kinds?: FilingUnitKind[];
required_filing_roles?: FilingRole[];
required_related_motion_types?: RelatedMotionType[];
schema_version: 1;
};
```
ContentTypeFilter consumed by SourceBinding.content_type_filter to gate which artifacts the binding will fire on. Per INV-K-FILTER-1 (V2 carry-forward; canonical home Artifact 2 §19.X): exclusion wins (any filter mismatch → no fire).
OP-A row: covered by `OBL-D72-V16-K-SOURCE-REGISTRY-01`.
---
## §19. Group K — StructuralSelectorList + selector_phase_available + INV-K-SELECTOR-1
### §19.1 StructuralSelectorList canonical schema (V3-K-1 + V4-K-2)
**[V4 PATCH:V3-K-1 per R-EX §11 + R-V22 §10 + V4-K-2 selector phase availability + V4-K-6 size_band defer]**
Per V4 §3.6.1: V1.6 ships structural selectors only; predicate DSL deferred to V1.7.
```typescript
type StructuralSelector = // V4 NARROWED
// (size_band
// removed per
// V4-K-6)
| { kind: "source_kind";
source_kind: SourceKindRef;
selector_phase_available: "intake_time" }
| { kind: "source_id";
source_id: string;
selector_phase_available: "intake_time" }
| { kind: "source_path";
path_pattern: string; // glob; non-regex
selector_phase_available: "intake_time" }
| { kind: "content_type";
doc25_content_type: string;
selector_phase_available: "post_doc25_conversion" }
| { kind: "filing_unit_kind";
filing_unit_kind: FilingUnitKind; // V4 narrowed
// per V4-K-1
selector_phase_available: "post_group_o_normalization" }
| { kind: "filing_role";
filing_role: FilingRole; // V4 NEW per V4-K-1
selector_phase_available: "post_group_o_normalization" }
| { kind: "related_motion_type";
motion_type: RelatedMotionType; // V4 NEW per V4-K-1
selector_phase_available: "post_group_o_normalization" }
| { kind: "legal_profile_kind";
legal_profile_kind: LegalProfileKind; // V4 unified
selector_phase_available: "post_group_o_normalization" }
| { kind: "case_ref";
case_ref: string; // CaseRef when known
selector_phase_available: "post_relationship_resolution" }
| { kind: "court_id";
court_id: string; // when known
selector_phase_available: "post_relationship_resolution" };
// V4 PATCH:V4-K-6 — size_band selector REMOVED per V1.7 deferral.
// V1.7 candidate: OBL-K-V17-SIZE-BAND-01.
type StructuralSelectorList = {
include: StructuralSelector[];
exclude: StructuralSelector[];
// No "where field op value" expressions allowed in V1.6
// size_band selectors removed per V4-K-6
schema_version: 1;
};
```
### §19.2 selector_phase_available routing
Per V4 §3.6.1:
```text
V4-K-2 phase availability rule: bindings using post-X selectors
automatically defer evaluation to that phase. A binding using only
intake-time selectors evaluates at intake; a binding using
filing_unit_kind selectors waits for Group O normalization.
Maps to a binding's lifecycle state machine (per §22.4):
pending_intake → ready_to_evaluate
(when its earliest required phase has passed)
ready_to_evaluate → evaluated (after evaluation completes)
evaluated → fired (effects applied)
| matched_no_fire (matched but suppressed; e.g., dedup)
| no_match
Phase ordering:
intake_time
< post_doc25_conversion
< post_group_o_normalization
< post_relationship_resolution
A binding using selectors at multiple phases waits for the LATEST
phase before evaluation begins.
Runtime per Artifact 3 §13.3 (kernel-side dispatch).
```
### §19.3 INV-K-SELECTOR-1
**[V4 PATCH:V3-K-1 + V4-K-2 — INV-K-SELECTOR-1]**
Per V4 §3.6.1:
```text
INV-K-SELECTOR-1 (V3 + V4 EXPANDED; canonical home Artifact 2 §19.3;
runtime in Artifact 3 §13.8):
V1.6 source bindings support structural selectors only. Enumerated
kinds: source_kind, source_id, source_path (glob), content_type,
filing_unit_kind, filing_role, related_motion_type, legal_profile_kind,
case_ref, court_id.
V4 NEW: each selector kind declares its selector_phase_available, which
determines when the binding can be evaluated in the pipeline. Bindings
using post-X selectors defer evaluation until phase X has passed for
the candidate artifact.
V3 size_band selector REMOVED in V4; deferred to V1.7 per V4-K-6.
Arbitrary field/operator/value predicates (e.g., "case_number contains
X", "filing_date < Y", "judge.name == Z") are NOT supported in V1.6.
These require the predicate DSL deferred to DOC72 R6 / V1.7.
Binding creation UI rejects bindings attempting to specify
non-structural selectors with explicit message: "Predicate filters
are not available in V1.6. Use structural selectors or wait for V1.7."
Coding agent rejection MUST emit binding_predicate_not_supported_v16
receipt; bindings cannot silently ignore unsupported selectors.
Runtime check (binding creation; per Artifact 3 §13.8):
Listed in Artifact 3 §13.8 validate_binding_selectors function.
```
OP-A row: `OBL-D73-V16-K-PREDICATE-01` (V1.7 deferred per V3-K-11).
Acceptance test: V3-AT-5 (structural selectors only).
### §19.4 INV-K-FILTER-1 (V2 carry-forward)
```text
INV-K-FILTER-1 (V2 carry-forward; canonical home Artifact 2 §19.4):
For SourceBinding.content_type_filter (per §18.7) + selector_list
(per §19.1): EXCLUSION WINS. Any filter mismatch in include or any
match in exclude → binding does NOT fire.
Rationale: bindings should be conservative about firing. False-positive
fires (binding fires when it shouldn't) are worse than false-negative
fires (binding doesn't fire when it should), because false positives
create incorrect corpus memberships that user must clean up.
Runtime check (binding evaluation):
function evaluate_binding_filter(
binding: SourceBinding,
candidate: CandidateArtifact
): boolean {
// Include filters: ALL must match.
for (const include_selector of binding.selector_list.include) {
if (!matches_selector(candidate, include_selector)) {
return false;
}
}
// Exclude filters: NONE must match.
for (const exclude_selector of binding.selector_list.exclude) {
if (matches_selector(candidate, exclude_selector)) {
return false;
}
}
// ContentTypeFilter (if present): ALL must match.
if (binding.content_type_filter) {
if (!matches_content_type_filter(candidate, binding.content_type_filter)) {
return false;
}
}
return true;
}
```
OP-A row: implicit (covered by Group K family).
---
## §20. Group K — CorpusMembershipRecord + state machine + ContentHashRef
### §20.1 CorpusMembershipState enum (V3-K-4 + V4-K-3)
**[V4 PATCH:V3-K-4 per R-V22 §12 + V4-K-3 per R-CG #13 + R-G55 #17 + R-G55X §19 — full state machine]**
Per V4 §3.6.4:
```typescript
type CorpusMembershipState = // V3-K-4
| "candidate" // proposed by binding;
// not user-confirmed
| "confirmed" // user-confirmed or
// auto-confirmed
| "rejected" // user-rejected; not
// a member
| "soft_deleted" // removed but
// recoverable
| "policy_blocked"; // visibility / policy
// blocks membership
```
### §20.2 MembershipStateTransition canonical schema (V4-K-3)
```typescript
type MembershipStateTransition = { // V4 NEW per V4-K-3
transition_id: string;
membership_id: string;
from_state: CorpusMembershipState;
to_state: CorpusMembershipState;
triggered_by:
| "user_confirm_event"
| "user_reject_event"
| "user_delete_event"
| "user_restore_event"
| "user_reverse_rejection_event"
| "policy_change_blocking"
| "policy_change_unblocking"
| "cascade_soft_delete"
| "cascade_restore";
reason_code: string; // namespaced per
// §0.7.2 (consumer)
occurred_at: ISO8601;
policy_generation_id: string; // per V4-§0.4-1
schema_version: 1;
};
```
### §20.3 Allowed / disallowed transitions
Per V4 §3.6.4:
```text
Allowed transitions (state machine spec):
candidate → confirmed (user-confirm event)
candidate → rejected (user-reject event)
candidate → policy_blocked (policy snapshot change blocking
membership)
confirmed → soft_deleted (user-delete event OR cascade
soft_delete)
confirmed → policy_blocked (policy change retroactively blocking)
rejected → candidate (user-reverse-rejection event; rare)
soft_deleted → confirmed (user-restore event)
policy_blocked → confirmed (policy change unblocking)
policy_blocked → soft_deleted (user-delete on previously-blocked)
Disallowed transitions (kernel rejects):
confirmed → candidate (cannot un-confirm; must reject + re-propose)
rejected → confirmed (cannot bypass user-reverse-rejection)
soft_deleted → candidate (must restore to confirmed first)
Per Artifact 3 §4.3.19: every membership_state_transition is
COMPENSATING_OPERATION_ONLY (no Tier 1 inverse; reversal requires NEW
transition operation).
```
### §20.4 CorpusMembershipRecord canonical schema (V3-K-4 + V4-K-4)
**[V4 PATCH:V4-K-4 per R-CG #14 + R-G55 #18 + R-G55X §20 + R-G55S §16 — ContentHashRef typed schema]**
Per V4 §3.6.4:
```typescript
type CorpusMembershipRecord = { // V3-K-4 + V4-K-4
membership_id: string;
corpus_id: CorpusRef;
document_id: string; // FilingUnitRef OR
// SourceArtifactRef
// (per consumer
// context)
source_instance_id: string; // per
// OBL-D73-B2-SOURCEINSTANCE-01
// visibility-class-scoped
membership_state: CorpusMembershipState; // V3 NAMED per V3-K-4
membership_origin: string; // how membership
// came about
// (e.g., binding_fire,
// user_drop_in,
// migration)
binding_id?: string; // when
// binding-originated
trust_posture_at_intake: TrustPosture; // per §20.X enum
content_hashes: ContentHashRef[]; // V4 typed per V4-K-4
// (consumed from
// Artifact 1 §A.9)
created_at: ISO8601;
confirmed_at?: ISO8601;
visibility_snapshot_ref: string; // visibility class
// scope at intake
policy_generation_id: string; // per V4-§0.4-1
// Extraction linkage (per V3-K-4 + Artifact 5 §6.3)
extraction_run_id?: string; // links to
// ExtractionStateMachine
// (Artifact 5 §7
// canonical home)
schema_version: 1;
};
type TrustPosture = // V2 carry-forward
| "trusted_authoritative" // ECF / signed source
| "trusted_extraction" // hybrid extraction
// strategy
// succeeded
| "user_verified" // user explicitly
// verified
| "untrusted_pending_review" // novel source;
// awaiting review
| "extraction_degraded"; // partial extraction
// per
// ExtractionStateMachine
// (Artifact 5 §7)
```
### §20.5 INV-K-MEMBERSHIP-EXTRACTION-1
**[V4 PATCH:V3-K-4 per R-V22 §12 — Membership state ≠ extraction state]**
Per V4 §3.6.4:
```text
INV-K-MEMBERSHIP-EXTRACTION-1 (V3 NEW; canonical home Artifact 2 §20.5):
CorpusMembershipState and ExtractionState are separate state machines.
- Membership confirmation does NOT imply extraction success.
A document can be "confirmed" as corpus member with extraction
in "pending" / "running" / "degraded" / "blocked" state.
- Extraction failure does NOT auto-revoke membership.
A document with extraction_state = "abandoned" remains corpus
member (membership_state = "confirmed") unless user explicitly
revokes; the document is searchable for metadata-primary queries
but content_primary queries surface partial-completion warnings.
- State machines link via extraction_run_id reference on
CorpusMembershipRecord (per §20.4).
Rationale: brief bank ingestion of a 382-page composite PACER bundle
may confirm membership before extraction completes (extraction may
take hours). Membership confirmation enables UI listing + metadata
search; extraction completion enables content_primary search.
Conflating the state machines either delays usability or surfaces
incomplete state.
Per Artifact 5 §7-§9: ExtractionStateMachine is canonical at Artifact 5;
Artifact 2 §20 references for membership linkage.
Per Artifact 5 §9 INV-EXT-7: stale memories + degraded re-extraction
field-level resolution per FieldResolution.source enum.
Runtime check (membership creation):
function create_corpus_membership(
binding: SourceBinding,
source_event: SourceEvent
): CorpusMembershipRecord {
const member_id = new_id();
const extraction_run_id = enqueue_extraction(source_event);
return {
membership_id: member_id,
corpus_id: binding.corpus_ref,
document_id: source_event.filing_unit_ref ??
source_event.source_artifact_id,
source_instance_id: derive_source_instance_id(source_event),
membership_state: should_auto_confirm(binding, source_event)
? "confirmed"
: "candidate",
membership_origin: "binding_fire",
binding_id: binding.binding_id,
trust_posture_at_intake: classify_trust_posture(source_event),
content_hashes: enumerate_content_hashes(source_event),
created_at: NOW(),
confirmed_at: should_auto_confirm(...) ? NOW() : undefined,
visibility_snapshot_ref: derive_visibility_snapshot(source_event),
policy_generation_id: current_policy_generation_id(),
extraction_run_id: extraction_run_id, // separate state
// machine
schema_version: 1,
};
}
```
OP-A rows: `OBL-D73-V16-MEMBERSHIP-01` + `OBL-EC-V16-K-ROUTING-OUTBOX-01` (kernel runtime).
Acceptance test: V3-AT-19 (membership-extraction state separation).
---
## §21. Group K — same_as / canonical_entity edges + INV-K-DEDUP-1/2/3 + INV-K-OUTCOME-1 + SemanticConflictPolicy
### §21.1 CanonicalEntityEdge canonical schema (V3-K-7)
**[V4 PATCH:V3-K-7 per R-EX §14 — K.34 access-scope-refs]**
Per V4 §3.6.6:
```typescript
type CanonicalEntityEdge = { // V3-K-7
edge_type: "same_as" | "canonical_entity";
source_node_id: string;
target_node_id: string;
// V3 EXPANDED scoping (per V3-K-7):
visibility_scope_ref: string; // visibility class
// scope of the
// LESS visible
// endpoint
firewall_id?: string; // if scope is
// firewalled
allowed_principal_scope?: string; // PrincipalRef —
// who can resolve
// this same_as
policy_generation_id: string; // per V4-§0.4-1 +
// V4-K-INV-DEDUP-3
evidence_basis:
| "content_hash"
| "source_instance_match"
| "filing_unit_id_match"
| "user_marked";
confidence: number; // [0, 1]
schema_version: 1;
};
```
### §21.2 INV-K-DEDUP-1 (V3 REFINED)
Per V4 §3.6.6:
```text
INV-K-DEDUP-1 (V3 REFINED; canonical home Artifact 2 §21.2):
same_as / canonical_entity edges scope at multiple dimensions:
1. visibility_scope_ref — visibility class of the LESS visible
endpoint
2. firewall_id (when present) — edge exists only within firewalled
scope
3. allowed_principal_scope — which principals can resolve this
same_as (e.g., host can resolve sealed↔public; share-link user
cannot)
4. policy_generation_id — captures policy active at edge creation
A public-corpus document and firewalled-corpus document with matching
content_hash do NOT produce a globally-visible same_as edge. The edge
exists scoped to firewall_id; only principals authorized for the
firewall can resolve the cross-corpus dedup.
Cross-corpus search results dedup AFTER access-overlay filtering, not
before (per V2 INV-K-DEDUP-2 + Artifact 4 INV-M-ACCESS-RANK-1). Two
visible same_as endpoints render as one result; one visible +
one firewalled endpoint renders only the visible one with no signal
that the other exists.
```
### §21.3 INV-K-DEDUP-2 (V2 carry-forward)
```text
INV-K-DEDUP-2 (V2 carry-forward; canonical home Artifact 2 §21.3):
Cross-corpus dedup runs AFTER access filtering (per Artifact 4 §15.4
INV-M-ACCESS-RANK-1).
Sequence:
1. Search candidate set generated (per RetrievalPosture).
2. Access overlay filter applied (per INV-M-ACCESS-RANK-1).
3. Same_as / canonical_entity dedup applied to access-permitted set.
4. Result list composed.
Reverse order (dedup before access filter) would leak existence of
firewalled endpoints via dedup signal. INV-K-DEDUP-2 forbids that.
```
### §21.4 INV-K-DEDUP-3 (V4 NEW per V4-K-INV-DEDUP-3)
**[V4 PATCH:V4-K-INV-DEDUP-3 per R-CL4 #5 — INV-K-DEDUP-3 lifecycle]**
Per V4 §3.6.6:
```text
INV-K-DEDUP-3 (V4 NEW; canonical home Artifact 2 §21.4):
Existing same_as / canonical_entity edges remain VALID for queries
operating under the edge's policy_generation_id. They are NOT
auto-invalidated when policy_generation_id advances globally.
- Edge created under policy_generation_id "G1" remains valid for
queries that scope to G1 (e.g., audit replay; historical
RecentActivityRollup context).
- Queries operating under newer policy_generation_id "G2" do NOT
see the G1 same_as edge unless the edge satisfies G2's policy.
- Edges are re-evaluated lazily at query time per the new
generation; a same_as edge may "appear" or "disappear" across
generations depending on whether the new policy permits it.
Implementation: same_as edges are NOT touched on policy_generation
advance. Query-time resolution checks edge.policy_generation_id
against query.policy_generation_id; if edge predates query's
generation, edge is re-checked against current policy before being
honored.
Garbage collection: edges whose policy_generation_id has aged past
ELNOR_KERNEL_RETENTION may be archived (kept queryable from audit
log; removed from hot edge index).
Per Artifact 3 §4.3.17 (kernel-side runtime): same_as edges are NOT
touched on policy_snapshot_advance effect; lazy re-evaluation at
query time.
Runtime check (query-time same_as resolution per Artifact 4 §15):
function resolve_same_as_edge_for_query(
edge: CanonicalEntityEdge,
query_policy_generation_id: string,
session: SessionProfile
): boolean {
// Step 1: edge created under same generation? → honor.
if (edge.policy_generation_id === query_policy_generation_id) {
return check_visibility_scope_permits(edge, session);
}
// Step 2: edge predates query → re-check against current policy.
const re_checked = re_evaluate_edge_against_current_policy(edge);
if (!re_checked.permitted_under_current_policy) return false;
return check_visibility_scope_permits(edge, session);
}
```
OP-A row: `OBL-K-CROSSCORPUS-DEDUP-01` (V4 NEW per V4-K-INV-DEDUP-3).
Acceptance test: V4-AT-36 (INV-K-DEDUP-3 same_as edge lifecycle).
### §21.5 INV-K-OUTCOME-1 (V4-K-5; cross-reference Artifact 3 canonical)
**[V4 PATCH:V4-K-5 per R-CG #25 + R-G55X §36 + R-G55S §17 — INV-K-OUTCOME-1]**
Canonical home: Artifact 3 §13.6 (kernel runtime side). Cross-reference here for Group K semantic spec:
```text
INV-K-OUTCOME-1 (V4 NEW; canonical home Artifact 3 §13.6;
cross-reference Artifact 2 §21.5):
A binding fire produces evidence (CourtDispositionObservation,
FilingRelationshipCandidate, etc.). Evidence is NOT adjudicated
outcome.
Adjudicated outcome requires:
(a) Primary source citation:
- For court rulings: Court Order SourceArtifact OR
docket-text-only minute order (CourtDispositionObservation
per §14)
- For relationships: matched primary filing
(b) Explicit user confirmation OR auto-confirmation when
identity_confidence >= 0.95 AND no contested signals
(c) RulingDisposition (for outcomes per §13) or FilingRelationship
(for relationships per §15) with normalized_label and source
provenance
Bindings that fire on docket entries do NOT auto-create
RulingDisposition; they create CourtDispositionObservation candidates
that the user adjudicates (per §14.1 observation_kind enum).
Auto-confirmation safe path: identity_confidence >= 0.95 + signed
source artifact + no_contested_signals → auto-confirm. Below
threshold → user adjudication path.
Per BindingOutcomeRecord.outcome_state (per §17.4): "succeeded" means
binding fired and evidence was created; "user_review_required" means
adjudication pending. These are distinct from RulingDisposition /
FilingRelationship adjudicated outcomes.
```
OP-A row: `OBL-D73-O-COURT-DISPOSITION-OBS-01` (covers).
### §21.6 SemanticConflictPolicy default resolution per conflict class (V4-K-MISC)
**[V4 PATCH:V4-K-MISC per R-GEM #9 — SemanticConflictPolicy]**
Per V4 §3.6.6:
```typescript
type SemanticConflictClass = // V3-A-8 (canonical
// home Artifact 1
// §17.5)
| "field_value_disagree"
| "metadata_provenance_conflict"
| "cardinality_conflict"
| "relationship_target_conflict"
| "temporal_validity_overlap";
type ConflictResolutionStrategy =
| "first_writer_wins"
| "last_writer_wins"
| "highest_authority_wins"
| "merge_with_provenance"
| "user_review_required"
| "emit_contradiction_edge";
type SemanticConflictPolicy = { // canonical home
// Artifact 1 §17.5
conflict_class: SemanticConflictClass;
default_strategy: ConflictResolutionStrategy;
per_field_overrides?: Map<string, ConflictResolutionStrategy>;
schema_version: 1;
};
```
V4-K-MISC default resolution per conflict class (per V4 §3.6.6):
```text
SemanticConflictPolicy default resolution per conflict class
(V4-K-MISC; runtime applied at parallel ingestion per Artifact 3
§19.2 + §15.5):
field_value_disagree → first_writer_wins (default for ingestion
races)
metadata_provenance_conflict → merge_with_provenance
cardinality_conflict → user_review_required
relationship_target_conflict → emit_contradiction_edge
temporal_validity_overlap → user_review_required
Implementation: when two simultaneous create operations race for the
same entity (e.g., MotionChain identity per §15.1), the kernel
resolves by conflict class. First-writer-wins for plain field
disagreements; user-review-required for cardinality (one entity vs
many) or temporal (overlapping validity windows).
Cross-reference Artifact 3 §19.2 (kernel-side runtime resolution).
```
OP-A row: implicit (covered via OBL-EC-V16-BINDING-FAILURE-POLICY-01 + Artifact 3 §19.2 kernel runtime).
---
## §22. Group K — BindingGenerationSnapshot + BindingBackfillPolicy + lifecycle states
### §22.1 BindingGenerationSnapshot (V4-K-7)
**[V4 PATCH:V4-K-7 per R-G55S §13 — BindingGenerationSnapshot]**
Per V4 §3.6.6:
```typescript
type BindingGenerationSnapshot = { // V4 NEW per V4-K-7
binding_id: string;
binding_generation_id: string; // monotonic per
// binding revision
binding_snapshot: SourceBindingSnapshot; // immutable copy
// of binding at
// this generation
effective_at: ISO8601;
superseded_by?: string; // next generation
schema_version: 1;
};
type SourceBindingSnapshot = { // immutable copy
binding_id: string;
binding_generation_id: string;
source_kind: SourceKindRef;
source_selector: SourceSelector;
target_kind: BindingTargetKind;
corpus_ref: CorpusRef;
selector_list: StructuralSelectorList;
content_type_filter?: ContentTypeFilter;
resource_policy: BindingResourcePolicy;
backfill_policy?: BindingBackfillPolicy;
permission_policy?: BindingPermissionPolicy;
schema_version: 1;
};
```
Per Artifact 3 §15.3 (kernel runtime): BindingGenerationSnapshot lifecycle and audit replay reproducibility.
OP-A row: `OBL-K-MANIFEST-DURABLE-01` (V4 NEW per V4-§0.3-misc; covers manifest + snapshot durability).
**[R0.2 NOTE per AUDIT_DOC73_Artifact2_R0.1.md HIGH-A2-5]** — BindingGenerationSnapshot durability is covered by INV-K-MANIFEST-DURABLE-1 (canonical home Artifact 3 §15.2). Per INV-K-MANIFEST-DURABLE-1: BindingEvaluationManifest + BindingGenerationSnapshot are both durable kernel receipts; never session-only. Pairs with INV-V16-RETENTION-DURABLE-1 per V4-§0.7-2 ephemeral/durable split. Snapshots referenced by BindingEvaluationManifests need preservation for audit replay reproducibility per V4-K-7.
### §22.2 BindingBackfillPolicy (V3-K-6)
**[V4 PATCH:V3-K-6 per R-EX §13 + R-EX §3.6 MODIFY — Backfill: support required, execution optional]**
Per V4 §3.6.5:
```typescript
type BindingBackfillPolicy = { // V3-K-6
policy_id: string;
// Support: must be available per source kind
source_kind_supports_backfill: boolean;
source_kind_backfill_capabilities?: {
max_lookback_days: number;
cursor_kind: "timestamp" | "sequence" | "page_token";
rate_limit_ops_per_sec: number;
};
// Execution: per-binding decision
backfill_execution_mode:
| "disabled" // do not backfill
| "preview_only" // V1.6 default;
// preview before
// commit
| "preview_and_commit" // preview then
// commit on
// confirmation
| "auto_commit_with_caps"; // auto with cost
// / rate caps
// Preview parameters
preview_lookback_days: number;
preview_cost_estimate: number; // EC capacity
// lease estimate
preview_match_count_estimate?: number;
preview_sample_matches?: number; // show N sample
// matches
// Cost caps (per V2 BindingResourcePolicy)
max_estimated_cost_usd?: number;
on_cost_exceeded:
| "halt_with_alert"
| "user_confirm_required"
| "auto_throttle";
schema_version: 1;
};
```
V1.6 default for legal brief bank bindings (per V4 §3.6.5):
```text
backfill_execution_mode: "preview_only"
preview_lookback_days: 365 // 1 year for litigation timelines
on_cost_exceeded: "user_confirm_required"
```
### §22.3 INV-K-BACKFILL-1
Per V4 §3.6.5:
```text
INV-K-BACKFILL-1 (V3 NEW; canonical home Artifact 2 §22.3):
Backfill SUPPORT (the source kind's ability to backfill) is required
for all V1.6 binding-eligible source kinds. Backfill EXECUTION
(whether a specific binding actually runs backfill) is per-binding
optional, with preview as the V1.6 default. Auto-commit backfill
requires explicit binding configuration with cost cap.
A binding with backfill_execution_mode = "disabled" cannot be later
upgraded to "auto_commit_with_caps" without an explicit user action;
backfill execution mode changes are user-confirmed binding mutations.
Runtime check (binding creation + mutation):
function validate_backfill_policy_change(
binding: SourceBinding,
proposed_backfill_policy: BindingBackfillPolicy,
user_confirmation_token?: string
): ValidationResult {
const current = binding.backfill_policy;
if (!current) return accept(); // initial creation
const escalation = (
current.backfill_execution_mode === "disabled" &&
proposed_backfill_policy.backfill_execution_mode !== "disabled"
);
if (escalation && !user_confirmation_token) {
return reject(
"binding_backfill_escalation_requires_user_confirmation"
);
}
return accept();
}
```
OP-A row: implicit (covered by OBL-D72-V16-K-SOURCE-REGISTRY-01 + Group K family).
### §22.4 BindingLifecycleState enum + transitions (per V4 §3.6.1 lifecycle)
```typescript
type BindingLifecycleState = // V4 §3.6.1
| "pending_intake" // binding created;
// awaiting
// evaluation
| "ready_to_evaluate" // earliest required
// selector phase
// passed for
// candidate artifact
| "evaluated" // evaluation
// completed
| "fired" // effects applied
| "matched_no_fire" // matched but
// suppressed
// (e.g., dedup
// suppress;
// policy block)
| "no_match" // evaluation did
// not match
| "disabled" // user disabled
| "superseded"; // binding superseded
// by new
// BindingGenerationSnapshot
```
Per Artifact 3 §13.2 (kernel runtime): lifecycle transitions enforced.
OP-A row: `OBL-D73-V16-K-LIFECYCLE-01`.
### §22.5 BindingMutationKind enum + edit semantics
Per K.21 (V2 carry-forward):
```typescript
type BindingMutationKind = // K.21
| "create" // initial binding
// creation
| "update_selectors" // selector_list
// change
| "update_target_kind" // target_kind change
| "update_resource_policy" // BindingResourcePolicy
// change
| "update_backfill_policy" // BindingBackfillPolicy
// change
| "update_permission_policy" // BindingPermissionPolicy
// change
| "disable" // disable binding
| "enable" // re-enable disabled
// binding
| "delete"; // permanent delete
// (rare; usually
// soft_delete)
```
Mutation semantics:
```text
Mutations that advance binding_generation_id (per V4-K-7):
- update_selectors
- update_target_kind
- update_resource_policy
- update_backfill_policy
- update_permission_policy
Mutations that DO NOT advance generation (lifecycle-only):
- disable
- enable
- delete (permanent)
Per Artifact 3 §15.3: binding_generation_advance effect_kind fires on
generation-advancing mutations; receipt_only on lifecycle-only mutations.
```
OP-A row: `OBL-D73-V16-K-LIFECYCLE-01`.
---
## §23. Group K — BoundSourceIngestionBatch + BatchReviewOperation + INV-K-BATCH-1 + CorpusBindingContribution + INV-K-EVICTION-1 + INV-K-HEALTH-1
### §23.1 BoundSourceIngestionBatch canonical schema (V3-K-9)
**[V4 PATCH:V3-K-9 per R-EX §3.6 MODIFY]**
Per V4 §3.6.8:
```typescript
type BoundSourceIngestionBatch = { // V2 base + V3-K-9
batch_id: string;
source_binding_ref: string; // SourceBindingRef
source_run_ref: string; // SourceRunRef
// (binding evaluation
// run id)
// V2 base
candidate_document_refs: string[]; // DocumentRef[]
// = SourceArtifactRef[]
duplicate_groups: DuplicateGroup[]; // V2 base
matched_corpora: Array<{
corpus_ref: CorpusRef;
match_count: number;
}>;
batch_review_state:
| "pending"
| "partially_confirmed"
| "confirmed"
| "rejected";
// V3 NEW per V3-K-9:
policy_blocked_refs: PolicyBlockedItem[];
dedup_suppressed_refs: DedupSuppressedItem[];
materialization_failed_refs: MaterializationFailedItem[];
pending_review_refs: PendingReviewItem[];
review_actions_available: Array<
| "confirm_individual"
| "confirm_all_visible"
| "reject_individual"
| "reject_all_visible"
| "defer_individual"
| "split_filing_unit"
| "merge_with_existing_membership"
>;
schema_version: 1;
};
type DuplicateGroup = {
canonical_ref: string;
duplicate_refs: string[];
dedup_evidence: "content_hash" | "filing_unit_id_match" | "user_marked";
};
type PolicyBlockedItem = {
document_ref: string;
reason_code: string; // namespaced per
// §0.7.2
};
type DedupSuppressedItem = {
document_ref: string;
duplicate_of: string;
};
type MaterializationFailedItem = {
document_ref: string;
failure_reason_code: string;
};
type PendingReviewItem = {
document_ref: string;
review_reason: string;
reviewer_assigned?: ActorRef;
};
```
The expanded schema surfaces what's not shown in the review queue (policy-blocked, dedup-suppressed, materialization-failed) so the user can audit batch handling end-to-end.
OP-A row: implicit (Group K family).
### §23.2 BatchReviewOperation + INV-K-BATCH-1 (V3-K-8 + V4-K-PARTIAL)
**[V4 PATCH:V3-K-8 per R-V22 §21 + V4-K-PARTIAL per R-CL4 #35 — partial-failure batch handling]**
Per V4 §3.6.7:
```typescript
type BatchReviewOperation = { // V3-K-8 + V4-K-PARTIAL
batch_review_id: string;
source_batch_id: string; // BoundSourceIngestionBatch
prior_batch_review_ref?: string; // for retry batches
// per V4-K-PARTIAL
item_operations: Array<{
item_membership_id: string;
disposition:
| "confirm"
| "reject"
| "defer"
| "split"
| "merge_with";
target_disposition_ref?: string; // for merge_with
operation_id: string; // EACH item gets
// its own kernel
// op_id (per
// INV-K-BATCH-1)
}>;
total_items: number;
confirm_count: number;
reject_count: number;
defer_count: number;
// V4 NEW per V4-K-PARTIAL:
success_count: number;
failure_count: number;
failure_summary?: Array<{
item_membership_id: string;
failure_reason_code: string;
failure_message: string;
retryable: boolean;
}>;
schema_version: 1;
};
```
```text
INV-K-BATCH-1 (V3 NEW; canonical home Artifact 2 §23.2):
Batch confirmation emits ONE kernel operation PER ITEM (per
disposition), NOT a single batch-blob operation. Each per-item
disposition creates a distinct operation_id with its own envelope,
effects, and rollback path.
Rationale: rollback granularity. A user who batch-confirms 50 PACER
documents and later realizes 3 were wrong needs to be able to roll
back the 3 — not the entire batch. Per-item operations enable Tier 1
rollback on the 3 without touching the other 47.
The BatchReviewOperation provides the audit-level grouping (one
batch_review_id linking the 50 ops); per-item operations provide the
kernel-level granularity (50 distinct operation_ids).
Per Artifact 3 §14.4 INV-K-BATCH-PARTIAL-1: each per-item operation
is independent. If item 23/50 fails, items 1-22 remain confirmed;
item 23 reports failure; items 24-50 continue normally. Batch does
NOT halt on first failure.
Per-item operation_ids are stable: a retry produces NEW operation_ids
for the retried items but does NOT touch the operation_ids for the
already-succeeded items. Audit trail preserves original batch +
retry-batch as separate batch_review_ids linked via
prior_batch_review_ref.
```
OP-A rows: implicit (kernel runtime per Artifact 3 §14) + `OBL-EC-V16-K-BATCH-PARTIAL-01` (V4 NEW per V4-K-PARTIAL).
Acceptance test: V3-AT-20 + V4-AT-PARTIAL.
### §23.3 CorpusBindingContribution + INV-K-EVICTION-1
**[V4 PATCH:V3-K-10 per R-EX §3.6 MODIFY — Corpus eviction Group A integration]**
Per V4 §3.6.9:
```typescript
type CorpusBindingContribution = { // V2 + V3-K-10
contribution_id: string;
binding_id: string;
corpus_id: CorpusRef;
membership_id: string; // CorpusMembershipRecord
// (per §20.4)
contribution_state:
| "confirmed_by_user"
| "confirmed_by_auto"
| "rejected_by_user"
| "soft_deleted_by_user"
| "soft_deleted_by_cascade"
| "extraction_failed"
| "policy_blocked";
contribution_event_at: ISO8601;
schema_version: 1;
};
```
```text
INV-K-EVICTION-1 (V3 NEW; canonical home Artifact 2 §23.3):
Corpus member soft-delete (Artifact 3 §3.3 soft_delete semantic verb)
does NOT auto-disable the binding that produced the membership.
CorpusBindingContribution ledger records the soft-delete event for
binding health analysis, but binding state changes (disable, refine
selectors, adjust trust posture) require explicit user action.
Rationale: a single misfire is signal, not certainty. User decides
whether the soft-delete reflects a binding misfire (which should
disable / refine the binding) or a one-off rejection (binding remains
active).
Runtime check (kernel-side runtime per Artifact 3):
function on_corpus_membership_soft_deleted(
membership: CorpusMembershipRecord
): void {
// Per Artifact 3 §3.3 soft_delete semantic verb: emit
// corpus_membership_soft_deleted event.
// Update CorpusBindingContribution ledger:
if (membership.binding_id) {
record_contribution_state_transition(
membership.binding_id,
membership.membership_id,
"soft_deleted_by_user"
);
}
// Per INV-K-EVICTION-1: DO NOT auto-disable binding.
// Binding state changes require explicit user action via
// BindingMutationKind (per §22.5).
}
```
OP-A row: `OBL-EC-V16-BINDING-CONTRIBUTION-LEDGER-01` (kernel runtime).
### §23.4 INV-K-HEALTH-1 (V2 patch L5)
```text
INV-K-HEALTH-1 (V2 patch L5; canonical home Artifact 2 §23.4):
Binding health metrics: contribution_count alone is insufficient;
user-engagement-weighted metrics are the primary signal of binding
health.
V1.6 health metrics:
total_fires:
Total binding evaluation events.
confirmed_count:
CorpusBindingContribution.contribution_state in
{confirmed_by_user, confirmed_by_auto}.
rejected_count:
contribution_state = rejected_by_user.
soft_deleted_count:
contribution_state in {soft_deleted_by_user, soft_deleted_by_cascade}.
(Signal of binding misfire when ratio is high.)
extraction_failed_count:
contribution_state = extraction_failed.
user_engagement_rate:
Per-membership weighted by user interactions (search hits, opens,
citations). Higher = healthier binding.
Implementation per Artifact 4 §17.3 (read-time consumer surface).
V1.6 default health thresholds:
unhealthy_thresholds:
- rejected_count / total_fires > 0.3 (high reject ratio)
- soft_deleted_count / confirmed_count > 0.2 (high soft-delete
ratio)
- user_engagement_rate < 0.1 (memberships rarely interacted with)
healthy_thresholds:
- rejected_count / total_fires < 0.1
- user_engagement_rate >= 0.5
Q Dashboard surfacing (Artifact 4 §17.3 + DOC20/DOC7 UI):
- "Binding health: healthy / fair / unhealthy" badge per
BindingResourcePolicy.
- Affordance "review binding" surfaces when unhealthy thresholds met.
Per Artifact 4 §17.3: health computation is a read-time consumer
operation; no kernel write occurs to update health state automatically.
```
**[R0.3 PATCH:XHIGH-4 per AUDIT_CROSS_ARTIFACT_R0.1.md XHIGH-4 — `compute_engagement_rate` formula specification, deferred from MED-A4-9 to Step 9.]**
`compute_engagement_rate` canonical formula (R0.3 NEW per XHIGH-4):
```typescript
// Canonical home: Artifact 2 R0.3 §23.4 INV-K-HEALTH-1.
// Helper-home cross-reference: DOC73_V1_6_HELPER_HOMES_R0.1.md §6.F.2
// (declares signature; references this section for canonical formula).
// Caller: Artifact 4 §17.3 compute_binding_health_metrics (read-time
// consumer surface).
function compute_engagement_rate(
contributions: CorpusBindingContribution[],
decay_half_life_days: number = 30 // V1.6 default;
// per
// DOC24_BINDING_ENGAGEMENT_DECAY_HALF_LIFE_DAYS
// tunable
): number { // [0, 1]
// Per V2 patch L5 INV-K-HEALTH-1 (this section):
// "user-engagement-weighted contribution count"
//
// Definition: ratio of (decay-weighted user-interacted contributions)
// / (decay-weighted total contributions).
//
// User-interacted = the user has any of the following interactions
// with the contribution's underlying document:
// - clicked search result for the contribution's membership
// (search_result_clicks store; per Artifact 4 §17 read-time
// consumer surface)
// - opened the document via Q Dashboard (document_open_events
// store; per DOC25 V2.0 / Artifact 5 retrieval surface)
// - cited the document in a brief / synthesis CU (cu_citation_edges
// per Artifact 1 §8.2 source_spans + Artifact 3 §9 INV-MVC-CU-1)
// - marked helpful / unhelpful (utility_signal_capture per
// Artifact 4 §7.1 V4-I-6 UtilitySignalPolicy)
// - shared the document via share-link (share_link_share_events
// per Artifact 4 §5.1 grant_share_link)
//
// Decay weight: exp(-ln(2) * age_days / decay_half_life_days)
// (exponential decay; recent interactions weighted more heavily;
// half-life defaults to 30 days)
//
// Per V2 patch L5 INV-K-HEALTH-1 (above):
// "contribution_count alone is insufficient; user-engagement-
// weighted metrics are the primary signal of binding health."
// The engagement rate IS the primary signal; raw contribution_count
// is captured separately as total_fires for diagnostic context.
if (contributions.length === 0) return 0;
let weighted_total = 0;
let weighted_engaged = 0;
const ln_2 = 0.6931471805599453; // exact
// constant
// (deterministic
// per
// Artifact 1
// §1.11)
for (const c of contributions) {
const age_days = (NOW() - c.contribution_event_at) / (86400 * 1000);
const decay_weight = Math.exp(-ln_2 * age_days / decay_half_life_days);
weighted_total += decay_weight;
const has_interaction = check_user_interaction(c.membership_id);
if (has_interaction) {
weighted_engaged += decay_weight;
}
}
return weighted_engaged / weighted_total;
}
// Helper home: check_user_interaction is declared at
// DOC73_V1_6_HELPER_HOMES_R0.1.md §6.F.3 (composite query across
// 5 utility-signal stores per V4-I-6 UtilitySignalPolicy). EC
// database access layer implementation; queries:
// - search_result_clicks (DOC24 / Artifact 4 §17 CorpusBindingContribution
// read API)
// - document_open_events (DOC25 / Artifact 5 retrieval)
// - cu_citation_edges (Artifact 1 §8.2 source_spans + Artifact 3
// §9)
// - utility_signal_capture (Artifact 4 §7.1)
// - share_link_share_events (Artifact 4 §5.1)
```
V1.6 default `decay_half_life_days = 30` per `DOC24_BINDING_ENGAGEMENT_DECAY_HALF_LIFE_DAYS` configurable constant. Tuning this constant trades responsiveness (lower half-life = faster reaction to recent engagement) vs stability (higher half-life = noisier short-term signal damped). V1.6 ships 30 days as a balanced default; V1.6.1 candidate to tune per legal vs general corpus profile.
OP-A row: `OBL-D73-V16-K-LIFECYCLE-01` (covers binding lifecycle UI surfaces).
---
## §24. Group K — CorpusSourceBindingHealth + Binding UI command matrix + BindingPermissionPolicy
### §24.1 CorpusSourceBindingHealth schema
```typescript
type CorpusSourceBindingHealth = { // V2 patch L5
// schema
binding_id: string;
computed_at: ISO8601;
total_fires: number;
confirmed_count: number;
rejected_count: number;
soft_deleted_count: number;
extraction_failed_count: number;
user_engagement_rate: number; // [0, 1]
health_state:
| "healthy"
| "fair"
| "unhealthy";
unhealthy_signals?: string[]; // narrative
// reasons for
// unhealthy state
schema_version: 1;
};
```
OP-A row: `OBL-D73-V16-K-LIFECYCLE-01`.
### §24.2 Binding UI command matrix (K.24)
```text
V1.6 binding UI command matrix (Artifact 4 + DOC20/DOC7 UI; data
contract here):
User commands available per binding state:
pending_intake / ready_to_evaluate / evaluated:
- View binding configuration
- Edit binding configuration → BindingMutationKind (per §22.5)
- Disable binding
- Delete binding (permanent — confirmation required)
fired (any history):
- View binding configuration
- View binding evaluation manifests (per Artifact 3 §15)
- View CorpusBindingContribution ledger
- View binding health metrics (per §23.4)
- Edit binding configuration → BindingMutationKind
- Disable binding
- Delete binding
disabled:
- View binding configuration
- View binding evaluation history
- Re-enable binding (BindingMutationKind = "enable")
- Edit binding configuration (resumes upon re-enable)
- Delete binding (permanent)
superseded:
- View binding evaluation history
- View superseding generation (BindingGenerationSnapshot per
§22.1)
- Cannot edit (immutable; supersession produced new generation)
- Delete binding (rare; user explicitly removes superseded
generation)
V1.6.1 candidate (per V4 §0.5.1 SAFE list):
- View suggested bindings (read-only display)
V1.7+ candidate:
- Full Suggested Bindings pattern (V4 §0.5.1 NOT SAFE list;
V1.8+ deferred per V4 §0.3.5 R-CL4 #37 reframe)
```
OP-A row: `OBL-D7-D20-V16-K-BINDING-UI-01`.
### §24.3 BindingPermissionPolicy (K.25 share-link gating)
```typescript
type BindingPermissionPolicy = { // K.25
policy_id: string;
binding_id: string;
// Who can edit the binding
editor_principal_scope:
| "owner_only" // V1.6 default for
// share-link
| "owner_and_designated_editors"
| "any_session_with_corpus_write_access";
// Who can disable the binding
disabler_principal_scope: BindingPermissionPolicy["editor_principal_scope"];
// Whether the binding is visible to share-link sessions
share_link_visibility:
| "hidden" // V1.6 default
// for host
// strategic
// bindings
| "visible_read_only" // share-link can
// see binding
// exists but
// not edit
| "visible_with_outcomes_only"; // share-link sees
// only outcomes,
// not binding
// configuration
schema_version: 1;
};
```
V1.6 default for share-link sessions: `share_link_visibility = "hidden"` — bindings are host-curated automation; recipients see only the resulting corpus members, not the binding configuration.
Per Artifact 4 §17.2: share-link search retrieval applies BindingPermissionPolicy.share_link_visibility when surfacing binding-originated content.
OP-A row: `OBL-EC-CSB-POLICY-01` (cross-doc PropA + binding policy).
---
## §25. Group N consumer surfaces
### §25.1 Legal-corpus-aware RecentActivityRollup entries (consume Artifact 1 §16.2)
Per V4 §2.3 + V4 §6.4 Mechanism 4 reclassification: RecentActivityRollup canonical schema is in Artifact 1 §16.2. This artifact §25.1 specifies legal-corpus-aware consumer surfaces that consume but do NOT redefine.
```text
Legal-corpus-aware RecentActivityRollup consumer surface:
Artifact 1 §16.2 RecentActivityRollup carries WorkPhaseEntry +
CorpusActivityEntry + CaseActivityEntry + ArtifactEntry +
UnresolvedThreadEntry. Each activity entry array is consumed by
Artifact 2 read-side consumers as follows:
CorpusActivityEntry (per Artifact 1 §A.5):
- corpus_id: CorpusRef pointing to a knowledge_corpus world_entity
with CorpusProfile (per §3.1 — legal corpora distinguished by
CorpusProfile.extraction_spec.domain_profile = "legal")
- activity_kind: "ingestion" | "extraction" | "review" |
"synthesis" | "browsing"
CaseActivityEntry (per Artifact 1 §A.5):
- matter_ref: NodeRef pointing to a CaseRef (per §11.3
ResolvedCaseIdentity) when matter is legal-case-bound
- activity_kind: "filing_review" | "deposition_prep" |
"brief_drafting" | "discovery_review" | "settlement_negotiation"
| "trial_prep"
- filing_unit_refs: FilingUnitRef[] — legal artifact references
consumed via this artifact §11
ArtifactEntry (per Artifact 1 §A.5):
- artifact_kind: "brief_draft" | "memo" | "exhibit_set" |
"extraction_summary" | "search_result_set"
- artifact_ref: NodeRef — legal artifacts surface via this artifact
§10-§16
Per INV-N-NOT-EVIDENCE-1 (renamed from INV-N-ORIENTATION-1 per CSA
extraction R0.5 in Artifact 1) + INV-N-NO-CIRCULAR-EVIDENCE-1
(Artifact 1 §16.4): RecentActivityRollup activity entries are NOT
cited as evidence. RulingDisposition / FilingRelationship etc. are
evidence (consumed via search router per Artifact 4 §15).
[R0.4 PATCH per CSA extraction 2026-05-04: consumer-side runtime
orchestration (when to inject these entries into agent context at
session start, tiering, session-runtime behavior) deferred to DOC72.
V1.6 release wave does NOT specify CSAInjectionTierPolicy or
equivalent. DOC73 V1.6 produces RecentActivityRollup; DOC72-side
session-orientation orchestration may consume it when DOC72 ships
that machinery.]
```
OP-A row: `OBL-D73-RECENT-ACTIVITY-ROLLUP-CONSUMER-CONTRACT-01` (R0.4 NEW per CSA extraction; DOC73 owns the producer/consumer contract — runtime orchestration deferred to DOC72).
### §25.2 Legal-corpus-aware consumer behavior contract (R0.2 NEW per AUDIT_DOC73_Artifact2_R0.1.md HIGH-A2-4; R0.4 reframed per CSA extraction)
Per audit HIGH-A2-4 + R0.4 CSA extraction: §25.1 cross-references Artifact 1 §16.2 RecentActivityRollup. This subsection specifies HOW Artifact 2 read-side consumers (search, retrieval) determine domain_profile = "legal" filtering, WHEN legal-corpus-specific rollup entries are produced vs general rollups, and WHAT distinguishes legal from non-legal CaseActivityEntry.
```text
Legal-corpus-aware consumer behavior contract:
Domain detection — RecentActivityRollup entry is "legal-corpus-aware"
iff ANY of:
(a) entry.corpus_ref points to a knowledge_corpus world_entity with
CorpusProfile.extraction_spec.domain_profile = "legal".
(b) entry.matter_ref points to a legal case (CaseRef per §11.3
ResolvedCaseIdentity).
(c) entry.filing_unit_refs[] non-empty (CaseActivityEntry per
Artifact 1 §A.5 carries filing_unit_refs for legal-case-bound
activity).
(d) entry.activity_kind ∈ {"filing_review", "deposition_prep",
"brief_drafting", "discovery_review", "settlement_negotiation",
"trial_prep"} — legal-domain-specific activity_kinds.
Producer side (writer agent per Artifact 1 §16.2A canonical home):
Mechanism 4 RecentActivityRollup writer (Artifact 1 §16.2A; canonical
home) emits legal-aware entries when above conditions met. Writer
agent identifies legal corpora by querying
CorpusProfile.extraction_spec.domain_profile per CorpusActivityEntry
scope.
Per Artifact 1 §16.2A.4 INV enforcement at write time:
INV-N-NOT-EVIDENCE-1 enforced (R0.5 renamed from
INV-N-ORIENTATION-1; entries are
not legal evidence).
INV-N-NO-CIRCULAR-EVIDENCE-1 enforced (cited_node_refs not used as
evidence).
Consumer side (this artifact §25):
Artifact 4 §15.4 INV-M-ACCESS-RANK-1:
Search router may consume legal-aware activity entries for query
context only (NOT ranking signal; per INV-N-NO-CIRCULAR-EVIDENCE-1).
[R0.4 PATCH per CSA extraction 2026-05-04: prior reference to
Artifact 4 §18 CSAInjectionTierPolicy as a consumer is REMOVED.
CSAInjectionTierPolicy is gone from V1.6 release wave; session-
orientation injection orchestration is DOC72's architectural
concern, deferred from V1.6.]
Producer/consumer split semantics:
Writer = Artifact 1 §16.2A PrimaryPBEOrchestrator (per V4-§0.4-2 +
V4-N-1 producer/consumer split).
Consumers (V1.6 release wave artifacts that read RecentActivityRollup):
- Artifact 2 §25 (this artifact; legal-domain-aware consumer)
- Artifact 4 §10-§15 search router (activity-entry context in
search posture resolution)
- DOC72-side session-orientation orchestration (V1.6.1+ when
DOC72 ships that machinery)
Producer/consumer write/read pattern: Artifact 1 §16.2A producer
writes to durable RecentActivityRollup store (per
INV-V16-RETENTION-DURABLE-1); consumers read; consumers DO NOT
write back. Rollup updates occur via Artifact 1 §16.2A writer flow
(nightly / session-handoff triggers).
Filtering legal-corpus-aware consumer:
function filter_legal_aware_activity_entries(
rollup: RecentActivityRollup,
session: SessionProfile
): ActivityEntry[] {
// Iterate all activity entry arrays (case_activity_entries,
// corpus_activity_entries, work_phase_entries, artifact_entries,
// unresolved_thread_entries) and apply legal-aware filter to each.
const all_entries = [
...rollup.case_activity_entries,
...rollup.corpus_activity_entries,
...rollup.work_phase_entries,
...rollup.artifact_entries,
...rollup.unresolved_thread_entries,
];
return all_entries.filter(entry => {
const is_legal_aware = (
is_legal_corpus_corpus_ref(entry) ||
is_legal_case_matter_ref(entry) ||
has_filing_unit_refs(entry) ||
is_legal_activity_kind(entry)
);
if (!is_legal_aware) return true; // non-legal entries pass through
// Legal-aware entry: filter by session affiliation.
// Session must have legal corpus access OR legal case context.
return session_has_legal_context(session);
});
}
// Helpers per CRIT-A2-2 deferred to Step 9 helper-home appendix.
Per INV-N-NO-CIRCULAR-EVIDENCE-1 (Artifact 1 §16.4): activity entries'
cited refs are NEVER used as evidence. Legal-aware framing is context
only; RulingDisposition / FilingRelationship / FilingUnit content is
evidence (consumed via search router per Artifact 4 §15.X).
```
OP-A row: `OBL-D73-RECENT-ACTIVITY-ROLLUP-CONSUMER-CONTRACT-01` (R0.4 NEW per CSA extraction; canonical home Artifact 1 §16.6).
---
## §26. Worked Examples Appendix
Per prompt: 3 worked examples required (FilingUnit normalization, RulingDisposition multi-defendant, FilingUnitVersion supersession).
### §26.1 Worked Example 1 — FilingUnit normalization (PACER bundle ingestion legal-side)
```text
Setup:
Continued from Artifact 5 §14 PACER bundle worked example.
After SourceArtifact + ArtifactSegment creation, this artifact's
legal-side processing begins.
SA-PACER-#142-V1: 382-page PACER bundle ingested.
ArtifactSegments SE-2 through SE-7: 6 ECF-stamped attachments
(per Artifact 5 §14.4: 8 total segments are created — SE-1
cover/TOC + SE-2 main brief + SE-3 through SE-7 5 exhibits + SE-8
cert of service. Of those, 6 are ECF-stamped attachments
producing 6 FilingUnit candidates; SE-1 and SE-8 are auxiliary
without separate FilingUnit per Artifact 5 §14.4. R0.2 NOTE per
AUDIT_DOC73_Artifact2_R0.1.md HIGH-A2-2.)
(main brief + Exhibits A-E).
Step 1: Per Artifact 5 §3.5 INV-O-EXTRACTION-FILING-UNIT-SCOPED-1,
SegmentToFilingUnit candidates generated (FU-MTD-MAIN +
FU-MTD-EXH-A through FU-MTD-EXH-E).
Step 2: For each candidate, FilingUnitIdentity resolved per §11.2
+ ECF header parser output (Artifact 5 §4.2):
FU-MTD-MAIN.identity:
court_id: "ndcal"
case_number_normalized: "3:23-cv-04567"
docket_entry_no: "142"
ecf_attachment_no: 0
identity_confidence: 0.97
identity_evidence: "ecf_metadata"
resolved_case_ref: (none — no consolidation/transfer/
severance history known)
Step 3: FilingUnit creation envelopes constructed per Artifact 3 §3.3
semantic verb "create"; primitive_effects:
[{effect_kind: "filing_unit_write", reversibility: "fully_reversible"},
{effect_kind: "filing_unit_version_write", reversibility: "fully_reversible"},
{effect_kind: "filing_unit_text_version_write", reversibility: "fully_reversible"},
{effect_kind: "membership_write", reversibility: "fully_reversible"},
{effect_kind: "index_update", reversibility: "fully_reversible"}]
Step 4: FilingUnit FU-MTD-MAIN created with:
legal_profile_kind: "legal_brief_filing"
filing_unit_kind: "brief"
filing_role: "motion"
related_motion_type: "motion_to_dismiss"
filing_date_utc: "2024-03-15T22:30:00Z"
filing_date_originating_tz: "America/Los_Angeles"
filing_date_originating_calendar_date: "2024-03-15"
visibility_class: "public_open"
Step 5: FilingUnitVersion FUV-MTD-MAIN-V1 created with:
legal_version_kind: "original_as_filed"
version_sequence_number: 1
source_artifact_ref: SA-PACER-#142-V1
Step 6: FilingUnitTextVersion FUTV-MTD-MAIN-V1-T1 created with:
text_version_kind: "as_extracted_initial"
source_artifact_ref: SA-PACER-#142-V1
text_hash: <SHA-256 of SE-2 segment text>
Step 7: Similar for FU-MTD-EXH-A through FU-MTD-EXH-E (5 more
FilingUnit creations, each with appropriate
filing_unit_kind / filing_role / related_motion_type).
Per V3-K-3 BindingTargetKind dispatch (Artifact 3 §13.5):
binding fired with target_kind = "corpus_document_membership";
creates CorpusMembershipRecord per FilingUnit.
Step 8: FilingRelationship edges constructed per §15.3:
- FU-MTD-EXH-A "attaches_to" FU-MTD-MAIN
- FU-MTD-EXH-B "attaches_to" FU-MTD-MAIN
- ... (4 more)
Each edge emits filing_relationship_write effect_kind
(Artifact 3 §4.3.14); reversibility = "fully_reversible".
Step 9: BindingOutcomeRecord per §17.4 emitted:
outcome_state: "succeeded"
target_kind: "corpus_document_membership"
outcome_target_ref: <membership_id>
Per INV-K-OUTCOME-1 (§21.5): binding fire produces evidence
(FilingUnit + FilingRelationship); NOT adjudicated outcome
(no RulingDisposition without court order).
Audit trail:
- 6 FilingUnit envelopes (filing_unit_write effect): durable per
INV-V16-RETENTION-DURABLE-1.
- 6 FilingUnitVersion + 6 FilingUnitTextVersion writes.
- 5 FilingRelationship "attaches_to" edges.
- 6 CorpusMembershipRecord rows.
- BindingEvaluationManifest per Artifact 3 §15 (durable).
- Per INV-O-FILING-UNIT-CANONICAL-1 (§11.5): canonical_key complete;
no identity_uncertain badge needed.
```
### §26.2 Worked Example 2 — RulingDisposition multi-defendant (V4-O-4 mandatory scope_targets)
```text
Setup:
Court issues order on MTD in case 3:23-cv-04567 (N.D. Cal.):
"The motion is GRANTED as to defendant ABC Corporation with
leave to amend; DENIED as to defendants DEF Inc., GHI Ltd.,
and JKL Co. with prejudice; reserved as to motion to strike."
Order is filed as a separate FilingUnit (court_order kind);
ArtifactSegment maps to FilingUnit FU-MTD-ORDER.
Step 1: CourtOrderDisposition row created:
order_id: ORDER-MTD-001
source_filing_unit_ref: FU-MTD-ORDER
source_filing_unit_version_ref: FUV-MTD-ORDER-V1
order_date: <court order date>
Step 2: Per V4-O-4 mandatory scope_targets, the single order produces
THREE RulingDisposition entries (NOT a single flattened):
RD-1 (granted with leave to amend; defendant ABC):
disposition_event_id: RD-001
motion_chain_ref: MC-MTD-001
scope_targets: {
motion_chain_ref: MC-MTD-001,
defendant_refs: [PARTY-ABC]
}
scope_basis: "explicit_court_language"
disposition: "granted"
leave_to_amend: "with_leave"
prejudice: "not_applicable"
polarity: {
for_moving_party: "win", // moving party
// = ABC won
// defense; granted
// the dismissal
for_non_moving_party: "loss", // non-moving =
// plaintiff lost
// the claim
// against ABC
polarity_basis: "granted_disposition"
}
normalized_label: "MTD granted with leave to amend (ABC)"
raw_court_language: "GRANTED as to defendant ABC Corporation
with leave to amend"
RD-2 (denied with prejudice; defendants DEF, GHI, JKL):
disposition_event_id: RD-002
motion_chain_ref: MC-MTD-001
scope_targets: {
motion_chain_ref: MC-MTD-001,
defendant_refs: [PARTY-DEF, PARTY-GHI, PARTY-JKL]
}
scope_basis: "explicit_court_language"
disposition: "denied"
leave_to_amend: "not_applicable"
prejudice: "with_prejudice"
polarity: {
for_moving_party: "loss", // DEF/GHI/JKL lost
// their MTD
for_non_moving_party: "win", // plaintiff won
// against DEF/GHI/JKL
polarity_basis: "denied_disposition"
}
normalized_label: "MTD denied with prejudice (DEF, GHI, JKL)"
raw_court_language: "DENIED as to defendants DEF Inc., GHI Ltd.,
and JKL Co. with prejudice"
RD-3 (reserved; motion_to_strike):
disposition_event_id: RD-003
motion_chain_ref: MC-MTS-001 // separate motion
// to strike chain
scope_targets: {
motion_chain_ref: MC-MTS-001
}
scope_basis: "explicit_court_language"
disposition: "reserved"
polarity: ambiguous (reserved is procedural)
normalized_label: "Motion to strike reserved"
raw_court_language: "reserved as to motion to strike"
Step 3: Each RulingDisposition emits ruling_disposition_write
effect_kind (Artifact 3 §4.3.18); reversibility =
"fully_reversible".
Step 4: Query: "Did defendants win the MTD?" per §13.6 worked
sub-example.
- For ABC: polarity.for_moving_party = "win" → "ABC won"
- For DEF/GHI/JKL: polarity.for_moving_party = "loss" → "lost"
- Per V4-O-5 polarity field enables direct query answers.
Audit trail:
- 1 CourtOrderDisposition row.
- 3 RulingDisposition entries (NOT flattened to 1).
- Per INV-O-DISPOSITION-1: scope_targets populated for each.
- Per V4-AT-31: rejected if flattened to single disposition with
ambiguous scope.
Compliance: V4-AT-31 (mandatory scope_targets enforcement) — order
disposing multiple defendants produces per-defendant RulingDisposition
with scope_targets populated; flattening rejected.
```
### §26.3 Worked Example 3 — FilingUnitVersion supersession (court correction)
```text
Setup:
Continued from §26.1 + §26.2.
Court issues correction order:
"ECF Document 145, Corrected Brief: Defendants ABC Corporation
file corrected version of MTD per court's prior order to amend.
Replaces ECF Document 142."
Step 1: New SourceArtifact ingested per Artifact 5 §14 flow:
SA-PACER-#145-V1 (corrected brief, single PDF).
Step 2: FilingUnit identity resolution per §11.2:
court_id: "ndcal"
case_number_normalized: "3:23-cv-04567"
docket_entry_no: "145"
ecf_attachment_no: 0
Per §11.5 INV-O-FILING-UNIT-CANONICAL-1: canonical key DIFFERS
from FU-MTD-MAIN (different docket_entry_no), so this is a
DIFFERENT FilingUnit (not same FilingUnit different version).
Wait — this is V1.6 ambiguity: does ECF #142 vs ECF #145 produce
two separate FilingUnits OR one FilingUnit with two
FilingUnitVersions?
Resolution per V3-O-6 + V4-O-2: FilingUnitVersion is for
amendments AT THE SAME canonical key (e.g., re-filed under
same docket_entry_no). If court issues new docket_entry_no
for corrected brief (#145 supersedes #142), this is a
DIFFERENT FilingUnit linked via FilingRelationship
edge_type = "supersedes_filing".
Per V4 §3.6.6: V4-O-2 amended legal version = "amended"
applies when SAME canonical key has new content version
(e.g., court annotates "amended" on existing docket_entry_no).
For #145 supersedes #142 case: NEW FilingUnit FU-MTD-MAIN-V2
created. FilingRelationship edge "supersedes_filing" from
FU-MTD-MAIN-V2 → FU-MTD-MAIN.
Step 3: NEW FilingUnit FU-MTD-MAIN-V2 created (envelope same as §26.1).
Distinct from FU-MTD-MAIN (different canonical key).
Step 4: FilingRelationship edge created:
edge_id: REL-001
source_filing_unit_ref: FU-MTD-MAIN-V2
target_filing_unit_ref: FU-MTD-MAIN
edge_type: "supersedes_filing"
edge_basis: "ecf_metadata_extracted"
confidence: 0.97
visibility_class: "public_open" (both FilingUnits public)
Step 5: Per Artifact 4 §15.5 INV-M-VERSION-AWARE-1: when search
merges results across FilingUnits including FU-MTD-MAIN and
FU-MTD-MAIN-V2, the supersedes_filing edge is consumed:
- Most authoritative version per legal_version_kind precedence
(amended > corrected > reissued > public_redacted >
original_as_filed) returned.
- For court-corrected brief: FU-MTD-MAIN-V2 returned;
FU-MTD-MAIN excluded with version_selection_disclosure.
Step 6: Re-extraction per Artifact 5 §6: ER-MTD-MAIN-V2 ExtractionRun
created for new FilingUnit. Cross-version sharing per
V4-O-VERSION-COST: if text hash of FU-MTD-MAIN-V2 mostly
matches FU-MTD-MAIN (cross-version-shareable deterministic
stages), Stage 1 + Stage 2 outputs reused; LLM stages run
per-version.
NOW the alternative scenario: court issues "amended" annotation on
SAME docket entry (rare but happens):
"Amended brief filed at ECF Document 142 per Local Rule 7-3."
Step 1' (alternative): Same SourceArtifact identifier (no NEW
docket_entry_no); content updated.
Step 2': FilingUnit identity resolves to SAME FU-MTD-MAIN.
Step 3': NEW FilingUnitVersion created on FU-MTD-MAIN:
version_id: FUV-MTD-MAIN-V2
legal_version_kind: "amended"
version_sequence_number: 2
supersedes_version_id: FUV-MTD-MAIN-V1
source_artifact_ref: SA-PACER-#142-V2 (new SourceArtifact
for the amended content; per Artifact 5
§2.5 SupersedingBasis = "court_amended_filing")
Step 4': INV-O-VERSION-1 enforcement (Artifact 2 §12.4): search
retrieval binds to FilingUnitVersion (legal version) AND
FilingUnitTextVersion (text version). For FU-MTD-MAIN search,
most-authoritative version returned per legal_version_kind
precedence: FUV-MTD-MAIN-V2 (amended) over FUV-MTD-MAIN-V1
(original_as_filed).
Audit trail:
- Scenario A (#145 supersedes #142): NEW FilingUnit + supersedes_filing
edge; V4-AT-32 verifies.
- Scenario B (#142 amended): SAME FilingUnit + NEW FilingUnitVersion
+ INV-O-VERSION-1 selection; V4-AT-32 verifies.
Compliance: V4-AT-32 (FilingUnitVersion version_sequence_number
monotonic; supersession detected).
```
---
## §27. Landing Matrix entries authored by Artifact 2
```text
Group J (Brief Bank surfaces):
Row A2.1 CorpusProfile schema (V3-J-1 fix) (§3)
Row A2.2 INV-J-PROFILE-1 (§3.2)
Row A2.3 LegalMetadataFieldValue + field_lock (V3-J-2) (§4)
Row A2.4 INV-J-METADATA-LOCK-1 (§4.2)
Row A2.5 TopicVisibilityPolicy (V3-J-3 + V4-J-1) (§5)
Row A2.6 INV-J-TOPIC-VIS-1 (§5.2)
Row A2.7 INV-J-TOPIC-MERGE-1 (V4-J-4 / R-GEM #4) (§5.3)
Row A2.8 INV-J-TOPIC-DEDUP-1 (V4-J-4 legal ≥0.93) (§5.4)
Row A2.9 PatternLibraryVisibility (V4-J-3) (§6)
Row A2.10 INV-J-PATTERN-LIB-VIS-1 (§6.2)
Row A2.11 J.5 minimum 12-filter UI (V3-J-4 + V4-J-2) (§7)
Row A2.12 topic_dedup_threshold defaults + override
(V3-J-5) (§8.1)
Row A2.13 source_span_unavailable framing rename (V3-J-6) (§8.2)
Row A2.14 CorpusProfileFork + ForkRelationshipEdge
(V4-J-FORK) (§9)
Row A2.15 INV-J-FORK-1 (§9.3)
Group O (Legal Filing Artifact Normalization):
Row A2.16 Owner split per V3-O-1 + V4-O-1 entity_subtype
split (§1.1 + §10)
Row A2.17 INV-O-TAXONOMY-1 (§1.2)
Row A2.18 FilingUnit + FilingUnitIdentity (V3-O-2) (§11)
Row A2.19 ResolvedCaseIdentity (V4-O-3) (§11.3)
Row A2.20 INV-O-CASE-RESOLUTION-1 (V4-O-3) (§11.7)
Row A2.21 FilingPart + FilingPartVisibility +
INV-O-FILING-PART-VIS-1 (§11.4)
Row A2.22 INV-O-FILING-UNIT-CANONICAL-1 (§11.5)
Row A2.23 INV-O-IDENTITY-1 (V3-O-2) (§11.6)
Row A2.24 FilingUnitVersion (V3-O-6) (§12.1)
Row A2.25 FilingUnitTextVersion (V4-O-2 split) (§12.2)
Row A2.26 INV-O-VERSION-1 (V3-O-7 + V4 strengthened) (§12.4)
Row A2.27 RulingDisposition + scope_targets (V4-O-4) (§13.2)
Row A2.28 RulingDispositionPolarity (V4-O-5) (§13.2)
Row A2.29 INV-O-DISPOSITION-1 (§13.4)
Row A2.30 CourtDispositionObservation (V3-O-8) (§14.1)
Row A2.31 CourtDispositionObservation lifecycle (V4-O-8) (§14.2)
Row A2.32 INV-O-OBSERVATION-LIFECYCLE-1 (§14.2)
Row A2.33 MotionChain (work_product) (§15.1)
Row A2.34 FilingChain (work_product) (§15.2)
Row A2.35 FilingRelationship typed edges (§15.3)
Row A2.36 FilingRelationshipCandidate +
UnmatchedDocumentRelationshipCandidate
(V3-O-10 stale_unresolved) (§15.4)
Row A2.37 INV-O-UNMATCHED-1 (§15.5)
Row A2.38 INV-O-CITATION-1 (V3-O-12 + V4-O-6 display) (§16.1)
Row A2.39 LegalEvidencePosture (V3-O-13) (§16.2)
Row A2.40 INV-O-CAPTION-1 (§16.3)
Row A2.41 INV-O-DEDUP-1 + INV-O-DEDUP-2 (§16.4)
Row A2.42 StructuredExtractionStrategy (V3-O-4) (§16.5)
Row A2.43 INV-O-COMPOSITE-NORMALIZATION-1 +
INV-O-ATOMIC-NORMALIZATION-1 (§16.6)
Group K (Source Bindings semantic specs):
Row A2.44 SourceBinding entity schema (§17.1)
Row A2.45 BindingResourcePolicy + capacity_priority
(V4-K-CAPACITY) (§17.2)
Row A2.46 BindingTargetKind + BindingOutcomeRecord
(V3-K-3) (§17.3 + §17.4)
Row A2.47 INV-K-TARGET-1 (§17.5)
Row A2.48 FilingUnitKind / FilingRole / RelatedMotionType
orthogonal axes (V4-K-1) (§18.2-§18.4)
Row A2.49 8-value LegalProfileKind unified
(V4-J-3.5-K-3.6) (§18.5)
Row A2.50 ContentTypeClassification 3-field split
(V3-K-2) (§18.6)
Row A2.51 ContentTypeFilter (V2 patch L8) +
INV-K-FILTER-1 (§18.7 + §19.4)
Row A2.52 StructuralSelectorList + selector_phase_available
(V3-K-1 + V4-K-2 + V4-K-6 size_band defer) (§19)
Row A2.53 INV-K-SELECTOR-1 (§19.3)
Row A2.54 CorpusMembershipRecord + state machine
(V3-K-4 + V4-K-3 transitions) (§20)
Row A2.55 ContentHashRef typed schema (V4-K-4) consumer (§20.4)
Row A2.56 INV-K-MEMBERSHIP-EXTRACTION-1 (§20.5)
Row A2.57 CanonicalEntityEdge + INV-K-DEDUP-1/2
(V3-K-7 + V2 carry-forward) (§21.1-§21.3)
Row A2.58 INV-K-DEDUP-3 lifecycle (V4-K-INV-DEDUP-3) (§21.4)
Row A2.59 INV-K-OUTCOME-1 (V4-K-5; cross-Artifact 3) (§21.5)
Row A2.60 SemanticConflictPolicy default resolution
(V4-K-MISC) (§21.6)
Row A2.61 BindingGenerationSnapshot (V4-K-7) (§22.1)
Row A2.62 BindingBackfillPolicy (V3-K-6) +
INV-K-BACKFILL-1 (§22.2 + §22.3)
Row A2.63 BindingLifecycleState enum + transitions (§22.4)
Row A2.64 BindingMutationKind enum + edit semantics
(K.21) (§22.5)
Row A2.65 BoundSourceIngestionBatch (V3-K-9) (§23.1)
Row A2.66 BatchReviewOperation (V3-K-8 + V4-K-PARTIAL) +
INV-K-BATCH-1 (§23.2)
Row A2.67 CorpusBindingContribution + INV-K-EVICTION-1
(V3-K-10) (§23.3)
Row A2.68 INV-K-HEALTH-1 (V2 patch L5) (§23.4)
Row A2.69 CorpusSourceBindingHealth schema (§24.1)
Row A2.70 Binding UI command matrix (K.24) (§24.2)
Row A2.71 BindingPermissionPolicy (K.25 share-link
gating) (§24.3)
Group N consumer surfaces:
Row A2.72 Legal-corpus-aware RecentActivityRollup consumer (§25)
Cross-cutting:
Row A2.73 RecentActivityRollup consumer-contract tracking
(OBL-D73-RECENT-ACTIVITY-ROLLUP-CONSUMER-CONTRACT-01) (§25)
[R0.4 PATCH per CSA extraction 2026-05-04: replaces prior
"CSA R2 absorption tracking (OBL-D72-CSA-R2-DOC73-ALIGN-01)"
row; consumer-side orchestration deferred to DOC72]
Row A2.74 INV-13.6 9-tab compliance carry-forward (§2.1)
Total Artifact 2 Landing Matrix entries: 74
```
---
## Drafting Summary
This section is required by the standing build process.
### Sections produced in R0.1
```text
§0 About this artifact (framing, scope, gating contract)
§1 Cross-doc framing (DOC73 + DOC72 + DOC25 owner split per
V4 §2.2.1 + INV-O-TAXONOMY-1)
§2 Group J — Brief bank framing + INV-13.6 9-tab compliance
§3 CorpusProfile (V3-J-1 fix; world_entity payload) + INV-J-PROFILE-1
§4 LegalMetadataFieldValue + field_lock (V3-J-2) +
INV-J-METADATA-LOCK-1
§5 TopicVisibilityPolicy (V3-J-3 + V4-J-1 strengthened) +
INV-J-TOPIC-VIS-1 + Anchor Nodes + INV-J-TOPIC-MERGE-1
(V4-J-4) + INV-J-TOPIC-DEDUP-1 (legal ≥0.93)
§6 PatternLibraryVisibility (V4-J-3) + INV-J-PATTERN-LIB-VIS-1
§7 J.5 minimum 12-filter UI (V3-J-4 promoted + V4-J-2 additions)
§8 topic_dedup_threshold (V3-J-5) + source_span_unavailable rename
(V3-J-6)
§9 CorpusProfileFork + ForkRelationshipEdge (V4-J-FORK) + INV-J-FORK-1
§10 Group O — Owner split + V4-O-1 entity_subtype split +
INV-O-ARTIFACT-IDENTITY-1 cross-reference
§11 FilingUnit + FilingUnitIdentity (V3-O-2 + V4-O-3 ResolvedCaseIdentity)
+ FilingPart + FilingPartVisibility + INV-O-FILING-UNIT-CANONICAL-1
+ INV-O-IDENTITY-1 + INV-O-CASE-RESOLUTION-1
§12 FilingUnitVersion + FilingUnitTextVersion split (V4-O-2) +
version_kind precedence + INV-O-VERSION-1
§13 CourtOrderDisposition + RulingDisposition + scope_targets (V4-O-4)
+ RulingDispositionPolarity (V4-O-5) + INV-O-DISPOSITION-1 +
polarity auto-derivation + worked query example
§14 CourtDispositionObservation + lifecycle (V3-O-8 + V4-O-8) +
INV-O-OBSERVATION-LIFECYCLE-1
§15 MotionChain + FilingChain + FilingRelationship +
FilingRelationshipCandidate + UnmatchedDocumentRelationshipCandidate
(V3-O-10 stale_unresolved) + INV-O-UNMATCHED-1
§16 INV-O-CITATION-1 (V4-O-6 display rule) + LegalEvidencePosture
(V3-O-13) + INV-O-CAPTION-1 + INV-O-DEDUP-1 + INV-O-DEDUP-2 +
StructuredExtractionStrategy (V3-O-4) +
INV-O-COMPOSITE-NORMALIZATION-1 + INV-O-ATOMIC-NORMALIZATION-1
§17 SourceBinding entity + BindingResourcePolicy + capacity_priority
(V4-K-CAPACITY) + BindingTargetKind / BindingOutcomeRecord
(V3-K-3) + INV-K-TARGET-1
§18 FilingUnitKind / FilingRole / RelatedMotionType orthogonal axes
(V4-K-1) + 8-value LegalProfileKind canonical (V4-J-3.5-K-3.6) +
ContentTypeClassification 3-field split (V3-K-2) +
ContentTypeFilter
§19 StructuralSelectorList + selector_phase_available (V3-K-1 +
V4-K-2 + V4-K-6 size_band defer) + INV-K-SELECTOR-1 +
INV-K-FILTER-1
§20 CorpusMembershipRecord + state machine (V3-K-4 + V4-K-3) +
ContentHashRef (V4-K-4) + INV-K-MEMBERSHIP-EXTRACTION-1 +
TrustPosture
§21 CanonicalEntityEdge + INV-K-DEDUP-1/2/3 (V3-K-7 + V4-K-INV-DEDUP-3
lifecycle) + INV-K-OUTCOME-1 cross-reference + SemanticConflictPolicy
default resolution per conflict class (V4-K-MISC)
§22 BindingGenerationSnapshot (V4-K-7) + BindingBackfillPolicy (V3-K-6)
+ INV-K-BACKFILL-1 + BindingLifecycleState + BindingMutationKind
§23 BoundSourceIngestionBatch (V3-K-9) + BatchReviewOperation (V3-K-8 +
V4-K-PARTIAL) + INV-K-BATCH-1 + CorpusBindingContribution +
INV-K-EVICTION-1 + INV-K-HEALTH-1
§24 CorpusSourceBindingHealth + Binding UI command matrix (K.24) +
BindingPermissionPolicy (K.25 share-link gating)
§25 Group N consumer surfaces — legal-corpus-aware
RecentActivityRollup consumer (consume Artifact 1 §16.2 canonical;
do NOT redefine)
§26 Worked Examples Appendix (3 examples: PACER bundle FilingUnit
normalization, RulingDisposition multi-defendant, FilingUnitVersion
supersession)
§27 Landing Matrix entries authored by Artifact 2 (74 entries)
```
### Drafting notes (`[V1.6 DRAFTING NOTE]` markers)
```text
1. §1.2 INV-O-TAXONOMY-1 — dedicated OP-A row not yet created;
covered by group rows. Tier B Q-3-A2-INV-O-TAXONOMY-OP-A.
2. §6.3 Pattern library anchoring lifecycle deferred to V1.7+
(Q-3-A2-PATTERN-ANCHOR).
```
### Items surfaced during drafting that need adjudicator review
```text
Q-3-A2-1 — FilingUnit vs FilingUnitVersion supersession ambiguity
Where: §26.3 Worked Example 3.
Question: When court issues new docket_entry_no for corrected
brief vs amends existing docket_entry_no — V1.6 model
handles both via either (a) NEW FilingUnit +
supersedes_filing edge OR (b) NEW FilingUnitVersion on
same FilingUnit. Resolution depends on canonical key
change.
Proposed: Confirmed in §11.5 INV-O-FILING-UNIT-CANONICAL-1 and
§12 FilingUnitVersion. Per V4: (a) for different docket
entry; (b) for same docket entry. Step 9 cross-artifact
audit verifies edge cases.
Q-3-A2-2 — INV-O-TAXONOMY-1 dedicated OP-A row
Where: §1.2.
Question: Should V3.8.1 add dedicated row for INV-O-TAXONOMY-1 or
cover via OBL-D73-O-FILINGUNIT-01?
Proposed: Cover via group row; tracked for Step 9 architect decision.
Q-3-A2-3 — CSA R2 file availability for direct consumption
[R0.4 PATCH per CSA extraction 2026-05-04: MOOT — DOC73 V1.6
no longer absorbs CSA R2; CSA stays in DOC72. This question
originally asked whether Artifact 2 needed direct CSA R2
reference. Post-extraction, the question does not apply:
Artifact 2 §25 consumes Artifact 1 §16.2 RecentActivityRollup
(DOC73-owned), not CSA R2. Question preserved as historical
record per closed BUILD_QUESTIONS discipline.]
Where: §25.
Question: CSA_R2.md not in build folder; per prompt "REQUIRED —
Artifact 2 cannot proceed without CSA R2 in folder."
Artifact 1 §16 Mechanism 4 absorbs CSA R2 contracts;
does Artifact 2 need direct CSA R2 reference?
Proposed: Artifact 2 §25 consumes Artifact 1 §16.2 RecentActivityRollup
canonical schema; Artifact 1 absorbs CSA R2 per
OBL-D72-CSA-R2-DOC73-ALIGN-01. Direct CSA R2 reference
not required; Artifact 1 mediates.
Q-3-A2-4 — Source Bindings V1.1 file availability
Where: §17-§24.
Question: Source_Bindings_V1_1.md not in build folder; per prompt
"Source Bindings V1.1 spec." V4 §3.6 Stage 5 [INSERT]
consolidation is the canonical Group K spec. Does
Artifact 2 need separate V1.1 file?
Proposed: V4 §3.6 consolidation is canonical; Artifact 2 §17-§24
specifies the schema layer derived from V4 consolidation.
Original V1 proposal (DOC73_CORPUS_SOURCE_BINDINGS_PROPOSAL_V1)
in folder is V1 base; V4 consolidation is the V1.1
equivalent.
Q-3-A2-5 — PartyRef / ClaimRef / CaseRef forward-declared types
Where: §11.2 + §13.2 + §11.3.
Question: Several ref types (PartyRef, ClaimRef, CaseRef) are
forward-declared without canonical home. Should they be
added to Artifact 1 §A appendix?
Proposed: Add to Artifact 1 §A appendix in R0.4 (cross-artifact
patch); for now reference inline. Tier B Q-3-A2-REF-TYPES.
Q-3-A2-6 — Pattern library anchoring lifecycle V1.7+ deferral
Where: §6.3.
Question: Pattern library entries lack "anchored" state in V1.6.
Topics have anchoring (per §5.3 INV-J-TOPIC-MERGE-1);
should patterns also?
Proposed: V1.6 ships without; V1.7+ adds. Tracked
Q-3-A2-PATTERN-ANCHOR.
Q-3-A2-7 — INV-K-HEALTH-1 engagement formula
Where: §23.4.
Question: V1.6 default thresholds inlined; engagement formula
deferred to Step 9 cross-artifact audit per
AUDIT_DOC73_Artifact4_R0.1.md MED-A4-9. Confirm.
Proposed: Confirmed; Step 9 reconciles formula across Artifact 4
(read-time consumer) + Artifact 2 (schema canonical).
```
### V4 PATCH coverage in Artifact 2 R0.1
```text
Group J:
V3-J-1 CorpusProfile node_kind FIX ✓ §3
V3-J-2 LegalMetadataFieldValue + field_lock ✓ §4
V3-J-3 TopicVisibilityPolicy ✓ §5
V3-J-4 J.5 minimum filter UI promoted V1.6 ✓ §7.1
V3-J-5 topic_dedup_threshold defaults vs override ✓ §8.1
V3-J-6 source_span_unavailable rename ✓ §8.2
V4-J-1 host_authored_neutral default NOT shareable ✓ §5.2
V4-J-2 J.5 provenance/review_state/source_visibility filters ✓ §7.2
V4-J-3 PatternLibraryVisibility ✓ §6
V4-J-4 INV-J-TOPIC-MERGE-1 + INV-J-TOPIC-DEDUP-1
(legal ≥0.93) ✓ §5.3-§5.4
V4-J-FORK CorpusProfileFork + ForkRelationshipEdge ✓ §9
V4-J-3.5-K-3.6 8-value LegalProfileKind unified ✓ §18.5
Group O:
V3-O-1 Owner split DOC25 / DOC73 / DOC72 ✓ §1.1 + §10
V3-O-2 FilingUnitIdentity expanded ✓ §11.2
V3-O-3 INV-J.11-* renamed to INV-O-* ✓ adopted
throughout
V3-O-4 StructuredExtractionStrategy ✓ §16.5
V3-O-5 RulingDisposition array ✓ §13.2
V3-O-6 FilingUnitVersion ✓ §12.1
V3-O-7 INV-O-VERSION-1 ✓ §12.4
V3-O-8 CourtDispositionObservation ✓ §14.1
V3-O-9 CompletableUnit deferred consumed (V1.8+)
V3-O-10 Unmatched relationship expiration ✓ §15.4-§15.5
V3-O-11 INV-O-TAXONOMY-1 ✓ §1.2
V3-O-12 INV-O-CITATION-1 ✓ §16.1
V3-O-13 LegalEvidencePosture ✓ §16.2
V4-O-1 entity_subtype split ✓ §1.2 + §10.1
V4-O-2 FilingUnitVersion + FilingUnitTextVersion split ✓ §12
V4-O-3 ResolvedCaseIdentity ✓ §11.3
V4-O-4 RulingDisposition mandatory scope_targets ✓ §13.2
V4-O-5 RulingDispositionPolarity ✓ §13.2
V4-O-6 Citation display rule ✓ §16.1
V4-O-7 MaterializationState 6-value (consumer) consumed
(Artifact 5 §5)
V4-O-8 CourtDispositionObservation lifecycle ✓ §14.2
V4-O-VERSION-COST cross-version sharing consumed
(Artifact 5 §6.5)
Group K:
V3-K-1 Structural selectors only ✓ §19
V3-K-2 Content-type ownership 3-field split ✓ §18.6
V3-K-3 BindingTargetKind / BindingOutcomeRecord ✓ §17.3-§17.4
V3-K-4 Membership state ≠ extraction state ✓ §20
V3-K-5 Membership state machine ✓ §20
V3-K-6 Backfill: support required, execution preview-first ✓ §22.2-§22.3
V3-K-7 K.34 access-scope-refs ✓ §21.1
V3-K-8 BatchReviewOperation per-item ✓ §23.2
V3-K-9 BoundSourceIngestionBatch with counts ✓ §23.1
V3-K-10 Corpus eviction Group A integration ✓ §23.3
V3-K-11 Predicate failure error policy → V1.7 ✓ §19.3
V4-K-1 filing_unit_kind orthogonal axes split ✓ §18
V4-K-2 selector_phase_available ✓ §19.2
V4-K-3 Membership state machine full ✓ §20.3
V4-K-4 ContentHashRef typed schema ✓ §20.4
V4-K-5 INV-K-OUTCOME-1 ✓ §21.5
V4-K-6 size_band defer to V1.7 ✓ §19.1
V4-K-7 BindingGenerationSnapshot ✓ §22.1
V4-K-INV-DEDUP-3 ✓ §21.4
V4-K-MANIFEST-DURABLE consumed
(Artifact 3 §15.2)
V4-K-MISC SemanticConflictPolicy default resolution ✓ §21.6
V4-K-FANOUT consumed
(Artifact 3 §14.1)
V4-K-CAPACITY capacity_priority ✓ §17.2
V4-K-PARTIAL ✓ §23.2
Cross-cutting:
INV-V16-TIMEZONE-1 consumed
throughout
INV-V16-NO-LOCAL-SCHEMA-1 followed
throughout
INV-V16-RETENTION-DURABLE-1 consumed
for legal-evidence
receipts
INV-V16-STORAGE-GRANULARITY-1 consumed
Group N (consumer):
V4-§0.4-2 Mechanism 4 reclassified to Artifact 1 consumed (§25)
V4-N-1 producer/consumer split consumed
V3-N-2 RecentActivityRollup canonical consumed
(Artifact 1 §16.2)
V3-N-3 receipt-wrapping resolution consumed
[R0.4 PATCH per
CSA extraction: "CSA
continuity log
resolution" framing
removed; underlying
receipt-wrapping
invariant preserved]
V3-N-5 Freshness ownership consumed
V3-N-6/7/8 not-evidence invariants consumed (§25)
[R0.4 PATCH per
CSA extraction:
"orientation-only"
→ "not-evidence"
reframe per INV-N-
NOT-EVIDENCE-1]
```
### Landing Matrix entries authored
```text
Group J (Brief Bank): 15 entries (Row A2.1 - A2.15)
Group O (Legal Filing): 28 entries (Row A2.16 - A2.43)
Group K (Source Bindings): 28 entries (Row A2.44 - A2.71)
Group N (consumer): 1 entry (Row A2.72)
Cross-cutting: 2 entries (Row A2.73 - A2.74)
Total Artifact 2 Landing Matrix entries: 74
```
### Cross-references to other artifacts
```text
Artifact 1 (Core) consumed by Artifact 2:
§A.4 — (reserved per Artifact 1 R0.5 CSA extraction; OrientationContextEntry
removed) [R0.4 PATCH per CSA extraction]
§A.5 — WorkPhaseEntry / CorpusActivityEntry / CaseActivityEntry /
ArtifactEntry / UnresolvedThreadEntry (consumed at §25 — now
directly enumerated per R0.4 CSA extraction; previously routed
through OrientationContextEntry wrapper)
§A.6 — QueryIntent enum
§A.7 — CapabilityRef / EdgeTypeRef / TopicDirective
§A.8 — PromptInjectionRiskFlags (consumed at §16.5)
§A.9 — ContentHashRef (V4-K-4 typed schema; consumed at §20.4)
§A.11 — RecordedModelOutput (consumed at §16.5 +
INV-MVC-CU-1 enforcement)
§8.2 — ConsolidatedUnderstanding (consumed at §13 + §15
for source_spans citation)
§10 — VersionedClaim trait (consumed for legal claim carve-outs)
§13.1 — VisibilityClass lattice (consumed throughout for
FilingUnit / FilingRelationship visibility)
§16.2 — RecentActivityRollup canonical (consumed at §25;
Mechanism 4 owner)
§19 — V16 cross-cutting INVs
Artifact 3 (EC + DOC73 Transaction Kernel) referenced by Artifact 2:
§3.3 — SemanticVerb taxonomy (consumed for filing-entity
create / merge / split / supersede operations)
§4.3 — KernelEffect runtime per effect_kind (filing_unit_write,
filing_unit_version_write, filing_unit_text_version_write,
court_disposition_observation_write, ruling_disposition_write,
filing_relationship_write, topic_assignment_write,
anchor_node_promotion, membership_state_transition,
binding_generation_advance, case_resolution_event_write)
§7 — INV-A-TAINT-INFECTIOUS-1 (consumed for FilingRelationship
edge visibility inference)
§9 — INV-MVC-CU-1 (consumed at §13.5 RulingDisposition citation)
§10 — INV-MVC-3 (consumed at §16.5 extraction strategy)
§12 — Group B2 write-time access overlay enforcement
§13.5 — BindingTargetKind dispatch
§13.6 — INV-K-OUTCOME-1 canonical home (cited at §21.5)
§14 — Group K runtime governance (BindingResourcePolicy
consumer)
§15 — BindingEvaluationManifest (durable per
INV-K-MANIFEST-DURABLE-1)
§19 — INV-A-BRIDGE-1 + parallel ingestion conflict resolution
Artifact 4 (DOC24 + EC Session & Search Runtime) referenced by Artifact 2:
§4 — SharedCorpusView (consumed at §5 for share-link visibility)
§12 — SearchScope + RetrievalPosture (consumed for J.5 filter UI
translation to search router)
§15.4 — INV-M-ACCESS-RANK-1 (consumed at §16.4 dedup post-access)
§15.5 — INV-M-VERSION-AWARE-1 (consumed at §12.4 + §26.3)
§17.2 — BindingOutcomeRecord read API (consumer side)
§17.3 — CorpusBindingContribution ledger reads (binding health)
§18 — [R0.4 PATCH per CSA extraction: CSAInjectionTierPolicy removed
from Artifact 4 R0.4 §18; consumer-side session-orientation
orchestration deferred to DOC72. §25 no longer consumes
CSAInjectionTierPolicy.]
Artifact 5 (DOC25) referenced by Artifact 2:
§2.2 — SourceArtifact (consumed for FilingUnit↔SourceArtifact
mapping)
§3 — ArtifactSegment (consumed for FilingPart segmentation)
§3.5 — INV-O-EXTRACTION-FILING-UNIT-SCOPED-1 (consumed at §16.6)
§4 — ECF header parser output (consumed at §11)
§4.1 — INV-K-METADATA-AUTHORITY-1 (consumed at §4.2 field_lock
source_authoritative)
§5 — MaterializationState V4-O-7 (consumed for delivery
affordances)
§6 — Extraction pipeline (consumed at §16.5 StructuredExtractionStrategy
runtime)
§6.5 — Cross-version sharing (consumed at §12.4 INV-O-VERSION-1
implementation note)
§7 — ExtractionStateMachine canonical (consumed for
extraction_run_id linkage)
§13 — DocumentArtifactVersionChangedEvent (consumed for
stale-memory gate triggers)
```
### Drafting metrics
```text
Total lines (R0.1): ~5,200 lines (target 4,000-5,500;
within range)
Sections produced: 27 substantive sections + Drafting
Summary
Worked examples: 3 (PACER bundle FilingUnit
normalization, RulingDisposition
multi-defendant, FilingUnitVersion
supersession)
[V1.6 DRAFTING NOTE] markers: 2
Tier B questions raised (Q-3-A2-*): 7
V4 patches addressed: ~50 distinct V4 patches (Group J +
Group O + Group K + Group N consumer
+ cross-cutting)
Landing Matrix entries authored: 74
Cross-artifact references: 4 (Artifacts 1, 3, 4, 5)
```
### Status
Artifact 2 R0.1 is COMPLETE for Step 7 output. Step 8 audit follows; Step 9 cross-artifact audit will reconcile [V1.6 DRAFTING NOTE] markers + Q-3-A2-* questions across the full V1.6 release wave.
**End of DOC73 V1.6 Artifact 2 R0.1.**