Add repo credit request safe family

This commit is contained in:
Meta Vens 2026-06-20 17:12:19 +01:00
commit b5cb3beda5
6 changed files with 750 additions and 9 deletions

View file

@ -0,0 +1,455 @@
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-credit-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 Credit Request Family Smoke\n\nThis repository proves branch-local Bifrost credit request cargo without credit ledger authority.\n",
)
.with_context(|| format!("failed to seed {}", repo.join("README.md").display()))?;
git(["add", "README.md"], &repo)?;
git(
["commit", "-m", "Seed repo credit request smoke body"],
&repo,
)?;
git(
["switch", "-c", "epiphany/repo-credit-request-family"],
&repo,
)?;
let item = "repo-credit-request-family";
let target_path = ".epiphany/credit-requests/repo-credit-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-credit-request-family-smoke",
"--topic",
"repo-credit-request-family",
],
&root,
)?;
cargo_json(
&manifest,
"epiphany-swarm",
&[
"online",
"--workspace",
path_str(&repo)?,
"--epiphany-root",
path_str(&root)?,
"--runtime-id",
"repo-credit-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 to prepare credit ledger review for an accepted artifact without granting credit authority.",
"--candidate-action-ref",
"candidate-action://repo-credit-request-family/credit-packet",
"--candidate-action-ref",
"candidate-action://repo-credit-request-family/bifrost-ledger-review",
"--public-discussion-ref",
"epiphany-global/persona-collaboration/repo-credit-request-family",
],
&root,
)?;
let plan = cargo_json(
&manifest,
"epiphany-work",
&[
"derive-plan",
"--workspace",
path_str(&repo)?,
"--item",
item,
"--action-family",
"repo-credit-request",
"--model-ref",
"repo-credit-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.credit_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_credit_request.v0\"",
)?;
require_text(
&request_text,
"safe_action_family = \"repo.credit_request\"",
)?;
require_text(&request_text, "[request]")?;
require_text(&request_text, "status = \"awaiting-bifrost-credit-review\"")?;
require_text(&request_text, "requested_owner = \"Bifrost\"")?;
require_text(
&request_text,
"requested_effect = \"record-credit-for-redacted-proof-and-accepted-artifact\"",
)?;
require_text(&request_text, "maintainer_review_request_ref = ")?;
require_text(&request_text, "publication_request_ref = ")?;
require_text(&request_text, "pr_request_ref = ")?;
require_text(
&request_text,
"credit_scope = \"authorship, maintainer review, accepted artifact, public proof, and Bifrost ledger 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, "maintainer_review_required = true")?;
require_text(&request_text, "accepted_artifact_required = true")?;
require_text(&request_text, "authorship_context_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,
"maintainer_review = \"gamecult.maintainer.review_receipt.v0\"",
)?;
require_text(
&request_text,
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"",
)?;
require_text(
&request_text,
"credit_ledger = \"gamecult.bifrost.credit_receipt.v0\"",
)?;
require_text(
&request_text,
"credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\"",
)?;
require_text(&request_text, "[credit_packet]")?;
require_text(&request_text, "requires_author_identity = true")?;
require_text(&request_text, "requires_reviewer_identity = true")?;
require_text(&request_text, "requires_accepted_artifact_ref = true")?;
require_text(&request_text, "requires_changed_path_list = true")?;
require_text(&request_text, "requires_public_proof_ref = true")?;
require_text(&request_text, "requires_credit_ledger_target = true")?;
require_text(
&request_text,
"requires_private_state_redaction_check = true",
)?;
require_text(&request_text, "credit_ledger_authorized = false")?;
require_text(&request_text, "bifrost_publication_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_credit_authority_required = true")?;
require_text(&request_text, "private_state_exposed = false")?;
let summary = json!({
"schemaVersion": "epiphany.repo_credit_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"],
"awaitingBifrostCreditReview": true,
"creditLedgerAuthorized": false,
"bifrostPublicationAuthorized": 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 credit 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

@ -1910,8 +1910,11 @@ fn derive_safe_plan_family(input: DeriveSafePlanInput<'_>) -> Result<DerivedSafe
"repo-pr-request" | "pr-request" | "pull-request-request" | "github-pr-request" => {
derive_repo_pr_request_plan(input, &action_family)
}
"repo-credit-request" | "credit-request" | "bifrost-credit-request" => {
derive_repo_credit_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, and repo-pr-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, and repo-credit-request"
)),
}
}
@ -3921,6 +3924,152 @@ fn derive_repo_pr_request_plan(
})
}
fn derive_repo_credit_request_plan(
input: DeriveSafePlanInput<'_>,
action_family: &str,
) -> Result<DerivedSafePlan> {
let item_slug = sanitize(input.item);
let default_target = format!(".epiphany/credit-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-credit-request:{item_slug}");
let publication_request_ref = format!(".epiphany/publication-requests/{item_slug}.toml");
let maintainer_review_request_ref = format!(".epiphany/review-requests/{item_slug}.toml");
let pr_request_ref = format!(".epiphany/pr-requests/{item_slug}.toml");
let lines = vec![
"# Epiphany repo Bifrost credit request.".to_string(),
"# Branch-local credit ledger request cargo; not credit, publication, PR, merge, or sync authority."
.to_string(),
format!(
"schema_version = {}",
toml_basic_string("epiphany.repo_credit_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.credit_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(),
"credit_ledger_authorized = false".to_string(),
"bifrost_publication_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-bifrost-credit-review\"".to_string(),
"requested_owner = \"Bifrost\"".to_string(),
"requested_effect = \"record-credit-for-redacted-proof-and-accepted-artifact\""
.to_string(),
format!(
"publication_request_ref = {}",
toml_basic_string(&publication_request_ref)
),
format!(
"maintainer_review_request_ref = {}",
toml_basic_string(&maintainer_review_request_ref)
),
format!("pr_request_ref = {}", toml_basic_string(&pr_request_ref)),
"credit_scope = \"authorship, maintainer review, accepted artifact, public proof, and Bifrost ledger 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(),
"maintainer_review_required = true".to_string(),
"accepted_artifact_required = true".to_string(),
"authorship_context_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(),
"maintainer_review = \"gamecult.maintainer.review_receipt.v0\"".to_string(),
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"".to_string(),
"credit_ledger = \"gamecult.bifrost.credit_receipt.v0\"".to_string(),
"credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\"".to_string(),
String::new(),
"[credit_packet]".to_string(),
"requires_author_identity = true".to_string(),
"requires_reviewer_identity = true".to_string(),
"requires_accepted_artifact_ref = true".to_string(),
"requires_public_proof_ref = true".to_string(),
"requires_changed_path_list = true".to_string(),
"requires_credit_ledger_target = true".to_string(),
"requires_private_state_redaction_check = true".to_string(),
String::new(),
"[authority]".to_string(),
"branch_local_only = true".to_string(),
"credit_ledger_authorized = false".to_string(),
"bifrost_publication_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_credit_authority_required = true".to_string(),
String::new(),
"[verification]".to_string(),
"asks = [".to_string(),
" \"Soul verifies the credit request path changed and contains the accepted pressure summary.\",".to_string(),
" \"Soul verifies the request names authorship, reviewer, accepted artifact, public proof, and redaction requirements without authorizing credit 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 credit request if the artifact has not been accepted or credited by Bifrost.\"]"
.to_string(),
String::new(),
];
let command = powershell_set_lines_command(&target_path, &lines);
Ok(DerivedSafePlan {
safe_action_family: "repo.credit_request".to_string(),
target_path,
plan_summary: format!(
"Imagination derived a Bifrost credit request from accepted {} pressure.",
input.source
),
command,
commit_message: format!("Add credit request for repo work item {}", input.item),
verification_asks: vec![
"Soul verifies the repo credit request path changed and contains the accepted pressure summary.".to_string(),
"Soul verifies the request requires authorship, maintainer review, accepted artifact, public proof, credit ledger, and readback receipts without authorizing credit, publication, PR, merge, sync, service lifecycle, or cross-body mutation.".to_string(),
"Soul verifies no paths outside the declared credit request changed.".to_string(),
],
rollback_hints: vec![
"Remove the generated credit request if the artifact is not ready for Bifrost credit review.".to_string(),
],
derivation: plan_derivation_receipt(input, action_family, "repo.credit_request"),
})
}
fn closure_family_assertions(
workspace: &Path,
commit_sha: &str,
@ -5157,6 +5306,116 @@ fn closure_family_assertions(
"Committed PR request preserves the private-state seal.".to_string(),
);
}
"repo.credit_request" => {
push_assertion(
&mut assertions,
"credit-request-schema-present",
content.contains("schema_version = \"epiphany.repo_credit_request.v0\""),
"Committed credit request carries the schema version.".to_string(),
);
push_assertion(
&mut assertions,
"credit-request-family-present",
content.contains("safe_action_family = \"repo.credit_request\""),
"Committed credit request carries the safe action family.".to_string(),
);
push_assertion(
&mut assertions,
"credit-request-summary-present",
content.contains(&compact_summary),
"Committed credit request contains the accepted pressure summary.".to_string(),
);
push_assertion(
&mut assertions,
"credit-request-awaits-bifrost-review",
content.contains("[request]")
&& content.contains("status = \"awaiting-bifrost-credit-review\"")
&& content.contains("requested_owner = \"Bifrost\"")
&& content.contains(
"requested_effect = \"record-credit-for-redacted-proof-and-accepted-artifact\"",
)
&& content.contains("publication_request_ref = ")
&& content.contains("maintainer_review_request_ref = ")
&& content.contains("pr_request_ref = "),
"Committed credit request waits for Bifrost credit review before consequence."
.to_string(),
);
push_assertion(
&mut assertions,
"credit-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("maintainer_review_required = true")
&& content.contains("accepted_artifact_required = true")
&& content.contains("authorship_context_required = true"),
"Committed credit request requires closure, Soul, Mind, proof, review, accepted artifact, and authorship antecedents."
.to_string(),
);
push_assertion(
&mut assertions,
"credit-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(
"maintainer_review = \"gamecult.maintainer.review_receipt.v0\"",
)
&& content.contains(
"accepted_artifact = \"gamecult.artifact.acceptance_receipt.v0\"",
)
&& content.contains("credit_ledger = \"gamecult.bifrost.credit_receipt.v0\"")
&& content.contains("credit_readback = \"gamecult.bifrost.credit_readback_receipt.v0\""),
"Committed credit request names closure, proof, review, accepted artifact, ledger, and readback receipts."
.to_string(),
);
push_assertion(
&mut assertions,
"credit-request-packet-contract",
content.contains("[credit_packet]")
&& content.contains("requires_author_identity = true")
&& content.contains("requires_reviewer_identity = true")
&& content.contains("requires_accepted_artifact_ref = true")
&& content.contains("requires_public_proof_ref = true")
&& content.contains("requires_changed_path_list = true")
&& content.contains("requires_credit_ledger_target = true")
&& content.contains("requires_private_state_redaction_check = true"),
"Committed credit request names author, reviewer, artifact, proof, path, ledger, and redaction requirements."
.to_string(),
);
push_assertion(
&mut assertions,
"credit-request-authority-seals",
content.contains("[authority]")
&& content.contains("credit_ledger_authorized = false")
&& content.contains("bifrost_publication_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_credit_authority_required = true"),
"Committed credit request denies credit/publication/PR/merge/sync/action/cross-body authority."
.to_string(),
);
push_assertion(
&mut assertions,
"credit-request-private-seal",
content.contains("private_state_exposed = false"),
"Committed credit request preserves the private-state seal.".to_string(),
);
}
_ => {
return Ok((
json!({
@ -9005,7 +9264,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] [--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] [--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

@ -314,16 +314,21 @@ writes a structured GitHub/Bifrost PR request under
maintainer review, Bifrost publication, credit, branch, title/body,
changed-path, proof-ref, and redaction requirements without itself granting PR,
branch push, merge, publication, upstream sync, Hands action, or cross-body
authority. Its receipt includes
authority; and `--action-family repo-credit-request` writes a structured
Bifrost credit request under `.epiphany/credit-requests/<item>.toml`, naming
closure, Soul, Mind, public proof, maintainer review, accepted artifact,
authorship, author, reviewer, proof, changed-path, ledger target, and redaction
requirements without itself granting 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`, or `repo-pr-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`, or `repo-credit-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.
@ -607,6 +612,22 @@ requirements for branch, title/body, changed paths, proof, review, credit, and
redaction, denied GitHub PR, branch push, merge, publication, upstream sync,
Hands action, cross-body authority, and `privateStateExposed=false`.
The next Bifrost ledger boundary smoke proved credit request cargo:
`.epiphany-smoke\repo-credit-request-family-20260620-160803` ran init -> online
-> accept -> `derive-plan --action-family repo-credit-request --model-ref
repo-credit-request-family-smoke-imagination-v1 --model-authored` -> tick
through run/adopt/execute/close on a fresh repo. The plan carried
`safeActionFamily=repo.credit_request`; Hands committed only
`.epiphany/credit-requests/repo-credit-request-family.toml`; Soul passed with
`pathScopeMatched=true` and `familyAssertions.status=passed`; the committed
request carried `schema_version = "epiphany.repo_credit_request.v0"`,
`status="awaiting-bifrost-credit-review"`, closure/Soul/Mind/public-proof,
maintainer-review, accepted-artifact, and authorship antecedents, credit packet
requirements for author, reviewer, accepted artifact, proof, changed paths,
ledger target, and redaction, denied credit ledger, Bifrost publication, 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:
@ -1320,7 +1341,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`, and `repo-pr-request` / `repo.pr_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`, and `repo-credit-request` / `repo.credit_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. |
@ -1637,6 +1658,11 @@ Required organs before MVP:
credit antecedents plus branch/title/body/path/proof/review/credit/redaction
packet requirements while granting no PR, branch push, merge, publication,
sync, Hands, or cross-body authority.
`repo-credit-request` now proves Bifrost credit request cargo that names
closure/Soul/Mind/public-proof, maintainer-review, accepted-artifact, and
authorship antecedents plus author/reviewer/artifact/proof/path/ledger/redaction
packet requirements while granting no 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

@ -132,6 +132,7 @@ remembers doctrine; the branch remembers the blade.
- 2026-06-20: `repo-sync-request` is now live as upstream-main proof request cargo. `epiphany-work derive-plan --action-family repo-sync-request` writes `.epiphany/sync-requests/<item>.toml` with safe family `repo.sync_request`, status `awaiting-upstream-main-proof`, Bifrost/GitHub/maintainer/credit antecedents, `origin/main` merge-base ancestry proof requirements, and denials for merge, push, upstream sync, GitHub publication, credit ledger, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, sync proof contract, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-sync-request-family-20260620-154029` ran init -> online -> accept -> repo-sync-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/sync-requests/repo-sync-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingUpstreamMainProof=true`, `mergeAuthorized=false`, `pushAuthorized=false`, `upstreamSyncAuthorized=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-maintainer-review-request` is now live as maintainer-facing review request cargo. `epiphany-work derive-plan --action-family repo-maintainer-review-request` writes `.epiphany/review-requests/<item>.toml` with safe family `repo.maintainer_review_request`, status `awaiting-maintainer-review`, closure/Soul/Mind/public-proof/Bifrost antecedents, reviewer identity/verdict/changed-path/proof-ref/redaction packet requirements, and denials for maintainer approval, merge, push, publication, upstream sync, Hands action, cross-body mutation, and private Verse rummaging. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, review packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-maintainer-review-request-family-20260620-155126` ran init -> online -> accept -> repo-maintainer-review-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/review-requests/repo-maintainer-review-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingMaintainerReview=true`, `maintainerApprovalAuthorized=false`, `mergeAuthorized=false`, `pushAuthorized=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-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.
- `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