Add repo work closure review receipts
This commit is contained in:
parent
1cf5252d14
commit
6c0c93fbff
5 changed files with 183 additions and 33 deletions
|
|
@ -219,6 +219,8 @@ struct CloseArgs {
|
|||
verification_command: Option<String>,
|
||||
verification_summary: Option<String>,
|
||||
modeling_summary: Option<String>,
|
||||
closure_model_ref: Option<String>,
|
||||
model_authored: bool,
|
||||
state_revision: u64,
|
||||
}
|
||||
|
||||
|
|
@ -726,6 +728,8 @@ fn parse_close_args(args: impl Iterator<Item = String>) -> Result<CloseArgs> {
|
|||
let mut verification_command = None;
|
||||
let mut verification_summary = None;
|
||||
let mut modeling_summary = None;
|
||||
let mut closure_model_ref = None;
|
||||
let mut model_authored = false;
|
||||
let mut state_revision = 0_u64;
|
||||
|
||||
let mut args = args.peekable();
|
||||
|
|
@ -747,6 +751,10 @@ fn parse_close_args(args: impl Iterator<Item = String>) -> Result<CloseArgs> {
|
|||
"--modeling-summary" => {
|
||||
modeling_summary = Some(take_string(&mut args, "--modeling-summary")?);
|
||||
}
|
||||
"--closure-model-ref" | "--model-ref" => {
|
||||
closure_model_ref = Some(take_string(&mut args, "--closure-model-ref")?);
|
||||
}
|
||||
"--model-authored" => model_authored = true,
|
||||
"--state-revision" => state_revision = take_u64(&mut args, "--state-revision")?,
|
||||
other => return Err(anyhow!("unexpected close argument {other:?}")),
|
||||
}
|
||||
|
|
@ -760,6 +768,8 @@ fn parse_close_args(args: impl Iterator<Item = String>) -> Result<CloseArgs> {
|
|||
verification_command,
|
||||
verification_summary,
|
||||
modeling_summary,
|
||||
closure_model_ref,
|
||||
model_authored,
|
||||
state_revision,
|
||||
})
|
||||
}
|
||||
|
|
@ -2843,11 +2853,86 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
fs::write(&stderr_artifact, &verification.stderr)
|
||||
.with_context(|| format!("failed to write {}", stderr_artifact.display()))?;
|
||||
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
||||
let verification_passed = verification.status.success();
|
||||
let declared_changed_paths =
|
||||
sorted_normalized_paths(string_array_from_json(&execute_receipt, &["changedPaths"]));
|
||||
let actual_changed_paths = sorted_normalized_paths(
|
||||
git_output(
|
||||
&workspace,
|
||||
&[
|
||||
"diff-tree",
|
||||
"--no-commit-id",
|
||||
"--name-only",
|
||||
"-r",
|
||||
&commit_sha,
|
||||
],
|
||||
)?
|
||||
.lines()
|
||||
.map(ToString::to_string)
|
||||
.collect(),
|
||||
);
|
||||
let path_scope_matched = declared_changed_paths == actual_changed_paths;
|
||||
let commit_stat = git_output(&workspace, &["show", "--stat", "--oneline", &commit_sha])?;
|
||||
let closure_model_authored = args.model_authored || args.closure_model_ref.is_some();
|
||||
let closure_review_id = format!("repo-work-close-{item_slug}-closure-review");
|
||||
let closure_review_path = artifact_dir.join(format!("work-close-{item_slug}-review.json"));
|
||||
let closure_review = json!({
|
||||
"schemaVersion": "epiphany.repo_work_closure_review.v0",
|
||||
"createdAt": now,
|
||||
"workspace": workspace,
|
||||
"receiptId": closure_review_id,
|
||||
"item": item,
|
||||
"owner": "Soul+Modeling",
|
||||
"stateGate": "Mind",
|
||||
"executeReceiptPath": execute_receipt_path,
|
||||
"runtimeStore": runtime_store,
|
||||
"handsReceipts": {
|
||||
"patchReceiptId": patch_receipt_id,
|
||||
"commandReceiptId": command_receipt_id,
|
||||
"commitReceiptId": commit_receipt_id,
|
||||
"commitSha": commit_sha
|
||||
},
|
||||
"verification": {
|
||||
"command": verification_command,
|
||||
"exitCode": verification.status.code(),
|
||||
"stdoutArtifact": normalize_path_for_receipt(&stdout_artifact),
|
||||
"stderrArtifact": normalize_path_for_receipt(&stderr_artifact),
|
||||
"passed": verification.status.success()
|
||||
},
|
||||
"sourceGrounding": {
|
||||
"declaredChangedPaths": declared_changed_paths,
|
||||
"actualChangedPaths": actual_changed_paths,
|
||||
"pathScopeMatched": path_scope_matched,
|
||||
"commitStat": compact_multiline(&commit_stat),
|
||||
"commitReceiptMatchedExecuteReceipt": true
|
||||
},
|
||||
"modelingReview": {
|
||||
"modelAuthored": closure_model_authored,
|
||||
"modelRef": args.closure_model_ref,
|
||||
"deterministicFallback": !closure_model_authored,
|
||||
"operatorAuthoredShellDetails": false,
|
||||
"summary": args.modeling_summary.clone()
|
||||
},
|
||||
"authoritySeal": {
|
||||
"branchLocalOnly": true,
|
||||
"publicationAuthorized": false,
|
||||
"mergeAuthorized": false,
|
||||
"serviceLifecycleAuthority": false,
|
||||
"crossRepoMutation": false,
|
||||
"privateStateExposed": false
|
||||
},
|
||||
"privateStateExposed": false,
|
||||
"nextSafeMove": "Soul may pass closure only when verification succeeds and actual git changed paths match the Hands-declared path scope."
|
||||
});
|
||||
write_json(&closure_review_path, &closure_review)?;
|
||||
let verification_passed = verification.status.success() && path_scope_matched;
|
||||
let soul_verdict_id = format!("repo-work-close-{item_slug}-soul-verdict");
|
||||
let soul_summary = args.verification_summary.unwrap_or_else(|| {
|
||||
if verification_passed {
|
||||
format!("Soul verified branch-local commit {commit_sha} for repo work item {item}.")
|
||||
} else if !path_scope_matched {
|
||||
format!(
|
||||
"Soul verification failed for branch-local commit {commit_sha}: actual changed paths did not match declared Hands path scope."
|
||||
)
|
||||
} else {
|
||||
format!("Soul verification failed for branch-local commit {commit_sha}.")
|
||||
}
|
||||
|
|
@ -2858,8 +2943,9 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
commit_receipt_id.clone(),
|
||||
normalize_path_for_receipt(&stdout_artifact),
|
||||
normalize_path_for_receipt(&stderr_artifact),
|
||||
normalize_path_for_receipt(&closure_review_path),
|
||||
];
|
||||
evidence_ids.extend(string_array_from_json(&execute_receipt, &["changedPaths"]));
|
||||
evidence_ids.extend(declared_changed_paths.clone());
|
||||
let soul_verdict = SoulVerdictReceipt {
|
||||
schema_version: SOUL_VERDICT_RECEIPT_SCHEMA_VERSION.to_string(),
|
||||
receipt_id: soul_verdict_id.clone(),
|
||||
|
|
@ -2874,6 +2960,11 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
evidence_ids: evidence_ids.clone(),
|
||||
risks: if verification_passed {
|
||||
Vec::new()
|
||||
} else if !path_scope_matched {
|
||||
vec![
|
||||
"Closure refused because actual git changed paths differ from Hands-declared scope."
|
||||
.to_string(),
|
||||
]
|
||||
} else {
|
||||
vec!["Closure verification command failed; publication remains blocked.".to_string()]
|
||||
},
|
||||
|
|
@ -2897,8 +2988,11 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
"verdict": soul_verdict.verdict,
|
||||
"summary": soul_verdict.summary,
|
||||
"stdoutArtifact": normalize_path_for_receipt(&stdout_artifact),
|
||||
"stderrArtifact": normalize_path_for_receipt(&stderr_artifact)
|
||||
"stderrArtifact": normalize_path_for_receipt(&stderr_artifact),
|
||||
"closureReviewReceiptId": closure_review_id,
|
||||
"closureReviewPath": normalize_path_for_receipt(&closure_review_path)
|
||||
},
|
||||
"closureReview": closure_review,
|
||||
"authority": {
|
||||
"branchLocalOnly": true,
|
||||
"publicationGateSatisfied": false,
|
||||
|
|
@ -2916,6 +3010,7 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
"receiptPath": closure_receipt_path,
|
||||
"item": failed_receipt["item"],
|
||||
"soul": failed_receipt["soul"],
|
||||
"closureReview": failed_receipt["closureReview"],
|
||||
"authority": failed_receipt["authority"],
|
||||
"privateStateExposed": false,
|
||||
"nextSafeMove": failed_receipt["nextSafeMove"],
|
||||
|
|
@ -2925,7 +3020,7 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
let modeling_summary = args.modeling_summary.unwrap_or_else(|| {
|
||||
format!(
|
||||
"Modeling records repo work item {item} changed [{}] at commit {commit_sha}; scheduler should stop implementation until publication review.",
|
||||
string_array_from_json(&execute_receipt, &["changedPaths"]).join(", ")
|
||||
declared_changed_paths.join(", ")
|
||||
)
|
||||
});
|
||||
let gateway_id = format!("repo-work-close-{item_slug}-mind-review");
|
||||
|
|
@ -2943,7 +3038,7 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
refused_effects: Vec::new(),
|
||||
reasons: vec![
|
||||
"Soul passed the branch-local Hands consequence.".to_string(),
|
||||
"Modeling summary is source-grounded in execute receipt and commit proof.".to_string(),
|
||||
"Modeling summary is source-grounded in execute receipt, closure review, and commit proof.".to_string(),
|
||||
"Mind admits closure metadata only; Bifrost still gates publication and merge.".to_string(),
|
||||
],
|
||||
contract: "Mind review for repo-work closure; admits the verified Modeling summary and publication gate without granting merge or service authority.".to_string(),
|
||||
|
|
@ -2981,13 +3076,17 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
"verdict": soul_verdict.verdict,
|
||||
"summary": soul_verdict.summary,
|
||||
"stdoutArtifact": normalize_path_for_receipt(&stdout_artifact),
|
||||
"stderrArtifact": normalize_path_for_receipt(&stderr_artifact)
|
||||
"stderrArtifact": normalize_path_for_receipt(&stderr_artifact),
|
||||
"closureReviewReceiptId": closure_review_id,
|
||||
"closureReviewPath": normalize_path_for_receipt(&closure_review_path)
|
||||
},
|
||||
"closureReview": closure_review,
|
||||
"modeling": {
|
||||
"summary": modeling_summary,
|
||||
"changedPaths": execute_receipt["changedPaths"],
|
||||
"commitSha": execute_receipt["handsReceipts"]["commitSha"],
|
||||
"source": "epiphany.repo_work_execute_receipt.v0"
|
||||
"source": "epiphany.repo_work_closure_review.v0",
|
||||
"modelAuthored": closure_model_authored
|
||||
},
|
||||
"mind": {
|
||||
"gatewayReviewId": mind_review.gateway_id,
|
||||
|
|
@ -3018,6 +3117,7 @@ fn run_close(args: CloseArgs) -> Result<Value> {
|
|||
"item": closure_receipt["item"],
|
||||
"handsReceipts": closure_receipt["handsReceipts"],
|
||||
"soul": closure_receipt["soul"],
|
||||
"closureReview": closure_receipt["closureReview"],
|
||||
"modeling": closure_receipt["modeling"],
|
||||
"mind": closure_receipt["mind"],
|
||||
"authority": closure_receipt["authority"],
|
||||
|
|
@ -3467,6 +3567,8 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
let adopt_receipt_path = work_receipt_path(&workspace, "adopt", &item);
|
||||
let execute_receipt_path = work_receipt_path(&workspace, "execute", &item);
|
||||
let close_receipt_path = work_receipt_path(&workspace, "close", &item);
|
||||
let close_review_receipt_path =
|
||||
artifact_dir.join(format!("work-close-{item_slug}-review.json"));
|
||||
let publish_receipt_path = work_receipt_path(&workspace, "publish", &item);
|
||||
let sync_receipt_path = work_receipt_path(&workspace, "sync", &item);
|
||||
let overview_receipt_path = artifact_dir.join(format!("work-overview-{item_slug}.json"));
|
||||
|
|
@ -3538,6 +3640,7 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
("run", &run_receipt_path),
|
||||
("adopt", &adopt_receipt_path),
|
||||
("execute", &execute_receipt_path),
|
||||
("close-review", &close_review_receipt_path),
|
||||
("close", &close_receipt_path),
|
||||
("publish", &publish_receipt_path),
|
||||
("sync", &sync_receipt_path),
|
||||
|
|
@ -3561,6 +3664,7 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
("run", &run_receipt_path),
|
||||
("adopt", &adopt_receipt_path),
|
||||
("execute", &execute_receipt_path),
|
||||
("close-review", &close_review_receipt_path),
|
||||
("close", &close_receipt_path),
|
||||
("publish", &publish_receipt_path),
|
||||
("sync", &sync_receipt_path),
|
||||
|
|
@ -3597,6 +3701,7 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
"runReceiptPath": existing_path_value(&run_receipt_path),
|
||||
"adoptReceiptPath": existing_path_value(&adopt_receipt_path),
|
||||
"executeReceiptPath": existing_path_value(&execute_receipt_path),
|
||||
"closeReviewReceiptPath": existing_path_value(&close_review_receipt_path),
|
||||
"closeReceiptPath": existing_path_value(&close_receipt_path),
|
||||
"publishReceiptPath": existing_path_value(&publish_receipt_path),
|
||||
"syncReceiptPath": existing_path_value(&sync_receipt_path),
|
||||
|
|
@ -4489,6 +4594,8 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
modeling_summary: Some(format!(
|
||||
"Modeling records scheduler-closed repo work item {item}; publication remains gated by Bifrost."
|
||||
)),
|
||||
closure_model_ref: None,
|
||||
model_authored: false,
|
||||
state_revision: 0,
|
||||
})?;
|
||||
status = "advanced".to_string();
|
||||
|
|
@ -5351,6 +5458,14 @@ fn compact_line(text: &str) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn compact_multiline(text: &str) -> Vec<String> {
|
||||
text.lines()
|
||||
.map(compact_line)
|
||||
.filter(|line| !line.is_empty())
|
||||
.take(40)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn compact_join(values: &[String]) -> String {
|
||||
if values.is_empty() {
|
||||
"none".to_string()
|
||||
|
|
@ -5363,6 +5478,16 @@ fn compact_join(values: &[String]) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn sorted_normalized_paths(paths: Vec<String>) -> Vec<String> {
|
||||
let mut normalized = normalize_paths(paths)
|
||||
.into_iter()
|
||||
.filter(|path| path != ".")
|
||||
.collect::<Vec<_>>();
|
||||
normalized.sort();
|
||||
normalized.dedup();
|
||||
normalized
|
||||
}
|
||||
|
||||
fn powershell_single_quoted(value: &str) -> String {
|
||||
format!("'{}'", value.replace('\'', "''"))
|
||||
}
|
||||
|
|
@ -5726,7 +5851,7 @@ fn print_usage() {
|
|||
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\
|
||||
execute --workspace <repo> [--item <id>] [--from-plan <path>] [--command <command>] [--changed-path <path>] [--commit-message <text>]\n\
|
||||
close --workspace <repo> [--item <id>] [--execute-receipt <path>] [--verification-command <command>]\n\
|
||||
close --workspace <repo> [--item <id>] [--execute-receipt <path>] [--verification-command <command>] [--closure-model-ref <ref>] [--model-authored]\n\
|
||||
publish --workspace <repo> [--item <id>] --change-summary <text> --justification <text> --verification-receipt <ref> --review-receipt <ref> --ledger-entry-id <id> --pull-request-url <url> --pull-request-title <text>\n\
|
||||
sync --workspace <repo> [--item <id>] [--publish-receipt <path>] [--upstream-ref origin/main] --merge-receipt <ref>\n\
|
||||
overview --workspace <repo> [--item <id>] [--accept-receipt <path>] [--no-write]\n\
|
||||
|
|
|
|||
|
|
@ -639,10 +639,17 @@ It reads `work-execute-<item>.json`, requires
|
|||
matches the recorded git SHA, then runs a verification command in the repo Body
|
||||
(`git show --stat --oneline <commit>` by default, or
|
||||
`--verification-command <command>` when supplied). The command stdout/stderr are
|
||||
sealed under `.epiphany/work/`, Soul writes
|
||||
`epiphany.soul.verdict_receipt`, Modeling records the execution/commit summary,
|
||||
and Mind writes gateway review plus state-commit receipts into runtime-spine.
|
||||
The final `.epiphany/work/work-close-<item>.json` receipt is
|
||||
sealed under `.epiphany/work/`. Closure also writes a structured
|
||||
`epiphany.repo_work_closure_review.v0` packet at
|
||||
`.epiphany/work/work-close-<item>-review.json`, recording the verification
|
||||
command/exit code, declared Hands paths, actual git commit paths, commit stat,
|
||||
optional model-review provenance from `--closure-model-ref` / `--model-authored`,
|
||||
and authority seals. Soul passes only when the verification command succeeds
|
||||
and actual git changed paths match the Hands-declared path scope. Soul then
|
||||
writes `epiphany.soul.verdict_receipt`, Modeling records the
|
||||
execution/commit/closure-review summary, and Mind writes gateway review plus
|
||||
state-commit receipts into runtime-spine. The final
|
||||
`.epiphany/work/work-close-<item>.json` receipt is
|
||||
`epiphany.repo_work_closure_receipt.v0` with
|
||||
`durableStateAdmitted=true`, `publicationGateSatisfied=true`, and
|
||||
`privateStateExposed=false`. It still does not grant publication, merge,
|
||||
|
|
@ -662,6 +669,20 @@ A fifth smoke proved the closure chain on a disposable fresh repo Body:
|
|||
the next tick returned `noop:none`, and every receipt summary reported
|
||||
`privateStateExposed=false`.
|
||||
|
||||
A richer closure-review smoke proved the typed Soul/Modeling bridge:
|
||||
`.epiphany-smoke\closure-review-20260620-135009` ran init -> online -> accept
|
||||
-> `derive-plan --action-family task-card --model-authored` -> run -> adopt ->
|
||||
execute -> `close --closure-model-ref smoke-closure-review-v0 --model-authored`
|
||||
-> overview -> export-proof. The close output carried
|
||||
`epiphany.repo_work_closure_review.v0`, `pathScopeMatched=true`,
|
||||
`modelAuthored=true`, Soul `passed`, and `privateStateExposed=false`; overview
|
||||
included a present `close-review` proof artifact row; redacted public proof
|
||||
included that row with SHA-256 and no local path fields. A tampered execute
|
||||
receipt declaring `README.md` while the commit actually changed
|
||||
`notes/epiphany-work/closure-review-request-task-card.toml` produced
|
||||
`verification-failed`, Soul `failed`, `pathScopeMatched=false`, and
|
||||
`privateStateExposed=false`.
|
||||
|
||||
`epiphany-work overview` is the first compact repo work sight/proof surface:
|
||||
|
||||
```powershell
|
||||
|
|
@ -982,8 +1003,8 @@ No: the machine is not yet Epiphany Online in the full MVP sense. The remaining
|
|||
gap is not "more permission prompts." The remaining gap is to make the
|
||||
existing typed artery run as a living repo organism:
|
||||
|
||||
- richer model-authored closure where Soul and Modeling inspect source and
|
||||
consequences beyond the deterministic mechanical path
|
||||
- deeper model-authored closure review beyond the first typed
|
||||
`epiphany.repo_work_closure_review.v0` packet
|
||||
- later non-planning action classes where Imagination can propose useful
|
||||
branch-local work beyond planning cargo without arbitrary shell authority
|
||||
- an Idunn-owned service lifecycle path for the queue-run pulse when the
|
||||
|
|
@ -1009,9 +1030,9 @@ temptation wearing clean robes.
|
|||
| 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`, and `task-card` / `repo.task_card`. `plan` remains manual quarantine scaffolding. | Deepen model-authored closure and any later non-planning action 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. | Add richer safe-family depth next; keep any future queue-run service launch/install behind Idunn and explicit operator 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 and writes deterministic Soul, Modeling, and Mind receipts. | Add richer model-authored closure where useful, while preserving deterministic local closure for simple mechanical work. |
|
||||
| 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. |
|
||||
| Repo work sight | `overview` emits compact proof rows and mirrors typed `epiphany.cultmesh.repo_work_overview.v0` event documents plus a latest key; Gjallar enumerates the history as queue rows and non-mutating action rows; Persona's Eve surface and Eve connection readbacks expose peer-readable gate/blocker/next-action rows; `queue-run` consumes the same queue for branch-local scheduler pulses. | Deepen the Persona-to-plan loop without moving action authority out of Hands/Self/Bifrost. |
|
||||
| Publication | `publish` routes Bifrost/GitHub receipts from closure or explicit Soul/Mind refs. | Keep publication Bifrost-owned; do not let scheduler publish. |
|
||||
| Upstream main sync | `sync` proves the published commit is contained by upstream main after explicit merge/sync authority. | Treat upstream-main sync as a required final proof for published work. |
|
||||
|
|
@ -1282,9 +1303,12 @@ Required organs before MVP:
|
|||
without operator shell details. Remaining work is richer closure depth and any
|
||||
later model-authored action classes that move beyond planning cargo while
|
||||
preserving the same authority seals.
|
||||
- Closure depth: deterministic Soul/Modeling/Mind closure exists for Hands
|
||||
commits; richer model-authored Soul/Modeling review remains to replace the
|
||||
current local verification rite where appropriate.
|
||||
- Closure depth: `close` now writes a structured
|
||||
`epiphany.repo_work_closure_review.v0` packet for Hands commits, records
|
||||
model-review provenance when supplied, refuses actual-vs-declared path-scope
|
||||
mismatch before Soul passes, and exposes the closure-review artifact through
|
||||
overview/export proof rows. Deeper model-authored Soul/Modeling review remains
|
||||
a later upgrade on top of this typed packet.
|
||||
- Repo work projection/run surface: local `epiphany-work overview` proof bundles, typed
|
||||
`epiphany.cultmesh.repo_work_overview.v0` event history plus latest-key
|
||||
projection, and Gjallar multi-item `repo-work-overview` action/readback rows
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Reference in a new issue