feat(github): idempotent per-item stage-report GitHub comments (#433, #442) - #449
Merged
Merged
Conversation
…442) Adds simplicio_loop/stage_report.py: an identity/idempotency-key/envelope module extending (not duplicating) the #295/#285/#301 idempotent comment primitives already in scripts/pr_evidence.py and simplicio_loop/github_lifecycle.py. - format_agent_identity/hostname_abbrev: "Name/Role - #XXXX - Model" identity string per #442, #XXXX being a 4-char abbreviated hostname so the same model/role reads distinctly across machines. - idempotency_key(run_id, item, stage, attempt, transition): stable across retries, per #442's exact spec. - build_marker(run_id, item): one stable per-work-item HTML marker so the SAME comment is updated across the full #433 lifecycle (discovered -> claimed -> intake/planning -> implementation -> safety -> review -> delivery/PR/checks/merge -> feedback/retry/recovery -> final audit -> COMPLETE|PARTIAL|BLOCKED|REGRESSED), on both the source issue and a linked PR. - render_stage_report: deterministic, sanitized (secrets/signed-URLs redacted), length-capped envelope with cross-links (issue/PR/commit), explicit PASS/REGRESSED/BLOCKED/NEEDS-HUMAN status tags, stages/AC tables, blockers, evidence, and next-gate sections. - publish_stage_report: publishes via the injected `publish_comment_fn` (scripts.pr_evidence.publish_comment) using the item's marker, so the real create-or-update path -- not a standalone helper -- is what performs the query-before-decide idempotency check. Re-queries and verifies the observed body hash, mirroring github_lifecycle.publish_lifecycle_state. Adds scripts/stage_report.py (preview/publish/selftest CLI, dry-run friendly, fail-closed on publish failure/unverified confirmation) and registers it in scripts/claims_audit.py's SELFTEST_SCRIPTS. 30 new tests (unit + CLI subprocess integration) cover identity formatting, idempotency-key stability/uniqueness, marker scoping, status-tag validation, sanitization/truncation, and the publish path's real create-vs-update behavior against a fake `gh` runner routed through the actual scripts.pr_evidence.publish_comment primitive. Built by Claude Sonnet 5 (Claude Code) via simplicio-loop. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
16 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #433, Closes #442.
covering the FULL lifecycle (discovered -> claimed -> intake/planning -> implementation ->
safety -> review A/B/C -> delivery/PR/checks/merge -> feedback/retry/recovery -> final audit ->
COMPLETE|PARTIAL|BLOCKED|REGRESSED), posted on both the source issue and the PR, extending (not
replacing) [P1][Feedback][Entrega] Instrumentar web_verify/video_evidence/pr_evidence, secao de progresso no PR e comentario idempotente de progresso na issue #301's single progress-comment scope.
identity
Nome/Papel - #XXXX - Modelo(4-char abbreviated hostname), idempotency keyrun_id + item + stage + attempt + transition, explicitPASS/REGRESSED/BLOCKED/NEEDS-HUMANstatus tags, cross-links between issue/PR/commit/evidence, and a stable marker for
find-and-update.
This PR implements both in one coherent module,
simplicio_loop/stage_report.py, rather thantwo overlapping mechanisms:
hostname_abbrev/format_agent_identity—Name/Role - #XXXX - Model,#XXXXbeing the4-char abbreviated hostname (never an issue number), so the same model/role reads distinctly
across machines ([P0][GitHub] Publicar progresso canônico em Issues/tasks e PRs #442 requirement 6).
idempotency_key(run_id, item, stage, attempt, transition)— stable across retries, exactly[P0][GitHub] Publicar progresso canônico em Issues/tasks e PRs #442's spec.
build_marker(run_id, item)— one stable per-work-item HTML marker(
<!-- simplicio-loop:stage-report:v1 run=<run_id> item=<item> -->) so the SAME comment isupdated across the entire lifecycle, on either an issue or a PR (PRs are addressed via the same
GitHub issue-comments endpoint).
render_stage_report— deterministic, sanitized (secrets/signed-URLs redacted), length-cappedenvelope with cross-links (issue/PR/commit), the four explicit status tags, stages/AC tables,
blockers, evidence, and next-gate sections. Rejects any status outside
PASS/REGRESSED/BLOCKED/NEEDS-HUMAN.publish_stage_report— publishes via an injectedpublish_comment_fn(
scripts.pr_evidence.publish_comment, the same fail-closed, marker-based, no-shell-interpolation primitive feat(github): implementar adapter transacional do ciclo de vida das issues com comentário único e idempotente #285/[EPIC][P0] Tornar o simplicio-loop production-grade: planejamento profundo, multi-device, multi-LLM e zero falso “done” #295/[P1][Feedback][Entrega] Instrumentar web_verify/video_evidence/pr_evidence, secao de progresso no PR e comentario idempotente de progresso na issue #301 already hardened) using the item's marker. This is the
fix for the adversarial-review bug class flagged in the task: the idempotency check
(
find_existing_comment) is exercised by the real publish path itself(
publish_stage_report->publish_comment_fn(..., marker=...)->find_existing_comment),not just a standalone unit-tested helper — proven directly in
tests/test_stage_report_unit.py::test_publish_stage_report_updates_same_id_on_retry_no_duplicateand the CLI's own
selftest. Also re-queries and confirms the observed body hash, mirroringgithub_lifecycle.publish_lifecycle_state.scripts/stage_report.py— CLI (preview/publish/selftest), dry-run friendly(
--dry-runor simply omitting both--issue/--pr), fail-closed on any publish failure or anunconfirmed re-query (exit 3), and registered in
scripts/claims_audit.py'sSELFTEST_SCRIPTS.What's out of scope (tracked, not claimed here)
The full #433 surface also calls for an outbox/reconciler, control-issue aggregate comment,
Project-item state sync, and instrumentation of every #424-#431 lifecycle event — those already
have (or will have) dedicated modules (
github_lifecycle.py's outbox/reconcile,loop_progress.pyfor aggregate %, the stage-agent contract modules for the actual event stream). This PR ships the
identity/idempotency-key/envelope/publish PRIMITIVE both issues actually asked to be defined and
wired, reusing rather than duplicating the existing create-or-update mechanics.
Test plan
python3 scripts/stage_report.py selftest— PASS (25/25): identity formatting, idempotency-key stability/uniqueness, marker scoping, render/status-tag validation, sanitize/truncate,
and the publish path wired against both a fake and the real
pr_evidence.publish_commentprimitive (create vs. update, no duplicate).
python3 -m pytest tests/test_stage_report_unit.py tests/test_stage_report_cli_integration.py -q— 30 passed.
python3 tests/test_stage_report_unit.py/python3 tests/test_stage_report_cli_integration.py(bare python3, no pytest) — both PASS.
gh issue view 433/442 --json stateconfirmed both still OPEN,gh pr list --search 433/442confirmed no duplicate PR, before opening this one.
python3 scripts/check.py(2120 collected tests across the repo) was kicked offlocally; it is a long-running repo-wide e2e/system suite and was still in progress at
submission time. The one pre-existing
claims_auditfailure it surfaces(
scripts/review_panel.py,scripts/stage_coordinator.pymissing fromSELFTEST_SCRIPTS/SELFTEST_EXEMPT) reproduces identically onmainbefore this branch'schanges and is unrelated to this PR.
Built by Claude Sonnet 5 (Claude Code) via simplicio-loop.