ELNOR REPO READER TEXT MIRROR Original path: Current Specs/DOC73/DOC73_Artifact2_R0.4.md Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- # 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["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 = { // 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 ): 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 on ." - 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: ." 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["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 updated to ; fork pinned to ; review available at "). 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 updated; fork pinned to ; 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>; // 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; // 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 by "). 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: 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; // 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; 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; 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: 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: 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: 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.**