From e48e2ad521eaeaecd07688721559de702e792ce1 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 13 Jul 2026 04:20:56 +0100 Subject: [PATCH] Separate doctrine update authority --- ...phany-repo-doctrine-review-family-smoke.rs | 15 ++- epiphany-core/src/bin/epiphany-work.rs | 108 +++++++++--------- .../closure_contracts/operations.rs | 107 +++++++++++++++++ ...onceptual-substitution-audit-2026-07-12.md | 13 +++ notes/epiphany-current-algorithmic-map.md | 1 + notes/fresh-workspace-handoff.md | 6 + state/ledgers.msgpack | Bin 474212 -> 474696 bytes state/map.yaml | 2 +- 8 files changed, 193 insertions(+), 59 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-repo-doctrine-review-family-smoke.rs b/epiphany-core/src/bin/epiphany-repo-doctrine-review-family-smoke.rs index 8e9653d8..94ed4277 100644 --- a/epiphany-core/src/bin/epiphany-repo-doctrine-review-family-smoke.rs +++ b/epiphany-core/src/bin/epiphany-repo-doctrine-review-family-smoke.rs @@ -222,7 +222,13 @@ fn run_smoke(args: Args) -> Result { )?; require_text(&request_text, "[request]")?; require_text(&request_text, "status = \"awaiting-doctrine-review\"")?; - require_text(&request_text, "requested_owner = \"Maintainer/Mind\"")?; + require_text(&request_text, "routing_owner = \"Self\"")?; + require_text( + &request_text, + "required_reviewers = [\"Maintainer\", \"Mind\", \"Soul\"]", + )?; + require_text(&request_text, "doctrine_admission_owner = \"Mind\"")?; + require_text(&request_text, "mutation_owner = \"Hands\"")?; require_text( &request_text, "requested_effect = \"review-repo-agent-doctrine-update\"", @@ -276,10 +282,9 @@ fn run_smoke(args: Args) -> Result { require_text(&request_text, "service_lifecycle_authority = false")?; require_text(&request_text, "cross_body_mutation_authorized = false")?; require_text(&request_text, "private_verse_rummaging = false")?; - require_text( - &request_text, - "maintainer_or_mind_doctrine_authority_required = true", - )?; + require_text(&request_text, "maintainer_review_required = true")?; + require_text(&request_text, "mind_admission_required = true")?; + require_text(&request_text, "hands_receipts_required = true")?; require_text(&request_text, "private_state_exposed = false")?; require_text( &agents_text, diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index 0e4cf7c5..3e79faad 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -5123,7 +5123,10 @@ fn derive_repo_doctrine_update_request_plan( "[request]".to_string(), format!("id = {}", toml_basic_string(&request_id)), "status = \"awaiting-doctrine-review\"".to_string(), - "requested_owner = \"Maintainer/Mind\"".to_string(), + "routing_owner = \"Self\"".to_string(), + "required_reviewers = [\"Maintainer\", \"Mind\", \"Soul\"]".to_string(), + "doctrine_admission_owner = \"Mind\"".to_string(), + "mutation_owner = \"Hands\"".to_string(), "requested_effect = \"review-repo-agent-doctrine-update\"".to_string(), format!("doctrine_target = {}", toml_basic_string(doctrine_target)), "change_surface = \"repo-local agent instructions and operating doctrine\"".to_string(), @@ -5163,7 +5166,9 @@ fn derive_repo_doctrine_update_request_plan( "service_lifecycle_authority = false".to_string(), "cross_body_mutation_authorized = false".to_string(), "private_verse_rummaging = false".to_string(), - "maintainer_or_mind_doctrine_authority_required = true".to_string(), + "maintainer_review_required = true".to_string(), + "mind_admission_required = true".to_string(), + "hands_receipts_required = true".to_string(), String::new(), "[verification]".to_string(), "asks = [".to_string(), @@ -7194,106 +7199,73 @@ fn closure_family_assertions( ); } "repo.doctrine_update_request" => { + let request = parse_repo_doctrine_update_request(&content).ok(); push_assertion( &mut assertions, "doctrine-update-request-schema-present", - content.contains("schema_version = \"epiphany.repo_doctrine_update_request.v0\""), + request + .as_ref() + .is_some_and(RepoDoctrineUpdateRequest::has_canonical_identity), "Committed doctrine update request carries the schema version.".to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-family-present", - content.contains("safe_action_family = \"repo.doctrine_update_request\""), + request + .as_ref() + .is_some_and(RepoDoctrineUpdateRequest::has_canonical_identity), "Committed doctrine update request carries the safe action family.".to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-summary-present", - content.contains(&compact_summary), + request + .as_ref() + .is_some_and(|value| value.summary == compact_summary), "Committed doctrine update request contains the accepted pressure summary." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-awaits-review", - content.contains("[request]") - && content.contains("status = \"awaiting-doctrine-review\"") - && content.contains("requested_owner = \"Maintainer/Mind\"") - && content.contains( - "requested_effect = \"review-repo-agent-doctrine-update\"", - ) - && content.contains("doctrine_target = \"AGENTS.md\"") - && content.contains("requires_source_grounding = true") - && content.contains("requires_human_or_maintainer_review = true"), + request.as_ref().is_some_and(RepoDoctrineUpdateRequest::has_coherent_routing), "Committed doctrine update request waits for Mind/maintainer review before doctrine consequence." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-antecedents-present", - content.contains("[antecedents]") - && content.contains("persona_or_human_feedback_required = true") - && content.contains("imagination_plan_required = true") - && content.contains("mind_adoption_required = true") - && content.contains("soul_review_required = true") - && content.contains("maintainer_review_required = true"), + request.as_ref().is_some_and(RepoDoctrineUpdateRequest::has_antecedent_contract), "Committed doctrine update request requires feedback, Imagination, Mind, Soul, and maintainer antecedents." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-receipt-contract", - content.contains("[required_receipts]") - && content.contains( - "imagination_plan = \"epiphany.repo_work_imagination_action_items_receipt.v0\"", - ) - && content.contains( - "mind_adoption = \"epiphany.repo_work_mind_adoption_decision.v0\"", - ) - && content.contains( - "soul_review = \"epiphany.repo_work_closure_review.v0\"", - ) - && content.contains( - "maintainer_review = \"gamecult.maintainer.review_receipt.v0\"", - ) - && content.contains("hands_commit = \"epiphany.hands.commit_receipt\""), + request.as_ref().is_some_and(RepoDoctrineUpdateRequest::has_receipt_contract), "Committed doctrine update request names Imagination, Mind, Soul, maintainer, and Hands receipts." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-packet-contract", - content.contains("[doctrine_packet]") - && content.contains("requires_current_doctrine_ref = true") - && content.contains("requires_proposed_change_summary = true") - && content.contains("requires_invariant_impact = true") - && content.contains("requires_rehydration_impact = true") - && content.contains("requires_rollback_plan = true") - && content.contains("requires_private_state_redaction_check = true"), + request.as_ref().is_some_and(RepoDoctrineUpdateRequest::has_packet_contract), "Committed doctrine update request names doctrine diff, invariant, rehydration, rollback, and redaction requirements." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-authority-seals", - content.contains("[authority]") - && content.contains("direct_doctrine_mutation_authority = false") - && content.contains("direct_hands_authority = false") - && content.contains("direct_mind_state_commit = false") - && content.contains("publication_authorized = false") - && content.contains("merge_authorized = false") - && content.contains("service_lifecycle_authority = false") - && content.contains("cross_body_mutation_authorized = false") - && content.contains("private_verse_rummaging = false") - && content - .contains("maintainer_or_mind_doctrine_authority_required = true"), + request.as_ref().is_some_and(RepoDoctrineUpdateRequest::has_authority_seals), "Committed doctrine update request denies doctrine/action/state/publication/service/cross-body authority." .to_string(), ); push_assertion( &mut assertions, "doctrine-update-request-private-seal", - content.contains("private_state_exposed = false"), + request + .as_ref() + .is_some_and(|value| !value.private_state_exposed), "Committed doctrine update request preserves the private-state seal.".to_string(), ); } @@ -13978,6 +13950,7 @@ idunn_deployment_authority_required = true "repo.artifact_acceptance_request", "repo.metrics_request", "repo.readiness_review_request", + "repo.doctrine_update_request", "repo.secret_policy_request", "repo.dependency_policy_request", "repo.deployment_config", @@ -14032,6 +14005,35 @@ idunn_deployment_authority_required = true ); } + #[test] + fn doctrine_comment_cannot_counterfeit_hands_authority_seal() { + let text = r#" +schema_version = "epiphany.repo_doctrine_update_request.v0" +safe_action_family = "repo.doctrine_update_request" +summary = "summary" +private_state_exposed = false +[request] +status = "awaiting-doctrine-review" +routing_owner = "Self" +required_reviewers = ["Maintainer", "Mind", "Soul"] +doctrine_admission_owner = "Mind" +mutation_owner = "Hands" +requested_effect = "review-repo-agent-doctrine-update" +doctrine_target = "AGENTS.md" +requires_source_grounding = true +requires_human_or_maintainer_review = true +[antecedents] +[required_receipts] +[doctrine_packet] +[authority] +direct_doctrine_mutation_authority = false +# direct_hands_authority = false +direct_hands_authority = true +"#; + let request = parse_repo_doctrine_update_request(text).expect("fixture is typed TOML"); + assert!(!request.has_authority_seals()); + } + #[test] fn modeling_finding_round_trips_and_refuses_private_state() -> Result<()> { let temp = tempfile::tempdir()?; diff --git a/epiphany-core/src/bin/epiphany_work/closure_contracts/operations.rs b/epiphany-core/src/bin/epiphany_work/closure_contracts/operations.rs index 3aedd529..e261873e 100644 --- a/epiphany-core/src/bin/epiphany_work/closure_contracts/operations.rs +++ b/epiphany-core/src/bin/epiphany_work/closure_contracts/operations.rs @@ -549,3 +549,110 @@ impl RepoDeploymentRequest { pub(super) fn parse_repo_deployment_request(text: &str) -> Result { toml::from_str(text).context("deployment request is not valid typed TOML") } + +#[derive(Debug, Deserialize)] +pub(super) struct RepoDoctrineUpdateRequest { + pub(super) schema_version: String, + pub(super) safe_action_family: String, + pub(super) summary: String, + pub(super) private_state_exposed: bool, + request: RepoDoctrineRequestBody, + antecedents: std::collections::BTreeMap, + required_receipts: std::collections::BTreeMap, + doctrine_packet: std::collections::BTreeMap, + authority: std::collections::BTreeMap, +} +impl RepoDoctrineUpdateRequest { + pub(super) fn has_canonical_identity(&self) -> bool { + self.schema_version == "epiphany.repo_doctrine_update_request.v0" + && self.safe_action_family == "repo.doctrine_update_request" + } + pub(super) fn has_coherent_routing(&self) -> bool { + let r = &self.request; + r.status == "awaiting-doctrine-review" + && r.routing_owner == "Self" + && r.required_reviewers == ["Maintainer", "Mind", "Soul"] + && r.doctrine_admission_owner == "Mind" + && r.mutation_owner == "Hands" + && r.requested_effect == "review-repo-agent-doctrine-update" + && r.doctrine_target == "AGENTS.md" + && r.requires_source_grounding + && r.requires_human_or_maintainer_review + } + pub(super) fn has_antecedent_contract(&self) -> bool { + [ + "persona_or_human_feedback_required", + "imagination_plan_required", + "mind_adoption_required", + "soul_review_required", + "maintainer_review_required", + ] + .iter() + .all(|key| self.antecedents.get(*key) == Some(&true)) + } + pub(super) fn has_receipt_contract(&self) -> bool { + [ + ( + "imagination_plan", + "epiphany.repo_work_imagination_action_items_receipt.v0", + ), + ( + "mind_adoption", + "epiphany.repo_work_mind_adoption_decision.v0", + ), + ("soul_review", "epiphany.repo_work_closure_review.v0"), + ("maintainer_review", "gamecult.maintainer.review_receipt.v0"), + ("hands_commit", "epiphany.hands.commit_receipt"), + ] + .iter() + .all(|(key, value)| self.required_receipts.get(*key).is_some_and(|v| v == value)) + } + pub(super) fn has_packet_contract(&self) -> bool { + [ + "requires_current_doctrine_ref", + "requires_proposed_change_summary", + "requires_invariant_impact", + "requires_rehydration_impact", + "requires_rollback_plan", + "requires_private_state_redaction_check", + ] + .iter() + .all(|key| self.doctrine_packet.get(*key) == Some(&true)) + } + pub(super) fn has_authority_seals(&self) -> bool { + [ + "direct_doctrine_mutation_authority", + "direct_hands_authority", + "direct_mind_state_commit", + "publication_authorized", + "merge_authorized", + "service_lifecycle_authority", + "cross_body_mutation_authorized", + "private_verse_rummaging", + ] + .iter() + .all(|key| self.authority.get(*key) == Some(&false)) + && [ + "maintainer_review_required", + "mind_admission_required", + "hands_receipts_required", + ] + .iter() + .all(|key| self.authority.get(*key) == Some(&true)) + } +} +#[derive(Debug, Deserialize)] +struct RepoDoctrineRequestBody { + status: String, + routing_owner: String, + required_reviewers: Vec, + doctrine_admission_owner: String, + mutation_owner: String, + requested_effect: String, + doctrine_target: String, + requires_source_grounding: bool, + requires_human_or_maintainer_review: bool, +} +pub(super) fn parse_repo_doctrine_update_request(text: &str) -> Result { + toml::from_str(text).context("doctrine update request is not valid typed TOML") +} diff --git a/notes/conceptual-substitution-audit-2026-07-12.md b/notes/conceptual-substitution-audit-2026-07-12.md index 79ba28aa..bee02ae3 100644 --- a/notes/conceptual-substitution-audit-2026-07-12.md +++ b/notes/conceptual-substitution-audit-2026-07-12.md @@ -1232,6 +1232,19 @@ trees. Direct source inventory now reports 56 substring occurrences across seven remaining families. +## Reviewer OR-gate as doctrine authority + +`repo.doctrine_update_request` named `Maintainer/Mind` as one owner and +required `maintainer_or_mind` doctrine authority, collapsing review and +admission into an ambiguous OR gate. Typed operations closure now requires the +actual chain: Imagination authors, Self routes, Maintainer reviews, Soul +verifies, Mind admits doctrine state, and Hands performs the `AGENTS.md` +mutation under receipts. A comment cannot counterfeit Hands denial. + +All remaining substring-backed families are presentation-only. Direct source +inventory is 17 occurrences across worklog, planning/checklist notes, +managed/status sections, and task cards. + The same inspection found 33 consecutive duplicate `#[cfg(test)]` attributes on provider constructors/writers and their re-exports. One gate already makes each item test-only; the second owned nothing. The duplicates are removed. diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index 642d6e26..3f29b1ee 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -56,6 +56,7 @@ - Repo collaboration policy/topic files are proposals, not live social or renderer contracts. Imagination authors them, Persona owns discussion, Persona/Mind review policy, Mind admits repo policy, Bifrost owns publication, and requested public-room/Eve-surface identifiers remain unpublished until provider receipts exist. Epiphany does not own downstream Eve/TUI/GUI composition. - The deterministic `repo.tool_capabilities` and `repo.eve_surface` safe families are deleted. Expected tool ids and invented surface/row/lowering catalogs cannot substitute for host advertisements or provider-published composition graphs. Live paths are typed tool requests/host receipts, Odin discovery, Eve connection receipts, and provider-owned publication. - `repo.body_manifest` is deleted. An unconsumed `epiphany.toml` that invents Body/Verse/Eve identity and capability hints is not observed runtime state or admitted birth configuration. Runtime state, repo birth receipts, and provider advertisements own those facts. +- Doctrine update requests split authority: Imagination authors, Self routes, Maintainer reviews, Soul verifies, Mind admits doctrine state, and Hands mutates `AGENTS.md` under receipts. There is no Maintainer/Mind composite owner or OR gate. - `repo.planning_brief` is deleted. It contained no candidate work-item records and let copied global catalog/schema/closure constants self-attest as per-item planning and readiness evidence. The live preparation chain is consensus draft -> interpretation request -> objective draft -> Mind adoption. - There is no aggregate repo-swarm MVP gate. The former smoke manually aggregated fixture summaries into green rows and `demoReady=true`; it and its wrapper are deleted. Whole-organism readiness requires a live-fire path whose claimed consequences are observed at their owning boundaries. - Persona owner: `collaboration-feedback` writes public, bounded feedback only after that provider receipt exists. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index a65bd98a..52fc9619 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -406,6 +406,12 @@ belong to collaboration policy and the deleted manifest family is rejected. The recursive legacy smoke timed out and spawned nested Cargo trees, so it was not treated as proof. Direct inventory is 56 occurrences across seven families. +Doctrine review no longer has a `Maintainer/Mind` composite owner or OR gate. +Imagination authors, Self routes, Maintainer reviews, Soul verifies, Mind admits +doctrine state, and Hands mutates `AGENTS.md` under receipts. Typed operations +closure and a counterfeit-Hands fixture protect the chain. The remaining +source inventory is 17 occurrences across six presentation families. + Consensus Brief keeps its honest draft/unconverged semantics but no longer proves them with substring presence. Preparation owns its typed consensus, Imagination route, inputs, authority, and privacy closure; a malicious comment diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index b41d16b1d0ac438532b6d54870b423d585722e5d..3563d1bb31938e00ccb651596199e7fcf21493ec 100644 GIT binary patch delta 419 zcmYjNy-EW?5cbZ*D@0p`1Q`&qiDyg*F@Y2oq82fbq_T<2-6SsD?p}8H5>iMC3!fm~ zYX}Oyf!JBuSo;tb7VaLR79YzD-+Vv&@mYNND&B88tCe!IR=ap!@>)9&+s@c=rn7}%{HH!Cw1GBOr6Pi1PK%ESo7AetG7S%8=oh}pJJ JWnw>X2>^U56H@>H diff --git a/state/map.yaml b/state/map.yaml index f3fcc7ca..e2351fca 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -660,4 +660,4 @@ current_status: - Service lifecycle receipt history is now event-only: `load_epiphany_cultmesh_daemon_service_lifecycle_receipts` filters out the `epiphany-local/daemon-service-lifecycle-receipt/latest` mirror, while `load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt` remains the latest-state reader. Focused unit test `service_lifecycle_receipt_history_excludes_latest_mirror` proves two per-receipt writes return exactly two history records and latest points at the second. Fresh smoke `verse-query-lifecycle-history-filter-smoke` and live overview/triage `local-20260618-145632-497-efac6f0d` / `local-20260618-145632-321-867947af` prove compact swarm sights still expose service lifecycle attention plus the present elevated runbook artifact without daemon pokes or service mutation. Do not use a broad unscoped cargo test filter for this check on Windows; it fans out across bin harnesses and hit a broken pipe during this pass. - `epiphany-verse-query seed-compact` is the compact seed receipt for wrappers and read-only rites. The older `seed` command still prints the full local Verse context for explicit debugging, but compact wrapper modes now avoid full `seed`/final `query` readback after the combined overview proof exposed Windows debug stack overflow from full-context serialization pressure. last_completed_repo_swarm_cut: Huginn live-fire has crossed the first real repo Body from Persona pressure to branch-local Hands commit and Soul/Mind closure, and now has repeatable closure and redacted-public-proof mouths. On `E:\Projects\Huginn` branch `epiphany/huginn/first-awakening`, `tools/epiphany_local_run.ps1 -Mode repo-persona-intake` accepted item `huginn-inspection-readback-livefire`, Weksa/Persona intake remained sealed, and `epiphany-work derive-plan` lowered it to model-authored safe family `repo.status_section` for `README.md` only. `tools/epiphany_local_run.ps1 -Mode repo-swarm-run` advanced four bounded pulses: run-from-plan, adopt-from-plan, execute-from-plan, and close-from-execute. Huginn commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2` updated only `README.md`; closure receipt `.epiphany\work\work-close-huginn-inspection-readback-livefire.json` records status `closed`, Soul verdict `passed`, Mind state commit `repo-work-close-huginn-inspection-readback-livefire-mind-commit`, safe family `repo.status_section`, path scope `README.md`, Bifrost publication gate, and `privateStateExposed=false`. Verification also ran Huginn's TypeScript compiler through concrete Node path: `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json` passed. Native verifier `epiphany-repo-livefire-closure-smoke --workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` checks closure receipt, Mind map entry, overview gate/blocker, authority seals, and `git show` changed paths, returning `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, and `privateStateExposed=false`. Wrapper `tools/epiphany_local_run.ps1 -Mode repo-livefire-closure -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exposes the same read-only proof through the local operator mouth; artifact `local-20260621-190156-803-2f85ba15` printed commit, path, gate, blocker, Soul verdict, Mind commit receipt, and `privateStateExposed=False` without push, merge, publication, or target mutation. New wrapper `tools/epiphany_local_run.ps1 -Mode repo-work-public-proof -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exports the redacted proof bundle and repo-local Verse index without publishing; artifact `local-20260621-190645-345-4555b1dc` wrote `.epiphany\public\proof-bundles\repo-work-public-proof-huginn-inspection-readback-livefire.json`, proof id `repo-work-public-proof-huginn-inspection-readback-livefire`, SHA-256 `857545b199f3e37eb06c2e757e5cfc201958e46667bb1f8403fd333a22620f63`, nine artifact rows, zero publication rows, and `privateStateExposed=False`. swarm overview readback `local-20260621-190701-140-b9519ec6` sees the `REPO-WORK-PUBLIC-PROOF` row and action row from Huginn's repo-local Verse with the same SHA-256 while Bifrost publication remains missing. Launcher compact modes are now named compact operator-context modes instead of read-only modes, and `bifrost-public-proof` summaries print item, target public Verse, room, proof SHA-256, review receipts, and credit receipts so publication receipts are auditable without claiming upstream sync. - next_action: Continue the conceptual-substitution pass. repo.body_manifest is deleted because unconsumed epiphany.toml invented Body/Verse/Eve identity and capability hints; runtime state, repo birth receipts, and provider advertisements remain authoritative. A direct generator test proves collaboration policy owns its proposal fields and the deleted manifest family is rejected. Direct source inventory reports 56 content.contains occurrences across seven families. Next map repo.doctrine_update_request ownership and decide whether deterministic AGENTS.md cargo is an honest Maintainer/Mind proposal or another adopted-law fiction. The six tiny presentation families should be typed or demoted only after doctrine authority is clean. + next_action: Finish the closure conceptual-substitution pass. Doctrine requests now split Imagination authoring, Self routing, Maintainer review, Soul verification, Mind admission, and Hands mutation; no composite owner or OR gate remains. Every consequence-bearing closure family is typed or deleted. Direct source inventory is 17 content.contains occurrences across six presentation-only families: worklog, planning/checklist notes, managed/status sections, and task cards. Classify these explicitly as presentation-only and either type their small structural contracts or remove closure assertions that pretend presentation text is authority. Then audit beyond closure for remaining borrowed-owner strings and false provider mirrors.