Add repo metrics request safe family

This commit is contained in:
Meta Vens 2026-06-20 17:31:55 +01:00
commit 3bddf8ba18
6 changed files with 761 additions and 10 deletions

View file

@ -0,0 +1,461 @@
use anyhow::Context;
use anyhow::Result;
use anyhow::anyhow;
use chrono::Utc;
use serde_json::Value;
use serde_json::json;
use std::env;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
fn main() -> Result<()> {
let args = Args::parse()?;
let result = run_smoke(args)?;
println!("{}", serde_json::to_string_pretty(&result)?);
Ok(())
}
#[derive(Clone, Debug)]
struct Args {
root: PathBuf,
smoke_root: PathBuf,
}
impl Args {
fn parse() -> Result<Self> {
let mut root = env::current_dir().context("failed to resolve current directory")?;
let mut smoke_root = root.join(".epiphany-smoke");
let mut args = env::args().skip(1).peekable();
while let Some(arg) = args.next() {
match arg.as_str() {
"--root" => root = take_path(&mut args, "--root")?,
"--smoke-root" => smoke_root = take_path(&mut args, "--smoke-root")?,
other => return Err(anyhow!("unexpected argument {other:?}")),
}
}
Ok(Self { root, smoke_root })
}
}
fn run_smoke(args: Args) -> Result<Value> {
let root = args
.root
.canonicalize()
.with_context(|| format!("failed to resolve {}", args.root.display()))?;
let manifest = root.join("epiphany-core").join("Cargo.toml");
if !manifest.exists() {
return Err(anyhow!(
"could not find epiphany-core manifest at {}",
manifest.display()
));
}
fs::create_dir_all(&args.smoke_root)
.with_context(|| format!("failed to create {}", args.smoke_root.display()))?;
let stamp = Utc::now().format("%Y%m%d-%H%M%S").to_string();
let smoke_dir = args
.smoke_root
.join(format!("repo-metrics-request-family-{stamp}"));
if smoke_dir.exists() {
fs::remove_dir_all(&smoke_dir)
.with_context(|| format!("failed to clear {}", smoke_dir.display()))?;
}
fs::create_dir_all(&smoke_dir)
.with_context(|| format!("failed to create {}", smoke_dir.display()))?;
let repo = smoke_dir.join("repo-body");
fs::create_dir_all(&repo).with_context(|| format!("failed to create {}", repo.display()))?;
git(["init"], &repo)?;
git(
["config", "user.email", "epiphany-smoke@example.invalid"],
&repo,
)?;
git(["config", "user.name", "Epiphany Smoke"], &repo)?;
fs::write(
repo.join("README.md"),
"# Repo Metrics Request Family Smoke\n\nThis repository proves branch-local metrics request cargo without accounting authority.\n",
)
.with_context(|| format!("failed to seed {}", repo.join("README.md").display()))?;
git(["add", "README.md"], &repo)?;
git(
["commit", "-m", "Seed repo metrics request smoke body"],
&repo,
)?;
git(
["switch", "-c", "epiphany/repo-metrics-request-family"],
&repo,
)?;
let item = "repo-metrics-request-family";
let target_path = ".epiphany/metrics-requests/repo-metrics-request-family.toml";
let local_verse = repo.join(".epiphany").join("local-verse.ccmp");
cargo_json(
&manifest,
"epiphany-repo",
&[
"init",
"--workspace",
path_str(&repo)?,
"--epiphany-root",
path_str(&root)?,
"--swarm-id",
"repo-metrics-request-family-smoke",
"--topic",
"repo-metrics-request-family",
],
&root,
)?;
cargo_json(
&manifest,
"epiphany-swarm",
&[
"online",
"--workspace",
path_str(&repo)?,
"--epiphany-root",
path_str(&root)?,
"--runtime-id",
"repo-metrics-request-family-smoke",
"--local-verse-store",
path_str(&local_verse)?,
],
&root,
)?;
cargo_json(
&manifest,
"epiphany-work",
&[
"accept",
"--workspace",
path_str(&repo)?,
"--from",
"persona",
"--item",
item,
"--summary",
"Ask Bifrost and the maintainer to record compute, review, and artifact metrics without granting accounting authority.",
"--candidate-action-ref",
"candidate-action://repo-metrics-request-family/metrics-packet",
"--candidate-action-ref",
"candidate-action://repo-metrics-request-family/accounting-review",
"--public-discussion-ref",
"epiphany-global/persona-collaboration/repo-metrics-request-family",
],
&root,
)?;
let plan = cargo_json(
&manifest,
"epiphany-work",
&[
"derive-plan",
"--workspace",
path_str(&repo)?,
"--item",
item,
"--action-family",
"repo-metrics-request",
"--model-ref",
"repo-metrics-request-family-smoke-imagination-v1",
"--model-authored",
],
&root,
)?;
for _ in 0..4 {
cargo_json(
&manifest,
"epiphany-work",
&[
"tick",
"--workspace",
path_str(&repo)?,
"--epiphany-root",
path_str(&root)?,
"--item",
item,
"--cooldown-seconds",
"0",
],
&root,
)?;
}
let close_path = repo
.join(".epiphany")
.join("work")
.join(format!("work-close-{item}.json"));
let close = read_json(&close_path)?;
let request_text = fs::read_to_string(repo.join(target_path))
.with_context(|| format!("failed to read {}", repo.join(target_path).display()))?;
require_eq(
&plan,
&["derivation", "safeActionFamily"],
"repo.metrics_request",
)?;
require_eq(&close, &["status"], "closed")?;
require_eq(&close, &["soul", "verdict"], "passed")?;
require_eq(
&close,
&["closureReview", "familyAssertions", "status"],
"passed",
)?;
require_bool(
&close,
&["closureReview", "sourceGrounding", "pathScopeMatched"],
true,
)?;
require_bool(&close, &["privateStateExposed"], false)?;
require_text(
&request_text,
"schema_version = \"epiphany.repo_metrics_request.v0\"",
)?;
require_text(
&request_text,
"safe_action_family = \"repo.metrics_request\"",
)?;
require_text(&request_text, "[request]")?;
require_text(&request_text, "status = \"awaiting-metrics-review\"")?;
require_text(&request_text, "requested_owner = \"Bifrost/Maintainer\"")?;
require_text(
&request_text,
"requested_effect = \"record-compute-review-and-artifact-accounting\"",
)?;
require_text(&request_text, "publication_request_ref = ")?;
require_text(&request_text, "credit_request_ref = ")?;
require_text(&request_text, "artifact_acceptance_request_ref = ")?;
require_text(
&request_text,
"metrics_scope = \"model spend, review load, accepted artifact, public proof, and credit readback\"",
)?;
require_text(&request_text, "[antecedents]")?;
require_text(&request_text, "closure_review_required = true")?;
require_text(&request_text, "soul_verdict_required = true")?;
require_text(&request_text, "mind_commit_required = true")?;
require_text(&request_text, "public_proof_required = true")?;
require_text(&request_text, "accepted_artifact_required = true")?;
require_text(&request_text, "credit_request_required = true")?;
require_text(&request_text, "[required_receipts]")?;
require_text(
&request_text,
"closure_review = \"epiphany.repo_work_closure_review.v0\"",
)?;
require_text(
&request_text,
"soul_verdict = \"epiphany.soul.verification_verdict\"",
)?;
require_text(
&request_text,
"mind_commit = \"epiphany.mind.state_commit_receipt\"",
)?;
require_text(
&request_text,
"public_proof = \"epiphany.repo_work_public_proof_bundle.v0\"",
)?;
require_text(
&request_text,
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"",
)?;
require_text(
&request_text,
"model_spend = \"gamecult.metrics.model_spend_receipt.v0\"",
)?;
require_text(
&request_text,
"review_load = \"gamecult.metrics.review_load_receipt.v0\"",
)?;
require_text(
&request_text,
"credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\"",
)?;
require_text(&request_text, "[metrics_packet]")?;
require_text(&request_text, "requires_model_call_count = true")?;
require_text(&request_text, "requires_token_or_cost_summary = true")?;
require_text(&request_text, "requires_review_minutes_or_count = true")?;
require_text(&request_text, "requires_accepted_artifact_ref = true")?;
require_text(&request_text, "requires_public_proof_ref = true")?;
require_text(&request_text, "requires_credit_readback_ref = true")?;
require_text(
&request_text,
"requires_private_state_redaction_check = true",
)?;
require_text(&request_text, "metrics_ledger_authorized = false")?;
require_text(&request_text, "spend_authorized = false")?;
require_text(&request_text, "review_load_authorized = false")?;
require_text(&request_text, "credit_ledger_authorized = false")?;
require_text(&request_text, "github_pr_authorized = false")?;
require_text(&request_text, "merge_authorized = false")?;
require_text(&request_text, "publication_authorized = false")?;
require_text(&request_text, "upstream_sync_authorized = false")?;
require_text(&request_text, "hands_action_authorized = false")?;
require_text(&request_text, "cross_body_mutation_authorized = false")?;
require_text(
&request_text,
"bifrost_or_maintainer_metrics_authority_required = true",
)?;
require_text(&request_text, "private_state_exposed = false")?;
let summary = json!({
"schemaVersion": "epiphany.repo_metrics_request_family_smoke.v0",
"status": "ok",
"smokeDir": smoke_dir,
"repo": repo,
"branch": git_output(["branch", "--show-current"], &repo)?,
"item": item,
"safeActionFamily": plan["derivation"]["safeActionFamily"],
"targetPath": target_path,
"closeStatus": close["status"],
"soulVerdict": close["soul"]["verdict"],
"familyAssertionsStatus": close["closureReview"]["familyAssertions"]["status"],
"pathScopeMatched": close["closureReview"]["sourceGrounding"]["pathScopeMatched"],
"awaitingMetricsReview": true,
"metricsLedgerAuthorized": false,
"spendAuthorized": false,
"reviewLoadAuthorized": false,
"creditLedgerAuthorized": false,
"githubPrAuthorized": false,
"mergeAuthorized": false,
"publicationAuthorized": false,
"upstreamSyncAuthorized": false,
"handsActionAuthorized": false,
"privateStateExposed": false,
});
write_json(&smoke_dir.join("summary.json"), &summary)?;
Ok(summary)
}
fn cargo_json(manifest: &Path, bin: &str, args: &[&str], cwd: &Path) -> Result<Value> {
let output = Command::new("cargo")
.arg("run")
.arg("--quiet")
.arg("--manifest-path")
.arg(manifest)
.arg("--bin")
.arg(bin)
.arg("--")
.args(args)
.current_dir(cwd)
.output()
.with_context(|| format!("failed to run cargo bin {bin}"))?;
if !output.status.success() {
return Err(anyhow!(
"{bin} failed with status {:?}\nstdout:\n{}\nstderr:\n{}",
output.status.code(),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
));
}
serde_json::from_slice(&output.stdout).with_context(|| {
format!(
"{bin} did not emit JSON on stdout:\n{}",
String::from_utf8_lossy(&output.stdout)
)
})
}
fn git<const N: usize>(args: [&str; N], cwd: &Path) -> Result<()> {
let output = Command::new("git")
.args(args)
.current_dir(cwd)
.output()
.with_context(|| format!("failed to run git in {}", cwd.display()))?;
if output.status.success() {
Ok(())
} else {
Err(anyhow!(
"git failed in {} with status {:?}\nstdout:\n{}\nstderr:\n{}",
cwd.display(),
output.status.code(),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
))
}
}
fn git_output<const N: usize>(args: [&str; N], cwd: &Path) -> Result<String> {
let output = Command::new("git")
.args(args)
.current_dir(cwd)
.output()
.with_context(|| format!("failed to run git in {}", cwd.display()))?;
if output.status.success() {
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
} else {
Err(anyhow!(
"git failed in {} with status {:?}\nstdout:\n{}\nstderr:\n{}",
cwd.display(),
output.status.code(),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
))
}
}
fn read_json(path: &Path) -> Result<Value> {
let bytes = fs::read(path).with_context(|| format!("failed to read {}", path.display()))?;
serde_json::from_slice(&bytes).with_context(|| format!("failed to parse {}", path.display()))
}
fn write_json(path: &Path, value: &Value) -> Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)
.with_context(|| format!("failed to create {}", parent.display()))?;
}
fs::write(path, serde_json::to_vec_pretty(value)?)
.with_context(|| format!("failed to write {}", path.display()))
}
fn require_eq(value: &Value, path: &[&str], expected: &str) -> Result<()> {
let actual = path
.iter()
.try_fold(value, |current, key| current.get(*key))
.and_then(Value::as_str)
.unwrap_or("<missing>");
if actual == expected {
Ok(())
} else {
Err(anyhow!(
"expected {} to be {expected:?}, got {actual:?}",
path.join(".")
))
}
}
fn require_bool(value: &Value, path: &[&str], expected: bool) -> Result<()> {
let actual = path
.iter()
.try_fold(value, |current, key| current.get(*key))
.and_then(Value::as_bool);
if actual == Some(expected) {
Ok(())
} else {
Err(anyhow!(
"expected {} to be {expected}, got {:?}",
path.join("."),
actual
))
}
}
fn require_text(haystack: &str, needle: &str) -> Result<()> {
if haystack.contains(needle) {
Ok(())
} else {
Err(anyhow!(
"expected metrics request text to contain {needle:?}"
))
}
}
fn take_path(
args: &mut std::iter::Peekable<impl Iterator<Item = String>>,
flag: &str,
) -> Result<PathBuf> {
args.next()
.map(PathBuf::from)
.with_context(|| format!("missing value for {flag}"))
}
fn path_str(path: &Path) -> Result<&str> {
path.to_str()
.ok_or_else(|| anyhow!("path is not valid UTF-8: {}", path.display()))
}

