Add generic Bifrost Persona bridge mouth

This commit is contained in:
Meta Vens 2026-06-22 16:36:40 +01:00
commit ef729787fd
8 changed files with 1229 additions and 7 deletions

View file

@ -837,7 +837,7 @@ fn collect_coordinator_status(
"8",
],
)?;
let latest_persona = status_cli::native_json(
let latest_discord_persona = status_cli::native_json(
"epiphany-persona-discord",
&[
"latest",
@ -848,6 +848,29 @@ fn collect_coordinator_status(
],
)
.unwrap_or_else(|_| json!({"latestArtifacts": []}));
let latest_other_persona = status_cli::native_json(
"epiphany-persona-other",
&[
"latest",
"--artifact-dir",
&persona_dir.to_string_lossy(),
"--limit",
"8",
],
)
.unwrap_or_else(|_| json!({"latestArtifacts": []}));
let mut latest_artifacts = latest_discord_persona
.get("latestArtifacts")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
latest_artifacts.extend(
latest_other_persona
.get("latestArtifacts")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default(),
);
Ok(json!({
"threadId": thread_id,
"read": read,
@ -866,8 +889,8 @@ fn collect_coordinator_status(
"persona": {
"status": "ready",
"artifactDir": persona_dir,
"latestArtifacts": latest_persona.get("latestArtifacts").cloned().unwrap_or_else(|| json!([])),
"availableActions": ["PersonaBubble", "characterTurn"],
"latestArtifacts": latest_artifacts,
"availableActions": ["PersonaBubble", "characterTurn", "discordPersonaPost", "redditPersonaPost", "otherWorldPersonaRequest"],
},
}))
}

View file

@ -316,8 +316,17 @@ fn validate_status(status: &Value, rendered: &str) -> Result<()> {
&& items
.iter()
.any(|item| item.as_str() == Some("characterTurn"))
&& items
.iter()
.any(|item| item.as_str() == Some("discordPersonaPost"))
&& items
.iter()
.any(|item| item.as_str() == Some("redditPersonaPost"))
&& items
.iter()
.any(|item| item.as_str() == Some("otherWorldPersonaRequest"))
}),
"status view should expose Persona bubble and character-turn actions for Aquarium",
"status view should expose Persona bubble, character-turn, and Bifrost-routed public mouth actions for Aquarium",
)?;
require(
rendered.contains("Heartbeat") && rendered.contains("Persona"),

View file

@ -670,7 +670,7 @@ fn native_auxiliary_status(root: &Path) -> Result<NativeAuxiliaryStatus> {
"8",
],
)?;
let latest_persona = native_json(
let latest_discord_persona = native_json(
"epiphany-persona-discord",
&[
"latest",
@ -683,11 +683,36 @@ fn native_auxiliary_status(root: &Path) -> Result<NativeAuxiliaryStatus> {
.unwrap_or_else(
|error| json!({"status": "error", "error": error.to_string(), "latestArtifacts": []}),
);
let latest_other_persona = native_json(
"epiphany-persona-other",
&[
"latest",
"--artifact-dir",
&persona_dir.to_string_lossy(),
"--limit",
"8",
],
)
.unwrap_or_else(
|error| json!({"status": "error", "error": error.to_string(), "latestArtifacts": []}),
);
let mut latest_artifacts = latest_discord_persona
.get("latestArtifacts")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
latest_artifacts.extend(
latest_other_persona
.get("latestArtifacts")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default(),
);
let persona = json!({
"status": "ready",
"artifactDir": persona_dir,
"latestArtifacts": latest_persona.get("latestArtifacts").cloned().unwrap_or_else(|| json!([])),
"availableActions": ["personaBubble", "characterTurn", "discordPersonaPost"],
"latestArtifacts": latest_artifacts,
"availableActions": ["personaBubble", "characterTurn", "discordPersonaPost", "redditPersonaPost", "otherWorldPersonaRequest"],
});
let void_memory = native_json(
"epiphany-void-memory",

File diff suppressed because it is too large Load diff

View file

@ -40,6 +40,7 @@ remembers doctrine; the branch remembers the blade.
- The investment dossier readiness target is now explicit: `E:\Projects\gamecult-site\docs\gamecult_integrated_dossier.tex` expects Epiphany to be part of a Bifrost-first labor loop, not only a local Mom demo. The external proof bar is: Bifrost owns topics/work items/dispatch packets/receipts/credit/reward pressure; Epiphany executes bounded work; maintainers review artifacts; public/operator evidence records scope, consent, roles, model spend, review load, artifacts, accepted/rejected outcome, memory lessons, and case-study permission; and private worker/operator/agent context stays sealed. Diligence also asks for a live fresh-repo Epiphany demo, Bifrost work item/topic/agent transport/receipt/ledger demo, CultMesh status, VoidBot/Discord swarm demo, compute/output metrics, and security model for secrets/write permissions/public-private exports.
- Bifrost's identity-provider, GitHub bridge/work-sync, Patreon support-intake, and bridge-ledger slice is now upstream truth on `GameCult/Bifrost` `main` at commit `72ffa0d` after the bridge chain through `f1f9171`: `POST /auth/bifrost/register` creates a Bifrost-owned identity without OAuth, signs in with the Bifrost cookie, leaves membership at `Authenticated`, and records `BifrostIdentity` / `NormalizedBifrostIdentity` on `UserAccount`. That native Bifrost identity is the default authenticating identity for GameCult services that accept Bifrost trust. GitHub is hooked in two ways: bridge mutations use `tools/bifrost-bridge.mjs github-draft-pr` / `github-pr-comment` with hosted Bifrost gate/receipts, and the hosted GitHub webhook path syncs issues, PRs, and reviews into Bifrost work/review state. GitHub and Heimdall sign-in paths now ensure new accounts also get a Bifrost identity; Heimdall still owns outside-provider OAuth, account association, token custody, grants, capability/account claims, and provider support normalization. Hosted Persona/agent Discord, Reddit, and temporary `Other` future-public-surface bridge actions now require the supplied Bifrost identity to normalize through Bifrost's native identity law, resolve to a registered `UserAccount.NormalizedBifrostIdentity`, have a linked `HeimdallAccountId` on that same account, and carry a Heimdall-shaped reference before Bifrost authorizes the outside-account crossing; named surfaces still require surface-shaped references. `tools/bifrost-bridge.mjs other-request` is now the generic receipt-only CLI mouth for future public worlds: it records `Other`/`Other` bridge actions through the hosted ledger, carries identity/Heimdall/Epiphany provenance, executes no provider transport, and fails closed without Bifrost bridge base URL/token unless an operator uses the explicit dry-run recovery hatch outside a dispatched turn. Patreon support is hooked through Heimdall-signed patronage intake, not Bifrost-owned Patreon OAuth: `/heimdall/patron-support/events` verifies Heimdall HMAC, resolves linked `HeimdallAccountId`, records `ExternalPatronProvider.Patreon` support, writes patron point transactions, and derives current patron tier snapshots. Verified after adding the Patreon endpoint proof with `DOTNET_ROLL_FORWARD=Major dotnet test tests\Bifrost.Web.Tests\Bifrost.Web.Tests.csproj --filter "FullyQualifiedName~PlatformEndpointsTests"`: 37 passed; previous bridge CLI/platform proof with `BridgeCliTests|PlatformEndpointsTests` passed 66. Follow-up Bifrost commit `718ae94` syncs the provider advertisement and Eve interface binding to the current bridge truth: `print` advertises bridge action ledger, GitHub webhooks, and patron support intake; `print-surface`/`print-binding` expose GitHub, Discord, Reddit, future-surface, and Heimdall patron-support capabilities; README quick-start now names `other-request`. Verified with provider advertisement print/surface/export plus `DOTNET_ROLL_FORWARD=Major dotnet test tests\Bifrost.Web.Tests\Bifrost.Web.Tests.csproj --filter "FullyQualifiedName~ProviderAdvertisementTests|FullyQualifiedName~BridgeCliTests"`: 32 passed. Post-push `git status --short --branch` in `E:\Projects\Bifrost` reported `main...origin/main` clean.
- Persona public mouth crossings now fail closed on missing or wrong-surface authority cargo before any Bifrost CLI invocation. `epiphany-persona-discord post` and `epiphany-persona-reddit post` require a Bifrost identity plus a Heimdall-backed `heimdall:discord:*` or `heimdall:reddit:*` capability/account reference, write blocked candidate artifacts with `missing-bifrost-identity`, `missing-heimdall-capability-ref`, or `wrong-heimdall-capability-surface`, and smokes prove the bridged path still carries identity, run/lane/agent, source, authority, and surface-shaped Heimdall provenance. Verified sequentially with `cargo run --manifest-path .\epiphany-core\Cargo.toml --bin epiphany-persona-discord -- smoke` and `cargo run --manifest-path .\epiphany-core\Cargo.toml --bin epiphany-persona-reddit -- smoke`.
- Epiphany now has the matching generic Persona mouth for future Bifrost surfaces. `epiphany-persona-other` supports `draft`, `request`, `latest`, and `smoke`; records the same parent-side `epiphany.persona_speech_audit.v0` and CultMesh audit as the Discord/Reddit mouths; requires Bifrost identity plus a target-shaped Heimdall reference such as `heimdall:bluesky:*`; refuses missing bridge, missing identity, missing Heimdall reference, wrong-surface authority cargo, and repeated target saturation before transport; and invokes Bifrost `tools/bifrost-bridge.mjs other-request` with Epiphany run/lane/agent provenance when eligible. Native MVP status/coordinator Persona action lists expose `otherWorldPersonaRequest` beside Discord/Reddit, and the local wrapper build list includes the new binary. Verified with `epiphany-persona-other -- smoke`, Discord/Reddit Persona smokes, and focused `cargo check` for the touched binaries. `epiphany-mvp-status-smoke` could not run because the vendored `codex-app-server.exe` prerequisite was absent; rebuilding `codex-app-server` timed out twice without producing the binary.
- This Codex operator's own roadmap/todo posture has been retuned for this scale target, with the Epiphany Imagination specialist as an optional sub-agent rail rather than the whole point. `notes/epiphany-investor-readiness-roadmap.md` now says: make the local Mom MVP a repeatable proof bundle; build the Bifrost-first external-work bridge; add compute/review/accepted-artifact accounting; keep fresh-repo operation repeatable without supervisor contamination; keep public/operator-safe exports sealed; and treat angel capital as fuel for capacity, not command authority. The Imagination specialist prompt was also updated so investor-scale Objective Drafts must name Bifrost provenance, bounded Epiphany proof, maintainer review, receipts/ledger evidence, compute/output metrics, public/private export safety, consent, and legal/security gates.
- Local operator status runs now write typed CultMesh operator witnesses into `.epiphany-run/cultmesh/local-verse.ccmp`: `epiphany-operator-run` records the run intent before acting, `epiphany-operator-snapshot` distills the operator-safe MVP status artifact, and `epiphany-operator-run` records the completion receipt after success. The final `local-verse-context.json` is queried after those witnesses exist, so the operator read path sees latest run intent, snapshot, and receipt from the same local Verse vessel instead of treating separate JSON artifacts or side stores as truth.
- `epiphany-operator-snapshot from-status` also mirrors the latest native status `tools.invocations[]` row into the same local Verse as `epiphany.cultmesh.daemon_tool_invocation_intent.v0`, plus `epiphany.cultmesh.daemon_tool_invocation_receipt.v0` when runtime-spine has a receipt id. Runtime-spine remains the tool lifecycle owner and raw MCP JSON stays quarantined behind `epiphany.tool_invocation_intent.v0` / `epiphany.tool_invocation_receipt.v0`; the local Verse mirror is operator-safe routing/readback.

Binary file not shown.

View file

@ -82,6 +82,7 @@ active_subgoals:
- The GameCult integrated investment dossier at `E:\Projects\gamecult-site\docs\gamecult_integrated_dossier.tex` raises the Mom-ready bar from local demo to diligence-ready loop. Epiphany must be ready to prove Bifrost-first external work: a human/agent work item or topic originates in Bifrost, Epiphany decomposes and executes through bounded roles, maintainers review artifacts, Bifrost records receipts/credit, and operator-safe public evidence can be shown without exporting private worker/operator/agent context. The concrete readiness asks are fresh-repo Epiphany demo, Bifrost work item/topic/agent transport/receipt/ledger demo, compute spend and accepted-artifact metrics, and a security model for secrets, write permissions, and public/private exports. Discord, VoidBot, repo Personas, and ad hoc scripts must not become shadow governance or reward authorities.
- Bifrost bridge authority is now clarified, enforced, and pushed to `GameCult/Bifrost` upstream `main` through Bifrost commit `72ffa0d` after the bridge chain `445c279`, `23c02be`, `80a5392`, `19222bd`, `675c475`, `f1f9171`, and `72ffa0d`: Epiphany owns swarm execution, repo Body work, branch-local lanes, memory, evidence, and Persona cognition; Bifrost owns GameCult identity, native Bifrost registration/auth, governed external-world crossings, linked-account association, publication/credit/ledger receipts, patronage meaning, and GitHub/Discord/Reddit/future-public-surface bridge policy; Heimdall owns outside-provider OAuth, token custody, and verifiable capability/account/support claims that Bifrost associates with a Bifrost identity. The old Bifrost dispatch bridge was a transitional VoidBot-era worker queue, not the blessed Epiphany launcher. Local bridge tokens are actuator quarantine, not identity. Hosted Bifrost bridge actions store Bifrost identity, Heimdall capability/account reference, Epiphany run id, lane id, and agent identity; Persona/agent Discord, Reddit, or temporary `Other` outside-world actions are denied unless the Bifrost identity normalizes through Bifrost's native identity law, resolves to a registered `UserAccount.NormalizedBifrostIdentity`, that same account has a linked `HeimdallAccountId`, and named surface references are shaped for the requested target surface. GitHub is hooked as a governed bridge and work substrate: the local bridge CLI opens draft PRs and PR comments only through Bifrost gate/receipts, hosted policy requires target repositories and validates Bifrost request/governance provenance for GitHub actions, and GitHub webhooks sync issues, PRs, and reviews into Bifrost work/review state. Bifrost now has a native identity-provider slice: `POST /auth/bifrost/register` creates a Bifrost-owned account without OAuth, assigns `BifrostIdentity` / `NormalizedBifrostIdentity`, signs in with a Bifrost cookie, and leaves membership at `Authenticated` until invite/approval or Heimdall-backed grants elevate it; that Bifrost identity should be enough for most GameCult services that accept Bifrost trust, while GitHub and Heimdall paths now ensure new accounts also receive a Bifrost identity and Heimdall keeps outside-provider account association/token custody. Bifrost's local bridge CLI now exposes `other-request`, a receipt-only `BridgeTargetSurface.Other` / `BridgeActionKind.Other` crossing for future public worlds: it fails closed without `BIFROST_BRIDGE_BASE_URL` and `BIFROST_BRIDGE_TOKEN`, carries Bifrost identity plus Heimdall capability/account reference and Epiphany provenance into the hosted ledger, and deliberately executes no provider transport until the target surface earns a first-class actuator. Patreon support is hooked as Heimdall-signed patronage intake, not Bifrost-owned OAuth: `POST /heimdall/patron-support/events` verifies Heimdall HMAC, resolves the linked `HeimdallAccountId`, records `ExternalPatronProvider.Patreon` support events, writes patron point transactions, and derives current patron tier snapshots.
- Bifrost provider advertisement truth is now synced with the bridge implementation and pushed upstream at Bifrost commit `718ae94`: `tools/provider-advertisement.mjs print` names the current bridge action ledger, GitHub webhook work/review sync, and Heimdall patron-support intake endpoints; schemas call bridge action/receipt and patron support current hosted contracts; command boundaries name GitHub draft PR/comment, future-surface `other-request`, and Heimdall-signed Patreon/PayPal support facts; `print-surface` and `print-binding` expose read-only Eve/operator capability sight including `github-bridge`, `github-work-sync`, `future-surface-bridge`, and `heimdall-patron-support-intake`. Focused Bifrost proof `ProviderAdvertisementTests|BridgeCliTests` passed 32 tests, and the CultCache export path wrote advertisement, operator surface, and interface binding to a temporary witness successfully.
- Epiphany now has a generic Persona outside-world mouth for future surfaces. `epiphany-persona-other` supports `draft`, `request`, `latest`, and `smoke`; records the same parent-side `epiphany.persona_speech_audit.v0`/CultMesh audit as the Discord and Reddit mouths; requires Bifrost identity plus a surface-shaped Heimdall capability/account reference such as `heimdall:bluesky:*`; refuses missing bridge, missing identity, missing Heimdall reference, wrong Heimdall surface, and repeated target saturation before transport; and invokes Bifrost `tools/bifrost-bridge.mjs other-request` with Epiphany run/lane/agent provenance when eligible. MVP status/coordinator Persona action lists now expose `otherWorldPersonaRequest` beside Discord/Reddit public mouth actions, and the local wrapper build list includes the new binary. Verified with `epiphany-persona-other -- smoke`, Discord/Reddit Persona smokes, and focused `cargo check` for the touched status/coordinator/mouth binaries; `epiphany-mvp-status-smoke` could not run because the vendored `codex-app-server.exe` prerequisite was absent and rebuilding `codex-app-server` timed out twice without producing the binary.
- Use `notes/epiphany-investor-readiness-roadmap.md` as this Codex operator's investor-scale todo rail and as the optional Epiphany Imagination sub-agent planning rail. Angel capital is fuel for compute, review capacity, legal diligence, infrastructure, and public proof, not a governance throne. The operator roadmap is now: make the local Mom MVP a repeatable proof bundle; build the Bifrost-first external-work bridge; add model-spend/review-load/accepted-artifact accounting; keep fresh-repo operation repeatable without supervisor contamination; and keep public/operator-safe exports sealed against private worker/operator/agent context. Imagination should translate world-scale Colossus pressure into Bifrost-first Objective Drafts with consent, maintainer review, receipts/ledger evidence, compute/output metrics, public/private export safety, and bounded proof artifacts.
- The May 2026 teardown/rebuild migration is archived under `notes/archive/epiphany-ideal-architecture-rebuild-plan.md` unless a concrete regression reopens it. Preserve the new foundation: Epiphany view/coordinator policy lives in `epiphany-core`, runtime-spine owns job/result lifecycle identity through `runtime_links`, duplicate acceptance is receipt-keyed, public findings stay typed/sealed, view expansion requires a core contract, and app-server remains routing/adaptation rather than a second policy throne.
- Treat Phase 5 update/distill/propose/promote/read/notification as complete enough unless a concrete regression appears.

View file

@ -357,6 +357,7 @@ $modelRuntimeExe = Join-Path $TargetDir "debug\epiphany-model-runtime.exe"
$toolAdapterExe = Join-Path $TargetDir "debug\epiphany-tool-codex-mcp-spine.exe"
$heartbeatExe = Join-Path $TargetDir "debug\epiphany-heartbeat-store.exe"
$PersonaExe = Join-Path $TargetDir "debug\epiphany-persona-discord.exe"
$PersonaOtherExe = Join-Path $TargetDir "debug\epiphany-persona-other.exe"
$characterLoopExe = Join-Path $TargetDir "debug\epiphany-character-loop.exe"
$agentMemoryExe = Join-Path $TargetDir "debug\epiphany-agent-memory-store.exe"
$modelProvider = "openai-codex"
@ -423,6 +424,7 @@ if (-not $SkipBuild) {
"--bin", "epiphany-mvp-coordinator-smoke",
"--bin", "epiphany-heartbeat-store",
"--bin", "epiphany-persona-discord",
"--bin", "epiphany-persona-other",
"--bin", "epiphany-character-loop",
"--bin", "epiphany-agent-memory-store",
"--bin", "epiphany-agent-telemetry",