From 3b630d83a3afdfd7a9d5bc6bab94114c37ed97e7 Mon Sep 17 00:00:00 2001 From: sunjiajunsunjiajun Date: Sun, 19 Jul 2026 13:37:36 +0800 Subject: [PATCH 1/4] fix(agent): surface pending capsule review details --- ...26-07-19-pending-capsule-review-summary.md | 84 +++++++++++++++++++ ...9-pending-capsule-review-summary-design.md | 67 +++++++++++++++ src/rgit/_plugin/skills/rgit-capture/SKILL.md | 2 + src/rgit/agent_guidance.py | 9 +- tests/test_agent_guidance.py | 11 +++ tests/test_installer.py | 12 +++ 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md create mode 100644 docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md diff --git a/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md b/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md new file mode 100644 index 0000000..a33b263 --- /dev/null +++ b/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md @@ -0,0 +1,84 @@ +# Pending Capsule Review Summary Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Ensure agents list every pending capsule candidate in the user's language whenever a final response still requires review. + +**Architecture:** Add matching behavioral contracts to the generated global AGENTS guidance and the packaged `rgit-capture` skill. Keep translation in the presentation layer and preserve proposal ids, capsule names, code symbols, configuration keys, file paths, and stored records. + +**Tech Stack:** Python string rendering, Markdown skill instructions, pytest. + +**Spec:** `docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md` + +## Global Constraints + +- No new CLI command, dependency, or storage schema. +- List every candidate as stored name plus one-line intent; include key knobs only when they affect the choice. +- A candidate count alone is not an acceptable final review summary. +- Translate explanatory prose and intent into the user's current language, but preserve stable identifiers and stored data. + +--- + +### Task 1: Lock the final-feedback contract with failing tests + +**Files:** +- Modify: `tests/test_agent_guidance.py` +- Modify: `tests/test_installer.py` + +**Interfaces:** +- Consumes: `agent_guidance.render_global_block()` and the packaged `rgit-capture/SKILL.md`. +- Produces: regression tests for pending-detail and user-language requirements. + +- [ ] **Step 1: Add a global-guidance contract test** + +Add a test that checks the rendered block for instructions covering open +proposals, proposal ids, every candidate's name and one-line intent, conditional +key knobs, the prohibition on count-only summaries, user-language presentation, +and preservation of stable identifiers. + +- [ ] **Step 2: Add a capture-skill contract test** + +Extend the existing packaged-skill test to require a final-response fallback +with the same candidate-detail and language behavior. + +- [ ] **Step 3: Run the focused tests and verify RED** + +Run: `python -m pytest tests/test_agent_guidance.py tests/test_installer.py -q` + +Expected: the new assertions fail because neither instruction layer contains +the pending final-response contract yet. + +--- + +### Task 2: Add the matching instruction contracts + +**Files:** +- Modify: `src/rgit/agent_guidance.py` +- Modify: `src/rgit/_plugin/skills/rgit-capture/SKILL.md` + +**Interfaces:** +- Consumes: pending proposal data already available from `rgit pending --json`. +- Produces: agent instructions only; no runtime API changes. + +- [ ] **Step 1: Update global final-feedback guidance** + +Replace the current state-only sentence with a compact rule that lists pending +proposal details, follows the user's current language, preserves identifiers, +and forbids count-only summaries. + +- [ ] **Step 2: Add the capture-skill final-response fallback** + +After the normal review instructions, require the same presentation whenever a +proposal remains open at the end of a response. + +- [ ] **Step 3: Run focused tests and verify GREEN** + +Run: `python -m pytest tests/test_agent_guidance.py tests/test_installer.py tests/test_guidance_coupling.py -q` + +Expected: all tests pass. + +- [ ] **Step 4: Run the full suite** + +Run: `python -m pytest -q` + +Expected: all tests pass with no new warnings or failures. diff --git a/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md b/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md new file mode 100644 index 0000000..3f4b281 --- /dev/null +++ b/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md @@ -0,0 +1,67 @@ +# Pending Capsule Review Summary + +**Date:** 2026-07-19 +**Status:** approved + +## Problem + +When a run ends with open research-git proposals, an agent can report only the +number of capsule candidates awaiting review. The user cannot make the required +human decision because the final response omits the candidates' concrete +contents. + +The capture skill already asks the agent to show each candidate during the +normal review step, but the global guidance has no equivalent requirement for +the final response. There is also no fallback in the skill for a turn that ends +before the review decision is complete. + +## Design + +Use the same compact review contract in both instruction layers: + +- The global AGENTS guidance requires final feedback to report open proposals. + For every open proposal, list its stable proposal id and every candidate's + stored name plus a one-line explanation of its intent. Include key knobs only + when they affect the user's choice. A count alone is not sufficient. +- The `rgit-capture` skill keeps its normal interactive review flow and adds a + final-response fallback. If any proposal remains open when the agent is about + to finish, the agent presents the same candidate list and asks which names to + keep. +- User-facing explanations follow the language the user is currently using, + regardless of the language stored in the capsule. Proposal ids, capsule names, + code symbols, configuration keys, and file paths remain unchanged. +- Translation is presentation-only. It never changes candidates stored under + `.rgit`. + +## Output Shape + +```text +Pending capsule review + +Proposal prop_abc: +- reranking-retrieval: Add a reranking stage before final retrieval. +- cache-fallback: Fall back to uncached retrieval when cache lookup fails. + Key knob: fallback_timeout + +Tell me which capsule names to keep. Nothing is approved until you decide. +``` + +For a Chinese-speaking user, the intent and surrounding prose are presented in +Chinese while `prop_abc`, `reranking-retrieval`, `cache-fallback`, and +`fallback_timeout` remain unchanged. + +## Testing + +- Assert that the rendered global guidance requires pending proposal details, + rejects count-only summaries, and specifies user-language presentation with + stable identifiers. +- Assert that the packaged capture skill contains the same final-response + fallback and language rule. +- Keep guidance coupling and installer packaging tests passing. + +## Out of Scope + +- New CLI commands or output formats. +- Changes to proposal or capsule storage schemas. +- Translating or rewriting stored capsule records. +- Truncating candidate lists. The final response lists every candidate. diff --git a/src/rgit/_plugin/skills/rgit-capture/SKILL.md b/src/rgit/_plugin/skills/rgit-capture/SKILL.md index b8e1770..7d6205c 100644 --- a/src/rgit/_plugin/skills/rgit-capture/SKILL.md +++ b/src/rgit/_plugin/skills/rgit-capture/SKILL.md @@ -66,6 +66,8 @@ Lost the ids from step 2? Bare `rgit review` re-lists every open proposal with i 4. Echo the `approved -> ` lines back to the user, then continue to step 6. +If any proposal remains open when you are about to finish a response, include a `Pending capsule review` section before finishing. List each proposal id and every candidate's stored name and one-line intent; include key knobs only when they affect the choice, then ask which capsule names to keep. Never replace this list with only a candidate count. Present the explanations and intents in the language the user is currently using, even when the stored capsule uses another language. Do not translate proposal ids, capsule names, code symbols, configuration keys, or file paths. Translation is presentation-only; never rewrite the stored candidates. + ### 6. Infer graph edges (deterministic baseline + agent-judged relationships) After approval, wire the new capsules into the graph: diff --git a/src/rgit/agent_guidance.py b/src/rgit/agent_guidance.py index 4778a8f..63764c9 100644 --- a/src/rgit/agent_guidance.py +++ b/src/rgit/agent_guidance.py @@ -88,7 +88,14 @@ def render_global_block(mode: str = "default") -> str: "scan` stages a plan (plain `rgit init` offers it), then the " "`rgit-digest` skill drains the queue batch by batch.\n" "- In final feedback, mention any capsules created, approved, applied, " - "or skipped, plus important graph relations.\n" + "or skipped, plus important graph relations. If open proposals awaiting " + "review remain, list each proposal id and every candidate's stored name " + "and one-line intent; include key knobs only when they affect the choice. " + "A candidate count alone is not enough. Present explanations in the " + "language the user is currently using, regardless of the stored capsule " + "language. Keep proposal ids, capsule names, code symbols, configuration " + "keys, and file paths unchanged; translation is presentation-only and " + "must not modify the stored capsule.\n" ) provisional = f"{START}\n{body}{END}\n" h = canonical_hash(provisional) diff --git a/tests/test_agent_guidance.py b/tests/test_agent_guidance.py index 9a8bfaa..88365b4 100644 --- a/tests/test_agent_guidance.py +++ b/tests/test_agent_guidance.py @@ -184,6 +184,17 @@ def test_render_global_block_tells_agents_to_skip_mechanical_changes(): assert "Skip mechanical" in render_global_block() +def test_render_global_block_requires_pending_review_details_in_user_language(): + block = agent_guidance.render_global_block() + assert "open proposals awaiting review" in block + assert "every candidate's stored name and one-line intent" in block + assert "key knobs only when they affect the choice" in block + assert "A candidate count alone is not enough" in block + assert "language the user is currently using" in block + assert "Keep proposal ids, capsule names, code symbols, configuration keys, " \ + "and file paths unchanged" in block + + def test_render_emits_fingerprinted_start_marker(): block = agent_guidance.render_global_block() m = agent_guidance._START_RE.match(block) diff --git a/tests/test_installer.py b/tests/test_installer.py index 997320a..ae91934 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -351,6 +351,18 @@ def test_capture_skill_uses_cli_not_mcp_write_tools(): assert "resegment(" not in skill +def test_capture_skill_requires_pending_final_response_in_user_language(): + from rgit import installer + skill = (installer.plugin_dir() / "skills" / "rgit-capture" / "SKILL.md").read_text(encoding="utf-8") + assert "If any proposal remains open when you are about to finish a response" in skill + assert "every candidate's stored name and one-line intent" in skill + assert "key knobs only when they affect the choice" in skill + assert "Never replace this list with only a candidate count" in skill + assert "language the user is currently using" in skill + assert "Do not translate proposal ids, capsule names, code symbols, " \ + "configuration keys, or file paths" in skill + + def test_run_decodes_non_utf8_output_without_crashing(): # A child emitting bytes the locale codec can't strict-decode (the 0x94 from # issue #11) must not crash _run: UTF-8 + errors="replace" keeps it robust From 98748a07f46ef85777f573a4c2b6ef8d190ede78 Mon Sep 17 00:00:00 2001 From: sunjiajunsunjiajun Date: Mon, 20 Jul 2026 21:10:30 +0800 Subject: [PATCH 2/4] fix(skill): require explicit capsule review choice --- src/rgit/_plugin/skills/rgit-capture/SKILL.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rgit/_plugin/skills/rgit-capture/SKILL.md b/src/rgit/_plugin/skills/rgit-capture/SKILL.md index 7d6205c..c49570a 100644 --- a/src/rgit/_plugin/skills/rgit-capture/SKILL.md +++ b/src/rgit/_plugin/skills/rgit-capture/SKILL.md @@ -66,7 +66,9 @@ Lost the ids from step 2? Bare `rgit review` re-lists every open proposal with i 4. Echo the `approved -> ` lines back to the user, then continue to step 6. -If any proposal remains open when you are about to finish a response, include a `Pending capsule review` section before finishing. List each proposal id and every candidate's stored name and one-line intent; include key knobs only when they affect the choice, then ask which capsule names to keep. Never replace this list with only a candidate count. Present the explanations and intents in the language the user is currently using, even when the stored capsule uses another language. Do not translate proposal ids, capsule names, code symbols, configuration keys, or file paths. Translation is presentation-only; never rewrite the stored candidates. +If any proposal remains open when you are about to finish a response, include a `Pending capsule review` section before finishing. List each proposal id and every candidate's stored name and one-line intent; include key knobs only when they affect the choice. Never replace this list with only a candidate count. Present the explanations and intents in the language the user is currently using, even when the stored capsule uses another language. Do not translate proposal ids, capsule names, code symbols, configuration keys, or file paths. Translation is presentation-only; never rewrite the stored candidates. + +End that section with an explicit decision request. The response is incomplete unless it asks the user to choose one of: keep named capsules, keep all, or discard all. Give short reply examples in the user's language, such as `keep `, `keep all`, and `discard all`. Tell the user they only need to state their choice and that you will execute the review decision for them. Explain that kept candidates will be approved and stored as capsules; candidates they do not keep will be discarded. Do not approve, discard, or otherwise make a review decision before the user confirms. ### 6. Infer graph edges (deterministic baseline + agent-judged relationships) From 51527d9c2257f778e380bb415464b2973eaa92e8 Mon Sep 17 00:00:00 2001 From: sunjiajunsunjiajun Date: Mon, 20 Jul 2026 22:42:39 +0800 Subject: [PATCH 3/4] fix(skill): keep capsule review handoff concise --- src/rgit/_plugin/skills/rgit-capture/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rgit/_plugin/skills/rgit-capture/SKILL.md b/src/rgit/_plugin/skills/rgit-capture/SKILL.md index c49570a..eec4df2 100644 --- a/src/rgit/_plugin/skills/rgit-capture/SKILL.md +++ b/src/rgit/_plugin/skills/rgit-capture/SKILL.md @@ -68,7 +68,7 @@ Lost the ids from step 2? Bare `rgit review` re-lists every open proposal with i If any proposal remains open when you are about to finish a response, include a `Pending capsule review` section before finishing. List each proposal id and every candidate's stored name and one-line intent; include key knobs only when they affect the choice. Never replace this list with only a candidate count. Present the explanations and intents in the language the user is currently using, even when the stored capsule uses another language. Do not translate proposal ids, capsule names, code symbols, configuration keys, or file paths. Translation is presentation-only; never rewrite the stored candidates. -End that section with an explicit decision request. The response is incomplete unless it asks the user to choose one of: keep named capsules, keep all, or discard all. Give short reply examples in the user's language, such as `keep `, `keep all`, and `discard all`. Tell the user they only need to state their choice and that you will execute the review decision for them. Explain that kept candidates will be approved and stored as capsules; candidates they do not keep will be discarded. Do not approve, discard, or otherwise make a review decision before the user confirms. +Keep the handoff compact. Do not add a separate Git, capsule, or graph status list unless the user explicitly asked for those details. After the candidate list, end with exactly one short paragraph in the user's language that combines the unresolved status and decision request: ask which capsule names to keep, whether to keep all, or whether to discard all; state in the first person that you will execute the review for the user and that kept candidates will be approved and stored as capsules. Do not repeat candidate names as reply examples, render a separate decision menu, or say only that review "can" be executed. Do not approve, discard, or otherwise make a review decision before the user confirms. ### 6. Infer graph edges (deterministic baseline + agent-judged relationships) From d2cfcf27a8e429c63b312e95b3f90f242f4c2fb5 Mon Sep 17 00:00:00 2001 From: sunjiajunsunjiajun Date: Wed, 22 Jul 2026 16:55:46 +0800 Subject: [PATCH 4/4] test: replace brittle guidance text assertions --- ...26-07-19-pending-capsule-review-summary.md | 43 ++++++------------- ...9-pending-capsule-review-summary-design.md | 11 ++--- tests/test_agent_guidance.py | 11 ----- tests/test_installer.py | 12 ------ 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md b/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md index a33b263..d4edefd 100644 --- a/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md +++ b/docs/superpowers/plans/2026-07-19-pending-capsule-review-summary.md @@ -6,7 +6,7 @@ **Architecture:** Add matching behavioral contracts to the generated global AGENTS guidance and the packaged `rgit-capture` skill. Keep translation in the presentation layer and preserve proposal ids, capsule names, code symbols, configuration keys, file paths, and stored records. -**Tech Stack:** Python string rendering, Markdown skill instructions, pytest. +**Tech Stack:** Python string rendering, Markdown skill instructions, pytest, isolated Codex behavior validation. **Spec:** `docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md` @@ -19,34 +19,16 @@ --- -### Task 1: Lock the final-feedback contract with failing tests +### Task 1: Define the host-agent behavior check -**Files:** -- Modify: `tests/test_agent_guidance.py` -- Modify: `tests/test_installer.py` - -**Interfaces:** -- Consumes: `agent_guidance.render_global_block()` and the packaged `rgit-capture/SKILL.md`. -- Produces: regression tests for pending-detail and user-language requirements. - -- [ ] **Step 1: Add a global-guidance contract test** - -Add a test that checks the rendered block for instructions covering open -proposals, proposal ids, every candidate's name and one-line intent, conditional -key knobs, the prohibition on count-only summaries, user-language presentation, -and preservation of stable identifiers. - -- [ ] **Step 2: Add a capture-skill contract test** - -Extend the existing packaged-skill test to require a final-response fallback -with the same candidate-detail and language behavior. - -- [ ] **Step 3: Run the focused tests and verify RED** - -Run: `python -m pytest tests/test_agent_guidance.py tests/test_installer.py -q` - -Expected: the new assertions fail because neither instruction layer contains -the pending final-response contract yet. +- [ ] Create an isolated Git repository with a real `.rgit/` store and one + open proposal containing multiple English-language candidates. +- [ ] Load the branch versions of the global guidance and `rgit-capture` + skill, then ask an isolated Codex session to finish in another language + without approving, dismissing, or rewriting the proposal. +- [ ] Verify the final response includes every candidate and key choice-relevant + knob, preserves stable identifiers, requests the user's decision, and + leaves the stored proposal unchanged. --- @@ -71,11 +53,12 @@ and forbids count-only summaries. After the normal review instructions, require the same presentation whenever a proposal remains open at the end of a response. -- [ ] **Step 3: Run focused tests and verify GREEN** +- [ ] **Step 3: Run the existing focused tests** Run: `python -m pytest tests/test_agent_guidance.py tests/test_installer.py tests/test_guidance_coupling.py -q` -Expected: all tests pass. +Expected: existing guidance coupling and packaging tests pass without +hard-coding the new prose in test assertions. - [ ] **Step 4: Run the full suite** diff --git a/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md b/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md index 3f4b281..940cc64 100644 --- a/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md +++ b/docs/superpowers/specs/2026-07-19-pending-capsule-review-summary-design.md @@ -52,11 +52,12 @@ Chinese while `prop_abc`, `reranking-retrieval`, `cache-fallback`, and ## Testing -- Assert that the rendered global guidance requires pending proposal details, - rejects count-only summaries, and specifies user-language presentation with - stable identifiers. -- Assert that the packaged capture skill contains the same final-response - fallback and language rule. +- Run an isolated host-agent behavior check against a real pending proposal + with multiple candidates and a user language different from the stored + intents. +- Verify the final response lists every candidate, translates presentation + text, preserves stable identifiers, requests a review decision, and leaves + the stored proposal unchanged. - Keep guidance coupling and installer packaging tests passing. ## Out of Scope diff --git a/tests/test_agent_guidance.py b/tests/test_agent_guidance.py index 88365b4..9a8bfaa 100644 --- a/tests/test_agent_guidance.py +++ b/tests/test_agent_guidance.py @@ -184,17 +184,6 @@ def test_render_global_block_tells_agents_to_skip_mechanical_changes(): assert "Skip mechanical" in render_global_block() -def test_render_global_block_requires_pending_review_details_in_user_language(): - block = agent_guidance.render_global_block() - assert "open proposals awaiting review" in block - assert "every candidate's stored name and one-line intent" in block - assert "key knobs only when they affect the choice" in block - assert "A candidate count alone is not enough" in block - assert "language the user is currently using" in block - assert "Keep proposal ids, capsule names, code symbols, configuration keys, " \ - "and file paths unchanged" in block - - def test_render_emits_fingerprinted_start_marker(): block = agent_guidance.render_global_block() m = agent_guidance._START_RE.match(block) diff --git a/tests/test_installer.py b/tests/test_installer.py index ae91934..997320a 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -351,18 +351,6 @@ def test_capture_skill_uses_cli_not_mcp_write_tools(): assert "resegment(" not in skill -def test_capture_skill_requires_pending_final_response_in_user_language(): - from rgit import installer - skill = (installer.plugin_dir() / "skills" / "rgit-capture" / "SKILL.md").read_text(encoding="utf-8") - assert "If any proposal remains open when you are about to finish a response" in skill - assert "every candidate's stored name and one-line intent" in skill - assert "key knobs only when they affect the choice" in skill - assert "Never replace this list with only a candidate count" in skill - assert "language the user is currently using" in skill - assert "Do not translate proposal ids, capsule names, code symbols, " \ - "configuration keys, or file paths" in skill - - def test_run_decodes_non_utf8_output_without_crashing(): # A child emitting bytes the locale codec can't strict-decode (the 0x94 from # issue #11) must not crash _run: UTF-8 + errors="replace" keeps it robust