Type sync request closure semantics

This commit is contained in:
Meta Vens 2026-07-13 02:45:32 +01:00
commit 3fddc87d6d
6 changed files with 68 additions and 44 deletions

View file

@ -7723,97 +7723,76 @@ fn closure_family_assertions(
);
}
"repo.sync_request" => {
let request = parse_repo_sync_request(&content).ok();
push_assertion(
&mut assertions,
"sync-request-schema-present",
content.contains("schema_version = \"epiphany.repo_sync_request.v0\""),
request
.as_ref()
.is_some_and(RepoSyncRequest::has_canonical_identity),
"Committed sync request carries the schema version.".to_string(),
);
push_assertion(
&mut assertions,
"sync-request-family-present",
content.contains("safe_action_family = \"repo.sync_request\""),
request
.as_ref()
.is_some_and(RepoSyncRequest::has_canonical_identity),
"Committed sync request carries the safe action family.".to_string(),
);
push_assertion(
&mut assertions,
"sync-request-summary-present",
content.contains(&compact_summary),
request
.as_ref()
.is_some_and(|request| request.summary == compact_summary),
"Committed sync request contains the accepted pressure summary.".to_string(),
);
push_assertion(
&mut assertions,
"sync-request-awaits-upstream-proof",
content.contains("[request]")
&& content.contains("status = \"awaiting-upstream-main-proof\"")
&& content.contains("requested_owner = \"Bifrost\"")
&& content.contains(
"requested_effect = \"prove-published-commit-contained-by-upstream-main\"",
)
&& content.contains("publication_request_ref = "),
request
.as_ref()
.is_some_and(RepoSyncRequest::awaits_upstream_proof),
"Committed sync request waits for upstream-main proof instead of performing sync."
.to_string(),
);
push_assertion(
&mut assertions,
"sync-request-antecedents-present",
content.contains("[antecedents]")
&& content.contains("publication_receipt_required = true")
&& content.contains("github_publication_required = true")
&& content.contains("maintainer_review_required = true")
&& content.contains("credit_ledger_required = true")
&& content.contains("public_proof_required = true"),
request.as_ref().is_some_and(RepoSyncRequest::has_antecedent_contract),
"Committed sync request requires publication, maintainer review, credit, and proof antecedents."
.to_string(),
);
push_assertion(
&mut assertions,
"sync-request-receipt-contract",
content.contains("[required_receipts]")
&& content.contains("bifrost_publication = \"gamecult.bifrost.public_proof_publication_receipt.v0\"")
&& content.contains("github_publication = \"gamecult.github.publication_receipt.v0\"")
&& content.contains(
"maintainer_review = \"gamecult.maintainer.review_receipt.v0\"",
)
&& content.contains("credit_ledger = \"gamecult.bifrost.credit_receipt.v0\"")
&& content.contains(
"upstream_sync = \"epiphany.repo_work_upstream_main_sync.v0\"",
)
&& content.contains("ancestry_proof = \"git.merge_base_is_ancestor\""),
request.as_ref().is_some_and(RepoSyncRequest::has_receipt_contract),
"Committed sync request names publication, review, credit, sync, and ancestry proof receipts."
.to_string(),
);
push_assertion(
&mut assertions,
"sync-request-proof-contract",
content.contains("[sync_proof]")
&& content.contains("target_ref = \"origin/main\"")
&& content.contains("requires_fetch_before_check = true")
&& content.contains("requires_merge_base_ancestor_check = true")
&& content.contains("requires_clean_public_proof_readback = true")
&& content.contains("records_upstream_main_sha = true"),
request
.as_ref()
.is_some_and(RepoSyncRequest::has_proof_contract),
"Committed sync request names the upstream-main ancestry proof contract."
.to_string(),
);
push_assertion(
&mut assertions,
"sync-request-authority-seals",
content.contains("[authority]")
&& content.contains("merge_authorized = false")
&& content.contains("push_authorized = false")
&& content.contains("upstream_sync_authorized = false")
&& content.contains("github_publication_authorized = false")
&& content.contains("credit_ledger_authorized = false")
&& content.contains("hands_action_authorized = false")
&& content.contains("cross_body_mutation_authorized = false")
&& content.contains("operator_or_maintainer_authority_required = true"),
request.as_ref().is_some_and(RepoSyncRequest::has_authority_seals),
"Committed sync request denies merge/push/sync/publication/credit/action/cross-body authority."
.to_string(),
);
push_assertion(
&mut assertions,
"sync-request-private-seal",
content.contains("private_state_exposed = false"),
request
.as_ref()
.is_some_and(|request| !request.private_state_exposed),
"Committed sync request preserves the private-state seal.".to_string(),
);
}
@ -15478,6 +15457,7 @@ idunn_deployment_authority_required = true
for family in [
"repo.tool_request",
"repo.publication_request",
"repo.sync_request",
"repo.credit_request",
"repo.artifact_acceptance_request",
"repo.metrics_request",

View file

@ -637,6 +637,33 @@ pub(super) fn parse_repo_publication_request(text: &str) -> Result<RepoPublicati
toml::from_str(text).context("publication request is not valid typed TOML")
}
#[derive(Debug, Deserialize)]
pub(super) struct RepoSyncRequest {
pub(super) schema_version: String,
pub(super) safe_action_family: String,
pub(super) summary: String,
pub(super) private_state_exposed: bool,
request: RepoSyncRequestBody,
antecedents: RepoSyncAntecedents,
required_receipts: RepoSyncReceipts,
sync_proof: RepoSyncProof,
authority: RepoSyncAuthority,
}
impl RepoSyncRequest {
pub(super) fn has_canonical_identity(&self) -> bool { self.schema_version == "epiphany.repo_sync_request.v0" && self.safe_action_family == "repo.sync_request" }
pub(super) fn awaits_upstream_proof(&self) -> bool { self.request.status == "awaiting-upstream-main-proof" && self.request.requested_owner == "Bifrost" && self.request.requested_effect == "prove-published-commit-contained-by-upstream-main" && !self.request.publication_request_ref.is_empty() }
pub(super) fn has_antecedent_contract(&self) -> bool { let a=&self.antecedents; a.publication_receipt_required && a.github_publication_required && a.maintainer_review_required && a.credit_ledger_required && a.public_proof_required }
pub(super) fn has_receipt_contract(&self) -> bool { let r=&self.required_receipts; r.bifrost_publication == "gamecult.bifrost.public_proof_publication_receipt.v0" && r.github_publication == "gamecult.github.publication_receipt.v0" && r.maintainer_review == "gamecult.maintainer.review_receipt.v0" && r.credit_ledger == "gamecult.bifrost.credit_receipt.v0" && r.upstream_sync == "epiphany.repo_work_upstream_main_sync.v0" && r.ancestry_proof == "git.merge_base_is_ancestor" }
pub(super) fn has_proof_contract(&self) -> bool { let p=&self.sync_proof; p.target_ref == "origin/main" && p.requires_fetch_before_check && p.requires_merge_base_ancestor_check && p.requires_clean_public_proof_readback && p.records_upstream_main_sha }
pub(super) fn has_authority_seals(&self) -> bool { let a=&self.authority; a.branch_local_only && !a.merge_authorized && !a.push_authorized && !a.upstream_sync_authorized && !a.github_publication_authorized && !a.credit_ledger_authorized && !a.hands_action_authorized && !a.service_lifecycle_authority && !a.cross_body_mutation_authorized && !a.private_verse_rummaging && a.operator_or_maintainer_authority_required }
}
#[derive(Debug, Deserialize)] struct RepoSyncRequestBody { status:String, requested_owner:String, requested_effect:String, publication_request_ref:String }
#[derive(Debug, Deserialize)] struct RepoSyncAntecedents { publication_receipt_required:bool, github_publication_required:bool, maintainer_review_required:bool, credit_ledger_required:bool, public_proof_required:bool }
#[derive(Debug, Deserialize)] struct RepoSyncReceipts { bifrost_publication:String, github_publication:String, maintainer_review:String, credit_ledger:String, upstream_sync:String, ancestry_proof:String }
#[derive(Debug, Deserialize)] struct RepoSyncProof { target_ref:String, requires_fetch_before_check:bool, requires_merge_base_ancestor_check:bool, requires_clean_public_proof_readback:bool, records_upstream_main_sha:bool }
#[derive(Debug, Deserialize)] struct RepoSyncAuthority { branch_local_only:bool, merge_authorized:bool, push_authorized:bool, upstream_sync_authorized:bool, github_publication_authorized:bool, credit_ledger_authorized:bool, hands_action_authorized:bool, service_lifecycle_authority:bool, cross_body_mutation_authorized:bool, private_verse_rummaging:bool, operator_or_maintainer_authority_required:bool }
pub(super) fn parse_repo_sync_request(text:&str)->Result<RepoSyncRequest>{toml::from_str(text).context("sync request is not valid typed TOML")}
#[cfg(test)]
mod tool_request_tests {
use super::*;

View file

@ -897,6 +897,19 @@ accounting/publication requests and their counterfeit-seal tests;
`include!` preserves the original parent-private `pub(super)` boundary; the
split introduces no registry, generic validator, or wider crate API.
## Sync-request prose substituted for ancestry evidence
`repo.sync_request` closure previously treated matching text as Bifrost review,
publication receipts, Git ancestry requirements, and denied sync authority. It
now parses exact typed semantics inside external governance. Upstream
containment remains evidence produced through the named fetch/merge-base proof;
the request grants no merge, push, sync, publication, credit, Hands, lifecycle,
or cross-body authority. The class-level guard prevents substring fallback.
Ten high-authority families are now typed; 667 substring assertions remain in
the measured closure region. External governance is 933 lines and remains a
bounded physical domain rather than returning to the facade slab.
## Unresolved: provider receipts without chronology
Bifrost body-change/GitHub publication receipts are externally owned and their

View file

@ -271,6 +271,10 @@ facade over `closure_contracts/external_governance.rs` and
`closure_contracts/operations.rs`. Keep new contracts with their consequence
owner; do not reunify the slab or widen its parent-private API.
Sync-request closure is now typed within external governance and guarded
against substring fallback. Current count: ten typed high-authority families
and 667 remaining closure substring assertions.
The latest structural count is 32 closure family branches, 744 remaining
substring assertions in the closure region, and 1,284 lines in
`closure_contracts.rs`. Do not blindly generate a struct forest for every

Binary file not shown.

View file

@ -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. Nine high-authority closure families, including publication request, are typed and guarded against regaining substring authority. The closure region still has 32 family branches and 704 substring assertions; the former 1,458-line contract slab is now a parent-private lexical facade over external_governance and operations authority domains. Do not substitute a blind struct forest for coherent ownership. Prioritize consequence-bearing request families, collapse shared syntax only when a named invariant earns it, and leave presentation-only markdown checks out of policy machinery. Repo-personality and verse-query smoke recursive deletion are canonically confined; 32 timestamped smokes have no recursive-delete path; all ten generated UUID temp leaves across binaries and coordinator tests require exclusive creation before cleanup. Continue auditing remaining reset helpers for provenance substituted for resolved scope. Operational/evidence/self-state and operator mirrors follow owned clocks; identity chains are typed; scheduling/runbook selection do not parse prose; writerless readiness-review is deleted. Bifrost provider receipts still need provider chronology. Continue auditing evidence/security mirrors and adapters for borrowed authority.
next_action: Continue the conceptual-substitution pass. Ten high-authority closure families, including publication and sync requests, are typed and guarded against regaining substring authority. The closure region still has 32 family branches and 667 substring assertions; closure contracts remain a parent-private lexical facade over external_governance and operations authority domains. Do not substitute a blind struct forest for coherent ownership. Prioritize consequence-bearing request families, collapse shared syntax only when a named invariant earns it, and leave presentation-only markdown checks out of policy machinery. Repo-personality and verse-query smoke recursive deletion are canonically confined; 32 timestamped smokes have no recursive-delete path; all ten generated UUID temp leaves across binaries and coordinator tests require exclusive creation before cleanup. Continue auditing remaining reset helpers for provenance substituted for resolved scope. Operational/evidence/self-state and operator mirrors follow owned clocks; identity chains are typed; scheduling/runbook selection do not parse prose; writerless readiness-review is deleted. Bifrost provider receipts still need provider chronology. Continue auditing evidence/security mirrors and adapters for borrowed authority.