View file

@ -1918,8 +1918,11 @@ fn derive_safe_plan_family(input: DeriveSafePlanInput<'_>) -> Result<DerivedSafe
| "accepted-artifact-request" => {
derive_repo_artifact_acceptance_request_plan(input, &action_family)
}
"repo-metrics-request" | "metrics-request" | "accounting-request" => {
derive_repo_metrics_request_plan(input, &action_family)
}
other => Err(anyhow!(
"unsupported derive-plan action family {other:?}; supported families are append-worklog, planning-note, checklist-note, section-note, repo-status-section, task-card, repo-manifest, repo-tool-capabilities, repo-collaboration-topic, repo-consensus-brief, repo-objective-draft, repo-adoption-request, repo-scheduling-request, repo-work-order, repo-verification-request, repo-publication-request, repo-sync-request, repo-maintainer-review-request, repo-pr-request, repo-credit-request, and repo-artifact-acceptance-request"
"unsupported derive-plan action family {other:?}; supported families are append-worklog, planning-note, checklist-note, section-note, repo-status-section, task-card, repo-manifest, repo-tool-capabilities, repo-collaboration-topic, repo-consensus-brief, repo-objective-draft, repo-adoption-request, repo-scheduling-request, repo-work-order, repo-verification-request, repo-publication-request, repo-sync-request, repo-maintainer-review-request, repo-pr-request, repo-credit-request, repo-artifact-acceptance-request, and repo-metrics-request"
)),
}
}
@ -4224,6 +4227,154 @@ fn derive_repo_artifact_acceptance_request_plan(
})
}
fn derive_repo_metrics_request_plan(
input: DeriveSafePlanInput<'_>,
action_family: &str,
) -> Result<DerivedSafePlan> {
let item_slug = sanitize(input.item);
let default_target = format!(".epiphany/metrics-requests/{item_slug}.toml");
let target_path = validate_toml_target_path(input.target_path.unwrap_or(&default_target))?;
let candidate_refs =
string_array_from_json(input.accept_receipt, &["feedback", "candidateActionRefs"]);
let public_refs =
string_array_from_json(input.accept_receipt, &["feedback", "publicDiscussionRefs"]);
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
let request_id = format!("repo-metrics-request:{item_slug}");
let publication_request_ref = format!(".epiphany/publication-requests/{item_slug}.toml");
let credit_request_ref = format!(".epiphany/credit-requests/{item_slug}.toml");
let artifact_acceptance_request_ref =
format!(".epiphany/artifact-acceptance-requests/{item_slug}.toml");
let lines = vec![
"# Epiphany repo metrics request.".to_string(),
"# Branch-local accounting request cargo; not spend, review, credit, publication, PR, merge, or sync authority.".to_string(),
format!(
"schema_version = {}",
toml_basic_string("epiphany.repo_metrics_request.v0")
),
format!("item = {}", toml_basic_string(input.item)),
format!("created_at = {}", toml_basic_string(&now)),
format!("source = {}", toml_basic_string(input.source)),
format!("summary = {}", toml_basic_string(&compact_line(input.summary))),
format!(
"safe_action_family = {}",
toml_basic_string("repo.metrics_request")
),
format!("model_authored = {}", input.model_authored),
format!(
"model_ref = {}",
toml_basic_string(input.model_ref.unwrap_or("deterministic-fallback"))
),
"operator_authored_shell_details = false".to_string(),
"hands_authority_granted = false".to_string(),
"metrics_ledger_authorized = false".to_string(),
"spend_authorized = false".to_string(),
"review_load_authorized = false".to_string(),
"credit_ledger_authorized = false".to_string(),
"github_pr_authorized = false".to_string(),
"merge_authorized = false".to_string(),
"publication_authorized = false".to_string(),
"upstream_sync_authorized = false".to_string(),
"durable_state_admitted = false".to_string(),
"service_lifecycle_authority = false".to_string(),
"cross_repo_mutation = false".to_string(),
"private_state_exposed = false".to_string(),
format!("candidate_action_refs = {}", toml_array(&candidate_refs)),
format!("public_discussion_refs = {}", toml_array(&public_refs)),
String::new(),
"[request]".to_string(),
format!("id = {}", toml_basic_string(&request_id)),
"status = \"awaiting-metrics-review\"".to_string(),
"requested_owner = \"Bifrost/Maintainer\"".to_string(),
"requested_effect = \"record-compute-review-and-artifact-accounting\"".to_string(),
format!(
"publication_request_ref = {}",
toml_basic_string(&publication_request_ref)
),
format!("credit_request_ref = {}", toml_basic_string(&credit_request_ref)),
format!(
"artifact_acceptance_request_ref = {}",
toml_basic_string(&artifact_acceptance_request_ref)
),
"metrics_scope = \"model spend, review load, accepted artifact, public proof, and credit readback\""
.to_string(),
String::new(),
"[antecedents]".to_string(),
"closure_review_required = true".to_string(),
"soul_verdict_required = true".to_string(),
"mind_commit_required = true".to_string(),
"public_proof_required = true".to_string(),
"accepted_artifact_required = true".to_string(),
"credit_request_required = true".to_string(),
String::new(),
"[required_receipts]".to_string(),
"closure_review = \"epiphany.repo_work_closure_review.v0\"".to_string(),
"soul_verdict = \"epiphany.soul.verification_verdict\"".to_string(),
"mind_commit = \"epiphany.mind.state_commit_receipt\"".to_string(),
"public_proof = \"epiphany.repo_work_public_proof_bundle.v0\"".to_string(),
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"".to_string(),
"model_spend = \"gamecult.metrics.model_spend_receipt.v0\"".to_string(),
"review_load = \"gamecult.metrics.review_load_receipt.v0\"".to_string(),
"credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\"".to_string(),
String::new(),
"[metrics_packet]".to_string(),
"requires_model_call_count = true".to_string(),
"requires_token_or_cost_summary = true".to_string(),
"requires_review_minutes_or_count = true".to_string(),
"requires_accepted_artifact_ref = true".to_string(),
"requires_public_proof_ref = true".to_string(),
"requires_credit_readback_ref = true".to_string(),
"requires_private_state_redaction_check = true".to_string(),
String::new(),
"[authority]".to_string(),
"branch_local_only = true".to_string(),
"metrics_ledger_authorized = false".to_string(),
"spend_authorized = false".to_string(),
"review_load_authorized = false".to_string(),
"credit_ledger_authorized = false".to_string(),
"github_pr_authorized = false".to_string(),
"merge_authorized = false".to_string(),
"publication_authorized = false".to_string(),
"upstream_sync_authorized = false".to_string(),
"hands_action_authorized = false".to_string(),
"service_lifecycle_authority = false".to_string(),
"cross_body_mutation_authorized = false".to_string(),
"private_verse_rummaging = false".to_string(),
"bifrost_or_maintainer_metrics_authority_required = true".to_string(),
String::new(),
"[verification]".to_string(),
"asks = [".to_string(),
" \"Soul verifies the metrics request path changed and contains the accepted pressure summary.\",".to_string(),
" \"Soul verifies the request names model spend, review load, accepted artifact, public proof, credit readback, and redaction requirements without authorizing ledger writes.\",".to_string(),
" \"Soul verifies no publication, PR, merge, sync, Hands, service lifecycle, or cross-body authority is granted.\"".to_string(),
"]".to_string(),
String::new(),
"[rollback]".to_string(),
"hints = [\"Remove the metrics request if the work is not ready for Bifrost/maintainer accounting review.\"]"
.to_string(),
String::new(),
];
let command = powershell_set_lines_command(&target_path, &lines);
Ok(DerivedSafePlan {
safe_action_family: "repo.metrics_request".to_string(),
target_path,
plan_summary: format!(
"Imagination derived a repo metrics request from accepted {} pressure.",
input.source
),
command,
commit_message: format!("Add metrics request for repo work item {}", input.item),
verification_asks: vec![
"Soul verifies the repo metrics request path changed and contains the accepted pressure summary.".to_string(),
"Soul verifies the request requires model spend, review load, accepted artifact, public proof, and credit readback receipts without authorizing metrics ledger writes, spend, review-load mutation, publication, PR, merge, sync, service lifecycle, or cross-body mutation.".to_string(),
"Soul verifies no paths outside the declared metrics request changed.".to_string(),
],
rollback_hints: vec![
"Remove the generated metrics request if the work is not ready for accounting review.".to_string(),
],
derivation: plan_derivation_receipt(input, action_family, "repo.metrics_request"),
})
}
fn closure_family_assertions(
workspace: &Path,
commit_sha: &str,
@ -5683,6 +5834,118 @@ fn closure_family_assertions(
.to_string(),
);
}
"repo.metrics_request" => {
push_assertion(
&mut assertions,
"metrics-request-schema-present",
content.contains("schema_version = \"epiphany.repo_metrics_request.v0\""),
"Committed metrics request carries the schema version.".to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-family-present",
content.contains("safe_action_family = \"repo.metrics_request\""),
"Committed metrics request carries the safe action family.".to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-summary-present",
content.contains(&compact_summary),
"Committed metrics request contains the accepted pressure summary.".to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-awaits-review",
content.contains("[request]")
&& content.contains("status = \"awaiting-metrics-review\"")
&& content.contains("requested_owner = \"Bifrost/Maintainer\"")
&& content.contains(
"requested_effect = \"record-compute-review-and-artifact-accounting\"",
)
&& content.contains("publication_request_ref = ")
&& content.contains("credit_request_ref = ")
&& content.contains("artifact_acceptance_request_ref = "),
"Committed metrics request waits for Bifrost/maintainer review before consequence."
.to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-antecedents-present",
content.contains("[antecedents]")
&& content.contains("closure_review_required = true")
&& content.contains("soul_verdict_required = true")
&& content.contains("mind_commit_required = true")
&& content.contains("public_proof_required = true")
&& content.contains("accepted_artifact_required = true")
&& content.contains("credit_request_required = true"),
"Committed metrics request requires closure, Soul, Mind, proof, accepted artifact, and credit request antecedents."
.to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-receipt-contract",
content.contains("[required_receipts]")
&& content.contains(
"closure_review = \"epiphany.repo_work_closure_review.v0\"",
)
&& content.contains(
"soul_verdict = \"epiphany.soul.verification_verdict\"",
)
&& content.contains("mind_commit = \"epiphany.mind.state_commit_receipt\"")
&& content.contains(
"public_proof = \"epiphany.repo_work_public_proof_bundle.v0\"",
)
&& content.contains(
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"",
)
&& content.contains("model_spend = \"gamecult.metrics.model_spend_receipt.v0\"")
&& content.contains("review_load = \"gamecult.metrics.review_load_receipt.v0\"")
&& content.contains(
"credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\"",
),
"Committed metrics request names closure, proof, artifact, spend, review-load, and credit readback receipts."
.to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-packet-contract",
content.contains("[metrics_packet]")
&& content.contains("requires_model_call_count = true")
&& content.contains("requires_token_or_cost_summary = true")
&& content.contains("requires_review_minutes_or_count = true")
&& content.contains("requires_accepted_artifact_ref = true")
&& content.contains("requires_public_proof_ref = true")
&& content.contains("requires_credit_readback_ref = true")
&& content.contains("requires_private_state_redaction_check = true"),
"Committed metrics request names model-call, cost, review-load, artifact, proof, credit, and redaction requirements."
.to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-authority-seals",
content.contains("[authority]")
&& content.contains("metrics_ledger_authorized = false")
&& content.contains("spend_authorized = false")
&& content.contains("review_load_authorized = false")
&& content.contains("credit_ledger_authorized = false")
&& content.contains("github_pr_authorized = false")
&& content.contains("merge_authorized = false")
&& content.contains("publication_authorized = false")
&& content.contains("upstream_sync_authorized = false")
&& content.contains("hands_action_authorized = false")
&& content.contains("cross_body_mutation_authorized = false")
&& content
.contains("bifrost_or_maintainer_metrics_authority_required = true"),
"Committed metrics request denies metrics/spend/review/credit/PR/merge/publication/sync/action/cross-body authority."
.to_string(),
);
push_assertion(
&mut assertions,
"metrics-request-private-seal",
content.contains("private_state_exposed = false"),
"Committed metrics request preserves the private-state seal.".to_string(),
);
}
_ => {
return Ok((
json!({
@ -9531,7 +9794,7 @@ fn print_usage() {
"usage: epiphany-work <persona-intake|accept|derive-plan|plan|run|adopt|execute|close|publish|sync|overview|export-proof|tick|queue-run|serve> ...\n\
persona-intake --workspace <repo> --item <id> --message <text> [--topic <topic>] [--store <local-verse.ccmp>] [--runtime-id <id>]\n\
accept --workspace <repo> --from <persona|bifrost|persona-or-bifrost> --item <id> [--summary <text>] [--topic <topic>] [--store <local-verse.ccmp>] [--runtime-id <id>] [--online-receipt <path>] [--public-discussion-ref <ref>] [--candidate-action-ref <ref>]\n\
derive-plan --workspace <repo> [--item <id>] [--accept-receipt <path>] [--action-family append-worklog|planning-note|checklist-note|section-note|repo-status-section|task-card|repo-manifest|repo-tool-capabilities|repo-collaboration-topic|repo-consensus-brief|repo-objective-draft|repo-adoption-request|repo-scheduling-request|repo-work-order|repo-verification-request|repo-publication-request|repo-sync-request|repo-maintainer-review-request|repo-pr-request|repo-credit-request|repo-artifact-acceptance-request] [--target-path <path>] [--model-ref <ref>] [--model-authored] [--action-summary <text>] [--verification-ask <text>] [--stop-condition <text>] [--escalation-reason <text>]\n\
derive-plan --workspace <repo> [--item <id>] [--accept-receipt <path>] [--action-family append-worklog|planning-note|checklist-note|section-note|repo-status-section|task-card|repo-manifest|repo-tool-capabilities|repo-collaboration-topic|repo-consensus-brief|repo-objective-draft|repo-adoption-request|repo-scheduling-request|repo-work-order|repo-verification-request|repo-publication-request|repo-sync-request|repo-maintainer-review-request|repo-pr-request|repo-credit-request|repo-artifact-acceptance-request|repo-metrics-request] [--target-path <path>] [--model-ref <ref>] [--model-authored] [--action-summary <text>] [--verification-ask <text>] [--stop-condition <text>] [--escalation-reason <text>]\n\
plan --workspace <repo> [--item <id>] --objective <text> --plan-summary <text> --command <command> --changed-path <path> --commit-message <text> [--adoption-evidence-ref <ref>]\n\
run --workspace <repo> [--item <id>] [--accept-receipt <path>] [--runtime-store <path>] [--requested-path <path>]\n\
adopt --workspace <repo> [--item <id>] [--run-receipt <path>] [--from-plan <path>] [--plan-summary <text>] [--adoption-evidence-ref <ref>]\n\

View file

@ -326,17 +326,22 @@ Soul, Mind, public proof, maintainer review, Hands commit, artifact reference,
commit SHA, changed paths, review verdict, public proof, acceptance rationale,
and redaction requirements without itself granting artifact acceptance, credit
ledger, publication, PR, merge, upstream sync, Hands action, or cross-body
authority. Its receipt includes
authority; and `--action-family repo-metrics-request` writes a structured
accounting request under `.epiphany/metrics-requests/<item>.toml`, naming model
spend, review load, accepted artifact, public proof, credit readback, and
redaction requirements without itself granting metrics ledger, spend,
review-load, credit ledger, publication, PR, merge, upstream sync, Hands action,
or cross-body authority. Its receipt includes
`epiphany.repo_work_plan_derivation.v0`, mode `append-worklog`,
`planning-note`, `checklist-note`, `section-note`, `repo-status-section`, or
`task-card`, `repo-manifest`, `repo-tool-capabilities`, or
`repo-collaboration-topic`, `repo-consensus-brief`, `repo-objective-draft`, or
`repo-adoption-request`, `repo-scheduling-request`, `repo-work-order`, or
`repo-verification-request`, `repo-publication-request`, `repo-sync-request`, or
`repo-maintainer-review-request`, `repo-pr-request`, `repo-credit-request`, or
`repo-artifact-acceptance-request`, a `safeActionFamily`, and an authority seal
forbidding publication, merge, service lifecycle mutation, cross-repo mutation,
and private state exposure.
`repo-maintainer-review-request`, `repo-pr-request`, `repo-credit-request`,
`repo-artifact-acceptance-request`, or `repo-metrics-request`, a
`safeActionFamily`, and an authority seal forbidding publication, merge, service
lifecycle mutation, cross-repo mutation, and private state exposure.
These deterministic families are quarantine scaffolding on the road to
model-authored Imagination, but they are no longer operator-authored shell
details.
@ -654,6 +659,22 @@ rationale, and redaction, denied artifact acceptance, credit ledger, GitHub PR,
merge, publication, upstream sync, Hands action, cross-body authority, and
`privateStateExposed=false`.
The next accounting boundary smoke proved metrics request cargo:
`.epiphany-smoke\repo-metrics-request-family-20260620-162919` ran init ->
online -> accept -> `derive-plan --action-family repo-metrics-request
--model-ref repo-metrics-request-family-smoke-imagination-v1 --model-authored`
-> tick through run/adopt/execute/close on a fresh repo. The plan carried
`safeActionFamily=repo.metrics_request`; Hands committed only
`.epiphany/metrics-requests/repo-metrics-request-family.toml`; Soul passed with
`pathScopeMatched=true` and `familyAssertions.status=passed`; the committed
request carried `schema_version = "epiphany.repo_metrics_request.v0"`,
`status="awaiting-metrics-review"`, closure/Soul/Mind/public-proof,
accepted-artifact, and credit-request antecedents, metrics packet requirements
for model calls, token/cost summary, review load, accepted artifact, proof,
credit readback, and redaction, denied metrics ledger, spend, review-load,
credit ledger, GitHub PR, merge, publication, upstream sync, Hands action,
cross-body authority, and `privateStateExposed=false`.
### Landed Work Run Gate
The sixth front door exists as native Rust:
@ -1367,7 +1388,7 @@ temptation wearing clean robes.
| Repo Body birth | `epiphany-repo init` exists and writes repo-local stores plus branch workbench intent. | Keep birth startup-only, review-gated, and branch-oriented. |
| Local Verse online | `epiphany-swarm online` seeds repo-local CultMesh, standing-faculty SoA, topology, liveness, Eve, and tool sight. | Keep private Verse sealed while exposing operator-safe repo status. |
| Persona/Bifrost intake | `epiphany-work accept` records pressure and candidate action refs without Hands authority. `epiphany-work persona-intake` now invokes the Persona bubble speech-audit path, records public discussion and candidate-action refs, then delegates to `accept`; wrapper mode `repo-persona-intake` exposes the operator mouth. | Deepen the intake-to-Imagination interpreter so richer model-authored action items can be proposed without granting Hands, publication, or durable-state authority at the mouth edge. |
| Imagination planning | `derive-plan` now writes a typed `epiphany.repo_work_imagination_action_items_receipt.v0` before the executable plan receipt. The action-item receipt can carry model provenance, allowed safe family, requested paths, verification asks, stop conditions, escalation reasons, and private-state seals; command text remains deterministic safe-family lowering for `append-worklog`, `planning-note`, `checklist-note`, `section-note` / `repo.markdown_managed_section`, `repo-status-section` / `repo.status_section`, `task-card` / `repo.task_card`, `repo-manifest` / `repo.body_manifest`, `repo-tool-capabilities` / `repo.tool_capabilities`, `repo-collaboration-topic` / `repo.collaboration_topic`, `repo-consensus-brief` / `repo.consensus_brief`, `repo-objective-draft` / `repo.objective_draft`, `repo-adoption-request` / `repo.adoption_request`, `repo-scheduling-request` / `repo.scheduling_request`, `repo-work-order` / `repo.work_order`, `repo-verification-request` / `repo.verification_request`, `repo-publication-request` / `repo.publication_request`, `repo-sync-request` / `repo.sync_request`, `repo-maintainer-review-request` / `repo.maintainer_review_request`, `repo-pr-request` / `repo.pr_request`, `repo-credit-request` / `repo.credit_request`, and `repo-artifact-acceptance-request` / `repo.artifact_acceptance_request`. `plan` remains manual quarantine scaffolding. | Deepen model-authored planning and further useful repo-owned configuration classes without turning model text into arbitrary shell authority. |
| Imagination planning | `derive-plan` now writes a typed `epiphany.repo_work_imagination_action_items_receipt.v0` before the executable plan receipt. The action-item receipt can carry model provenance, allowed safe family, requested paths, verification asks, stop conditions, escalation reasons, and private-state seals; command text remains deterministic safe-family lowering for `append-worklog`, `planning-note`, `checklist-note`, `section-note` / `repo.markdown_managed_section`, `repo-status-section` / `repo.status_section`, `task-card` / `repo.task_card`, `repo-manifest` / `repo.body_manifest`, `repo-tool-capabilities` / `repo.tool_capabilities`, `repo-collaboration-topic` / `repo.collaboration_topic`, `repo-consensus-brief` / `repo.consensus_brief`, `repo-objective-draft` / `repo.objective_draft`, `repo-adoption-request` / `repo.adoption_request`, `repo-scheduling-request` / `repo.scheduling_request`, `repo-work-order` / `repo.work_order`, `repo-verification-request` / `repo.verification_request`, `repo-publication-request` / `repo.publication_request`, `repo-sync-request` / `repo.sync_request`, `repo-maintainer-review-request` / `repo.maintainer_review_request`, `repo-pr-request` / `repo.pr_request`, `repo-credit-request` / `repo.credit_request`, `repo-artifact-acceptance-request` / `repo.artifact_acceptance_request`, and `repo-metrics-request` / `repo.metrics_request`. `plan` remains manual quarantine scaffolding. | Deepen model-authored planning and further useful repo-owned configuration classes without turning model text into arbitrary shell authority. |
| Self scheduling | `tick` and `serve` prove one-step branch-local advancement, brake refusal, active-turn refusal, cooldown, and stale-turn recovery; `tick` now routes executed branch-local work through the existing Soul/Modeling/Mind `close` gate; `queue-run` selects tick-actionable rows from the typed repo-work queue and delegates to `tick`; `epiphany-swarm run` is the bounded operator mouth over that queue/tick physiology; `repo-work-service-plan` and `repo-work-service-runbook` write Idunn lifecycle receipts/artifacts for the same queue-run command without launching it. | Keep any future queue-run service launch/install behind Idunn and explicit operator authority. |
| Branch-local Hands work | `adopt` and `execute` create approved Hands gates, run planned commands, stage declared paths, commit on `epiphany/*`, and write receipts. | Keep mutation branch-contained and receipt-backed; broaden only through typed plan families, not ad hoc shell freedom. |
| Soul/Modeling/Mind closure | `close` verifies the Hands commit, writes `epiphany.repo_work_closure_review.v0`, refuses path-scope mismatches, and writes Soul, Modeling, and Mind receipts. | Deepen model-authored closure review beyond the first structured closure-review packet while preserving deterministic local closure for simple mechanical work. |
@ -1694,6 +1715,11 @@ Required organs before MVP:
antecedents plus artifact/commit/path/review/proof/rationale/redaction packet
requirements while granting no artifact acceptance, credit ledger,
publication, PR, merge, sync, Hands, or cross-body authority.
`repo-metrics-request` now proves accounting request cargo that names
closure/Soul/Mind/public-proof, accepted-artifact, and credit-request
antecedents plus model-call/token-cost/review-load/artifact/proof/credit-readback/redaction
packet requirements while granting no metrics ledger, spend, review-load,
credit ledger, publication, PR, merge, sync, Hands, or cross-body authority.
Remaining work is later model-authored action classes that can change more
useful repo-owned configuration without arbitrary shell authority.
- Closure depth: `close` now writes a structured

View file

@ -134,6 +134,7 @@ remembers doctrine; the branch remembers the blade.
- 2026-06-20: `repo-pr-request` is now live as GitHub/Bifrost PR request cargo. `epiphany-work derive-plan --action-family repo-pr-request` writes `.epiphany/pr-requests/<item>.toml` with safe family `repo.pr_request`, status `awaiting-pr-publication-review`, closure/Soul/Mind/public-proof, maintainer-review, Bifrost-publication, and credit antecedents, branch/title/body/path/proof/review/credit/redaction packet requirements, and denials for GitHub PR, branch push, merge, publication, upstream sync, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, PR packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-pr-request-family-20260620-160046` ran init -> online -> accept -> repo-pr-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/pr-requests/repo-pr-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingPrPublicationReview=true`, `githubPrAuthorized=false`, `branchPushAuthorized=false`, `mergeAuthorized=false`, `publicationAuthorized=false`, `upstreamSyncAuthorized=false`, `handsActionAuthorized=false`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are richer model-authored planning depth beyond deterministic safe-family lowering, more useful repo-owned configuration/action families, and Idunn-owned queue-run service lifecycle under explicit operator authority.
- 2026-06-20: `repo-credit-request` is now live as Bifrost credit request cargo. `epiphany-work derive-plan --action-family repo-credit-request` writes `.epiphany/credit-requests/<item>.toml` with safe family `repo.credit_request`, status `awaiting-bifrost-credit-review`, closure/Soul/Mind/public-proof, maintainer-review, accepted-artifact, and authorship antecedents, author/reviewer/artifact/proof/path/ledger/redaction packet requirements, and denials for credit ledger, Bifrost publication, GitHub PR, merge, publication, upstream sync, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, credit packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-credit-request-family-20260620-160803` ran init -> online -> accept -> repo-credit-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/credit-requests/repo-credit-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingBifrostCreditReview=true`, `creditLedgerAuthorized=false`, `bifrostPublicationAuthorized=false`, `githubPrAuthorized=false`, `mergeAuthorized=false`, `publicationAuthorized=false`, `upstreamSyncAuthorized=false`, `handsActionAuthorized=false`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are richer model-authored planning depth beyond deterministic safe-family lowering, more useful repo-owned configuration/action families, and Idunn-owned queue-run service lifecycle under explicit operator authority.
- 2026-06-20: `repo-artifact-acceptance-request` is now live as accepted-artifact request cargo. `epiphany-work derive-plan --action-family repo-artifact-acceptance-request` writes `.epiphany/artifact-acceptance-requests/<item>.toml` with safe family `repo.artifact_acceptance_request`, status `awaiting-artifact-acceptance-review`, closure/Soul/Mind/public-proof, maintainer-review, and Hands-commit antecedents, artifact/commit/path/review/proof/rationale/redaction packet requirements, and denials for artifact acceptance, credit ledger, GitHub PR, merge, publication, upstream sync, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, artifact packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-artifact-acceptance-request-family-20260620-161559` ran init -> online -> accept -> repo-artifact-acceptance-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/artifact-acceptance-requests/repo-artifact-acceptance-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingArtifactAcceptanceReview=true`, `artifactAcceptanceAuthorized=false`, `creditLedgerAuthorized=false`, `githubPrAuthorized=false`, `mergeAuthorized=false`, `publicationAuthorized=false`, `upstreamSyncAuthorized=false`, `handsActionAuthorized=false`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are richer model-authored planning depth beyond deterministic safe-family lowering, more useful repo-owned configuration/action families, and Idunn-owned queue-run service lifecycle under explicit operator authority.
- 2026-06-20: `repo-metrics-request` is now live as Bifrost/maintainer accounting request cargo. `epiphany-work derive-plan --action-family repo-metrics-request` writes `.epiphany/metrics-requests/<item>.toml` with safe family `repo.metrics_request`, status `awaiting-metrics-review`, closure/Soul/Mind/public-proof, accepted-artifact, and credit-request antecedents, model-call/token-cost/review-load/artifact/proof/credit-readback/redaction packet requirements, and denials for metrics ledger, spend, review-load, credit ledger, GitHub PR, merge, publication, upstream sync, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, metrics packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-metrics-request-family-20260620-162919` ran init -> online -> accept -> repo-metrics-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/metrics-requests/repo-metrics-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingMetricsReview=true`, `metricsLedgerAuthorized=false`, `spendAuthorized=false`, `reviewLoadAuthorized=false`, `creditLedgerAuthorized=false`, `githubPrAuthorized=false`, `mergeAuthorized=false`, `publicationAuthorized=false`, `upstreamSyncAuthorized=false`, `handsActionAuthorized=false`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are richer model-authored planning depth beyond deterministic safe-family lowering, more useful repo-owned configuration/action families, and Idunn-owned queue-run service lifecycle under explicit operator authority.
- `service-execution-runbook` makes that next cut repeatable: it generates the exact elevated wrapper command sequence without mutating the service manager, continues after per-step failure to preserve more receipts, runs `service-execution-audit` in `finally`, exits nonzero if any step failed, and seals a typed runbook lifecycle receipt. Run the generated artifact only with explicit operator authority.
- `service-execution-audit` is the non-mutating acceptance proof after the elevated rite: it reports `complete` only when typed lifecycle receipts prove the runbook witness plus expected elevated chain, and otherwise reports the missing/failed sealed checks.
- `service-tick` is the non-elevated scheduler pulse proof: it writes the latest daemon scheduler receipt through durable policy ownership and local wrapper receipts.

Binary file not shown.

File diff suppressed because one or more lines are too long