ELNOR REPO READER TEXT MIRROR Original path: Active Working and Red Team/DOC23 Working/DOC23 Red Teaming/Add B Adj Card Review 5.29/DOC23_Addenda_B_Red_Team_Deep_Review_Consolidated_Report.md Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- # DOC23 Addenda B — Consolidated Deep Red-Team Review and Spec-Inclusion Package **Prepared for:** Will / ELNOR architecture review **Subject:** DOC23 Addenda B red-team adjudication card, follow-up deep passes, math/formula audit, and final spec-inclusion package **Status:** Review synthesis and proposed amendment package. This is not an accepted operative spec until Will approves and it is folded into the appropriate files. --- ## 0. Source Pack and Scope This document consolidates the full round of review responses addressing the DOC23 Addenda B red-team adjudication card. It incorporates: - The review request prompt for the consolidated adjudication card. - The attached adjudication card: `DOC23_ADDENDA_B_RT_ADJUDICATION_CARD_CONSOLIDATED.md`. - Current project carryover context for the ELNOR repo and DOC23 Addenda B operating context. - The current Addenda B family topology reviewed during the round: Core R0.7.1, Outcome Evaluator/Revisor V3.3.1, Evaluation Common Contracts V1.1.1, Source Workspace V1.0.1, Task Forum + Run Board V1.0.1, Feedback Delivery V1.0.1, plus the DOC23 R3.1/R3.1.1 task-system context. The review did **not** write to the GitHub repo. All schemas and section anchors below are proposed amendment content. --- ## 1. Executive Top-Line The adjudication card is directionally strong and catches many real defects, but it does **not** yet hold together as a build-ready patch package. The main reason is that many proposed fixes add new schemas without enough lifecycle, derivation, invalidation, source-of-truth, or command-registration discipline. The deepest recurring bug is that the proposed system often stores derived truth as if it were canonical truth: `passed`, support status, reliability status, task health, budget-quality impact, finding lifecycle, and reliance status all need derivation records and invalidation rules. The biggest corrections are: 1. **A-01 must be implemented as one canonical immutable `EvaluationFindingEvent` plus a mutable `EvaluationFindingRecord` projection.** A single mutable mega-record will corrupt replay and audit. 2. **Pattern C needs an explicit `EvaluationChainResolutionReceipt`.** “Consumer policy” is not enough for audit or control flow. 3. **B-24 needs a full sufficiency detector.** The card’s four triggers are incomplete, and routing every insufficiency to a Hard Call is wrong. 4. **C-01 cannot stop at a Formula Registry.** It needs `FormulaEvaluationReceipt`, `MetricObservation`, `MetricRollup`, finite-number policy, zero-denominator policy, sample/censoring policy, and test vectors. 5. **B-25 is a false positive against live V3.3.1.** The live step base already has `depends_on_step_ids`; the real issue is duplicate dependency representations and dependency-edge drift. 6. **The Professional Reliance Layer should be kept, but only as a derived/read-model layer over canonical receipts, snapshots, and formula derivations.** It must not become another truth store. The single most likely implementation failure is a coding agent building locally plausible pieces that do not share source-of-truth semantics. The fix package should therefore be applied in phases: shared contracts first, math/derivation second, runtime state machines third, source/forum/feedback governance fourth, reliance/UI surfaces fifth, and conformance fixtures last. --- ## 2. Master Decision Table This table captures the consolidated position from the full review round. Rows not expanded in later sections should remain as card-accepted unless they are affected by a merge or source-of-truth rewrite. | ID | Final view | Summary | |---|---|---| | A-01 | Accept with major rewrite | Collapse the two finding schemas, but use immutable event + current projection, not a mutable mega-record. | | A-02 | Accept, modify | Move `evaluated_target` and `evaluation_basis` into `EvaluationResultEnvelope`; bundle fields become projections. | | A-03 | Accept, harden | Add chain registry with participant roles, expected producers, timeout/partial state, and resolution receipt. | | A-04 | Accept, harden | Add explicit route-resolution policy and emitted `EvaluationChainResolutionReceipt`. | | A-05 | Accept, rewrite | Do not collapse blocker authority to a boolean; add typed `BlockingAuthorityEvaluation`. | | A-06 | Accept, modify | Split runtime states from emitted dispositions; add/normalize `max_iterations_reached`; use one state matrix. | | A-07 | Accept | Replace boolean pass with verdict/status taxonomy and define indeterminate causes/limitations. | | A-08 | Merge with B-23 | Routing completeness and multi-fire/idempotency are one `FeedbackRoutingResolutionPolicy`. | | A-09 | Accept, modify | TypeOwnerRegistry is right; do not delete positive observations unless replaced by a positive observation surface. | | A-10 | Accept, modify | Move wrapper to Common; avoid Addenda-B-specific `overall_state` for all producers. | | A-11 | Cut as written / already present | Live V3.3.1 already defines `LearningMode`; use `production | signal_generation | calibration`, not `cross_calibration`. | | A-12 | Accept | Define human feedback event with governance fields. | | A-13 | Accept | One canonical learning-signal envelope in Common; Core imports it. | | A-14 | Accept | TypeOwnerRegistry fixes owner drift; Pattern C qualitative-slice missing should be error. | | A-15 | Accept, modify | Build-ready claim must be gated on owner registry, cross-doc insert absorption, command registry, and degraded behavior. | | A-16 | Accept / critical | Meaning-bearing repair must execute only through `revision_in` or revision-compatible declared port. | | A-17 | Accept | Revisor is planner, not mutation target; it should not declare `revision_in`. | | A-18 | Accept | Bundle emission must have matrix and absence reasons. | | A-19 | Accept | `proposed` finding needs negative exit to dismissed. | | A-20 | Accept | Add explicit unanchored-judgment acknowledgment fields. | | A-21 | Accept via A-01 | Artifact-targeted finding needs version ref or absence reason. | | A-22 | Accept | Pending consumers need degraded-mode behavior. | | A-23 | Accept, rewrite | Split jurisdictional authority from legal treatment/adverseness; do not choose precedence between different concepts. | | A-24 | Accept | Fix parallel Judge/Evaluator example to match real topology. | | A-25 | Fold into A-03 | Normalize chain ID naming. | | A-26 | Accept, harden | Define `FindingMatchKey` including stable artifact ID and evidence/source signatures. | | A-27 | Accept | Use workspace-native snapshot hash set, not `Record`. | | B-01 | Accept | Add unified `RevisionExecutionLifecycle`. | | B-02 | Accept, modify | Use existing `RevisionPlanStepKind`; do not add parallel `StepKind`. | | B-03 | Accept, deepen | Workspace writes need operation API, event sequence, preconditions, lock lease, and receipts. | | B-04 | Accept | Rolling-hash same-artifact steps must be sequentialized. | | B-05 | Merge with B-06/B-20 | Revalidation cascade convergence, dependency deadlock, and cascade race are one state-machine problem. | | B-06 | Merge with B-05/B-20 | Use `OutcomeDependencyGraphPolicy` and `RevalidationCascadeRun`. | | B-07 | Accept | Add parallel batch finalization receipt. | | B-08 | Accept, modify | Unify with existing failure enums rather than creating a third taxonomy. | | B-09 | Accept | Split candidate lifecycle from artifact head; model side-effect candidates separately. | | B-10 | Accept, harden | Cancel must be receipt/idempotency-bound and side-effect-aware. | | B-11 | Accept | Add skip protocol and receipts. | | B-12 | Accept | Policy freshness needs fields or EC policy source-of-truth. | | B-13 | Accept | ResearchNeed needs atomic lease. | | B-14 | Accept, modify | Add forum deadlock breaker; remove `task_agent_decides`. | | B-15 | Accept, target DOC12 | Register `plan_review` in DOC12 room-kind registry; Forum consumes it. | | B-16 | Accept, modify | Sort risk ascending or rename to safety score; add deterministic final tie. | | B-17 | Accept | Typed feedback ports should be required for V1; discriminator fallback only if overloaded port remains. | | B-18 | Accept, modify | Closed-choice hard calls need non-empty options; some calls need `freeform_required`. | | B-19 | Accept | Dispatcher emits `hard_call_resolved` receipt. | | B-20 | Merge with B-05/B-06 | Success must wait for cascade quiescence. | | B-21 | Accept | Learning signals emit after referenced receipts persist. | | B-22 | Accept | Pattern C Judge needs independent invocation budget/cadence. | | B-23 | Merge with A-08 | Routing multi-fire requires idempotency policy. | | B-24 | Accept, major rewrite | Full sufficiency detector with coverage, attempts, procedure universe, metrics, and typed terminal route. | | B-25 | Cut as written | Already covered in live V3.3.1; replace with dependency canonicalization/drift row. | | B-26 | Accept | Collapse `revalidation_trigger` / `revalidation_expectation` into one policy object. | | B-27 | Accept | Regenerate must carry previous-attempt hashes and reject identical outputs. | | C-01 | Accept, major harden | Formula Registry plus evaluation receipts, observations, rollups, finite-number policy, and test vectors. | | C-02 | Accept, harden | Split success and waste metrics; add censoring/window policy. | | C-03 | Accept | Remove predicted future hashes from LLM output; Dispatcher computes hashes. | | C-04 | Accept, harden | Add real sub-agent reputation formula and severity-weighted regression. | | C-05 | Accept | Use latency distribution p50/p90/p99 instead of arithmetic mean. | | C-06 | Accept, harden | Add insufficient-sample states and zero-denominator semantics. | | C-07 | Accept, rewrite | Replace scalar cost estimate with multidimensional `CostVector`. | | C-08 | Accept, rewrite | Novelty needs metric spec and discriminated union for no-neighbor case. | | C-09 | Accept, harden | Add task-mode/template formula; fix zero-weight and NaN bugs. | | C-10 | Accept | Rename lexical hash and require semantic-version review. | | D-01 | Accept, harden | Complete source-kind taint map plus trust basis and transitive propagation. | | D-02 | Accept | Workspace taint aggregates by max taint and privilege. | | D-03 | Accept | One canonical Source Workspace identity. | | D-04 | Accept, rewrite | Keep tier 0 as tool-receipt-only; no tier-0 `SourceRecord`. | | D-05 | Accept | ResearchNeed scope, lease, refs, and `human_needed` exit. | | D-06 | Accept, harden | Evidence anchors, payload registry, extractor-vs-source distinction; support-status derivation. | | D-07 | Merge with D-09/D-12/D-24 | Board governance envelope, publication, retention, matter firewall. | | D-08 | Accept, harden | Context packet request/receipt/omission manifest plus read-model invalidation. | | D-09 | Merge with D-07/D-12/D-24 | Record all audit events privately; publish selectively. | | D-10 | Accept, harden | Assistance request needs endpoint/lease/timeout/answer schema; moderator fallback cannot let Task Agent decide substance. | | D-11 | Accept | Board digest needs selection policy. | | D-12 | Merge with D-07/D-09/D-24 | Run Board retention/compaction/event-class governance. | | D-13 | Accept, harden | RunGuidance persists via event/projection, lifecycle, contested filter, and cross-run selection path. | | D-14 | Accept, harden | Command registry must be mandatory for every action/surface. | | D-15 | Accept, harden | Sub-agent output contracts plural; fallback per coordination point; plan verifier policy. | | D-16 | Merge with B-03 | Source Workspace API operations need schemas and receipts. | | D-17 | Accept | Anchor/hash hygiene and non-empty structured anchors. | | D-18 | Accept | Repeated-failure detection uses stable artifact ID, not versioned refs. | | D-19 | Accept, update to CostVector | Per-module source-acquisition cost uses `CostVector`, not old `CostEstimate`. | | D-20 | Accept, modify | Split library-promotion candidate queue from durable library write. | | D-21 | Accept | Split overloaded `requires_background_progress`. | | D-22 | Accept | Stable anchors and softened backward-compat claim. | | D-23 | Accept | Dispatch expectations make “silent ignoring” enforceable. | | D-24 | Merge with D-07/D-09/D-12 | Matter firewall precedes visibility scope. | | G-01 | Keep, harden | EvaluationContractReview is coherent; add lifecycle and command linkage. | | G-02 | Keep, rewrite | RevisionReviewPacket should not store current reviewer action; actions are receipts. | | G-03 | Keep, harden | EvidencePackage needs support derivation receipts. | | G-04 | Keep, replace | Replace thin `KnownGoodState` with `KnownGoodCheckpoint`. | | G-05 | Keep, harden | BudgetNarrative consumes cost vectors and forecast-vs-actual reconciliation. | | G-06 | Keep, rewrite | TaskReliancePacket is derived from input manifest and invalidated by changes. | | G-07 | Keep, harden | AttentionLedger is read model plus command registry. | | G-08 | Keep | TaskHealthCard is a derived surface, no new truth. | | G-09 | Keep | Cost forecast needs pre-run `TaskRunCostForecast`. | | G-10 | Keep | Reviewability should unify over findings, revision packets, and audit view. | | G-11 | Keep | Contestability must be surfaced proactively. | | G-12 | Keep | WorkProductCertification renders TaskReliancePacket; no new truth. | | G-13 | Keep | FindingsInbox is read model over canonical findings and matter scope. | | G-14 | Keep | RunDiff reads run records, cost vectors, reliance/read models. | | G-15 | Keep | DecisionAuditView reads chain resolutions, policy decisions, receipts. | | G-16 | Keep | RunReplayPreview uses TaskReplay modes and side-effect ledger. | | G-17 | Keep | TaskRunFork + irreversible side-effect ledger is correct replacement for ShadowWorkspace. | | G-18 | Keep, harden | ExplanationTrace must be user-visible rationale only, no hidden chain-of-thought capture. | | G-19 | Keep, rewrite | Do not promise deterministic replay; define replay modes and divergence receipts. | | G-20 | Keep | Unified Evaluation Chain view renders chain registry/resolution. | | G-21 | Keep | Chaos/concurrency/math/reliance fixtures should gate the amendment package. | --- ## 3. Cross-Cutting Invariants for the Amendment Package ### 3.1 Immutable event vs mutable projection A recurring defect in the card is that the same record is treated as both immutable evidence and mutable live state. This breaks audit and replay. The fix is a set-wide event/projection pattern. ```ts type CanonicalEventRef = StorageRef; type ProjectionRef = StorageRef; interface EventProjectionLink { canonical_event_ref: CanonicalEventRef; current_projection_ref: ProjectionRef; projection_event_seq: number; projection_valid_at: ISO8601; schema_version: "1.0"; } // Examples of required splits: // EvaluationFindingEvent -> EvaluationFindingRecord // RunGuidanceCreationEvent -> RunGuidanceItemCurrent // RunBoardAuditEvent -> RunBoardVisiblePost // SourceWorkspaceOperation -> SourceWorkspaceCurrentState // RevisionReviewPacket -> RevisionReviewDecisionReceipt / current review state // TaskReliancePacket -> RelianceInvalidationEvent / current certification view ``` Required validation: ```ts validation.mutable_state_inside_immutable_snapshot validation.current_projection_without_source_event validation.projection_event_seq_out_of_date validation.lifecycle_transition_without_receipt ``` ### 3.2 Derived read models cannot create new truth Every UI/read-model surface introduced by §G or DOC20/DOC21/DOC22 must be a projection over canonical receipts, snapshots, events, formulas, and policy decisions. ```ts interface DerivedReadModelRecord { read_model_id: string; read_model_kind: | "TaskReliancePacket" | "TaskHealthCard" | "FindingsInbox" | "WorkProductCertification" | "RunDiff" | "DecisionAuditView" | "EvidencePackage" | "EvaluationChainView" | "AttentionLedger" | "BudgetNarrative"; input_manifest_ref: StorageRef; derivation_policy_ref: StorageRef; formula_eval_receipt_refs: StorageRef[]; valid_from_event_seq: number; valid_until_event_seq?: number; invalidated_by_event_ref?: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface ReadModelInvalidationSpec { producer_event_kind: string; invalidates_read_models: DerivedReadModelRecord["read_model_kind"][]; invalidation_scope: "same_run" | "same_task" | "same_matter" | "specific_refs"; target_refs?: StorageRef[]; schema_version: "1.0"; } ``` Required validation: ```ts validation.read_model_without_input_manifest validation.lifecycle_event_without_read_model_invalidation validation.context_packet_valid_after_invalidation_event validation.read_model_asserts_unbacked_truth ``` ### 3.3 Formula outputs require derivation receipts Any score, status, pass/fail boolean, reputation, cost rollup, quality index, claim-support label, or reliance status must be backed by a formula/derivation receipt. ```ts interface FormulaEvaluationReceipt { receipt_id: string; formula_id: string; formula_semantic_version: string; producer_ref: string; task_id?: string; run_id?: string; input_refs: StorageRef[]; input_manifest_hash: string; input_value_hash: string; output_ref: StorageRef; output_value_hash: string; omitted_input_names: string[]; missing_input_policy_applied?: MissingInputPolicy; zero_denominator_policy_applied?: ZeroDenominatorPolicy; finite_number_check: | "passed" | "failed_nan" | "failed_infinity" | "coerced_to_indeterminate"; validation_codes: string[]; computed_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.metric_without_formula_spec validation.metric_value_without_formula_receipt validation.formula_output_nan_or_infinity validation.derived_boolean_without_formula_receipt validation.derived_enum_without_derivation_receipt ``` ### 3.4 Externalization and provider calls are side effects Source Research and Source Workspace expose actions that can leave the system: web/API/database queries, browser opens, native opens, Finder reveals, Save As, Export, email source fetches, and connector reads. These must not sit outside the side-effect discipline. ```ts type WorkspaceExternalizationKind = | "open_in_browser" | "open_native_app" | "show_in_finder" | "save_as" | "export_bundle" | "external_source_query" | "connector_fetch" | "api_call" | "email_source_fetch" | "browser_session_read"; interface WorkspaceExternalizationPolicy { policy_id: string; externalization_kind: WorkspaceExternalizationKind; requires_user_confirmation: boolean; requires_redaction_preview: boolean; allowed_data_classes: Array<"public" | "internal" | "privileged" | "local_only">; allowed_taint_classes: TaintClass[]; max_cost_vector_ref?: StorageRef; provider_logging_warning_required: boolean; receipt_required: true; replay_policy: ReplayPolicy; warning_text: string; schema_version: "1.0"; } interface WorkspaceExternalizationReceipt { receipt_id: string; externalization_kind: WorkspaceExternalizationKind; workspace_id: string; source_record_refs: SourceRecordRef[]; destination_ref?: StorageRef; policy_ref: string; user_confirmation_ref?: StorageRef; redaction_preview_ref?: StorageRef; cost_vector_ref?: StorageRef; status: "completed" | "blocked_by_policy" | "cancelled" | "failed"; irreversible_disclosure_possible: boolean; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.workspace_externalization_without_policy validation.privileged_workspace_export_without_confirmation validation.external_source_query_without_receipt validation.externalization_cost_cap_missing ``` --- ## 4. §A — Cross-Document Contract and Schema Fixes ### A-01 / A-05 — Canonical EvaluationFinding **Final decision:** unify the two incompatible schemas, but not into one mutable mega-record. Use one canonical immutable finding event and one current-state projection. FD gets a thin display/routing view. #### Spec insertion — Common Contracts §4.2A ```ts type FindingState = | "proposed" | "active" | "contested" | "resolved" | "superseded_by_revision" | "superseded_by_source_change" | "expired" | "user_approved" | "tool_verified" | "human_verified" | "rejected_by_user" | "dismissed" | "unrecoverable"; type BlockingAuthorityBasis = | "deterministic_check" | "source_reference" | "tool_verification" | "rubric_criterion" | "user_instruction" | "saved_criteria" | "human_label" | "multi_reviewer_consensus" | "subjective_blocking_allowed"; type SubjectiveBlockingPermission = | "not_allowed" | "allowed_by_outcome_definition" | "allowed_by_user_instruction" | "allowed_by_human_review"; interface BlockingAuthorityEvaluation { satisfied: boolean; basis: BlockingAuthorityBasis[]; subjective_blocking_permission: SubjectiveBlockingPermission; evaluated_policy_ref?: PolicyEvaluationRef; explanation: string; schema_version: "1.0"; } interface FindingMatchKey { failure_kind: FailureKind; artifact_stable_id?: string; target_scope_ref: ArtifactScopeRef | null; criterion_id?: string; finding_summary_hash: string; normalized_finding_text_hash: string; evidence_signature_hash?: string; source_workspace_snapshot_hash?: string; schema_version: "1.0"; } interface EvaluationFindingEvent { finding_event_id: string; // fndevt-{ulid} finding_id: string; // stable logical finding identity result_id: string; producer_kind: ProducerKind; producer_module_id: string; producer_activation_seq: number; finding_kind: FindingKind; finding_text: string; explanation: string; severity: "low" | "medium" | "high" | "blocking"; emitted_state: "proposed" | "active"; assurance_basis: AssuranceBasis[]; blocking_authority: BlockingAuthorityEvaluation; confidence_score: number; // 0..1 confidence_basis: ConfidenceBasis[]; confidence_explanation: string; target_artifact_ref?: StorageRef; target_artifact_version_ref?: StorageRef; target_scope_ref?: ArtifactScopeRef; target_criterion_id?: string; affected_claim_refs: ClaimRef[]; evidence_refs: StorageRef[]; verification_record_refs: StorageRef[]; supporting_material_snapshot_refs: StorageRef[]; based_on_artifact_version_ref?: StorageRef; based_on_artifact_version_absent_reason?: | "non_artifact_target" | "human_review_no_artifact" | "process_observation"; based_on_source_workspace_snapshot_ref?: StorageRef; based_on_board_digest_ref?: StorageRef; evaluation_snapshot_ref: StorageRef; match_key: FindingMatchKey; taint_class: TaintClass; data_class: "public" | "internal" | "privileged" | "local_only"; matter_id?: string; privileged: boolean; policy_decision_refs: PolicyEvaluationRef[]; created_at: ISO8601; schema_version: "2.0"; } interface EvaluationFindingRecord { finding_id: string; canonical_event_ref: StorageRef; // EvaluationFindingEvent current_state: FindingState; current_severity: "low" | "medium" | "high" | "blocking"; lifecycle_transition_refs: StorageRef[]; // FindingLifecycleTransitionReceipt[] superseded_by_finding_id?: string; expires_at?: ISO8601; last_validated_against_artifact_version_ref?: StorageRef; last_validated_against_source_workspace_snapshot_ref?: StorageRef; updated_at: ISO8601; schema_version: "1.0"; } interface FindingLifecycleTransitionReceipt { receipt_id: string; finding_id: string; from_state: FindingState; to_state: FindingState; transition_reason: | "router_admitted" | "user_contested" | "user_confirmed" | "tool_verified" | "revision_resolved" | "source_changed" | "target_version_changed" | "expired_by_policy" | "dismissed_duplicate" | "rejected_by_user" | "marked_unrecoverable"; actor_ref: string; evidence_refs: StorageRef[]; created_at: ISO8601; schema_version: "1.0"; } interface FeedbackFindingView { finding_id: string; source_finding_event_ref: StorageRef; current_finding_record_ref: StorageRef; display_summary: string; display_explanation: string; finding_kind: FindingKind; severity: "low" | "medium" | "high" | "blocking"; lifecycle_state: FindingState; blocking_authority_satisfied: boolean; blocking_authority_basis: BlockingAuthorityBasis[]; routed_action_refs: StorageRef[]; schema_version: "1.1"; } ``` Required lints: ```ts validation.finding_state_mutated_inside_immutable_envelope validation.finding_current_projection_without_event validation.blocking_finding_without_authority validation.model_judgment_only_blocker_without_permission validation.feedback_finding_view_authority_drift validation.progress_signal_match_key_drift validation.artifact_targeted_finding_missing_version_ref ``` ### A-02 / A-03 / A-04 / A-25 — Pattern C envelope and chain resolution **Issue:** Pattern C currently depends on fields living in the feedback bundle, not the envelope, and route conflict resolution is left to vague consumer policy. #### Spec insertion — Common Contracts §3 ```ts interface EvaluationResultEnvelope { // existing fields retained unless superseded result_id: string; producer_kind: ProducerKind; outcome_id: string; run_id: string; evaluated_target: EvaluatedTarget; evaluation_basis: EvaluationBasis; // migration window only; derived from evaluated_target target_artifact_ref: StorageRef | null; target_artifact_version_ref: StorageRef | null; target_scope_ref: ArtifactScopeRef | null; target_evaluation_chain_id?: string; evaluation_snapshot_ref: StorageRef; route_recommendation: EvaluationRouteRecommendation; schema_version: string; } ``` Required validation: ```ts validation.envelope_target_projection_drift validation.envelope_basis_missing validation.chain_id_name_drift ``` #### Spec insertion — Common Contracts §3.7 ```ts type EvaluationChainKind = | "pattern_c_evaluator_then_judge" | "experiment_internal" | "multi_producer"; type EvaluationChainStatus = | "open" | "partial" | "complete" | "timed_out" | "superseded" | "invalidated"; interface EvaluationChainRegistryRecord { chain_id: string; chain_kind: EvaluationChainKind; task_id: string; run_id: string; target_artifact_ref: StorageRef | null; target_artifact_version_ref: StorageRef | null; target_scope_ref: ArtifactScopeRef | null; evaluation_snapshot_ref: StorageRef; expected_producers: ProducerKind[]; received_result_ids: string[]; participant_roles: Array<{ producer_kind: ProducerKind; producer_module_id: string; role: "upstream_evaluator" | "downstream_judge" | "parallel_scorer" | "observer"; required: boolean; }>; status: EvaluationChainStatus; timeout_at?: ISO8601; created_at: ISO8601; completed_at?: ISO8601; superseded_by_chain_id?: string; validation_failures: Array< | "chain_id_missing" | "chain_target_mismatch" | "chain_stale_snapshot" | "chain_ambiguous" | "chain_consumer_timeout" | "missing_expected_producer" >; schema_version: "1.0"; } interface EvaluationChainResolutionPolicy { policy_id: string; chain_kind: EvaluationChainKind; qualitative_blockers_survive_numeric_pass: boolean; judge_can_override_evaluator: boolean; override_allowed_only_for_finding_states: FindingState[]; route_precedence: | "blocking_qualitative_first" | "judge_quantitative_first" | "human_if_disagreement"; disagreement_route: | "human_review" | "task_agent_assessment" | "block_until_resolved" | "prefer_blocking"; schema_version: "1.0"; } const DEFAULT_PATTERN_C_RESOLUTION_POLICY: EvaluationChainResolutionPolicy = { policy_id: "default.pattern_c.v1", chain_kind: "pattern_c_evaluator_then_judge", qualitative_blockers_survive_numeric_pass: true, judge_can_override_evaluator: false, override_allowed_only_for_finding_states: ["contested", "dismissed", "rejected_by_user"], route_precedence: "blocking_qualitative_first", disagreement_route: "human_review", schema_version: "1.0" }; interface EvaluationChainResolutionReceipt { receipt_id: string; chain_id: string; chain_kind: EvaluationChainKind; result_ids_considered: string[]; resolved_verdict: "passed" | "failed" | "indeterminate" | "not_applicable"; resolved_route: | "pass_path" | "fail_path" | "human_review_path" | "retry_path" | "block_until_resolved"; decisive_result_id?: string; qualitative_blockers_preserved: boolean; quantitative_pass_overridden_by_blocker: boolean; conflict_type?: | "none" | "qualitative_fail_quantitative_pass" | "qualitative_pass_quantitative_fail" | "indeterminate_mismatch" | "missing_expected_producer" | "snapshot_mismatch"; policy_ref: string; explanation: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.pattern_c_chain_id_mismatch validation.pattern_c_chain_without_resolution_receipt validation.pattern_c_route_conflict_unresolved validation.pattern_c_snapshot_mismatch validation.pattern_c_missing_expected_producer ``` ### A-06 / A-07 — outcome state, disposition, verdict, and limitation taxonomy ```ts type OutcomeEvaluationRuntimeState = | "pending" | "pending_dependency" | "evaluating" | "dirty"; type OutcomeEvaluationDisposition = | "satisfied" | "needs_revision" | "needs_information" | "needs_verification" | "needs_human_judgment" | "unable_to_evaluate" | "blocked_by_policy" | "regressed" | "upstream_failure" | "unrecoverable" | "superseded" | "max_iterations_reached"; type OutcomeEvaluationState = OutcomeEvaluationRuntimeState | OutcomeEvaluationDisposition; type EvaluationVerdict = | "passed" | "failed" | "indeterminate" | "not_applicable"; type EvaluationLimitationKind = | "insufficient_evidence" | "human_judgment_needed" | "missing_capability" | "source_unavailable" | "policy_blocked" | "stale_evidence" | "unable_to_ground_claim" | "unchecked_claims_present" | "unreviewed_candidate_revision" | "external_side_effect_unverified"; type IndeterminateCause = | "missing_information" | "missing_source" | "stale_source" | "missing_capability" | "policy_block" | "human_judgment_required" | "conflicting_evidence" | "tool_failure" | "timeout" | "unsupported_scope" | "blocked_before_substantive_verdict"; type SubstantiveVerdictStatus = | "substantive_verdict_reached" | "blocked_before_substantive_verdict" | "partial_substantive_verdict"; interface OutcomeStateMatrixEntry { state: OutcomeEvaluationState; state_class: "runtime" | "disposition"; emitted_to_envelope: boolean; terminal: boolean; verdict_mapping?: EvaluationVerdict; feedback_branch: FeedbackBranch; blocks_downstream_default: boolean; revisor_default_action: | "none" | "revise" | "research" | "verify" | "hard_call" | "abort" | "process_gap"; ui_label: string; learning_eligibility: "eligible" | "diagnostic_only" | "ineligible"; } ``` Required validation: ```ts validation.runtime_state_emitted_to_envelope validation.disposition_without_verdict_mapping validation.indeterminate_without_cause validation.evaluation_decision_boolean_pass_legacy ``` ### A-08 / B-23 — feedback routing resolution and idempotency ```ts type FeedbackBranch = | "on_satisfied" | "on_needs_revision" | "on_needs_more_sources" | "on_needs_source_verification" | "on_needs_human_judgment" | "on_blocked_by_policy" | "on_upstream_failure" | "on_unrecoverable" | "on_repeated_failure" | "none"; type RoutingFirePolicy = | "first_match_only" | "all_matching_with_idempotency"; interface FeedbackRoutingResolutionPolicy { policy_id: string; branch_order: FeedbackBranch[]; branch_handlers: Record; fire_policy: RoutingFirePolicy; duplicate_suppression_window_ms: number; schema_version: "1.0"; } interface FeedbackDeliveryRecord { delivery_id: string; feedback_bundle_id: string; result_id: string; branch: FeedbackBranch; consumer_module_id: string; consumer_activation_seq: number; delivery_idempotency_key: string; // hash(run_id + result_id + branch + consumer) payload_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface FeedbackDispatchExpectation { expectation_id: string; feedback_bundle_id: string; consumer_module_id: string; consumer_activation_seq: number; expected_receipt_kind: "FeedbackConsumptionReceipt"; grace_period_ms: number; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.feedback_branch_missing_handler validation.feedback_branch_unregistered validation.feedback_delivery_duplicate_without_idempotency validation.feedback_consumed_without_receipt validation.feedback_bundle_absence_unexplained ``` ### A-09 / A-15 / A-22 — TypeOwnerRegistry and build-ready gate ```ts type TypeOwnerStatus = | "canonical" | "imported" | "pending_absorption" | "deprecated" | "retired"; type PendingConsumerDegradedBehavior = | "persist_only" | "suppress_promotion" | "disable_ui_affordance" | "emit_validation_warning" | "block_route"; interface TypeOwnerRegistryEntry { type_name: string; canonical_owner_doc: OwnerDoc; canonical_section_anchor: string; status: TypeOwnerStatus; imported_by_docs: OwnerDoc[]; replacement_type_name?: string; pending_consumer_behavior?: PendingConsumerDegradedBehavior; schema_version: "1.0"; } interface BuildReadyGate { gate_id: string; target_doc_family: "DOC23_ADDENDA_B"; required_type_owner_registry_clean: true; required_pending_absorption_rows_closed_or_degraded: true; required_command_registry_entries_complete: true; required_cross_doc_insert_obligations_absorbed_or_stubbed: true; required_validation_suite_refs: StorageRef[]; schema_version: "1.0"; } ``` Rules: ```ts // EvaluationAffirmation should not remain phantom. // If removed, replace the product need with PositiveEvaluationObservation. interface PositiveEvaluationObservation { observation_id: string; result_id: string; outcome_id: string; observed_passed_criterion_ids: string[]; positive_summary: string; evidence_refs: StorageRef[]; formula_eval_receipt_ref?: StorageRef; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.type_owner_drift validation.pending_owner_without_degraded_behavior validation.build_ready_gate_failed validation.phantom_type_reference validation.positive_observation_missing_for_passed_criteria_when_required ``` ### A-11 — LearningMode correction The card’s proposed `cross_calibration` member is wrong. Live V3.3.1 already enumerates the value set; the correct values are: ```ts type LearningMode = | "production" | "signal_generation" | "calibration"; ``` Required validation: ```ts validation.learning_mode_value_drift validation.learning_mode_redeclared_outside_owner ``` ### A-16 / A-17 — direct repair wiring and Revisor planner boundary ```ts interface PortRevisionEligibility { port_id: string; module_id: string; revision_compatible: boolean; // default false module_revision_capability_ref?: StorageRef; // required when true } // Normative rule: // A meaning-bearing OutcomeRepairInstruction may EXECUTE only through: // (a) port_id == "revision_in", or // (b) revision_compatible == true with ModuleRevisionCapability coverage. // All other direct wiring (instruction_in, data_in, context_in) is advisory context only. interface RevisorPlannerInputPorts { feedback_bundle_in: PortRef; repair_instruction_in: PortRef; evaluation_result_in: PortRef; // Revisor must not expose revision_in. } ``` Required validation: ```ts validation.repair_routed_to_non_revision_port validation.revisor_declares_revision_in validation.meaning_bearing_repair_without_revision_capability ``` ### A-18 — feedback-bundle emission discipline ```ts type FeedbackBundleEmissionRule = "always" | "on_failure_only" | "never"; type FeedbackBundleAbsentReason = | "not_emitted_by_design" | "not_applicable" | "policy_filtered"; interface FeedbackEmissionMatrixEntry { producer_kind: "outcome_evaluator" | "judge" | "deterministic_scorer"; verdict: EvaluationVerdict; emits_envelope: boolean; emits_feedback_bundle: FeedbackBundleEmissionRule; } interface EvaluationResultEmissionRecord { result_id: string; envelope_ref: StorageRef; feedback_bundle_ref?: StorageRef; feedback_bundle_absent_reason?: FeedbackBundleAbsentReason; emission_matrix_entry_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.feedback_bundle_absence_unexplained validation.feedback_bundle_emitted_against_matrix validation.envelope_missing_for_result ``` ### A-23 — split jurisdictional authority from legal treatment ```ts type CoreAuthorityLevel = | "binding" | "persuasive" | "advisory" | "unknown"; type LegalTreatmentStatus = | "current" | "negative_treatment" | "overruled" | "limited" | "distinguished" | "adverse" | "unknown"; interface ApplicabilityScope { scope_kind: | "legal_jurisdiction" | "regulatory_domain" | "business_unit" | "technical_platform" | "time_period" | "geography" | "audience" | "matter" | "custom"; scope_value: string; authority_level?: CoreAuthorityLevel; domain_specific_payload?: Record; schema_version: "1.1"; } interface LegalSourcePayload { court?: string; jurisdiction?: string; date?: string; source_authority_level?: CoreAuthorityLevel; treatment_status?: LegalTreatmentStatus; holdings?: string[]; useful_propositions?: string[]; pincite_refs?: StorageRef[]; schema_version: "1.1"; } ``` Required validation: ```ts validation.legal_payload_authority_level_legacy validation.authority_level_projection_drift validation.legal_treatment_status_missing_when_legal_source ``` ### A-26 — progress-signal/finding matching ```ts interface ProgressSignalRecord { signal_id: string; outcome_id: string; run_id: string; current_finding_match_key: FindingMatchKey; previous_finding_match_key?: FindingMatchKey; same_reason_as_previous: boolean; strategy_switch_recommended: boolean; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.progress_signal_match_key_drift validation.repeated_failure_key_missing_artifact_stable_id validation.evidence_signature_hash_missing_for_source_bound_finding ``` ### A-27 — source workspace snapshot hashes ```ts interface SourceWorkspaceSnapshotHashSet { source_workspace_ref: string; source_workspace_head_hash: string; source_record_hashes: Record; source_set_hashes?: Record; research_need_queue_hash?: string; verification_record_hashes?: Record; freshness_record_hashes?: Record; run_guidance_hashes?: Record; schema_version: "1.0"; } interface EvaluationSnapshot { snapshot_id: string; artifact_state_refs: StorageRef[]; source_workspace_state_ref?: StorageRef; source_workspace_snapshot_hashes: SourceWorkspaceSnapshotHashSet[]; policy_snapshot_ref: StorageRef; capability_snapshot_ref: StorageRef; created_at: ISO8601; schema_version: "1.1"; } ``` Required validation: ```ts validation.source_workspace_hash_typed_as_artifact_hash validation.evaluation_snapshot_missing_workspace_hash_set validation.workspace_snapshot_hash_mismatch ``` --- ## 5. §B — Runtime, Concurrency, and Distributed-System Fixes ### B-01 — RevisionExecutionLifecycle ```ts type RevisionExecutionLifecycleState = | "plan_compiled" | "dispatch_pending" | "dispatched" | "step_running" | "step_receipt_received" | "waiting_dependency" | "waiting_hard_call" | "revalidating" | "cascade_running" | "regression_detected" | "terminal_satisfied" | "terminal_failed" | "terminal_blocked" | "cancelled"; interface RevisionExecutionLifecycleTransition { from_state: RevisionExecutionLifecycleState; to_state: RevisionExecutionLifecycleState; triggered_by_receipt_kind: | "RevisionOperationReceipt" | "HardCallResolutionReceipt" | "FeedbackConsumptionReceipt" | "SourceWorkspaceOperationReceipt" | "TaskCancelReceipt" | "TaskSkipReceipt" | "RevalidationCascadeReceipt"; guard_condition?: string; schema_version: "1.0"; } ``` Required validation: ```ts validation.revision_lifecycle_illegal_transition validation.revision_lifecycle_missing_receipt validation.terminal_state_without_terminal_receipt ``` ### B-02 — idempotency using existing RevisionPlanStepKind Do not add a new parallel `StepKind`; use the live `RevisionPlanStepKind`. ```ts interface StepIdempotencyKey { run_id: string; plan_id: string; step_id: string; step_kind: RevisionPlanStepKind; target_ref_hash: string; input_payload_hash: string; // RFC 8785 canonical JSON hash attempt_class: "first" | "retry" | "regenerate"; previous_attempt_hash?: string; schema_version: "1.0"; } function stepIdempotencyKeyString(key: StepIdempotencyKey): string { return sha256(canonicalJson(key)); } ``` Required validation: ```ts validation.step_idempotency_key_missing validation.step_idempotency_kind_unregistered validation.step_idempotency_parallel_enum_drift ``` ### B-03 / D-16 — Source Workspace operation API ```ts type SourceWorkspaceOperationKind = | "read_workspace_snapshot" | "add_source_record" | "update_source_record" | "append_source_query_record" | "update_research_need" | "answer_research_need" | "add_verification_record" | "add_freshness_record" | "mark_source_stale" | "record_tier_transition" | "create_source_set" | "update_source_set" | "promote_library_candidate" | "export_workspace_bundle"; interface SourceWorkspaceMutationPrecondition { workspace_id: string; expected_workspace_head_hash: string; expected_event_seq: number; target_record_ref?: StorageRef; expected_target_record_hash?: string; lock_mode: "optimistic_event_seq" | "pessimistic_write_lock"; lock_lease_ref?: StorageRef; on_conflict: | "abort_and_reevaluate" | "queue_behind_lock" | "fail_outcome"; schema_version: "1.0"; } interface SourceWorkspaceOperation { operation_id: string; operation_kind: SourceWorkspaceOperationKind; task_id: string; run_id?: string; workspace_id: string; actor_ref: string; idempotency_key: string; precondition?: SourceWorkspaceMutationPrecondition; // required for mutation kinds payload_ref?: StorageRef; policy_decision_refs: PolicyEvaluationRef[]; data_class: "public" | "internal" | "privileged" | "local_only"; taint_class: TaintClass; matter_id?: string; privileged: boolean; created_at: ISO8601; schema_version: "1.0"; } interface SourceWorkspaceOperationReceipt { receipt_id: string; operation_id: string; operation_kind: SourceWorkspaceOperationKind; workspace_id: string; prior_workspace_head_hash?: string; new_workspace_head_hash?: string; prior_event_seq?: number; new_event_seq?: number; status: | "applied" | "read_completed" | "conflict" | "rejected_by_policy" | "failed"; conflict_reason?: | "workspace_head_hash_mismatch" | "event_seq_mismatch" | "target_record_hash_mismatch" | "lock_unavailable"; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.workspace_mutation_without_precondition validation.workspace_event_seq_conflict validation.workspace_api_operation_unregistered validation.workspace_receipt_missing_head_hash validation.workspace_read_without_snapshot_receipt ``` ### B-04 / C-03 — rolling-hash and future-hash correction ```ts type MutationMode = "candidate_only" | "rolling_hash_in_place"; interface InPlaceMutationLock { step_id: string; target_section_anchor_hash: string; expected_base_version_id: string; expected_pre_hash: string; // runtime-read at lock acquisition, not LLM-predicted } interface RevisionPlan { plan_id: string; mutation_mode: MutationMode; in_place_mutation_locks?: InPlaceMutationLock[]; steps: RevisionPlanStep[]; // No predicted_post_hash in LLM output contract. } interface RevisionOperationReceipt { receipt_id: string; step_id: string; expected_pre_hash?: string; produced_post_hash?: string; // Dispatcher writes after execution created_at: ISO8601; schema_version: "1.0"; } ``` Rules: ```ts // Rolling-hash mode requires sequential execution across all steps mutating the same artifact. // Parallelism is permitted only across disjoint artifacts or candidate-only steps. ``` Required validation: ```ts validation.revision_plan_contains_predicted_post_hash validation.in_place_lock_missing_expected_pre_hash validation.rolling_hash_parallel_steps_same_artifact validation.rolling_hash_same_artifact_dependency_missing ``` ### B-05 / B-06 / B-20 — cascade convergence and dependency deadlock ```ts interface OutcomeDependencyGraphPolicy { policy_id: string; reject_declared_cycles: boolean; on_cycle_detected: "reject_graph" | "hard_call" | "prefer_declared_priority"; terminal_upstream_failure_cascades_immediately: boolean; pending_dependency_state_entry_rechecks_upstream_failure: boolean; schema_version: "1.0"; } interface RevalidationCascadeRun { cascade_run_id: string; originating_receipt_ref: StorageRef; task_id: string; run_id: string; origin_outcome_id: string; visited_outcome_ids: string[]; active_outcome_ids: string[]; depth: number; max_depth: number; status: | "running" | "quiescent" | "cycle_detected" | "max_depth_exceeded" | "aborted"; terminal_reason?: | "all_dependents_revalidated" | "cycle_detected" | "max_depth_exceeded" | "upstream_failure_cascade" | "cancelled"; created_at: ISO8601; completed_at?: ISO8601; schema_version: "1.0"; } interface RevalidationCascadeReceipt { receipt_id: string; cascade_run_id: string; status: RevalidationCascadeRun["status"]; affected_outcome_ids: string[]; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.outcome_dependency_cycle validation.revalidation_cascade_loop validation.revalidation_cascade_max_depth_exceeded validation.success_marked_before_cascade_quiescent validation.pending_dependency_not_rechecked_after_upstream_failure ``` ### B-10 / B-11 / B-18 / B-19 — Hard Call, cancel, skip, and resolution receipts ```ts type HardCallBlockingScope = | "entire_run" | "segment" | "artifact" | "outcome" | "module" | "side_effect_only"; type HardCallResponseMode = | "closed_choice" | "freeform_required" | "closed_choice_with_other"; interface HardCallPendingPolicy { hard_call_id: string; blocking_scope: HardCallBlockingScope; blocked_refs: string[]; allowed_to_continue_refs: string[]; context_visible_to_continuing_modules: | "none" | "hard_call_pending_summary" | "full_context_redacted"; on_defer: "continue_with_warning" | "pause_scope" | "abort_scope"; on_timeout: "escalate" | "abort" | "continue_with_warning"; timeout_ms?: number; schema_version: "1.0"; } interface HardRevisionCall { hard_call_id: string; response_mode: HardCallResponseMode; options: HumanDecisionOption[]; prompt_text: string; default_if_no_response?: HumanDecisionOption; pending_policy: HardCallPendingPolicy; created_at: ISO8601; schema_version: "1.1"; } interface HardCallResolutionReceipt { receipt_id: string; hard_call_id: string; operation_kind: "hard_call_resolved"; dispatcher_actor_ref: string; resolved_by_user_ref: string; selected_option_id?: string; freeform_response_ref?: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface TaskCancelProtocol { cancel_request_id: string; task_id: string; run_id: string; requested_by_ref: string; cancel_scope: | "entire_run" | "segment" | "module_activation" | "revision_plan" | "side_effect_intent"; target_refs: string[]; in_flight_handling: | "request_graceful_stop" | "preempt_immediately" | "finish_current_step_then_stop"; side_effect_policy: | "do_not_cancel_executed_side_effects" | "cancel_unexecuted_intents" | "create_corrective_artifact"; candidate_disposition: | "discard" | "retain_for_manual_review" | "orphan_until_reconciled"; source_workspace_disposition: | "retain_records" | "mark_records_cancelled" | "rollback_if_uncommitted"; learning_signal_policy: | "suppress_success_signals" | "emit_cancel_diagnostic_only" | "emit_full_signals_with_cancel_flag"; user_receipt_ref?: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface TaskSkipReceipt { skip_id: string; target_ref: string; skipped_by_ref: string; reason: "not_applicable" | "user_directed" | "dependency_unavailable" | "policy_blocked"; downstream_effect: "none" | "marks_dependents_not_applicable" | "requires_human_ack"; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.hard_call_options_empty validation.hard_call_closed_choice_needs_two_options validation.hard_call_freeform_missing_response_schema validation.hard_call_resolved_without_dispatcher_receipt validation.cancel_ignores_executed_side_effect validation.skip_without_receipt ``` ### B-14 — Forum deadlock breaker ```ts interface ForumDeliberationPolicy { room_id: string; max_deliberation_ticks: number; consensus_threshold_pct: number; on_no_consensus: | "forum_deadlock_hard_call" | "prefer_safest_policy_allowed_proposal" | "pause_and_request_user"; schema_version: "1.0"; } ``` Rule: `task_agent_decides` must not be an allowed terminal behavior. Task Agent may recommend, not decide or mutate. Required validation: ```ts validation.forum_deadlock_without_policy validation.forum_policy_allows_task_agent_decides validation.forum_no_consensus_without_terminal_route ``` ### B-16 — deterministic concurrency tie-breaker ```ts interface RevisionPlanConcurrencyProfile { plan_id: string; required_for_overall_pass: boolean; high_stakes: boolean; outcome_priority: number; // lower wins plan_risk_score: number; // lower risk wins estimated_lock_duration_ms: number; cost_vector_ref?: StorageRef; deterministic_final_key: string; // ULID or lexicographic plan_id schema_version: "1.0"; } ``` Normative ordering: ```ts RULE concurrency_tie_breaker: 1. required_for_overall_pass = true > false 2. high_stakes = true > false 3. outcome_priority ascending 4. plan_risk_score ascending 5. estimated_lock_duration_ms ascending 6. deterministic_final_key ascending ``` Required validation: ```ts validation.concurrency_tie_breaker_uses_wall_clock validation.concurrency_tie_breaker_risk_sort_inverted validation.concurrency_tie_breaker_missing_final_key ``` ### B-24 — sufficiency detection contract **Final decision:** critical and real. The card’s trigger set is incomplete and routing every case to Hard Call is wrong. Use a real detector with capability coverage, procedure universe, attempt signatures, improvement metrics, and typed terminal routes. ```ts type SufficiencyTrigger = | "no_capability_covers_outcome" | "capability_unavailable_or_unhealthy" | "policy_prohibits_required_step" | "all_policy_allowed_procedures_exhausted" | "max_attempts_without_material_score_improvement" | "identical_output_loop_detected" | "evidence_insufficient_to_proceed" | "verification_unresolvable" | "contradictory_requirements" | "precondition_unresolvable" | "budget_cap_prevents_minimal_sufficient_attempt" | "external_side_effect_requires_ungranted_approval" | "cascade_cycle_detected"; type SufficiencyTerminalRoute = | "needs_information" | "needs_verification" | "needs_human_judgment" | "unable_to_evaluate" | "blocked_by_policy" | "unrecoverable" | "process_gap_out"; interface SufficiencyDetectionPolicy { policy_id: string; min_attempts_before_no_improvement: number; // default 2 no_improvement_window: number; // default 2 improvement_metric_ref: string; // FormulaSpec ID epsilon: number; // default 0.03 on 0..1 calibrated score max_total_attempts: number; procedure_universe_scope: | "declared_applicable" | "policy_allowed_only" | "safe_without_human_gate" | "all_known_with_policy_labels"; require_capability_snapshot: true; require_policy_snapshot: true; require_attempt_signature_hash: true; schema_version: "1.0"; } interface CapabilityCoverageAssessment { assessment_id: string; outcome_id: string; capability_snapshot_ref: StorageRef; required_capabilities: CapabilityRef[]; available_capabilities: CapabilityRef[]; coverage_state: | "covered" | "partially_covered" | "not_covered" | "covered_but_unhealthy"; gaps: Array<{ required_capability_ref: CapabilityRef; gap_kind: "missing" | "unhealthy" | "policy_blocked" | "version_incompatible"; evidence_ref?: StorageRef; }>; schema_version: "1.0"; } interface CandidateRepairProcedure { procedure_id: string; strategy_kind: RepairStrategyKind; repair_target: RepairTarget; required_capabilities: CapabilityRef[]; policy_allowed: boolean; safety_class: | "mechanical" | "meaning_bearing" | "privileged" | "external_side_effect"; tried: boolean; exhausted: boolean; inapplicable_reason?: | "missing_capability" | "policy_blocked" | "unsafe_without_human" | "already_failed_same_signature" | "requires_missing_evidence" | "requires_ungranted_side_effect"; schema_version: "1.0"; } interface ProcedureAttemptRecord { attempt_id: string; procedure_id: string; revision_plan_ref?: StorageRef; strategy_kind: RepairStrategyKind; input_signature_hash: string; output_signature_hash?: string; score_before?: CalibratedScore; score_after?: CalibratedScore; score_delta?: number; terminal_status: | "succeeded" | "failed" | "no_material_improvement" | "policy_blocked" | "capability_failed" | "regressed" | "identical_output_rejected" | "not_attempted_missing_evidence"; receipt_refs: StorageRef[]; schema_version: "1.0"; } interface SufficiencyDetectionResult { detection_id: string; outcome_id: string; run_id: string; evaluated_at: ISO8601; policy_ref: string; no_sufficient_procedure: boolean; triggered_by: SufficiencyTrigger[]; coverage_assessment_ref: StorageRef; candidate_procedures: CandidateRepairProcedure[]; attempts: ProcedureAttemptRecord[]; best_score_seen?: CalibratedScore; best_artifact_version_ref?: StorageRef; blocking_research_need_refs: string[]; decisive_policy_decision_refs: PolicyEvaluationRef[]; terminal_route: SufficiencyTerminalRoute; hard_call_required: boolean; hard_call_kind?: | HardRevisionCallKind | "no_sufficient_procedure" | "contradictory_requirements" | "budget_scope_decision"; process_gap_signal_ref?: StorageRef; rationale: string; schema_version: "1.0"; } ``` Normative routing: ```ts RULE sufficiency_terminal_route: IF terminal_route == "needs_information": emit OutcomeEvaluationDisposition.needs_information + ResearchNeed. DO NOT raise Hard Call unless no research/user information route exists. IF terminal_route == "needs_verification": emit OutcomeEvaluationDisposition.needs_verification + VerificationRequestStep. IF terminal_route == "blocked_by_policy": emit OutcomeEvaluationDisposition.blocked_by_policy with PolicyDecisionRef. Raise Hard Call only if the user can alter the governing policy boundary. IF terminal_route == "process_gap_out": emit OutcomeEvaluationDisposition.unable_to_evaluate + TaskProcessGapSignal. Task Agent may propose a graph patch; it cannot mutate graph directly. IF terminal_route == "needs_human_judgment": raise HardRevisionCall. IF terminal_route == "unrecoverable": emit OutcomeEvaluationDisposition.unrecoverable and stop retrying. ``` Required validation: ```ts validation.sufficiency_protocol_without_detection validation.no_improvement_without_metric validation.no_improvement_without_epsilon validation.procedure_exhaustion_without_candidate_universe validation.hard_call_raised_when_no_human_choice_available validation.sufficiency_retry_after_terminal_detection validation.insufficiency_marker_not_mapped_to_outcome_state ``` ### B-25 — false positive; replace with dependency canonicalization Live V3.3.1 already has `depends_on_step_ids`. The accepted card row should be cut as written and replaced. ```ts interface RevisionPlanStepBase { step_id: string; step_order: number; step_kind: RevisionPlanStepKind; depends_on_step_ids: string[]; target_refs: StorageRef[]; revalidation_policy: RevisionStepRevalidationPolicy; revalidation_rationale: string; schema_version: "1.0"; } interface DependencyEdge { from_step_id: string; to_step_id: string; edge_kind: | "requires_output" | "requires_artifact_version" | "requires_human_resolution" | "requires_source_answer" | "requires_verification"; schema_version: "1.0"; } // Source-of-truth rule: // RevisionPlanStepBase.depends_on_step_ids is canonical. // RevisionPlan.dependency_edges, if present, is a derived read model. // If both are present, they must be isomorphic. ``` Required validation: ```ts validation.revision_plan_dependency_edge_drift validation.revision_plan_step_dependency_undefined validation.revision_plan_cycle validation.revision_plan_dependency_targets_missing_step ``` ### B-26 — revalidation policy field collapse ```ts type RevisionStepRevalidationPolicyKind = | "none" | "revalidate_targeted_outcomes" | "revalidate_declared_dependents" | "revalidate_full_closure" | "revalidate_full_task"; interface RevisionStepRevalidationPolicy { policy_kind: RevisionStepRevalidationPolicyKind; outcomes_to_recheck: outcome_id[]; closure_policy_ref?: StorageRef; success_hint?: string; rationale: string; schema_version: "1.0"; } interface TypedRevisionInstruction { instruction_id: string; revalidation_policy_ref: StorageRef; // points to base policy; no duplicate expectation schema_version: "1.1"; } ``` Required validation: ```ts validation.revalidation_policy_ambiguous validation.revalidation_policy_ref_missing validation.revalidation_trigger_legacy_field_present validation.revalidation_expectation_legacy_field_present ``` ### B-27 — regenerate loop guard ```ts interface RegenerateRevisionPayload { revision_intent: "regenerate"; previous_attempt_hashes: string[]; required_variation_policy: | "change_sampling_parameters" | "change_prompt_strategy" | "change_module_or_escalate" | "human_review_required"; schema_version: "1.0"; } interface RegenerateAttemptReceipt { receipt_id: string; input_hash: string; output_hash: string; matched_previous_attempt: boolean; action_taken: | "accepted_new_output" | "rejected_identical_output" | "escalated" | "changed_generation_policy"; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.regenerate_missing_previous_attempt_hashes validation.regenerate_identical_output validation.regenerate_loop_after_identical_rejection ``` --- ## 6. §C — Math, Scoring, Metrics, and Formula Audit ### C-01 — Formula Registry plus computation receipts A Formula Registry alone is not sufficient. It must be paired with formula evaluation receipts, observation/rollup separation, finite-number policy, sample policy, and test vectors. ```ts type NumericUnit = | "unitless" | "ratio" | "probability" | "score_0_1" | "count" | "tokens" | "usd" | "milliseconds" | "seconds" | "percent" | "custom"; type MetricValueKind = | "count" | "ratio" | "mean" | "median" | "quantile" | "calibrated_score" | "correlation" | "distribution" | "cost_vector" | "boolean_derived" | "enum_derived"; type MissingInputPolicy = | "fail_validation" | "return_indeterminate" | "exclude_with_recorded_omission" | "default_value_with_audit" | "block_computation"; type ZeroDenominatorPolicy = | "return_indeterminate_insufficient_data" | "return_zero" | "return_one" | "fail_validation"; type FiniteNumberPolicy = | "reject_nan_infinity" | "coerce_to_indeterminate" | "allow_only_in_test_fixture"; interface FormulaInputSpec { name: string; type_ref: SchemaRef; required: boolean; allowed_units?: NumericUnit[]; allowed_range?: [number, number]; missing_input_policy_override?: MissingInputPolicy; } interface FormulaOutputSpec { value_kind: MetricValueKind; unit: NumericUnit; range?: [number, number]; higher_is_better?: boolean; finite_number_policy: FiniteNumberPolicy; } interface FormulaTestVector { test_vector_id: string; input_ref: StorageRef; expected_output_ref: StorageRef; expected_validation_codes: string[]; schema_version: "1.0"; } interface FormulaSpec { formula_id: string; owner_doc: OwnerDoc; semantic_version: string; purpose: string; expression_ref: StorageRef; expression_language: | "deterministic_typescript" | "sql_read_model" | "declarative_metric_dsl" | "human_review_required"; inputs: FormulaInputSpec[]; output: FormulaOutputSpec; missing_input_policy: MissingInputPolicy; zero_denominator_policy?: ZeroDenominatorPolicy; rounding_policy: | "no_rounding_store_full_precision" | "round_display_only" | "round_to_6_decimal_places"; sample_policy?: { min_sample_size: number; insufficient_sample_result: "indeterminate" | "emit_with_low_confidence"; window_required: boolean; }; confidence_interval_policy?: { required: boolean; interval_level: 0.8 | 0.9 | 0.95 | 0.99; method: | "wilson" | "bootstrap" | "normal_approximation" | "bayesian_beta" | "not_applicable"; }; test_vectors: FormulaTestVector[]; schema_version: "1.0"; } interface MetricObservation { observation_id: string; metric_id: string; formula_eval_receipt_ref: StorageRef; subject_ref: StorageRef; observed_at: ISO8601; value_ref: StorageRef; data_class: "public" | "internal" | "privileged" | "local_only"; matter_id?: string; schema_version: "1.0"; } interface MetricRollup { rollup_id: string; metric_id: string; subject_scope_ref: StorageRef; measurement_window: DateRange; included_observation_refs: StorageRef[]; excluded_observation_refs: Array<{ observation_ref: StorageRef; exclusion_reason: | "outside_window" | "wrong_subject_scope" | "right_censored" | "policy_filtered" | "duplicate" | "invalidated"; }>; formula_eval_receipt_ref: StorageRef; sample_size: number; value_ref: StorageRef; confidence_interval?: [number, number]; confidence_interval_level?: 0.8 | 0.9 | 0.95 | 0.99; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.metric_without_formula_spec validation.metric_value_without_formula_receipt validation.metric_rollup_without_window validation.metric_rollup_includes_invalidated_observation validation.formula_output_nan_or_infinity validation.formula_test_vector_missing validation.formula_version_drift validation.correlation_metric_declared_as_ratio ``` ### C-01 / C-09 — `normalizeCriterionWeights` corrected The proposed Appendix J function filtered out unanchored LLM judgment before applying the declared policy, failed negative/NaN weights, and could return empty/zero-weight maps. ```ts function assertFiniteNonNegative(value: number, code: string): void { if (!Number.isFinite(value) || value < 0) { throw new Error(code); } } function aggregationEligibleCriteria( criteria: Criterion[], policy: OutcomeComplianceScoringConfig ): Criterion[] { const unanchored = criteria.filter(c => c.scoring_basis === "unanchored_llm_judgment"); if (unanchored.length > 0) { if (policy.unanchored_llm_judgment_policy === "indeterminate") { throw new Error("validation.unanchored_required_criterion_indeterminate"); } if (policy.unanchored_llm_judgment_policy === "exclude") { return criteria.filter(c => c.scoring_basis !== "unanchored_llm_judgment"); } if (policy.unanchored_llm_judgment_policy === "include_with_audit_flag") { return criteria; } } return criteria; } function normalizeCriterionWeights( criteria: Criterion[], policy: OutcomeComplianceScoringConfig ): Record { const eligible = aggregationEligibleCriteria(criteria, policy); if (eligible.length === 0) { throw new Error("validation.no_aggregation_eligible_criteria"); } const rawWeights = eligible.map(c => { let rawWeight: number; if (policy.default_weight_policy === "from_criterion_weight") { if (c.weight == null) { throw new Error("validation.criterion_weight_missing_under_from_criterion_weight"); } rawWeight = c.weight; } else if (policy.default_weight_policy === "from_priority") { const priority = c.priority ?? "should_have"; rawWeight = policy.priority_weight_map[priority]; if (rawWeight == null) { throw new Error("validation.criterion_priority_weight_missing"); } } else { rawWeight = 1; } assertFiniteNonNegative(rawWeight, "validation.criterion_weight_invalid"); return [c.criterion_id, rawWeight] as const; }); const sum = rawWeights.reduce((acc, [, w]) => acc + w, 0); if (!Number.isFinite(sum) || sum <= 0) { throw new Error("validation.criterion_weight_sum_zero"); } return Object.fromEntries(rawWeights.map(([id, w]) => [id, w / sum])); } ``` Required validation: ```ts validation.unanchored_required_criterion_indeterminate validation.criterion_weight_invalid validation.criterion_priority_weight_missing validation.criterion_weight_sum_zero validation.no_aggregation_eligible_criteria ``` ### C-01 — QualityIndex derived pass status ```ts interface QualityIndex { aggregate_score: number; // 0..1 pass_threshold: number; // 0..1 required_gate_failures: string[]; aggregation_method: | "all_required_then_weighted_mean" | "weighted_mean" | "min_required_score" | "all_or_nothing"; missing_dimension_policy: | "fail_required" | "exclude_optional_with_penalty" | "indeterminate"; derived_pass_status: | "passed" | "failed_threshold" | "failed_required_gate" | "indeterminate"; formula_eval_receipt_ref: StorageRef; metric_semantics_version: string; schema_version: "1.1"; } // Rule: // if required_gate_failures.length > 0 -> failed_required_gate // else if aggregate_score >= pass_threshold -> passed // else -> failed_threshold ``` Required validation: ```ts validation.quality_index_pass_status_drift validation.quality_index_without_formula_receipt validation.quality_index_score_out_of_range ``` ### C-02 — revision-cycle metrics with censoring ```ts type OutcomeCycleTerminalClass = | "succeeded" | "failed_unrecoverable" | "max_iterations_reached" | "blocked_by_policy" | "needs_human_judgment" | "needs_information" | "cancelled_by_user" | "still_open_right_censored"; interface RevisionCycleOutcomeObservation { observation_id: string; outcome_id: string; run_id: string; cycle_count: number; terminal_class: OutcomeCycleTerminalClass; terminal_state_ref?: StorageRef; right_censored_at?: ISO8601; observation_window: DateRange; cost_vector_ref?: StorageRef; formula_eval_receipt_ref?: StorageRef; schema_version: "1.0"; } interface RevisionCycleEfficiencyRollup { rollup_id: string; measurement_window: DateRange; avg_cycles_to_success?: number; wasted_cycle_burn_rate?: number; right_censored_rate: number; max_iterations_rate: number; included_observation_refs: StorageRef[]; formula_eval_receipt_ref: StorageRef; schema_version: "1.0"; } ``` ### C-04 — sub-agent reputation formula ```ts interface SeverityWeightedRegressionRate { accepted_count: number; regression_introduced_count: number; severity_breakdown: Record<"minor" | "major" | "critical", number>; severity_weights: Record<"minor" | "major" | "critical", number>; // default 1,2,5 unweighted_regression_rate: number | null; severity_weighted_penalty_rate: number | null; zero_denominator_policy: ZeroDenominatorPolicy; formula_eval_receipt_ref: StorageRef; schema_version: "1.0"; } interface SubAgentReputationFormulaConfig { formula_id: "sub_agent_reputation_score_v1"; weights: { hit_rate: number; attribution_lift: number; inverse_regression_penalty: number; inverse_cost_penalty: number; false_negative_penalty: number; false_positive_penalty: number; }; false_negative_weight_multiplier: number; // default 2 min_invocation_count: number; // default 10 confidence_interval_method: "wilson" | "bayesian_beta" | "bootstrap"; output_range: [0, 1]; schema_version: "1.0"; } interface SubAgentReputationScore { sub_agent_ref: SubAgentRef; current_score: number | null; score_status: "computed" | "insufficient_sample" | "quarantined_by_policy"; component_scores: { hit_rate_score?: number; attribution_lift_score?: number; regression_penalty_score?: number; cost_penalty_score?: number; false_negative_penalty_score?: number; false_positive_penalty_score?: number; }; formula_config_ref: StorageRef; formula_eval_receipt_ref: StorageRef; sample_size: number; confidence_interval?: [number, number]; confidence_interval_level?: 0.8 | 0.9 | 0.95 | 0.99; schema_version: "1.0"; } ``` ### C-07 — CostVector and cost records ```ts type CostDimension = | "usd" | "input_tokens" | "output_tokens" | "cached_input_tokens" | "cache_write_tokens" | "local_compute_seconds" | "wall_clock_ms" | "external_api_calls" | "external_api_usd" | "storage_bytes" | "human_review_minutes"; interface CostDistribution { expected: number; p50?: number; p90?: number; p99?: number; hard_cap?: number; unit: CostDimension; } interface CostVector { cost_vector_id: string; components: Partial>; basis: | "historical" | "model_priced" | "provider_quote" | "heuristic" | "measured_actual"; estimator_confidence: "calibrated" | "uncalibrated" | "experimental"; sample_size?: number; measurement_window?: DateRange; assumptions: string[]; formula_eval_receipt_ref?: StorageRef; schema_version: "1.0"; } interface TaskCostRecord { cost_record_id: string; task_id: string; run_id?: string; module_id?: string; activation_seq?: number; planned_cost_vector_ref?: StorageRef; actual_cost_vector_ref?: StorageRef; cost_class: | "logical_llm_work" | "infrastructure_retry" | "source_research" | "doc24_packet_assembly" | "external_tool" | "local_compute" | "human_review"; created_at: ISO8601; schema_version: "1.0"; } type CostCorrelationPolicy = | "assume_independent_monte_carlo" | "assume_perfect_correlation_upper_bound" | "empirical_joint_distribution"; ``` Rules: ```ts // Cost vectors add only matching CostDimension units. // p90/p99 aggregation must not sum independent quantiles unless correlation_policy is declared. ``` Required validation: ```ts validation.cost_vector_unit_mismatch validation.cost_quantile_sum_without_correlation_policy validation.scalar_cost_estimate_legacy_field_present validation.cost_vector_negative_component ``` ### C-08 — novelty assessment union ```ts type NoveltyAssessment = | NoveltyAssessmentWithNeighbor | NoveltyAssessmentNoNeighbor; interface NoveltyMetricSpec { metric_id: string; feature_vector_definition_ref: StorageRef; embedding_model_ref?: string; distance_metric: | "cosine_distance" | "euclidean_normalized" | "jaccard" | "hybrid"; distance_range: [0, 1]; no_pattern_fallback: | "novelty_one" | "indeterminate" | "use_domain_baseline"; calibration_dataset_ref: StorageRef; threshold_default: number; metric_semantics_version: string; schema_version: "1.0"; } interface NoveltyAssessmentBase { input_signature_hash: string; metric_spec_ref: string; metric_semantics_version: string; schema_version: "1.1"; } interface NoveltyAssessmentWithNeighbor extends NoveltyAssessmentBase { neighbor_state: "nearest_pattern_found"; closest_pattern_id: string; closest_pattern_distance: number; similarity_score: number; novelty_score: number; forces_fresh_reasoning: boolean; triggers_task_agent: boolean; } interface NoveltyAssessmentNoNeighbor extends NoveltyAssessmentBase { neighbor_state: "no_pattern_found"; no_pattern_fallback_applied: | "novelty_one" | "indeterminate" | "use_domain_baseline"; closest_pattern_id?: never; closest_pattern_distance?: never; similarity_score?: never; novelty_score: number | null; forces_fresh_reasoning: boolean; triggers_task_agent: boolean; indeterminate_reason?: "no_pattern_and_policy_indeterminate"; } ``` Required validation: ```ts validation.novelty_no_neighbor_has_distance validation.novelty_neighbor_missing_distance validation.novelty_metric_space_undefined ``` ### C-09 — template match formula corrected ```ts type TemplateMatchComponent = | "semantic_intent_match" | "task_type_match" | "input_contract_match" | "output_contract_match" | "capability_availability_match" | "entity_context_match" | "user_preference_match" | "prior_assessment_score" | "recency_or_staleness_score"; type TemplateMatchComponents = Record; type TemplateMatchWeights = Record; interface TemplateMatchFormula { formula_id: "template_match_score_v1"; component_weights: TemplateMatchWeights; hard_veto_cap: number; soft_penalty_max_total: number; schema_version: "1.0"; } function assertScore01(value: number, code: string): void { if (!Number.isFinite(value) || value < 0 || value > 1) { throw new Error(code); } } function computeTemplateOverallScore( components: TemplateMatchComponents, weights: TemplateMatchWeights, softPenaltySum: number, hardVetoCount: number, formula: TemplateMatchFormula ): number { let weighted = 0; let totalWeight = 0; for (const key of Object.keys(formula.component_weights) as TemplateMatchComponent[]) { const value = components[key]; const weight = weights[key]; assertScore01(value, "validation.template_match_component_out_of_range"); if (!Number.isFinite(weight) || weight < 0) { throw new Error("validation.template_match_weight_invalid"); } weighted += value * weight; totalWeight += weight; } if (!Number.isFinite(totalWeight) || totalWeight <= 0) { throw new Error("validation.template_match_total_weight_zero"); } if ( !Number.isFinite(softPenaltySum) || softPenaltySum < 0 || softPenaltySum > formula.soft_penalty_max_total ) { throw new Error("validation.template_match_soft_penalty_invalid"); } assertScore01(formula.hard_veto_cap, "validation.template_match_hard_veto_cap_invalid"); const normalized = weighted / totalWeight; const penalized = Math.max(0, Math.min(1, normalized - softPenaltySum)); return hardVetoCount > 0 ? Math.min(penalized, formula.hard_veto_cap) : penalized; } ``` Required validation: ```ts validation.template_match_weight_invalid validation.template_match_total_weight_zero validation.template_match_soft_penalty_invalid validation.template_match_hard_veto_cap_invalid validation.template_match_output_nan ``` ### Calibration metrics The live metric language calling correlation a “numerator” is mathematically wrong. Use calibrated metric specs. ```ts interface CalibrationMetricSpec { metric_id: | "planner_confidence_brier_score" | "planner_confidence_expected_calibration_error" | "novelty_threshold_precision_recall" | "novelty_threshold_auc" | "confidence_convergence_spearman"; predicted_value_field: string; observed_outcome_field: string; observed_outcome_encoding: | "binary_success" | "time_to_event" | "ordinal" | "continuous_delta"; sample_policy: { min_sample_size: number; insufficient_sample_result: "indeterminate"; }; binning_policy?: { bin_count: number; binning_method: "equal_width" | "equal_frequency"; }; censoring_policy?: { right_censored_allowed: boolean; right_censored_handling: | "exclude" | "survival_model" | "count_as_non_converged_after_window"; observation_window: DurationISO8601; }; formula_ref: string; schema_version: "1.0"; } interface CalibrationMetricResult { result_id: string; metric_spec_ref: string; metric_value: number | null; indeterminate_reason?: "insufficient_sample" | "invalid_inputs" | "all_one_class"; sample_size: number; positive_count?: number; negative_count?: number; confidence_interval?: [number, number]; formula_eval_receipt_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.correlation_metric_declared_as_ratio validation.calibration_metric_without_sample_policy validation.calibration_metric_all_one_class validation.calibration_metric_without_censoring_policy ``` ### C-10 — lexical hash vs semantic version ```ts interface CriterionIdentityFields { criterion_id: string; criterion_text_hash: string; // lexical hash criterion_semantics_version: string; // bumped only after reviewed meaning change semantic_review_receipt_ref?: StorageRef; schema_version: "1.0"; } ``` Required validation: ```ts validation.criterion_semantics_hash_legacy_name validation.criterion_semantics_version_unbumped_on_meaning_change validation.semantic_version_bumped_without_review_receipt ``` --- ## 7. §D — Source Workspace, Forum, Board, Taint, and Governance ### D-01 / D-02 — source-kind taint defaults and transitive taint ```ts type SourceTrustBasis = | "user_supplied" | "internal_library" | "official_api" | "verified_authority_database" | "web_unverified" | "connector_authenticated" | "manual_override_policy" | "unknown"; interface SourceKindTaintDefault { source_kind: SourceRecord["source_kind"]; default_taint_class: TaintClass; required_trust_basis?: SourceTrustBasis[]; allow_override: boolean; schema_version: "1.0"; } const SOURCE_KIND_TAINT_DEFAULTS: SourceKindTaintDefault[] = [ { source_kind: "document", default_taint_class: "user_trusted_bounded", allow_override: true }, { source_kind: "email", default_taint_class: "user_trusted_bounded", allow_override: true }, { source_kind: "file", default_taint_class: "user_trusted_bounded", allow_override: true }, { source_kind: "prior_task_output", default_taint_class: "user_trusted_bounded", allow_override: true }, { source_kind: "library_entry", default_taint_class: "internal_corpus_trusted", allow_override: true }, { source_kind: "web_source", default_taint_class: "external_untrusted", allow_override: true }, { source_kind: "custom", default_taint_class: "unclassified", allow_override: true }, { source_kind: "api_result", default_taint_class: "external_authority_trusted", required_trust_basis: ["official_api"], allow_override: true }, { source_kind: "database_record", default_taint_class: "external_authority_trusted", required_trust_basis: ["verified_authority_database"], allow_override: true }, { source_kind: "case_law", default_taint_class: "external_authority_trusted", required_trust_basis: ["verified_authority_database"], allow_override: true }, { source_kind: "statute", default_taint_class: "external_authority_trusted", required_trust_basis: ["verified_authority_database", "official_api"], allow_override: true }, { source_kind: "regulation", default_taint_class: "external_authority_trusted", required_trust_basis: ["verified_authority_database", "official_api"], allow_override: true }, { source_kind: "financial_filing", default_taint_class: "external_authority_trusted", required_trust_basis: ["official_api"], allow_override: true }, { source_kind: "expert_report", default_taint_class: "user_trusted_bounded", allow_override: true }, { source_kind: "technical_doc", default_taint_class: "external_untrusted", allow_override: true } ]; interface SanitizationNode { node_id: string; input_taint: TaintClass; output_taint: TaintClass; method: "human_review" | "structural_strip" | "policy_filter"; evidence_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface TaintAggregationPolicy { policy_id: string; workspace_taint_rule: "max_taint"; any_privileged_record_marks_workspace_privileged: true; matter_scope_rule: "max_scope_within_matter_only"; schema_version: "1.0"; } ``` Required validation: ```ts validation.source_kind_taint_unmapped validation.external_authority_without_trust_basis validation.taint_not_inherited_through_summary validation.workspace_taint_missing_aggregation_policy validation.taint_downgrade_without_sanitization_node ``` ### D-04 — tier 0 as receipt-only, not SourceRecord ```ts type SourceDocumentationTier = 0 | 1 | 2 | 3 | 4; type SourceMaterializationKind = | "tool_receipt_only" // tier 0 | "source_record" // tiers 1-3 | "workspace_bundle"; // tier 4 interface SourceRecord { source_id: string; tier: 1 | 2 | 3; source_kind: SourceKind; // existing fields... } interface EphemeralSourceLookupReceipt { receipt_id: string; query_id?: string; tool_receipt_ref: StorageRef; source_title_or_label?: string; lookup_purpose: string; may_support_downstream_claims: false; created_at: ISO8601; schema_version: "1.0"; } interface SourceTierTransitionReceipt { receipt_id: string; source_id: string; from_tier: SourceRecord["tier"]; to_tier: SourceRecord["tier"]; transition_reason: string; actor_ref: string; cleared_by_access_tier?: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.tier0_source_record_materialized validation.claim_depends_on_tier0_lookup validation.source_tier_transition_not_persisted validation.source_tier_demotion_without_authority ``` ### D-05 / B-13 — ResearchNeed scope and lease ```ts type ResearchNeedScope = "run" | "task" | "workspace"; type ResearchNeedStatus = | "open" | "leased" | "answered" | "human_needed" | "unresolved" | "cancelled"; interface ResearchNeed { need_id: string; need_scope: ResearchNeedScope; task_id: string; run_id?: string; workspace_id: string; target_refs: Array; question: string; status: ResearchNeedStatus; answer_ref?: StorageRef; human_needed_reason?: string; unresolved_reason?: string; created_at: ISO8601; updated_at: ISO8601; schema_version: "1.1"; } interface ResearchNeedLease { need_id: string; leased_by_module_id: string; lease_token: string; acquired_at: ISO8601; expires_at: ISO8601; on_expiry: "release_for_reclaim" | "escalate" | "mark_abandoned"; satisfied_by_result_ref?: StorageRef; schema_version: "1.0"; } ``` Required validation: ```ts validation.research_need_scope_missing validation.research_need_run_id_on_task_scope_conflict validation.research_need_double_leased validation.research_need_human_needed_without_exit ``` ### D-06 / G-03 — evidence anchors and claim-support derivation ```ts type EvidenceAnchorSupportStrength = | "direct" | "indirect" | "contextual" | "contradicts"; interface SourceEvidenceAnchor { anchor_id: string; source_record_ref: SourceRecordRef; anchor_kind: | "page" | "quote" | "section" | "timestamp" | "row" | "url_fragment" | "paragraph" | "line_range"; anchor_locator: string; supports_claim_refs: ClaimRef[]; support_strength: EvidenceAnchorSupportStrength; extracted_text_ref?: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface DomainPayloadRegistryRef { domain_payload_kind: string; domain_payload_schema_ref: SchemaRef; domain_payload_version: string; } type ClaimSupportStatus = | "supported" | "partially_supported" | "unsupported" | "contradicted" | "not_checked" | "indeterminate_stale_or_unverified"; interface ClaimSupportDerivationPolicy { policy_id: string; required_for_supported: { min_direct_supporting_anchors: number; require_verified_source: boolean; allow_stale_source: boolean; allow_contradicting_anchor: boolean; }; partial_support_rule: | "any_indirect_or_contextual_anchor" | "direct_anchor_unverified" | "domain_specific"; contradiction_rule: | "any_direct_contradiction_controls" | "weighted_by_authority" | "human_review_required"; formula_ref: string; schema_version: "1.0"; } interface ClaimSupportDerivationReceipt { receipt_id: string; claim_ref: ClaimRef; policy_ref: string; supporting_anchor_refs: StorageRef[]; contradicting_anchor_refs: StorageRef[]; source_verification_refs: StorageRef[]; source_freshness_refs: StorageRef[]; applicability_scope_refs: StorageRef[]; derived_support_status: ClaimSupportStatus; decisive_reason: | "direct_verified_support" | "partial_indirect_support" | "no_supporting_anchor" | "direct_contradiction" | "stale_or_unverified_source" | "not_checked"; formula_eval_receipt_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.claim_support_status_without_derivation validation.evidence_anchor_without_claim_ref validation.domain_payload_without_registry_ref validation.extractor_missing_reported_as_source_missing ``` ### D-07 / D-09 / D-12 / D-24 — Run Board governance, publication, retention, matter firewall ```ts type RunBoardEventClass = | "module_lifecycle" | "artifact_event" | "side_effect_event" | "error_retry" | "gate_decision" | "evaluation_finding" | "repair_instruction" | "source_update" | "user_comment" | "task_agent_recommendation" | "cost_duration" | "run_lifecycle"; interface RunBoardGovernanceEnvelope { data_class: "public" | "internal" | "privileged" | "local_only"; taint_class: TaintClass; privileged: boolean; matter_id?: string; policy_decision_refs: PolicyEvaluationRef[]; visibility_scope: | "private_audit_only" | "same_module" | "same_segment" | "same_matter_modules" | "selected_participants" | "user_only"; redaction_required: boolean; schema_version: "1.0"; } interface RunBoardPublicationPolicy { policy_id: string; auto_publish_event_classes: RunBoardEventClass[]; max_visible_posts_per_run: number; suppress_data_classes: Array<"privileged" | "local_only">; publish_redacted_stub_when_suppressed: boolean; rate_limit_per_minute: number; schema_version: "1.0"; } interface RunBoardAuditEvent { event_id: string; task_id: string; run_id: string; event_class: RunBoardEventClass; payload_ref: StorageRef; governance: RunBoardGovernanceEnvelope; event_seq: number; created_at: ISO8601; schema_version: "1.0"; } interface RunBoardVisiblePost { post_id: string; source_event_id: string; rendered_payload_ref: StorageRef; redacted: boolean; withheld_reason?: "privileged" | "local_only" | "volume_cap" | "matter_firewall" | "policy"; lifecycle_state: "active" | "superseded" | "retracted"; created_at: ISO8601; schema_version: "1.0"; } ``` Matter rule: ```ts // A post with matter_id == X is visible only to readers operating under matter_id == X. // visibility_scope scopes within the matter; it cannot cross the matter boundary. ``` Required validation: ```ts validation.run_board_event_without_governance validation.visible_post_cross_matter_leak validation.suppressed_event_without_audit_stub validation.passive_board_autopublish_without_policy ``` ### D-08 — context packet request/receipt/omission/invalidation ```ts type TaskContextAudience = | "module" | "sub_agent" | "task_agent" | "user" | "forum_room"; interface TaskRunContextPacketRequest { request_id: string; task_id: string; run_id: string; audience: TaskContextAudience; requested_max_tokens: number; required_item_refs: StorageRef[]; optional_item_refs: StorageRef[]; staleness_policy: "fresh_only" | "allow_stale_with_warning" | "best_effort"; created_at: ISO8601; schema_version: "1.0"; } interface OmittedPacketItem { item_ref: StorageRef; omission_reason: | "token_budget" | "permission" | "stale" | "policy" | "not_relevant" | "unavailable"; required: boolean; } interface TaskRunContextPacketAssemblyReceipt { receipt_id: string; request_id: string; packet_ref: StorageRef; packet_content_hash: string; actual_token_count: number; omitted_items: OmittedPacketItem[]; valid_until_event_seq?: number; invalidated_by_event_kinds: string[]; created_at: ISO8601; schema_version: "1.0"; } interface PerActivationContextBudget { activation_id: string; max_total_tokens: number; packet_token_count: number; board_digest_token_count: number; feedback_bundle_token_count: number; total_token_count: number; schema_version: "1.0"; } ``` Required validation: ```ts validation.context_packet_without_request validation.context_packet_without_assembly_receipt validation.per_activation_context_budget_exceeded validation.required_packet_item_omitted_without_block_or_warning ``` ### D-10 — ModuleAssistanceRequest ```ts interface ModuleAssistanceRequest { request_id: string; task_id: string; run_id: string; requester_ref: string; target: | "module" | "subagent" | "task_agent" | "user" | "forum_room"; target_endpoint_ref: StorageRef; answer_schema_ref: SchemaRef; request_kind: | "clarification" | "substantive_review" | "process_gap" | "source_help" | "format_help" | "policy_help"; response_policy: | "required_before_continue" | "optional_until_timeout" | "advisory_only"; lease: { holder_ref: string; lease_version: string; acquired_at: ISO8601; expires_at: ISO8601; }; timeout_ms: number; on_timeout: | "resume_with_warning" | "abort" | "escalate_human" | "ask_task_agent_then_pause"; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.module_assistance_request_without_endpoint validation.assistance_request_without_answer_schema validation.moderator_failure_without_fallback validation.task_agent_substantive_decision_forbidden ``` ### D-13 — RunGuidance event/projection ```ts type RunGuidanceLifecycleState = | "proposed" | "active" | "contested" | "superseded" | "expired" | "rejected"; interface RunGuidanceCreationEvent { event_id: string; guidance_id: string; source_feedback_bundle_ref: StorageRef; guidance_text: string; scope_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } interface RunGuidanceItemCurrent { guidance_id: string; canonical_event_ref: StorageRef; lifecycle_state: RunGuidanceLifecycleState; cross_run_eligible: boolean; selected_by_doc24_context_policy: boolean; superseded_by_guidance_id?: string; updated_at: ISO8601; schema_version: "1.0"; } interface RunGuidanceLifecycleReceipt { receipt_id: string; guidance_id: string; from_state: RunGuidanceLifecycleState; to_state: RunGuidanceLifecycleState; actor_ref: string; reason: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.run_guidance_consumed_while_contested validation.run_guidance_cross_run_injected_without_doc24_selection validation.run_guidance_lifecycle_transition_without_receipt ``` ### D-14 / §G command closure — mandatory command registry ```ts interface TaskCommandRegistryEntry { command_id: string; request_schema_ref: SchemaRef; response_schema_ref: SchemaRef; durable_write: | "required" | "none" | "explicit_no_op"; required_policy_checks: string[]; idempotency_key_required: boolean; telemetry_event_kind: string; read_model_invalidations: DerivedReadModelRecord["read_model_kind"][]; failure_codes: string[]; owning_doc: OwnerDoc; schema_version: "1.0"; } ``` Required validation: ```ts validation.user_action_without_command_registry_entry validation.command_missing_idempotency_key validation.command_missing_read_model_invalidation validation.phantom_button_no_command ``` ### D-15 — sub-agent contracts and fallbacks ```ts type AllowedCoordinationPoint = | "source_research" | "evaluation" | "revision_planning" | "format_review" | "plan_verifier"; interface SubAgentFallbackPolicy { coordination_point: AllowedCoordinationPoint; on_no_sub_agent: | "use_primary_module" | "skip_with_warning" | "hard_call" | "degrade_quality_with_note"; schema_version: "1.0"; } interface SubAgentCoordinationProfile { profile_id: string; allowed_coordination_points: AllowedCoordinationPoint[]; output_contract_refs: StorageRef[]; fallback_policies: SubAgentFallbackPolicy[]; schema_version: "1.0"; } interface PlanVerifierRequirementPolicy { policy_id: string; required_when_plan_risk_score_gte: number; required_for_external_side_effects: boolean; required_for_privileged_meaning_bearing_revisions: boolean; on_unavailable: "hard_call" | "pause" | "degrade_with_user_notice"; schema_version: "1.0"; } ``` Required validation: ```ts validation.sub_agent_point_without_fallback validation.output_contract_singular_legacy_field_present validation.plan_verifier_required_but_missing ``` ### D-17 — anchors and hash hygiene ```ts interface StructuredAnchor { section_id?: string; field_path?: string; citation_ref?: string; row_id?: string; cell_ref?: string; schema_version: "1.0"; } interface TextAnchor { start_offset: number; end_offset: number; context_before: string; context_after: string; context_hash: string; hash_algorithm: "sha256_canonical_text_v1"; schema_version: "1.0"; } ``` Rules: ```ts // StructuredAnchor must populate at least one locator field. // TextAnchor.context_hash is computed at creation and validated at resolve. // HardCallResolution reusable hashes use canonicalized whitespace/key order before hashing. ``` Required validation: ```ts validation.structured_anchor_empty validation.context_hash_unverified validation.hard_call_hash_unnormalized ``` ### D-20 — library promotion gate ```ts interface LibraryPromotionCandidate { candidate_id: string; source_record_ref: SourceRecordRef; workspace_id: string; requested_by_ref: string; status: "queued" | "approved" | "rejected" | "promoted" | "cancelled"; created_at: ISO8601; schema_version: "1.0"; } interface LibraryPromotionGate { gate_id: string; min_tier: 2 | 3; requires_verification_state: "verified" | "not_required"; ec_policy_decision_ref: PolicyEvaluationRef; requires_access_tier: string; privileged_sources_auto_promote_allowed: false; schema_version: "1.0"; } interface LibraryPromotionReceipt { receipt_id: string; candidate_id: string; gate_ref: StorageRef; durable_library_write_ref?: StorageRef; status: "promoted" | "blocked_by_policy" | "rejected"; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.library_promotion_without_gate validation.library_promotion_candidate_confused_with_durable_write validation.privileged_source_auto_promoted ``` ### D-21 — split background-progress overload ```ts interface RunExecutionRequirements { requires_background_execution: boolean; schema_version: "1.0"; } interface ModuleProgressBehavior { emits_progress_heartbeat: boolean; heartbeat_interval_ms?: number; schema_version: "1.0"; } ``` Required validation: ```ts validation.requires_background_progress_legacy_field_present validation.background_execution_heartbeat_confused ``` --- ## 8. §G — Professional Reliance Layer ### 8.1 Architectural ruling The Professional Reliance Layer is a strong product direction and should be kept. It is the layer that makes an output reviewable by a professional rather than merely “completed by an agent.” The artifacts are coherent: contract review, revision review, evidence binder, known-good checkpoint, budget narrative, reliance packet, attention ledger, certification, findings inbox, run diff, decision audit, replay preview, chain view, and fixtures. The layer is not yet implementable as originally written because many records are assertion-shaped. The fix is: every §G artifact is a derived/read-model artifact over canonical events, receipts, formula derivations, evidence anchors, policy decisions, source workspace snapshots, and chain resolution receipts. §G should not write new durable truth except via registered commands and receipts. ### 8.2 Reliance lifecycle, manifest, derivation, and invalidation ```ts type RelianceArtifactLifecycleState = | "draft" | "ready_for_review" | "user_reviewed" | "issued" | "superseded" | "invalidated" | "archived"; type RelianceStatus = | "safe_to_rely_within_scope" | "rely_with_limitations" | "not_safe_to_rely" | "human_review_required"; type RelianceLimitationKind = | EvaluationLimitationKind | "unchecked_claims_present" | "stale_source_present" | "unresolved_research_need" | "unreviewed_candidate_revision" | "policy_warning" | "external_side_effect_unverified" | "pattern_c_chain_unresolved" | "evidence_package_missing"; interface RelianceInputManifest { final_artifact_refs: StorageRef[]; evaluation_chain_ids: string[]; evaluation_chain_resolution_receipt_refs: StorageRef[]; evaluation_snapshot_refs: StorageRef[]; source_workspace_snapshot_refs: StorageRef[]; evidence_package_refs: StorageRef[]; revision_review_packet_refs: StorageRef[]; hard_call_resolution_refs: StorageRef[]; policy_decision_refs: PolicyEvaluationRef[]; budget_narrative_ref?: StorageRef; known_good_checkpoint_refs: string[]; created_from_event_seq: number; input_manifest_hash: string; schema_version: "1.0"; } interface RelianceStatusDerivation { status: RelianceStatus; decisive_input_refs: StorageRef[]; unresolved_limitations: RelianceLimitationKind[]; required_human_review_refs: StorageRef[]; scope_statement: string; derivation_policy_ref: string; formula_eval_receipt_ref?: StorageRef; explanation: string; schema_version: "1.0"; } interface TaskReliancePacket { packet_id: string; task_id: string; run_id: string; input_manifest: RelianceInputManifest; reliance_derivation: RelianceStatusDerivation; lifecycle_state: RelianceArtifactLifecycleState; generated_by_ref: string; reviewed_by_user_ref?: string; issued_at?: ISO8601; invalidated_by_event_ref?: StorageRef; matter_id?: string; data_class: "public" | "internal" | "privileged" | "local_only"; taint_class: TaintClass; privileged: boolean; user_visible_summary: string; schema_version: "1.1"; } interface RelianceInvalidationEvent { event_id: string; packet_id: string; invalidation_kind: | "artifact_version_changed" | "source_workspace_changed" | "finding_lifecycle_changed" | "policy_decision_superseded" | "hard_call_resolution_expired" | "evidence_package_superseded" | "evaluation_chain_resolution_changed"; triggering_ref: StorageRef; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.reliance_packet_without_input_manifest validation.reliance_status_not_derivable validation.reliance_packet_stale_snapshot validation.work_product_certification_without_reliance_packet ``` ### G-01 — EvaluationContractReview ```ts interface EvaluationContractReview { review_id: string; task_id: string; run_id?: string; compiled_plan_ref: StorageRef; interpreted_goal: string; criteria_summary: string[]; threshold_summary: string[]; source_requirements: string[]; required_capabilities: CapabilityRef[]; hard_call_triggers: HardRevisionCallKind[]; estimated_cost_vector_ref?: StorageRef; material_differences_from_preview?: string[]; user_approval_required: boolean; approval_status: | "pending" | "approved" | "rejected" | "edited" | "waived_by_policy"; approval_ref?: StorageRef; lifecycle_state: RelianceArtifactLifecycleState; command_ref?: string; created_at: ISO8601; schema_version: "1.1"; } ``` ### G-02 — RevisionReviewPacket and decision receipts ```ts type RevisionReviewPacketState = | "generated" | "review_pending" | "accepted" | "rejected" | "forked" | "changes_requested" | "restored_known_good" | "superseded"; interface RevisionReviewPacket { packet_id: string; task_id: string; run_id: string; revision_plan_ref: StorageRef; before_artifact_version_ref: StorageRef; candidate_artifact_version_ref: StorageRef; semantic_diff_ref: StorageRef; finding_to_change_map: Record; preservation_constraint_result_refs: StorageRef[]; source_changes: SourceRecordRef[]; revalidation_result_refs: StorageRef[]; regression_risk_summary: string; state: RevisionReviewPacketState; decision_receipt_refs: StorageRef[]; created_at: ISO8601; schema_version: "1.1"; } interface RevisionReviewDecisionReceipt { receipt_id: string; packet_id: string; action: | "accept" | "reject" | "fork" | "request_changes" | "restore_known_good_state" | "no_user_review_required"; actor_ref: string; rationale?: string; resulting_candidate_state?: ArtifactVersionState; command_ref?: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.revision_review_packet_contains_current_action validation.review_decision_without_receipt validation.meaning_bearing_revision_without_review_packet_or_policy_waiver ``` ### G-03 — EvidencePackage ```ts interface EvidencePackageClaimEntry { claim_ref: ClaimRef; supporting_anchor_refs: StorageRef[]; contradicting_anchor_refs: StorageRef[]; support_status: ClaimSupportStatus; support_derivation_receipt_ref: StorageRef; } interface EvidencePackage { evidence_package_id: string; task_id: string; run_id: string; final_artifact_refs: StorageRef[]; source_workspace_snapshot_ref: StorageRef; source_record_refs: SourceRecordRef[]; evidence_anchor_refs: StorageRef[]; claim_support_map: EvidencePackageClaimEntry[]; unresolved_research_need_refs: string[]; stale_or_unverified_source_refs: SourceRecordRef[]; data_class: "public" | "internal" | "privileged" | "local_only"; matter_id?: string; taint_class: TaintClass; privileged: boolean; created_at: ISO8601; schema_version: "1.1"; } ``` ### G-04 — KnownGoodCheckpoint Replace `KnownGoodState` with a checkpoint that can actually support restore/fork. ```ts interface KnownGoodCheckpoint { checkpoint_id: string; task_id: string; run_id: string; label: string; artifact_head_refs: StorageRef[]; artifact_version_refs: StorageRef[]; source_workspace_snapshot_refs: StorageRef[]; run_workspace_snapshot_ref?: StorageRef; graph_topology_snapshot_ref: StorageRef; policy_snapshot_ref: StorageRef; capability_snapshot_ref: StorageRef; event_seq: number; irreversible_side_effect_refs: StorageRef[]; created_by_ref: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.known_good_checkpoint_missing_policy_snapshot validation.known_good_checkpoint_missing_capability_snapshot validation.restore_checkpoint_ignores_irreversible_side_effects ``` ### G-05 / G-09 — cost forecast and BudgetNarrative ```ts interface TaskRunCostForecast { forecast_id: string; task_id: string; planned_run_id?: string; planned_cost_vector_ref: StorageRef; optional_helper_cost_vector_refs: StorageRef[]; non_degradable_mode_cost_vector_refs: StorageRef[]; skipped_if_budget_constrained: string[]; forecast_confidence: "calibrated" | "uncalibrated" | "experimental"; created_at: ISO8601; schema_version: "1.0"; } interface BudgetNarrative { budget_narrative_id: string; task_id: string; run_id: string; planned_forecast_ref?: StorageRef; actual_cost_record_refs: StorageRef[]; forecast_vs_actual_summary: string; summary: string; skipped_optional_helpers: string[]; preserved_non_degradable_modes: string[]; degraded_modes_used: string[]; quality_impact_summary: string; formula_eval_receipt_refs: StorageRef[]; created_at: ISO8601; schema_version: "1.1"; } ``` ### G-07 / G-13 — AttentionLedger and FindingsInbox ```ts type AttentionKind = | "hard_call_pending" | "blocked_item" | "contested_finding" | "approval_required" | "research_need_human" | "reliance_review_required" | "revision_review_pending"; interface AttentionLedgerItem { item_id: string; task_id: string; run_id?: string; matter_id?: string; attention_kind: AttentionKind; source_ref: StorageRef; summary: string; priority: "low" | "medium" | "high" | "blocking"; command_ref?: string; lifecycle_state: "open" | "resolved" | "dismissed" | "superseded"; created_at: ISO8601; resolved_at?: ISO8601; schema_version: "1.0"; } interface FindingsInboxFilter { matter_id?: string; severity?: Array<"low" | "medium" | "high" | "blocking">; finding_state?: FindingState[]; producer_kind?: ProducerKind[]; schema_version: "1.0"; } ``` ### G-08 / G-12 / G-14 / G-15 / G-20 — derived UI surfaces ```ts interface TaskHealthCard { task_id: string; run_id?: string; health_status: "healthy" | "warning" | "blocked" | "failed" | "review_required"; active_blocker_refs: StorageRef[]; latest_verdict_refs: StorageRef[]; budget_status_ref?: StorageRef; reliance_packet_ref?: StorageRef; derived_read_model_ref: StorageRef; schema_version: "1.0"; } interface WorkProductCertification { certification_id: string; task_reliance_packet_ref: StorageRef; rendered_certification_ref: StorageRef; issued_by_ref?: string; issue_command_ref?: string; lifecycle_state: RelianceArtifactLifecycleState; created_at: ISO8601; schema_version: "1.0"; } interface RunDiff { run_diff_id: string; left_run_id: string; right_run_id: string; artifact_diff_refs: StorageRef[]; plan_diff_ref?: StorageRef; outcome_diff_refs: StorageRef[]; cost_diff_ref?: StorageRef; reliance_diff_ref?: StorageRef; derived_read_model_ref: StorageRef; schema_version: "1.0"; } interface DecisionAuditView { audit_view_id: string; target_decision_ref: StorageRef; chain_resolution_receipt_refs: StorageRef[]; finding_refs: StorageRef[]; policy_decision_refs: PolicyEvaluationRef[]; hard_call_resolution_refs: StorageRef[]; explanation_trace_ref?: StorageRef; derived_read_model_ref: StorageRef; schema_version: "1.0"; } interface UnifiedEvaluationChainView { view_id: string; chain_id: string; chain_registry_record_ref: StorageRef; chain_resolution_receipt_ref?: StorageRef; qualitative_finding_refs: StorageRef[]; quantitative_result_refs: StorageRef[]; final_route_summary: string; derived_read_model_ref: StorageRef; schema_version: "1.0"; } ``` ### G-17 — TaskRunFork and side-effect ledger ```ts interface IrrevocableSideEffectAtFork { side_effect_id: string; kind: string; executed_at: ISO8601; note: "not_reversible_in_fork"; receipt_ref: StorageRef; } interface TaskRunFork { fork_id: string; parent_run_id: string; forked_from_checkpoint_ref: string; // KnownGoodCheckpoint new_run_id: string; fork_reason: string; irrevocable_side_effects_at_fork: IrrevocableSideEffectAtFork[]; created_at: ISO8601; schema_version: "1.0"; } ``` ### G-18 — ExplanationTrace without hidden chain-of-thought ```ts interface ExplanationTrace { trace_id: string; trace_kind: "evaluation" | "revision" | "routing" | "reliance"; causal_steps: Array<{ step_id: string; input_refs: StorageRef[]; operation_receipt_ref?: StorageRef; output_refs: StorageRef[]; rationale_summary: string; // user-visible explanation only evidence_refs: StorageRef[]; }>; hidden_reasoning_included: false; schema_version: "1.0"; } ``` Required validation: ```ts validation.explanation_trace_contains_hidden_reasoning validation.explanation_trace_without_causal_steps ``` ### G-19 — TaskReplay modes and divergence Do not promise deterministic replay for LLM/tool/web/provider-dependent steps. ```ts type TaskReplayMode = | "audit_reconstruction" | "deterministic_reexecution" | "best_effort_rerun" | "simulation_from_recorded_outputs"; interface TaskReplayRequest { replay_request_id: string; task_id: string; source_run_id: string; replay_mode: TaskReplayMode; checkpoint_ref?: StorageRef; known_good_checkpoint_ref?: string; allow_external_side_effects: false; allow_external_queries: boolean; model_reexecution_policy: | "reuse_recorded_outputs" | "same_model_if_available" | "current_equivalent_model"; created_at: ISO8601; schema_version: "1.0"; } interface ReplayDivergenceRecord { divergence_id: string; replay_request_id: string; divergence_kind: | "model_output_drift" | "tool_output_drift" | "source_state_changed" | "policy_changed" | "capability_unavailable" | "non_replayable_side_effect"; source_step_ref: StorageRef; original_output_hash?: string; replay_output_hash?: string; explanation: string; created_at: ISO8601; schema_version: "1.0"; } ``` Required validation: ```ts validation.replay_attempts_external_side_effect validation.deterministic_replay_with_nondeterministic_step validation.replay_divergence_unrecorded ``` ### §G command registry entries Every §G surface action must close through a command. ```ts interface RelianceLayerCommandRegistryEntry { command_id: | "reliance.issue_work_product_certification" | "reliance.invalidate_packet" | "revision_review.accept_candidate" | "revision_review.reject_candidate" | "revision_review.request_changes" | "revision_review.restore_known_good" | "evidence.export_package" | "finding.contest" | "finding.confirm" | "task_replay.preview" | "task_replay.create_fork" | "attention.resolve_item"; request_schema_ref: SchemaRef; response_schema_ref: SchemaRef; durable_write: | "required" | "none" | "explicit_no_op"; required_policy_checks: string[]; idempotency_key_required: boolean; read_model_invalidations: DerivedReadModelRecord["read_model_kind"][]; empty_state_behavior: string; blocked_state_behavior: string; degraded_state_behavior: string; error_state_behavior: string; owning_doc: OwnerDoc; schema_version: "1.0"; } ``` Required validation: ```ts validation.g_surface_action_without_command validation.g_surface_missing_empty_state validation.g_surface_missing_degraded_state validation.g_surface_missing_error_state ``` --- ## 9. Completeness, Wrong Merges, Wrong Splits, and New Issues ### 9.1 Rows to merge - **A-08 + B-23** -> `FeedbackRoutingResolutionPolicy` with branch coverage and idempotency. - **B-05 + B-06 + B-20** -> `OutcomeDependencyGraphPolicy` + `RevalidationCascadeRun`. - **B-03 + D-16** -> Source Workspace operation API with preconditions and receipts. - **D-07 + D-09 + D-12 + D-24** -> Run Board governance envelope, publication policy, retention/compaction, and matter firewall. - **D-06 + G-03** -> evidence anchors plus `ClaimSupportDerivationReceipt` supporting EvidencePackage. - **G-05 + G-09** -> cost forecast plus BudgetNarrative with forecast-vs-actual reconciliation. ### 9.2 Rows to cut or mark already present - **B-25 as written**: live spec already has `depends_on_step_ids`; replace with dependency canonicalization. - **A-11 as written**: live spec already defines `LearningMode`; correct value set is `production | signal_generation | calibration`. - **Any new parallel `StepKind` enum**: use existing `RevisionPlanStepKind`. - **G-19 wording “deterministic replay”**: keep TaskReplay but with explicit replay modes. ### 9.3 New issues to add #### N-01 — universal formula/derivation contract Add `FormulaEvaluationReceipt`, `MetricObservation`, `MetricRollup`, and derived status receipt requirements. This is the real backbone of §C and §G. #### N-02 — immutable-event/current-projection pattern Apply to findings, guidance, board posts, source workspace state, reliance packets, and revision-review decisions. #### N-03 — read-model invalidation Every lifecycle event that changes source workspace, artifact version, finding state, policy decision, hard call resolution, evidence package, or evaluation chain resolution must invalidate affected read models. #### N-04 — Source Workspace externalization policy External source queries and open/save/export actions must be governed as side effects. #### N-05 — §G command closure Every §G UI action must have command registry entry, empty/degraded/error state, durable write or explicit no-op, idempotency, telemetry, and read-model invalidation. #### N-06 — patch sequencing gate The fix package itself needs a normative sequence. ```ts type AddendaBPatchPhase = | "phase_1_shared_contracts" | "phase_2_math_and_derivation" | "phase_3_runtime_state_machines" | "phase_4_source_forum_feedback_governance" | "phase_5_reliance_ui_surfaces" | "phase_6_conformance_fixtures"; interface AddendaBPatchSequencingGate { phase: AddendaBPatchPhase; required_prior_phases: AddendaBPatchPhase[]; required_validation_passes: string[]; blocks_if_failed: boolean; schema_version: "1.0"; } ``` Recommended order: ```ts phase_1_shared_contracts: TypeOwnerRegistry, EvaluationFinding event/projection, envelope target fields, state matrix, Pattern C resolution receipt. phase_2_math_and_derivation: FormulaSpec, FormulaEvaluationReceipt, MetricObservation, MetricRollup, CostVector, corrected scoring functions. phase_3_runtime_state_machines: RevisionExecutionLifecycle, sufficiency detector, cascade run, dependency canonicalization, revalidation policy collapse, replay modes. phase_4_source_forum_feedback_governance: SourceWorkspaceOperation API, externalization policy, source taint defaults, board governance, matter firewall, routing idempotency. phase_5_reliance_ui_surfaces: Professional Reliance Layer read models, command registry entries, invalidation rules, DOC20/DOC21/DOC22 registrations. phase_6_conformance_fixtures: math test vectors, NaN/zero-denominator fixtures, replay divergence, source externalization, matter leakage, taint laundering, cascade loops. ``` --- ## 10. Conformance Fixtures and Test Requirements The amendment package should not be accepted without fixtures. Required fixture clusters: ```ts type AddendaBConformanceFixtureKind = | "finding_event_projection" | "pattern_c_route_conflict" | "formula_nan_zero_denominator" | "template_match_zero_weight" | "novelty_no_neighbor" | "sub_agent_reputation_insufficient_sample" | "source_workspace_concurrent_write" | "workspace_externalization_privileged_export" | "rolling_hash_parallel_same_artifact" | "revalidation_cascade_cycle" | "sufficiency_no_capability" | "sufficiency_missing_evidence" | "regenerate_identical_output" | "forum_cross_matter_leak" | "taint_laundering_through_summary" | "run_board_suppressed_event_stub" | "reliance_packet_invalidation" | "replay_divergence" | "hard_call_empty_options" | "command_registry_phantom_button"; interface AddendaBConformanceFixture { fixture_id: string; fixture_kind: AddendaBConformanceFixtureKind; input_bundle_ref: StorageRef; expected_validation_codes: string[]; expected_terminal_state?: string; expected_receipt_refs?: StorageRef[]; schema_version: "1.0"; } ``` Required validation: ```ts validation.accepted_patch_without_conformance_fixture validation.conformance_fixture_missing_expected_validation validation.conformance_fixture_not_executed_before_build_ready ``` --- ## 11. Final Answers to the Three Explicit Questions ### 11.1 A-01 — should `EvaluationFinding` be unified? Yes. Keeping the two schemas separate preserves a broken producer/consumer seam. The right implementation is **not** the card’s thin mutable canonical record; it is one immutable `EvaluationFindingEvent`, one mutable `EvaluationFindingRecord`, and one FD-owned `FeedbackFindingView` projection. This avoids breaking producers because producers emit immutable events, while consumers that need lifecycle state read the projection. It also preserves FD’s blocker-authority semantics through typed `BlockingAuthorityEvaluation` rather than a naked boolean. The exact schema to apply is in §4 above. ### 11.2 Professional Reliance Layer — does it work? Conceptually, yes. The layer is exactly the right product feature for high-stakes professional work: it creates a reviewable contract, reviewable revision packet, evidence binder, reliance cover memo, budget narrative, known-good checkpoint, and audit/replay surfaces. But the version in the card is not yet implementable because it is assertion-shaped and lacks lifecycle, derivation, invalidation, command closure, and empty/degraded/error states. It should be kept and hardened as follows: - Every §G artifact is a derived read model over canonical events/receipts/snapshots. - Every status has a derivation policy and receipt. - Every packet has invalidation rules. - Every user action maps to a command registry entry. - Every UI surface has empty, blocked, degraded, and error states. - `KnownGoodState` becomes `KnownGoodCheckpoint`. - `TaskReplay` uses replay modes, not a blanket deterministic-replay promise. - `ExplanationTrace` stores user-visible rationale summaries only, never hidden reasoning. The exact schemas are in §8. ### 11.3 B-24 — does the sufficiency detection contract work? The card’s idea is critical, but its authored schema is too shallow. The four triggers are a useful seed, not a complete detector. The real detector must cover missing capability, unhealthy capability, policy prohibition, exhausted procedure universe, no material score improvement, identical-output loops, insufficient evidence, unresolvable verification, contradictory requirements, unresolved preconditions, budget caps, ungranted side-effect approval, and cascade cycles. Routing every insufficiency to a Hard Call is wrong. The terminal route depends on what could actually fix the problem: ```ts missing evidence -> needs_information or needs_verification missing capability -> unable_to_evaluate + process_gap_out policy prohibition -> blocked_by_policy contradictory judgment -> needs_human_judgment / Hard Call repeated no improvement -> max_iterations_reached or unrecoverable identical regeneration -> identical_output_rejected, then replan/escalate ``` The exact schema to apply is in §5, under B-24. --- ## 12. Final Recommendations 1. **Do not apply the adjudication card as “accept all except verifies.”** Apply it as a staged amendment package with the rewrites above. 2. **Start with shared contracts.** If A-01, A-02/A-03/A-04, A-06/A-07, TypeOwnerRegistry, and FormulaEvaluationReceipt are wrong, every downstream surface inherits drift. 3. **Treat math as executable code, not prose.** Every formula needs typed inputs, missing/zero/finite policy, test vectors, and evaluation receipts. 4. **Treat §G as read-model/product UX over canonical receipts.** It should produce trust, not new truth. 5. **Do not write a second durable truth path.** All durable writes still route through EC and command registry discipline. 6. **Require fixtures before build-ready.** The fixes are heavily stateful and concurrency-sensitive; they need conformance tests, not just schemas. 7. **Update DOC20/DOC21/DOC22 for every §G surface.** The Professional Reliance Layer introduces real UI/control surfaces and must not become phantom UI. 8. **Update OP-A at close of integration.** The review surfaced new cross-doc obligations; they should be tracked explicitly when the patch package is accepted. The adjudication card is valuable, but the deeper pass shows the amendment package must become more systematic: canonical events, derived projections, formula receipts, explicit side-effect/externalization gates, command closure, and invalidation. Those are the structural moves that will make the DOC23 Addenda B set genuinely buildable instead of merely comprehensive.