acceptance packet: panels lead the prompt, partial rows never resolve, lifecycle from the canonical root; shared review projects retire once

Authoritative review round of P3: the acceptance-panel block was appended after
large review JSON and head-truncated away at 8 000 chars — it now leads the
bounded prompt and truncated reasons carry `reason_omitted_chars` plus a response
reference; a partial `tool_trajectory` section is typed `partial` (dispatchable,
never resolving for API-only acceptance reviewers); acceptance reads a compact
root-task→skill projection (`state/skill_review_root_tasks.jsonl`, appended by
terminal skill reviews, enrolled as a hot store) instead of every skill's whole
review history; skill-lifecycle identity keys are derived from the real skill
tool schemas (incl. toggle/publish and the `user_repo` bucket); lifecycle history
is read from the canonical root on split-root topologies.

Custody (AP10): a shared review project was never retired when the lowest run id
settled first and deferred — the last sibling to settle now attempts regardless
of order and one project-level PROJECT_RETIRED row discharges every sharer on
replay, so contributor receipts bind a consistent final settlement.
delegate_custody.py stays at exactly 1 600 lines. The size-ratchet manifest is
deliberately left untouched (one regeneration at synthesis).

Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
This commit is contained in:
Ouroboros 2026-09-03 23:21:08 +03:00
parent 083ee96e83
commit 6a6db620cf
13 changed files with 353 additions and 84 deletions

View file

@ -41,6 +41,9 @@ def _write_history(drive_root: pathlib.Path, name: str, root_task_id: str) -> No
"root_task_id": root_task_id}) + "\n",
encoding="utf-8",
)
projection = drive_root / "state" / "skill_review_root_tasks.jsonl"
with projection.open("a", encoding="utf-8") as handle:
handle.write(json.dumps({"root_task_id": root_task_id, "skill": name}) + "\n")
def _ctx(drive_root: pathlib.Path, tmp_path: pathlib.Path, task_id: str) -> ToolContext:
@ -95,11 +98,48 @@ def test_a_skill_lifecycle_tool_call_names_the_skill_without_a_payload_edit(tmp_
"""A free delegation lane integrates a patch and never calls write_file, so
the lifecycle tools are the only carrier of the name in that shape."""
trace = {"tool_calls": [
{"tool": "skill_review", "args": {"skill_name": "delegated"}},
{"tool": "skill_preflight", "args": {"name": "probed"}},
{"tool": "skill_review", "args": {"skill": "delegated"}},
{"tool": "skill_preflight", "args": {"skill": "probed"}},
{"tool": "skill_exec", "args": {"skill": "executed", "script": "scripts/run.py"}},
{"tool": "toggle_skill", "args": {"skill": "toggled", "enabled": True}},
{"tool": "submit_skill_to_hub", "args": {
"skill": "published", "confirm_public_submission": True,
}},
{"tool": "edit_text", "args": {
"root": "skill_payload", "bucket": "user_repo",
"skill_name": "user-repo-skill", "path": "SKILL.md",
"old_text": "old", "new_text": "new",
}},
{"tool": "run_command", "args": {"cmd": "ls"}},
]}
assert skill_names_touched_by_trace(trace) == ["delegated", "probed"]
assert skill_names_touched_by_trace(trace) == [
"delegated", "probed", "executed", "toggled", "published",
"user-repo-skill",
]
def test_split_root_packet_reads_skill_lifecycle_from_the_canonical_root(tmp_path):
canonical = tmp_path / "canonical"
execution = tmp_path / "execution"
canonical.mkdir()
execution.mkdir()
_write_skill(canonical, "canonical-skill")
ctx = ToolContext(
repo_dir=tmp_path, drive_root=execution, budget_drive_root=canonical,
task_id="task-split-skill",
)
packet = build_task_acceptance_evidence(
ctx,
llm_trace={"tool_calls": [{
"tool": "skill_review", "args": {"skill": "canonical-skill"},
}]},
drive_root=execution,
task_id="task-split-skill",
)
assert packet["skill_lifecycle"][0]["name"] == "canonical-skill"
assert packet["skill_lifecycle"][0].get("present", True) is True
def test_the_packet_carries_the_section_and_the_vocabulary_resolves_it(tmp_path):