Separate Persona crossing requests from publication

This commit is contained in:
Meta Vens 2026-07-13 17:19:52 +01:00
commit f6f9250b5b
5 changed files with 27 additions and 9 deletions

View file

@ -48,7 +48,8 @@ struct PersonaSpeechAudit {
recent_window_count: usize,
repeated_opening_count: usize,
repeated_topic_count: usize,
same_target_post_count: usize,
#[serde(rename = "sameTargetPostCount")]
same_target_crossing_count: usize,
audit_path: PathBuf,
}
@ -57,7 +58,7 @@ struct RecentPersonaSpeech {
opening_key: String,
topic_key: String,
target: Option<String>,
posted: bool,
crossing_recorded: bool,
}
fn main() -> Result<()> {
@ -447,9 +448,9 @@ fn audit_persona_speech(
.iter()
.filter(|speech| !topic_key.is_empty() && speech.topic_key == topic_key)
.count();
let same_target_post_count = recent
let same_target_crossing_count = recent
.iter()
.filter(|speech| speech.posted && speech.target.as_deref() == Some(&target_key))
.filter(|speech| speech.crossing_recorded && speech.target.as_deref() == Some(&target_key))
.count();
let mut reasons = Vec::new();
if public_request && repeated_opening_count >= 2 {
@ -458,7 +459,7 @@ fn audit_persona_speech(
if public_request && repeated_topic_count >= 3 {
reasons.push("repeated-topic".to_string());
}
if public_request && same_target_post_count >= 3 {
if public_request && same_target_crossing_count >= 3 {
reasons.push("target-saturation".to_string());
}
if content.trim().len() > 9000 {
@ -491,7 +492,7 @@ fn audit_persona_speech(
recent_window_count: recent.len(),
repeated_opening_count,
repeated_topic_count,
same_target_post_count,
same_target_crossing_count,
audit_path,
};
write_json(&audit.audit_path, &serde_json::to_value(&audit)?)?;
@ -512,7 +513,7 @@ fn audit_persona_speech(
recent_window_count: audit.recent_window_count as u32,
repeated_opening_count: audit.repeated_opening_count as u32,
repeated_topic_count: audit.repeated_topic_count as u32,
same_channel_post_count: audit.same_target_post_count as u32,
same_channel_post_count: audit.same_target_crossing_count as u32,
reasons: audit.reasons.clone(),
artifact_ref: audit.audit_path.display().to_string(),
created_at_utc: audit.created_at.clone(),
@ -850,7 +851,7 @@ fn recent_persona_speech(artifact_dir: &Path, limit: usize) -> Vec<RecentPersona
opening_key: audit["openingKey"].as_str().unwrap_or_default().to_string(),
topic_key: audit["topicKey"].as_str().unwrap_or_default().to_string(),
target: audit["requestedPublicTarget"].as_str().map(str::to_string),
posted: payload["status"].as_str() == Some("requested"),
crossing_recorded: payload["status"].as_str() == Some("requested"),
})
})
.collect()

View file

@ -1508,3 +1508,13 @@ receipt may prove publication or delivery.
The bridge smoke also stopped hard-coding an obsolete provider topology. It now
checks the evidence-state vocabulary and private-state seal rather than
asserting that a named surface must remain live forever.
## Crossing request is not publication
The generic Persona mouth correctly emits a Bifrost `other-request`, but its
recent-speech model called a `requested` artifact `posted` and used that fiction
for repetition pressure. It now records `crossing_recorded` and counts
`same_target_crossing_count`. Repetition protection still observes real request
effects; it no longer implies that an outside provider published them. The v0
serialized `sameTargetPostCount` field remains only as a compatibility name and
does not own the internal model.

View file

@ -580,3 +580,10 @@ Epiphany reports `provider-ready`, `prepared`, or `missing`, with explicit
native bridge smoke validates evidence vocabulary rather than stale provider
topology and was repaired to the current native status CLI. It passes alongside
259 library tests and all-bin compilation.
The generic Persona Other mouth no longer models accepted Bifrost requests as
posts. Recent speech tracks `crossing_recorded` and
`same_target_crossing_count`; actual publication still requires an external
transport receipt. The old v0 `sameTargetPostCount` spelling is serialization-
only compatibility. Native Other-mouth smoke, 259 library tests, and all-bin
compilation pass.

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 observation-to-consequence audit. Provider advertisement/readiness now remains `provider-ready`/`prepared`/`missing` in Epiphany instead of becoming `live`; only Bifrost transport receipts prove delivery. Next inspect Persona mouth result statuses and bridge audit projections for request acceptance or receipt presence standing in for successful publication. Keep closure's zero-substring invariant.
next_action: Continue the observation-to-consequence audit. Provider readiness no longer becomes live transport, and the Persona Other mouth models Bifrost request crossings rather than posts; only external transport receipts prove publication. Next inspect caller-controlled Persona draft/bubble statuses and Discord/Reddit receipt validation for caller text or receipt presence standing in for eligibility or successful publication. Keep closure's zero-substring invariant.