From 46d90cb80e553e5dfc6a80cbb842d2db074c220f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 08:02:50 +0000 Subject: [PATCH] chore: convert CE compound-engineering-v3.13.1 --- .last-processed | 2 +- dist/.claude-plugin/plugin.json | 4 +- dist/.codex-plugin/plugin.json | 2 +- dist/.cursor-plugin/plugin.json | 2 +- dist/AGENTS.md | 2 +- dist/CHANGELOG.md | 8 + dist/references/agent-prompts/manifest.json | 2 +- .../ce-brainstorm/references/handoff.md | 20 +- .../references/universal-brainstorming.md | 2 +- dist/skills/ce-ideate/SKILL.md | 2 +- .../references/post-ideation-workflow.md | 13 +- .../references/universal-ideation.md | 2 +- dist/skills/ce-plan/SKILL.md | 10 +- .../skills/ce-plan/references/plan-handoff.md | 21 +- .../ce-plan/references/plan-sections.md | 3 +- .../ce-plan/references/universal-planning.md | 4 +- dist/skills/ce-proof/SKILL.md | 39 +- .../skills/ce-proof/references/hitl-review.md | 393 ------------------ dist/skills/lfg/SKILL.md | 36 +- dist/skills/lfg/references/review-followup.md | 12 +- 20 files changed, 96 insertions(+), 483 deletions(-) delete mode 100644 dist/skills/ce-proof/references/hitl-review.md diff --git a/.last-processed b/.last-processed index aac0c69..9d9d2d9 100644 --- a/.last-processed +++ b/.last-processed @@ -1 +1 @@ -compound-engineering-v3.13.0 +compound-engineering-v3.13.1 diff --git a/dist/.claude-plugin/plugin.json b/dist/.claude-plugin/plugin.json index 02ef55d..dc65be9 100644 --- a/dist/.claude-plugin/plugin.json +++ b/dist/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ce-lite", - "version": "3.13.0-lite", + "version": "3.13.1-lite", "description": "Lightweight-delegation variant of compound-engineering. Agent registrations removed; specialist prompts loaded on demand from references/agent-prompts/. See https://github.com/ak2k/ce-lite.", "author": { "name": "Kieran Klaassen", @@ -23,6 +23,6 @@ "image-generation" ], "ce_lite": { - "upstream_tag": "compound-engineering-v3.13.0" + "upstream_tag": "compound-engineering-v3.13.1" } } diff --git a/dist/.codex-plugin/plugin.json b/dist/.codex-plugin/plugin.json index e45e613..c0644d6 100644 --- a/dist/.codex-plugin/plugin.json +++ b/dist/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "compound-engineering", - "version": "3.13.0", + "version": "3.13.1", "description": "AI-powered development tools for code review, research, design, and workflow automation.", "author": { "name": "Kieran Klaassen", diff --git a/dist/.cursor-plugin/plugin.json b/dist/.cursor-plugin/plugin.json index 9e21063..9ebdcee 100644 --- a/dist/.cursor-plugin/plugin.json +++ b/dist/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "compound-engineering", "displayName": "Compound Engineering", - "version": "3.13.0", + "version": "3.13.1", "description": "AI-powered development tools for code review, research, design, and workflow automation.", "author": { "name": "Kieran Klaassen", diff --git a/dist/AGENTS.md b/dist/AGENTS.md index 0d95951..3ec8a07 100644 --- a/dist/AGENTS.md +++ b/dist/AGENTS.md @@ -92,7 +92,7 @@ Important: Just because the developer's installed plugin may be out of date, it' ## Known External Limitations -**Proof HITL surfaces a ghost "AI collaborator" agent** (noted 2026-04-16, may change): The Proof API auto-joins any header-less `/state` read under a synthetic `ai:auto-` identity, so docs created by the `skills/proof/` HITL workflow show a phantom participant alongside `Compound Engineering`. The only way to suppress it is to set `ownerId: "agent:ai:compound-engineering"` on create — but that transfers document ownership to the agent and prevents the user from claiming it into their Proof library, so we don't use it. Treat as cosmetic noise; don't reintroduce the `ownerId` workaround. Tracked upstream: https://github.com/EveryInc/proof/issues/951. +**Proof surfaces a ghost "AI collaborator" agent** (noted 2026-04-16, may change): The Proof API auto-joins any header-less `/state` read under a synthetic `ai:auto-` identity, so docs created by the `ce-proof` publish/share workflow show a phantom participant alongside `Compound Engineering`. The only way to suppress it is to set `ownerId: "agent:ai:compound-engineering"` on create — but that transfers document ownership to the agent and prevents the user from claiming it into their Proof library, so we don't use it. Treat as cosmetic noise; don't reintroduce the `ownerId` workaround. Tracked upstream: https://github.com/EveryInc/proof/issues/951. ## Skill Design Principles diff --git a/dist/CHANGELOG.md b/dist/CHANGELOG.md index 9140942..b122a7d 100644 --- a/dist/CHANGELOG.md +++ b/dist/CHANGELOG.md @@ -9,6 +9,14 @@ All notable changes to the compound-engineering plugin will be documented in thi The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.13.1](https://github.com/EveryInc/compound-engineering-plugin/compare/compound-engineering-v3.13.0...compound-engineering-v3.13.1) (2026-06-17) + + +### Bug Fixes + +* **lfg:** run ce-simplify-code before review; clarify report-only contract ([#952](https://github.com/EveryInc/compound-engineering-plugin/issues/952)) ([d8d688b](https://github.com/EveryInc/compound-engineering-plugin/commit/d8d688b30d97eb5efc3142cec16dd8314ac48e47)) +* **proof:** replace HITL review loop with one-way publish ([#957](https://github.com/EveryInc/compound-engineering-plugin/issues/957)) ([68dd787](https://github.com/EveryInc/compound-engineering-plugin/commit/68dd787f98c734f57f6e40f1e8a6e29cb8584719)) + ## [3.13.0](https://github.com/EveryInc/compound-engineering-plugin/compare/compound-engineering-v3.12.0...compound-engineering-v3.13.0) (2026-06-15) diff --git a/dist/references/agent-prompts/manifest.json b/dist/references/agent-prompts/manifest.json index 5bdd156..5192a76 100644 --- a/dist/references/agent-prompts/manifest.json +++ b/dist/references/agent-prompts/manifest.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "upstream_tag": "compound-engineering-v3.13.0", + "upstream_tag": "compound-engineering-v3.13.1", "agent_count": 43, "agents": [ { diff --git a/dist/skills/ce-brainstorm/references/handoff.md b/dist/skills/ce-brainstorm/references/handoff.md index cb8defb..7b0c25b 100644 --- a/dist/skills/ce-brainstorm/references/handoff.md +++ b/dist/skills/ce-brainstorm/references/handoff.md @@ -47,8 +47,8 @@ Present only the options that apply. Renumber so visible options stay contiguous 1. **Plan implementation with `ce-plan` (Recommended)** - Move to `ce-plan` for structured implementation planning. Shown only when `Resolve Before Planning` is empty. 2. **Agent review of requirements doc with `ce-doc-review`** - Dispatch reviewer agents to check the doc for coherence, feasibility, scope, and other persona-specific issues; auto-apply safe fixes; route remaining findings interactively. Shown only when a requirements document exists **and `OUTPUT_FORMAT=md`** — ce-doc-review's walkthrough applies markdown-only mutations (`##`/`###` heading inserts, single-file markdown edits via apply-set) and would corrupt an HTML artifact, so HTML brainstorms skip this option until ce-doc-review gains HTML-aware mutation support. Under HTML mode, surface a one-line note above the menu: `Agent review unavailable in output:html mode — ce-doc-review is markdown-only today. Switch to output:md if you want a review pass.` -3. **Open in Proof — review and comment to iterate with the agent** - Open the doc in Every's Proof editor, iterate with the agent via comments, or copy a link to share with others. Shown only when a requirements document exists. **Render only when `OUTPUT_FORMAT=md`** (Proof operates on markdown and cannot ingest HTML). -3. **Open in browser** — open the HTML requirements file locally for review and sharing. Shown only when a requirements document exists. **Render only when `OUTPUT_FORMAT=html`.** Replaces "Open in Proof" at the same slot under exclusive output mode — the doc is either markdown OR HTML, never both, so exactly one of the two labels applies per run. +3. **Publish to Proof — shareable link** - Publish the requirements doc to Every's Proof editor and get a shareable link to read, comment on, or share with others. One-way: the local doc stays canonical. Shown only when a requirements document exists. **Render only when `OUTPUT_FORMAT=md`** (Proof operates on markdown and cannot ingest HTML). +3. **Open in browser** — open the HTML requirements file locally for review and sharing. Shown only when a requirements document exists. **Render only when `OUTPUT_FORMAT=html`.** Replaces "Publish to Proof" at the same slot under exclusive output mode — the doc is either markdown OR HTML, never both, so exactly one of the two labels applies per run. 4. **Build it now with `ce-work` (skip planning)** - Skip planning and move to `ce-work`; suited to lightweight, well-defined changes. Shown only when `Resolve Before Planning` is empty **and** scope is lightweight, success criteria are clear, scope boundaries are clear, and no meaningful technical or research questions remain (the "direct-to-work gate"). 5. **More clarifying questions to sharpen the doc** - Keep refining scope, edge cases, constraints, and preferences through further dialogue. Always shown. 6. **Done for now** - Pause; the requirements doc is saved and can be resumed later. Always shown. @@ -73,25 +73,17 @@ Immediately load the `ce-work` skill in the current session using the finalized **If user selects "More clarifying questions to sharpen the doc":** Return to Phase 1.3 (Collaborative Dialogue) and continue asking the user clarifying questions one at a time to further refine scope, edge cases, constraints, and preferences. Continue until the user is satisfied, then return to Phase 4. Do not show the closing summary yet. -**If user selects "Open in Proof — review and comment to iterate with the agent":** +**If user selects "Publish to Proof — shareable link":** -Load the `ce-proof` skill in HITL-review mode with: +Load the `ce-proof` skill to publish the requirements doc. Pass: - **source file:** `docs/brainstorms/YYYY-MM-DD--requirements.md` - **doc title:** `Requirements: ` - **identity:** `ai:compound-engineering` / `Compound Engineering` -- **recommended next step:** `ce-plan` (shown in the ce-proof skill's final terminal output) -Follow the HITL-review workflow in the ce-proof skill (the ce-proof skill loads its own hitl-review reference). It uploads the doc, prompts the user for review in Proof's web UI, ingests filtered comment threads, applies agreed edits through the current Proof edit APIs, replies/resolves in-thread, and syncs the final markdown back to the source file atomically on proceed. +ce-proof creates a shared Proof doc from the requirements file (Create and Share workflow), binds the display name, and returns the share URL. Surface the URL to the user — they can open it to read, comment, or share with others — then return to the Phase 4 options and re-render the menu. This is a one-way publish: the local doc stays canonical and nothing syncs back, so option eligibility is unchanged (no need to re-evaluate `Resolve Before Planning`, the direct-to-work gate, or residual findings on account of Proof). -When the ce-proof skill returns control: - -- `status: proceeded` with `localSynced: true` → the requirements doc on disk now reflects the review. Return to the Phase 4 options and re-render the menu (the doc may have changed substantially during review, so option eligibility can shift — re-evaluate `Resolve Before Planning`, direct-to-work gate, and residual ce-doc-review findings against the updated doc). -- `status: proceeded` with `localSynced: false` → the reviewed version lives in Proof at `docUrl` but the local copy is stale. Offer to pull the Proof doc to `localPath` using the ce-proof skill's Pull workflow. Re-render the Phase 4 menu after the pull completes (or is declined). If the pull was declined, include a one-line note above the menu that `` is stale vs. Proof — otherwise `Plan implementation` / `Build it now` / `Agent review of requirements doc` will silently read the pre-review copy. -- `status: done_for_now` → the doc on disk may be stale if the user edited in Proof before leaving. Offer to pull the Proof doc to `localPath` so the local requirements file stays in sync, then return to the Phase 4 options. If the pull was declined, include the stale-local note above the menu. `done_for_now` means the user stopped the HITL loop without syncing — it does not mean they ended the whole brainstorm. -- `status: aborted` → fall back to the Phase 4 options without changes. - -If the initial upload fails (network error, Proof API down), retry once after a short wait. If it still fails, tell the user the upload didn't succeed and briefly explain why, then return to the Phase 4 options — don't leave them wondering why the option did nothing. +If the upload fails (network error, Proof API down), retry once after a short wait. If it still fails, tell the user the upload didn't succeed and briefly explain why, then return to the Phase 4 options — don't leave them wondering why the option did nothing. **If user selects "Open in browser":** Display the absolute path to the `.html` requirements file so the user can open it locally. Where the platform exposes a browser-opening primitive (e.g., `open` on macOS, `xdg-open` on Linux, `start` on Windows), the agent may invoke it directly; otherwise print the absolute path and let the user open it. After the path is displayed (or the browser is opened), return to the Phase 4 options so the user can pick a follow-up action. diff --git a/dist/skills/ce-brainstorm/references/universal-brainstorming.md b/dist/skills/ce-brainstorm/references/universal-brainstorming.md index 5e5f0c2..104f4c4 100644 --- a/dist/skills/ce-brainstorm/references/universal-brainstorming.md +++ b/dist/skills/ce-brainstorm/references/universal-brainstorming.md @@ -59,5 +59,5 @@ When the conversation has enough material to narrow — reflect back what you've - **Create a plan** → hand off to `/ce-plan` with the decided goal and constraints - **Save summary to disk** → write the summary as a markdown file in the current working directory -- **Open in Proof (web app) — review and comment to iterate with the agent** → load the `ce-proof` skill to open the doc in Every's Proof editor, iterate with the agent via comments, or copy a link to share with others +- **Publish to Proof — shareable link** → load the `ce-proof` skill to publish the doc to Every's Proof editor and get a shareable link to read, comment on, or share with others (one-way; the local summary stays canonical) - **Done** → the conversation was the value, no artifact needed diff --git a/dist/skills/ce-ideate/SKILL.md b/dist/skills/ce-ideate/SKILL.md index 3daed2d..70dbf2b 100644 --- a/dist/skills/ce-ideate/SKILL.md +++ b/dist/skills/ce-ideate/SKILL.md @@ -210,7 +210,7 @@ Do not prescribe correction phrases ("say X to switch"). State the inferred mode **Active confirmation on mode ambiguity.** Only fire when mode classification is genuinely ambiguous *after* 0.2 settled the subject — e.g., "our docs" could mean repo docs (repo-grounded) or public marketing docs (elsewhere-software). Most subjects settled in 0.2 classify cleanly here. When ambiguous, ask one confirmation question via the blocking tool with two self-contained labels naming the two candidate interpretations in plain language (e.g., "Treat as repo docs in this codebase" vs "Treat as public marketing docs") — never leak internal mode names. Otherwise the one-sentence inferred-mode statement is sufficient; do not ask. -**Routing rule (non-software mode).** When Decision 2 = non-software, still run Phase 1 Elsewhere-mode grounding (user-context synthesis + web-research by default; skip phrases honored). Learnings-researcher is skipped by default in this mode — the CWD's `docs/solutions/` rarely transfers to naming, narrative, personal, or non-digital business topics; see Phase 1 for the full rationale. Then load `references/universal-ideation.md` and follow it in place of Phase 2's software frame dispatch and the Phase 5 menu narrative. This load is non-optional — the file contains the domain-agnostic generation frames, critique rubric, and wrap-up menu that replace Phase 2 and the post-ideation menu for this mode, and none of those details live in this main body. Improvising from memory produces the wrong facilitation for non-software topics. Do not run the repo-specific codebase scan at any point. The deliverable is auto-written here too (per `references/post-ideation-workflow.md` Phase 4); if the user opens a markdown deliverable in Proof and it fails, the §5.1 Proof handling applies and the auto-written local file remains the intact record. +**Routing rule (non-software mode).** When Decision 2 = non-software, still run Phase 1 Elsewhere-mode grounding (user-context synthesis + web-research by default; skip phrases honored). Learnings-researcher is skipped by default in this mode — the CWD's `docs/solutions/` rarely transfers to naming, narrative, personal, or non-digital business topics; see Phase 1 for the full rationale. Then load `references/universal-ideation.md` and follow it in place of Phase 2's software frame dispatch and the Phase 5 menu narrative. This load is non-optional — the file contains the domain-agnostic generation frames, critique rubric, and wrap-up menu that replace Phase 2 and the post-ideation menu for this mode, and none of those details live in this main body. Improvising from memory produces the wrong facilitation for non-software topics. Do not run the repo-specific codebase scan at any point. The deliverable is auto-written here too (per `references/post-ideation-workflow.md` Phase 4); if the user publishes a markdown deliverable to Proof and it fails, the §5.1 Proof handling applies and the auto-written local file remains the intact record. #### 0.4 Context-Substance Gate (Elsewhere Modes Only) diff --git a/dist/skills/ce-ideate/references/post-ideation-workflow.md b/dist/skills/ce-ideate/references/post-ideation-workflow.md index 90c5915..db8721a 100644 --- a/dist/skills/ce-ideate/references/post-ideation-workflow.md +++ b/dist/skills/ce-ideate/references/post-ideation-workflow.md @@ -75,7 +75,7 @@ This ranked list doubles as the index the user references when choosing an idea ### 4.3 Open It - **HTML:** in an interactive session, best-effort open the file in the browser via the platform's open primitive (`open` on macOS, `xdg-open` on Linux, `start` on Windows); always print the absolute path so it can be reopened or shared. Skip auto-open in headless / pipeline runs (no interactive surface). -- **Markdown:** print the path. Proof (the markdown iterate surface) is reached through the Phase 5 menu — it is a network action, not auto-invoked. +- **Markdown:** print the path. Proof (the markdown share surface) is reached through the Phase 5 menu — it is a network action, not auto-invoked. ## Phase 5: Next Steps @@ -88,7 +88,7 @@ The deliverable already exists (Phase 4), so the menu is purely *what next* — Offer four options (self-contained labels with the distinguishing word front-loaded so they stay distinct when truncated). Option 1 is **format-keyed** — render exactly one of its two labels per run, matching `OUTPUT_FORMAT`: 1. *(when `OUTPUT_FORMAT=html`)* **Open in browser** — open the saved HTML deliverable (re-open if it was already opened). - *(when `OUTPUT_FORMAT=md`)* **Open and iterate in Proof** — open the saved markdown in Proof's HITL review loop; reviewed edits sync back to the local file. + *(when `OUTPUT_FORMAT=md`)* **Publish to Proof** — publish the saved markdown to Proof and get a shareable link; one-way, the local file stays canonical. 2. **Brainstorm one idea with `ce-brainstorm`** — commit a chosen idea to a requirements doc; leaves ce-ideate. Asks which idea first. 3. **Iterate on one idea (adjust / ask, stay here)** — sharpen or interrogate a chosen idea before committing. Asks which idea and how. 4. **Done — keep the file and stop.** @@ -97,16 +97,15 @@ Offer four options (self-contained labels with the distinguishing word front-loa If the user already named an idea inline (e.g. "brainstorm the table tool", "tighten the highlighter idea"), skip the "which idea?" follow-up for §5.2 / §5.3. -### 5.1 Open in Browser (html) / Open and Iterate in Proof (md) +### 5.1 Open in Browser (html) / Publish to Proof (md) -- **HTML — Open in browser.** (Re)open the saved file via the platform primitive where available; otherwise print the absolute path. Return to the Phase 5 menu. No Proof, no sync — the HTML file is the canonical record. -- **Markdown — Open and iterate in Proof.** The local markdown file already exists (Phase 4), so Proof is a review surface over it, not the primary record. Load the `ce-proof` skill in HITL-review mode with: +- **HTML — Open in browser.** (Re)open the saved file via the platform primitive where available; otherwise print the absolute path. Return to the Phase 5 menu. No Proof — the HTML file is the canonical record. +- **Markdown — Publish to Proof.** The local markdown file already exists (Phase 4) and stays canonical; Proof is a one-way published copy, not a sync target. Load the `ce-proof` skill to publish, passing: - **source file:** the saved `.md` file from Phase 4. - **doc title:** `Ideation: ` or the doc's H1. - **identity:** `ai:compound-engineering` / `Compound Engineering`. - - **recommended next step:** `/ce-brainstorm`. - On return, the proof skill syncs the reviewed markdown back to the local file; then return to the Phase 5 menu on any status. If the Proof handoff fails after the proof skill's internal retry plus one orchestrator-side retry (~2s pause, narrated as "Retrying Proof... attempt 2/2"), tell the user Proof is unavailable and that the local file is intact at ``, then return to the menu — the deliverable was never at risk (it was written in Phase 4). *(If the user explicitly asked for Proof during an HTML run: Proof is markdown-only and cannot ingest HTML, so render a throwaway markdown copy of the survivors as the Proof source, do not upload the `.html`, and note Proof edits won't sync back into the HTML canonical.)* + ce-proof creates a shared Proof doc (Create and Share workflow) and returns the share URL. Surface it to the user, then return to the Phase 5 menu — nothing syncs back to disk. If the Proof handoff fails after the proof skill's internal retry plus one orchestrator-side retry (~2s pause, narrated as "Retrying Proof... attempt 2/2"), tell the user Proof is unavailable and that the local file is intact at ``, then return to the menu — the deliverable was never at risk (it was written in Phase 4). *(If the user explicitly asked for Proof during an HTML run: Proof is markdown-only and cannot ingest HTML, so render a throwaway markdown copy of the survivors as the Proof source and do not upload the `.html`.)* ### 5.2 Brainstorm One Idea diff --git a/dist/skills/ce-ideate/references/universal-ideation.md b/dist/skills/ce-ideate/references/universal-ideation.md index ff48322..745abd0 100644 --- a/dist/skills/ce-ideate/references/universal-ideation.md +++ b/dist/skills/ce-ideate/references/universal-ideation.md @@ -99,7 +99,7 @@ Wrap up with the same flow as `references/post-ideation-workflow.md` Phases 4– Then offer the Phase 5 next-steps menu via the platform's blocking question tool (`AskUserQuestion` in Claude Code — call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded; `request_user_input` in Codex; `ask_user` in Gemini / Pi). Fall back to a numbered list only when no blocking tool exists or the call errors. Never silently skip. Four options, option 1 format-keyed: -1. **Open in browser** *(html)* / **Open and iterate in Proof** *(md)* — open the deliverable (per §5.1). On Proof failure the auto-written local file stays intact. +1. **Open in browser** *(html)* / **Publish to Proof** *(md)* — open the HTML deliverable, or publish the markdown to Proof for a shareable link (per §5.1). On Proof failure the auto-written local file stays intact. 2. **Brainstorm one idea with `ce-brainstorm`** — go deeper on one chosen idea (asks which). In universal mode this is **not** the first step of an implementation chain — there is no `ce-plan` → `ce-work` after; `ce-brainstorm` develops the idea further (a name into a brand brief, a plot into an outline, a decision into a weighed framework) and ends there. Seed it with the idea's substance + a provenance pointer (per §5.2) — not the whole file. 3. **Iterate on one idea (adjust / ask, stay here)** — sharpen or interrogate a chosen idea before committing; adjustments rewrite the file, Q&A does not (per §5.3). 4. **Done — keep the file and stop.** diff --git a/dist/skills/ce-plan/SKILL.md b/dist/skills/ce-plan/SKILL.md index 7dbd92d..dbd05ab 100644 --- a/dist/skills/ce-plan/SKILL.md +++ b/dist/skills/ce-plan/SKILL.md @@ -791,27 +791,27 @@ When deepening is warranted, read `references/deepening-workflow.md` for confide ##### 5.3.8–5.4 Document Review, Final Checks, and Post-Generation Options -**STOP. Load `references/plan-handoff.md` now before continuing.** It carries the full instructions for 5.3.8 (document review), 5.3.9 (final checks and cleanup), and 5.4 (post-generation handoff, including the Proof HITL flow, post-HITL re-review, and Issue Creation branching). **This load is non-optional** — without it, the agent renders the post-generation menu, captures the user's selection, and stops without firing the routed action. Document review at 5.3.8 runs unconditionally for `OUTPUT_FORMAT=md` regardless of whether the confidence check already ran; for `OUTPUT_FORMAT=html`, plan-handoff's 5.3.8 format gate skips ce-doc-review because its mutation mechanics are markdown-only today. The default mode for markdown is headless (`mode:headless`) — `safe_auto` fixes apply silently, remaining findings surface contextually above the menu, and a deeper interactive review is opt-in via free-form prompt. +**STOP. Load `references/plan-handoff.md` now before continuing.** It carries the full instructions for 5.3.8 (document review), 5.3.9 (final checks and cleanup), and 5.4 (post-generation handoff, including the Publish to Proof flow and Issue Creation branching). **This load is non-optional** — without it, the agent renders the post-generation menu, captures the user's selection, and stops without firing the routed action. Document review at 5.3.8 runs unconditionally for `OUTPUT_FORMAT=md` regardless of whether the confidence check already ran; for `OUTPUT_FORMAT=html`, plan-handoff's 5.3.8 format gate skips ce-doc-review because its mutation mechanics are markdown-only today. The default mode for markdown is headless (`mode:headless`) — `safe_auto` fixes apply silently, remaining findings surface contextually above the menu, and a deeper interactive review is opt-in via free-form prompt. After document review and final checks, print a one-line summary of the headless review state above the menu (e.g., `Doc review applied 3 fixes. 2 decisions, 1 proposed fix, 4 FYI observations remain (1 at P1).`; for HTML plans where 5.3.8 was skipped, print `Doc review skipped — ce-doc-review is markdown-only today; the HTML plan was not reviewed.`), then present the menu. The menu has 5 options when actionable findings remain (`proposed_fixes_count + decisions_count > 0`) and 4 options otherwise — including the FYI-only case AND the HTML-skip case (`skipped_reason: output_format_html`), both of which hide option 2 because ce-doc-review's walkthrough is gated to actionable markdown findings and would have nothing valid to walk through. See `references/plan-handoff.md` for the full rule. Render the 5-option menu as a numbered list in chat per the AGENTS.md narrow exception for legitimate option overflow, with the hint "Pick a number or describe what you want." On platforms whose blocking question tool has no option cap (Codex `request_user_input`, Pi `ask_user`), use the platform's blocking tool; when that tool is unavailable or errors (e.g., Codex edit modes where `request_user_input` is not exposed), fall back to the same numbered-list-in-chat rendering with the "Pick a number or describe what you want." hint. The 4-option case routes through the platform's blocking tool normally (`AskUserQuestion` in Claude Code — call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded), with the same numbered-list-in-chat fallback when no blocking tool is available or the call errors. Never silently skip the question. **Question:** "Plan ready at ``. What would you like to do next?" (use absolute path so the reference is clickable in modern terminals) -**Options.** Option 4's label matches the artifact's format. Under exclusive output mode, exactly one of "Open in Proof" or "Open in browser" applies per run — `OUTPUT_FORMAT=md` shows Proof; `OUTPUT_FORMAT=html` shows browser. Proof operates on markdown and cannot ingest HTML; the browser option opens the local `.html` file. Render the option matching the format produced this run. +**Options.** Option 4's label matches the artifact's format. Under exclusive output mode, exactly one of "Publish to Proof" or "Open in browser" applies per run — `OUTPUT_FORMAT=md` shows Proof; `OUTPUT_FORMAT=html` shows browser. Proof operates on markdown and cannot ingest HTML; the browser option opens the local `.html` file. Render the option matching the format produced this run. 1. **Start `/ce-work`** (recommended) - Begin implementing this plan in the current session 2. **Run deeper doc review** - Walk through the remaining findings interactively (full ce-doc-review walkthrough) 3. **Create Issue** - Create a tracked issue from this plan in your configured issue tracker (GitHub or Linear) -4. **Open in Proof (web app) — review and comment to iterate with the agent** - Open the doc in Every's Proof editor, iterate with the agent via comments, or copy a link to share with others. **Render only when `OUTPUT_FORMAT=md`.** +4. **Publish to Proof — shareable link** - Publish the plan to Every's Proof editor and get a shareable link to read, comment on, or share with others. One-way: the local plan file stays canonical. **Render only when `OUTPUT_FORMAT=md`.** 4. **Open in browser** - Open the HTML plan file locally for review and sharing. **Render only when `OUTPUT_FORMAT=html`.** 5. **Done for now** - Pause; the plan file is saved and can be resumed later -**Routing.** Act on the user's selection — do not just announce it. Elaborate sub-flows (Proof HITL state machine, Issue Creation tracker detection, post-HITL resync) live in `references/plan-handoff.md`. +**Routing.** Act on the user's selection — do not just announce it. Elaborate sub-flows (Issue Creation tracker detection) live in `references/plan-handoff.md`. - **Start `/ce-work`** — Invoke the `ce-work` skill via the platform's skill-invocation primitive (`Skill` in Claude Code, `Skill` in Codex, the equivalent on Gemini/Pi), passing the plan path as the skill argument. Do not merely tell the user to type `/ce-work` — fire the invocation now so the plan executes in this session. - **Run deeper doc review** — Re-invoke the `ce-doc-review` skill on the plan path **without** `mode:headless` so the interactive routing question and walkthrough fire. After it returns, re-render this menu with refreshed counts so the user can pick a next-stage action. - **Create Issue** — Detect the project tracker (`gh` for GitHub, `linear` for Linear) and create the issue from the plan file as described under "Issue Creation" in `references/plan-handoff.md`. After creation, display the issue URL and ask whether to proceed to `/ce-work` via the platform's blocking question tool. -- **Open in Proof (web app) — review and comment to iterate with the agent** — Load the `ce-proof` skill in HITL-review mode with the plan file as `source file`, the plan title as `doc title`, identity `ai:compound-engineering` / `Compound Engineering`, and recommended next step `/ce-work`. Then follow the post-HITL resync logic in `references/plan-handoff.md`, which handles the four `ce-proof` return statuses, re-runs `ce-doc-review` after material edits, and falls back gracefully on upload failure. +- **Publish to Proof — shareable link** — Load the `ce-proof` skill to publish the plan: create a shared Proof doc from the plan file (title = plan title; identity `ai:compound-engineering` / `Compound Engineering`), surface the share URL to the user, then return to this menu. One-way publish — the local plan file stays canonical, nothing syncs back. If the upload fails, see the graceful-fallback note in `references/plan-handoff.md`. - **Open in browser** — Display the absolute path to the `.html` plan file so the user can open it locally. Where the platform exposes a browser-opening primitive (e.g., `open` on macOS, `xdg-open` on Linux, `start` on Windows), the agent may use it; otherwise print the absolute path and let the user open it. Do not invoke `ce-work` from this option — the user picked HTML for review/sharing, not handoff. - **Done for now** — Display a brief confirmation that the plan file is saved and end the turn. Do not start follow-up work without an explicit further user prompt. diff --git a/dist/skills/ce-plan/references/plan-handoff.md b/dist/skills/ce-plan/references/plan-handoff.md index e1366c9..968a1ee 100644 --- a/dist/skills/ce-plan/references/plan-handoff.md +++ b/dist/skills/ce-plan/references/plan-handoff.md @@ -45,7 +45,7 @@ If artifact-backed mode was used: When `OUTPUT_FORMAT=md`, write the markdown directly per `references/markdown-rendering.md`. No HTML is composed. -After all mutations in this run have settled (initial write, deepening synthesis, ce-doc-review `safe_auto` fixes when `OUTPUT_FORMAT=md`, HITL Proof resync if any), the artifact at its single path reflects the final state. HTML runs skip the ce-doc-review autofix step (see 5.3.8 format gate). +After all mutations in this run have settled (initial write, deepening synthesis, ce-doc-review `safe_auto` fixes when `OUTPUT_FORMAT=md`), the artifact at its single path reflects the final state. Publishing to Proof is one-way and does not mutate the local file. HTML runs skip the ce-doc-review autofix step (see 5.3.8 format gate). ## 5.4 Post-Generation Options @@ -61,11 +61,11 @@ After all mutations in this run have settled (initial write, deepening synthesis 1. **Start `/ce-work`** (recommended) - Begin implementing this plan in the current session 2. **Run deeper doc review** - Walk through the remaining findings interactively (full ce-doc-review walkthrough) 3. **Create Issue** - Create a tracked issue from this plan in your configured issue tracker (GitHub or Linear) -4. **Open in Proof (web app) — review and comment to iterate with the agent** - Open the doc in Every's Proof editor, iterate with the agent via comments, or copy a link to share with others. **Render only when `OUTPUT_FORMAT=md`.** +4. **Publish to Proof — shareable link** - Publish the plan to Every's Proof editor and get a shareable link to read, comment on, or share with others. One-way: the local plan file stays canonical. **Render only when `OUTPUT_FORMAT=md`.** 4. **Open in browser** - Open the HTML plan file locally for review and sharing. **Render only when `OUTPUT_FORMAT=html`.** 5. **Done for now** - Pause; the plan file is saved and can be resumed later -**Option 4 format-keyed label.** Under exclusive output mode, the plan exists as exactly one artifact — `.md` or `.html`, never both. Render the option 4 label matching the produced format. Proof operates on markdown plans (it ingests the `.md` source and rewrites markdown), so it does not apply to HTML runs; the browser option opens the local `.html` file directly. `/ce-work` remains the recommended option in both modes — `ce-work` reads either format (see the ce-work skill's plan-input handling). +**Option 4 format-keyed label.** Under exclusive output mode, the plan exists as exactly one artifact — `.md` or `.html`, never both. Render the option 4 label matching the produced format. Proof ingests the `.md` source, so it does not apply to HTML runs; the browser option opens the local `.html` file directly. `/ce-work` remains the recommended option in both modes — `ce-work` reads either format (see the ce-work skill's plan-input handling). **Menu rendering:** The menu has 5 options, which exceeds the `AskUserQuestion` 4-option cap. Per the AGENTS.md narrow exception for legitimate option overflow, render this menu as a numbered list in chat with the hint "Pick a number or describe what you want." rather than trimming to fit the cap. Each option is a distinct destination/workflow and none are removable without losing real user choice (deeper review, issue creation, Proof, ce-work, and pause are each separately requested in practice). On platforms where blocking question tools have no option cap (e.g., Codex `request_user_input`, Pi `ask_user`), use the platform's blocking tool with all 5 options. When the platform's blocking tool is unavailable or errors (e.g., Codex edit modes where `request_user_input` is not exposed, or `ask_user` returns no match), fall back to the same numbered-list-in-chat rendering with the "Pick a number or describe what you want." hint — the same fallback the `AskUserQuestion` overflow path uses. Never silently skip the question. @@ -75,23 +75,16 @@ Based on selection (the bare per-option routing is also stated inline in the SKI - **Start `/ce-work`** -> Invoke the `ce-work` skill via the platform's skill-invocation primitive (`Skill` in Claude Code, `Skill` in Codex, the equivalent on Gemini/Pi), passing the plan path as the skill argument. Do not merely tell the user to type `/ce-work` — fire the invocation now so the plan executes in this session. - **Run deeper doc review** -> Re-invoke the `ce-doc-review` skill on the plan path **without** `mode:headless` so the interactive routing question and walkthrough fire. The headless pass already applied `safe_auto` fixes and recorded its findings in the session, so the interactive pass picks up where headless stopped — its R29 suppression rule prevents prior-round Skipped/Deferred entries from re-raising. After it returns, re-render this menu with the refreshed counts so the user can pick what to do next. - **Create Issue** -> Follow the Issue Creation section below -- **Open in Proof (web app) — review and comment to iterate with the agent** -> Load the `ce-proof` skill in HITL-review mode with: +- **Publish to Proof — shareable link** -> Load the `ce-proof` skill to publish the plan. Pass: - source file: `docs/plans/.md` - doc title: `Plan: ` - identity: `ai:compound-engineering` / `Compound Engineering` - - recommended next step: `/ce-work` (shown in the ce-proof skill's final terminal output) - Follow the HITL-review workflow in the ce-proof skill (the ce-proof skill loads its own hitl-review reference). It uploads the plan, prompts the user for review in Proof's web UI, ingests filtered comment threads, applies agreed edits through the current Proof edit APIs, replies/resolves in-thread, and syncs the final markdown back to the plan file atomically on proceed. + ce-proof creates a shared Proof doc from the plan file (Create and Share workflow), binds the display name, and returns the share URL. Surface the URL to the user — they can open it to read, comment, or share with others — then return to the post-generation options. This is a one-way publish: the local plan file stays canonical and nothing syncs back, so no re-review is needed and the menu re-renders with the same residual findings as before. - Note: the Proof flow only runs when `OUTPUT_FORMAT=md` (the menu only renders this option then). Proof ingests markdown; HTML plans use the local browser option instead. + Note: the Proof option only renders when `OUTPUT_FORMAT=md`. Proof ingests markdown; HTML plans use the local browser option instead. - When the ce-proof skill returns: - - `status: proceeded` with `localSynced: true` -> the plan on disk now reflects the review. Re-run `ce-doc-review` on the updated plan before re-rendering the menu — HITL can materially rewrite the plan body, so the prior ce-doc-review pass no longer covers the current file and section 5.3.8 requires a review before any handoff option is offered. Then return to the post-generation options with the refreshed residual findings. - - `status: proceeded` with `localSynced: false` -> the reviewed version lives in Proof at `docUrl` but the local copy is stale. Offer to pull the Proof doc to `localPath` using the ce-proof skill's Pull workflow. If the pull happened, re-run `ce-doc-review` on the pulled file before re-rendering the options (same 5.3.8 rationale — the local plan was materially updated by the pull). If the pull was declined, include a one-line note above the menu that `` is stale vs. Proof — otherwise `Start /ce-work` or `Create Issue` will silently use the pre-review copy. - - `status: done_for_now` -> the plan on disk may be stale if the user edited in Proof before leaving. Offer to pull the Proof doc to `localPath` so the local plan file stays in sync. If the pull happened, re-run `ce-doc-review` on the pulled file before re-rendering the options (same 5.3.8 rationale). If the pull was declined, include the stale-local note above the menu. `done_for_now` means the user stopped the HITL loop — it does not mean they ended the whole plan session; they may still want to start work or create an issue. - - `status: aborted` -> fall back to the options without changes. - - If the initial upload fails (network error, Proof API down), retry once after a short wait. If it still fails, tell the user the upload didn't succeed and briefly explain why, then return to the options — don't leave them wondering why the option did nothing. + If the upload fails (network error, Proof API down), retry once after a short wait. If it still fails, tell the user the upload didn't succeed and briefly explain why, then return to the options — don't leave them wondering why the option did nothing. - **Open in browser** -> Display the absolute path to the `.html` plan file so the user can open it locally. Where the platform exposes a browser-opening primitive (e.g., `open` on macOS, `xdg-open` on Linux, `start` on Windows), the agent may invoke it directly; otherwise print the absolute path and let the user open it. After the path is displayed (or the browser is opened), return to the post-generation options so the user can pick a follow-up action. - **Done for now** -> Display a brief confirmation that the plan file is saved and end the turn. Do not start follow-up work without an explicit further user prompt. - **Free-form prompts that target the findings** (e.g., the user types "review", "walk through", "deep review" instead of picking a numbered option) -> route as if they had picked `Run deeper doc review`. Do not loop back to the menu without firing the deeper review. **Exception:** when the envelope carries `skipped_reason: output_format_html`, do not fire ce-doc-review — instead, reply once with `ce-doc-review is markdown-only today; the HTML plan can't be reviewed without HTML-aware mutation support. Switch to /ce-plan output:md to regenerate as markdown if you want a review pass.` and loop back to the menu. diff --git a/dist/skills/ce-plan/references/plan-sections.md b/dist/skills/ce-plan/references/plan-sections.md index d9db4eb..288e6f8 100644 --- a/dist/skills/ce-plan/references/plan-sections.md +++ b/dist/skills/ce-plan/references/plan-sections.md @@ -227,8 +227,7 @@ semantics so downstream tooling can rely on them: - **`origin`** — repo-relative path to an upstream brainstorm requirements doc (e.g., `docs/brainstorms/2026-05-12-pagination-requirements.md`). Set when planning from an upstream brainstorm; carried for traceability - and re-resolved when `ce-plan` re-deepens. The HITL Proof flow uses - `origin` to trace back to the source brainstorm. + and re-resolved when `ce-plan` re-deepens. - **`deepened`** — ISO 8601 date marking the first time the confidence check substantively strengthened the plan. Presence affects Phase 0.1 resume fast-path logic (see `references/deepening-workflow.md`). diff --git a/dist/skills/ce-plan/references/universal-planning.md b/dist/skills/ce-plan/references/universal-planning.md index 53953fe..2762804 100644 --- a/dist/skills/ce-plan/references/universal-planning.md +++ b/dist/skills/ce-plan/references/universal-planning.md @@ -160,8 +160,8 @@ After structuring the plan, ask the user how they want to receive it using the p - Use filename convention: `YYYY-MM-DD--plan.md` - Start the document with a `# Title` heading, followed by `Created: YYYY-MM-DD` on the next line. No YAML frontmatter. -2. **Open in Proof (web app) — review and comment to iterate with the agent** — Open the doc in Every's Proof editor, iterate with the agent via comments, or copy a link to share with others. Load the `ce-proof` skill to create and open the document. +2. **Publish to Proof — shareable link** — Publish the doc to Every's Proof editor and get a shareable link to read, comment on, or share with others. Load the `ce-proof` skill to create the shared document and return the URL. One-way: nothing syncs back to disk. -3. **Save to disk AND open in Proof** — Do both: write the markdown file to disk and open the doc in Proof for review. +3. **Save to disk AND publish to Proof** — Do both: write the markdown file to disk and publish a shareable Proof copy for review. The local file stays canonical. Do not offer `/ce-work` (software-only) or issue creation (not applicable to non-software plans). diff --git a/dist/skills/ce-proof/SKILL.md b/dist/skills/ce-proof/SKILL.md index c9a5284..f67206c 100644 --- a/dist/skills/ce-proof/SKILL.md +++ b/dist/skills/ce-proof/SKILL.md @@ -1,6 +1,6 @@ --- name: ce-proof -description: Run human-in-the-loop review loops over markdown via Proof (proofeditor.ai) — share, view, comment on, edit, and sync collaborative docs. Use when the user says "view this in proof", "share to proof", "HITL this doc", or wants a shared markdown review surface for a spec, plan, or draft, including handoffs from ce-brainstorm, ce-ideate, or ce-plan. Do not trigger on "proof" meaning evidence, math proofs, proof-of-concept, or "proofread this". +description: Publish, view, comment on, and edit markdown via Proof (proofeditor.ai) — create a shareable doc, read a shared doc, and make comment/suggestion/block edits over its API. Use when the user says "view this in proof", "share to proof", "publish to proof", or wants a shareable markdown surface for a spec, plan, or draft, including publish handoffs from ce-brainstorm, ce-ideate, or ce-plan. Do not trigger on "proof" meaning evidence, math proofs, proof-of-concept, or "proofread this". allowed-tools: - Bash - Read @@ -22,14 +22,14 @@ Every write to a Proof doc must be attributed. Two fields carry the agent's iden - **Machine ID (`by` on every op, `X-Agent-Id` header):** `ai:compound-engineering` — stable, lowercase-hyphenated, machine-parseable. Appears in marks, events, and the API response. - **Display name (`name` on `POST /presence`):** `Compound Engineering` — human-readable, shown in Proof's presence chips and comment-author badges. -Set the display name once per doc session by posting to presence with the `X-Agent-Id` header; Proof binds the name to that agent ID for the session. These values are the defaults for any caller of this skill; callers running HITL review (`references/hitl-review.md`) may pass a different `identity` pair if a distinct sub-agent should own the doc. Do not use `ai:compound` or other ad-hoc variants — identity stays uniform unless a caller explicitly overrides it. +Set the display name once per doc session by posting to presence with the `X-Agent-Id` header; Proof binds the name to that agent ID for the session. These values are the defaults for any caller of this skill; a caller may pass a different `identity` pair if a distinct sub-agent should own the doc. Do not use `ai:compound` or other ad-hoc variants — identity stays uniform unless a caller explicitly overrides it. -## Human-in-the-Loop Review Mode +## Publish Mode -Human-in-the-loop iteration over an existing local markdown file: upload to Proof, let the user annotate in Proof's web UI, ingest feedback as in-thread replies and agreed edits, and sync the final doc back to disk. Two entry points, identical mechanics — load `references/hitl-review.md` for the full loop spec (invocation contract, mark classification, idempotent ingest passes, exception-based terminal reporting, end-sync atomic write) in either case: +The primary use is one-way publishing: take an existing local markdown file (a brainstorm, a plan, a learning, a draft), read its full contents and post them as the new doc's body (see "Workflow: Create and Share a New Document" for the source-file recipe — never publish placeholder content), and hand the user a shareable URL. The local file stays canonical — publishing does not sync anything back to disk. The user can open the link to read, comment, and share with others; the agent can also participate via the edit APIs below when given the URL. Two entry points, identical mechanics (see "Workflow: Create and Share a New Document"): -- **Direct user request** — a bare user phrase naming a local markdown file and asking to iterate collaboratively via Proof: "share this to proof so we can iterate", "iterate with proof on this doc", "HITL this file with me", "let's get feedback on this in proof", "open this in proof editor so I can review". The file is whichever markdown the user just created, edited, or referenced; if ambiguous, ask which file. This is a first-class entry point — do not require an upstream caller. -- **Upstream skill handoff** — `ce-brainstorm`, `ce-ideate`, or `ce-plan` finishes a draft and hands it off for human review before the next phase, passing the file path and title explicitly. +- **Direct user request** — a bare user phrase naming a local markdown file and asking to share it via Proof: "share this to proof", "publish this to proof", "open this in proof editor so I can review", "get me a proof link for this doc". The file is whichever markdown the user just created, edited, or referenced; if ambiguous, ask which file. This is a first-class entry point — do not require an upstream caller. +- **Upstream skill handoff** — `ce-brainstorm`, `ce-ideate`, or `ce-plan` finishes a draft and hands it off to publish for human review, passing the file path and title explicitly. ## Web API (Primary for Sharing) @@ -97,7 +97,7 @@ Comment, suggestion, and rewrite operations go to `POST https://www.proofeditor. **Wire-format reminder.** `/api/agent/{slug}/ops` uses a top-level `type` field; `/api/agent/{slug}/edit/v2` uses an `operations` array where each entry has `op`. Do not mix — sending `op` to `/ops` returns 422. -**Every mutation requires a `baseToken`.** Reuse the `mutationBase.token` from the most recent `/state` or `/snapshot` read, then update it from successful mutation responses (`.mutationBase.token`). On `BASE_TOKEN_REQUIRED` or `STALE_BASE`, re-read and retry once. Only do a pre-mutation read if no prior read has happened in this session or you need fresh document/comment/snapshot content. See the baseToken recipe in `references/hitl-review.md`. +**Every mutation requires a `baseToken`.** Reuse the `mutationBase.token` from the most recent `/state` or `/snapshot` read, then update it from successful mutation responses (`.mutationBase.token`). On `BASE_TOKEN_REQUIRED` or `STALE_BASE`, re-read and retry once. Only do a pre-mutation read if no prior read has happened in this session or you need fresh document/comment/snapshot content. `/edit/v2` block refs are a separate concern: they can drift across revisions, so re-fetch `/snapshot` for fresh refs before a block edit if any writes have landed since your last snapshot. @@ -147,7 +147,7 @@ Duplicate-mark incidents usually come from retrying a `comment.add` or `suggesti ]} ``` -Batch `/ops` supports `comment.reply`, `comment.resolve`, and `comment.unresolve` for existing threads. Use it for HITL ingest passes instead of issuing separate reply and resolve requests per thread. +Batch `/ops` supports `comment.reply`, `comment.resolve`, and `comment.unresolve` for existing threads. Use it to reply to and resolve multiple threads in one call instead of issuing separate reply and resolve requests per thread. **Resolve / unresolve a comment:** ```json @@ -211,7 +211,7 @@ Per-op body shape (singular `block` vs plural `blocks` is load-bearing — sendi | `find_replace_in_block` | `ref`, `find`, `replace`, `occurrence: "first" \| "all"` | | `find_replace_in_doc` | `find`, `replace`, `occurrence: "first" \| "all"`, optional `fromRef`, `toRef`, `block_filter` | -Read `/snapshot` to get block `ref` IDs and `mutationBase.token`. `ref` values are opaque request tokens tied to the snapshot/baseToken; re-read `/snapshot` before follow-up block edits if writes have landed. `operations` commits atomically — either every op lands or none do — so one `/edit/v2` call can batch dozens of block edits safely and efficiently (see the bulk-sweep guidance in `references/hitl-review.md` Phase 2.4). Successful full responses include the next `mutationBase.token` and fresh `snapshot.blocks[].ref` values for chaining. +Read `/snapshot` to get block `ref` IDs and `mutationBase.token`. `ref` values are opaque request tokens tied to the snapshot/baseToken; re-read `/snapshot` before follow-up block edits if writes have landed. `operations` commits atomically — either every op lands or none do — so one `/edit/v2` call can batch dozens of block edits safely and efficiently. Successful full responses include the next `mutationBase.token` and fresh `snapshot.blocks[].ref` values for chaining. For literal doc-wide sweeps, prefer `find_replace_in_doc` over many block replacements or a whole-doc rewrite. Validate large batches with `?dryRun=1` or `?validate=1`; use `?return=minimal` when you only need `ok`, `revision`, `appliedCount`, and the next `mutationBase`. @@ -320,11 +320,18 @@ curl -X POST "https://www.proofeditor.ai/api/agent/abc123/edit/v2?return=minimal ## Workflow: Create and Share a New Document +**Publishing a local file (the primary case):** read the file and JSON-encode its full contents into the `markdown` field with `jq --rawfile` so newlines, quotes, and backticks are escaped correctly. Never hand-write the body or leave the inline placeholder — that publishes a placeholder doc instead of the source artifact (the plan, requirements, or ideation file the caller passed). + ```bash -# 1. Create -RESPONSE=$(curl -s -X POST https://www.proofeditor.ai/share/markdown \ - -H "Content-Type: application/json" \ - -d '{"title":"My Doc","markdown":"# Title\n\nContent here."}') +SRC="docs/plans/2026-05-04-001-feat-foo-plan.md" # source file from the caller +TITLE="Plan: Foo" # caller-provided title + +# 1. Create — from a local source file: +RESPONSE=$(jq -n --arg title "$TITLE" --rawfile md "$SRC" '{title:$title, markdown:$md}' \ + | curl -s -X POST https://www.proofeditor.ai/share/markdown \ + -H "Content-Type: application/json" -d @-) +# (Ad-hoc inline content instead of a file: +# -d '{"title":"My Doc","markdown":"# Title\n\nContent here."}') # 2. Extract URL and token URL=$(echo "$RESPONSE" | jq -r '.tokenUrl') @@ -367,10 +374,10 @@ curl -X POST "https://www.proofeditor.ai/api/agent/$SLUG/edit/v2?return=minimal" ## Workflow: Pull a Proof Doc to Local -Sync the current Proof doc state to a local markdown file. Used by: +Sync the current Proof doc state to a local markdown file. Used for: -- HITL review end-sync (`references/hitl-review.md` Phase 5) when the doc originated from a local file - Ad-hoc snapshots of a Proof doc to disk (before closing the tab, archiving, handing off) +- Pulling a shared Proof doc that the user (or others) edited back down to a local working copy - Refreshing a local working copy against the live Proof version ```bash @@ -392,7 +399,7 @@ rm "$STATE_TMP" `jq -jr` (`-j` no trailing newline, `-r` raw string) streams the markdown bytes straight to the temp file without going through a shell variable, so trailing newlines survive intact. `mv` within the same filesystem is atomic — a crashed write leaves the original untouched rather than a half-written file. -**Confirm before writing when the pull isn't directly asked for.** If a workflow ends up pulling as a side-effect of a different action (e.g., HITL review completion), surface the impending write with a short confirm like "Sync reviewed doc to ``?" A silent overwrite is surprising — the user may have forgotten the local file exists in that session, or expected Proof to stay canonical until they explicitly asked to pull. +**Confirm before writing when the pull isn't directly asked for.** If a workflow ends up pulling as a side-effect of a different action, surface the impending write with a short confirm like "Sync Proof doc to ``?" A silent overwrite is surprising — the user may have forgotten the local file exists in that session, or expected Proof to stay canonical until they explicitly asked to pull. ## Safety diff --git a/dist/skills/ce-proof/references/hitl-review.md b/dist/skills/ce-proof/references/hitl-review.md deleted file mode 100644 index f1e4c56..0000000 --- a/dist/skills/ce-proof/references/hitl-review.md +++ /dev/null @@ -1,393 +0,0 @@ -# HITL Review Mode - -Human-in-the-loop iteration loop for a markdown document shared via Proof. Invoked either by an upstream skill (`ce-brainstorm`, `ce-ideate`, `ce-plan`) handing off a draft it produced, or directly by the user asking to iterate on an existing markdown file they already have on disk ("share this to proof and iterate", "HITL this doc with me"). Mechanics are identical in both cases: upload the local doc, let the user annotate in Proof's web UI, ingest feedback as in-thread replies and agreed edits, and sync the final doc back to disk. - -This mode assumes a local markdown file exists. There is no "from scratch" entry — if the user wants a fresh doc, create one with the normal proof create workflow first, then invoke HITL. - -Load this file when HITL review mode is requested — whether by an upstream caller or directly by the user. - ---- - -## Invocation Contract - -Inputs: - -- **Source file path** (required): absolute or repo-relative path to the local markdown file. When an upstream caller invokes this mode, it passes the path explicitly. When the user invokes directly ("share that doc to proof and let's iterate"), derive the path from conversation context — the file the user just referenced, created, or edited. If ambiguous, ask the user which file. -- **Doc title** (required): display title for the Proof doc. Upstream callers pass this explicitly; on direct-user invocation, default to the file's H1 heading, falling back to the filename (minus extension) if no H1 exists. -- **Recommended next step** (optional, caller-specific): short string the caller wants echoed in the final terminal output (e.g., "Recommended next: `/ce-plan`"). Not used on direct-user invocation — the terminal report simply summarizes the iteration and asks what's next. - -Agent identity is fixed, not a parameter: every API call uses agent ID `ai:compound-engineering` and display name `Compound Engineering`. Callers do not override this. - -Return shape (used by upstream callers to resume their handoff; also shown to the user in the terminal when invoked directly): - -- `status`: `proceeded` | `done_for_now` | `aborted` -- `localPath`: the source file path (same as input) -- `localSynced`: `true` if Phase 5 wrote the reviewed doc back to `localPath`; `false` if the user declined the sync and local is stale. Only present on `proceeded`. -- `docUrl`: the tokenUrl for the Proof doc -- `openThreadCount`: number of unresolved threads still in the doc -- `revision`: final doc revision after end-sync (only on `proceeded`) - ---- - -## Phase 1: Upload and Wait - -1. Read the local markdown file into memory. Remember this content as `uploadedMarkdown` — Phase 5 compares against it to detect whether anything changed during the session. -2. `POST https://www.proofeditor.ai/share/markdown` with `{title, markdown}` → capture `slug`, `accessToken`, `tokenUrl` -3. `POST /api/agent/{slug}/presence` with `X-Agent-Id: ai:compound-engineering`, `x-share-token: `, body `{"name":"Compound Engineering","status":"reading","summary":"Uploaded doc for review"}` -4. Display prominently in the terminal: - - ``` - Doc ready for review: - ``` - -5. Ask the user with the platform's blocking question tool: `AskUserQuestion` in Claude Code (call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded), `request_user_input` in Codex, `ask_user` in Gemini, `ask_user` in Pi (requires the `pi-ask-user` extension). Fall back to presenting options in chat only when no blocking tool exists in the harness or the call errors (e.g., Codex edit modes) — not because a schema load is required. Never silently skip the question. - - **Question:** "Highlight text in Proof to leave a comment. The agent will read each one, reply in-thread or apply the fix, then sync changes back to your local file. What's next?" - - **Options:** - - **I'm done with feedback — read it and apply** - - **I have no feedback — proceed** - - If the user is still reviewing, they leave the prompt open — the blocking question waits naturally. A third "still working" option would be a no-op wrapper for that. - - On **I have no feedback — proceed**: skip to Phase 5 (end-sync); return to caller with `status: proceeded`. - - On **I'm done with feedback**: continue to Phase 2. - ---- - -## Phase 2: Ingest Pass - -A single pass over the current doc state. Deterministic, idempotent, derivable from marks — no session cache, no sidecar state. - -At the start of the pass, update presence to `status: "acting"` with a short summary like `"Reading your feedback"` so anyone watching the Proof tab sees the agent is live on their comments. Update to `status: "waiting"` before the Phase 3 terminal report so the tab signals "ball is in your court" while the terminal asks for the next signal. Same `POST /presence` call as Phase 1 — just different `status`/`summary`. - -### 2.1 Read fresh state - -``` -GET /api/agent/{slug}/state?kinds=comment -Headers: x-share-token: -``` - -Capture: -- `markdown` (current body — includes any user direct edits and accepted suggestions) -- `revision` -- `marks` (object keyed by markId, filtered to comment marks) -- `mutationBase.token` — the baseToken required for this round's mutations - -### 2.2 Identify marks that need attention - -Filter `marks` to items where **all** of the following hold: - -- `kind` is `comment` (the `?kinds=comment` read should already guarantee this, but keep the local guard) -- `by` starts with `human:` (authored by a human, not the agent) -- `resolved` is `false` -- Either `thread` has no entry authored by any `ai:*` identity, **OR** the latest entry in `thread` is authored by `human:*` with an `at` timestamp newer than the latest `ai:*` entry (user responded to a prior agent reply) - -Skip everything else. Agent-authored marks, resolved threads, non-comment marks, and threads already replied to with no new human response are done. Do not build needs-reply filters from `by` alone — Proof's full `marks` bag can include provenance/authored marks that share a `human:` prefix but are not review comments. - -### 2.3 Read each mark and decide how to respond - -The point of HITL is to give the user a natural way to steer the doc without dragging every decision into the terminal. Most feedback can be auto-applied. Only escalate when the agent genuinely can't make a confident call alone. - -Real feedback blends types — "this is wrong, rename to Y" is both objection and directive; "why X? I'd prefer Z" is both question and suggestion. Don't force a clean classification. Read the comment text, the anchored `quote`, and any prior thread replies, and decide: - -**Can the agent apply a fix directly with confidence?** Imperatives ("rename X to Y", "remove this", "add a section about Z") usually qualify. Apply the edit, reply with a one-line summary of what changed, resolve. - -**Is this a question with a clear answer?** Answer in-thread. Resolve if the answer stands on its own. If answering surfaces a new decision the user should weigh in on, leave open and surface it in the terminal report. - -**Is this a disagreement?** ("this is wrong", "contradicts §2", "this won't work"). Evaluate the claim against current content. If the agent agrees, fix and reply "Agreed — updated to X". If the agent disagrees, reply with the reasoning and leave open. Don't silently apply an objection without evaluating it — the whole point is that the user flagged it *because* they think the plan is wrong. - -**Is the intent genuinely unclear?** First try: attempt the most reasonable interpretation, apply it, and reply "I read this as X — let me know if I should revert." That's cheaper than a round-trip when stakes are low. Ask for clarification only when the interpretations lead to meaningfully different outcomes. When asking, use the platform's blocking question tool for a quick multiple-choice when the options are discrete, or leave it as an open thread comment when free-form response is more natural. Either way the thread stays open so the next pass picks up the user's reply. - -**Invariant:** every attention-needing mark ends the pass with an agent reply in its thread. Unreplied = "still to do" — the next pass re-classifies it. This is what makes the loop idempotent without a sidecar: mark state *is* the state. Even when the agent disagrees or can't decide, reply (with reasoning or a question) rather than silently skip. - -**Batch thread replies and resolves.** Build all thread responses during the pass, then write them with a single `/ops` batch whenever possible. `comment.reply` accepts `resolve: true`, so a handled thread should usually be one operation, not `reply` plus `resolve`. The batched `/ops` shape uses one `baseToken` and one mutation: - -```json -{"by":"ai:compound-engineering","baseToken":"","operations":[ - {"type":"comment.reply","markId":"","text":"Updated the terminology.","resolve":true}, - {"type":"comment.reply","markId":"","text":"I disagree because X; leaving this open."} -]} -``` - -Only include existing-thread comment mutations in a batch: `comment.reply`, `comment.resolve`, and `comment.unresolve`. Leave `resolve` off (or set it false) when the thread remains open for a user decision. This replaces the older pattern of N separate reply/resolve calls or sub-agent parallelism; batching is faster, easier to reason about, and creates one authoritative marks mutation. - -### 2.4 Apply edits - -The user is collaborating in the doc, not waiting on approval. Every mutation works with live clients — only whole-doc `rewrite.apply` is gated. Pick the tool that matches intent: - -**Default: `/edit/v2` for agent-applied content changes.** The comment thread is the review/audit trail: the user asked for the change, the agent applies it, then replies in-thread with what changed. Use block edits for direct fixes, insertions, deletions, and coordinated rewrites so the doc does not accumulate extra suggestion marks for work the user already requested. - -**Use `suggestion.add` with `status: "accepted"`** when a visible track-change mark is itself valuable — for example, the user asked to preserve a reject-to-revert affordance for a specific edit, or the change is judgment-sensitive enough that the visible suggestion trail is clearer than only replying in the comment thread. One call creates the suggestion mark *and* commits the change. - -```json -{"type":"suggestion.add","kind":"replace","quote":"","content":"","by":"ai:compound-engineering","status":"accepted","baseToken":""} -``` - -Use `kind: "insert" | "delete" | "replace"` as appropriate; all three support `status: "accepted"`. - -**Use `/edit/v2` especially when:** - -- **Atomicity is required** — multiple coordinated edits must commit together or not at all (e.g., insert new section + update a reference in another block + delete the obsolete paragraph). `/edit/v2` takes an `operations` array that commits atomically; separate `suggestion.add` calls can partially succeed. -- **Pre-user self-correction** — the agent is fixing its own output *before* the user has looked at the doc (e.g., spotted a mistake mid-ingest-pass). A tracked mark would imply "there was an old version," which is misleading from the user's perspective. -- **Pure structural insertion with no quote anchor** — adding an entirely new block/section where no existing text serves as an anchor. `suggestion.add` requires a `quote`; `/edit/v2` has `insert_before` / `insert_after` keyed on block `ref`. -- **Structural list-item or block removal** — `suggestion.add` with `kind: "delete"` only deletes the text inside a list item; the bullet marker (`*`, `-`, or numeric `1.`) stays behind as an orphan line. Use `/edit/v2 delete_block` to remove an entire block, or `find_replace_in_block` to splice out the item plus its surrounding whitespace cleanly. - -```bash -# Get snapshot for block refs + baseToken -curl -s "https://www.proofeditor.ai/api/agent/{slug}/snapshot" -H "x-share-token: " -# Apply -curl -X POST "https://www.proofeditor.ai/api/agent/{slug}/edit/v2" \ - -H "Content-Type: application/json" -H "x-share-token: " \ - -H "X-Agent-Id: ai:compound-engineering" -H "Idempotency-Key: " \ - -d '{"by":"ai:compound-engineering","baseToken":"","operations":[...]}' -``` - -Per-op body shape (singular `block` for `replace_block`; plural `blocks:[{markdown},...]` for anything that can add content; the server returns 422 on the wrong shape): - -```json -{"op":"replace_block","ref":"b8","block":{"markdown":"new content"}} -{"op":"insert_after","ref":"b3","blocks":[{"markdown":"new block"}]} -{"op":"insert_before","ref":"b3","blocks":[{"markdown":"new block"}]} -{"op":"delete_block","ref":"b6"} -{"op":"find_replace_in_block","ref":"b4","find":"old","replace":"new","occurrence":"first"} -{"op":"find_replace_in_doc","find":"old","replace":"new","occurrence":"all"} -{"op":"replace_range","fromRef":"b2","toRef":"b5","blocks":[{"markdown":"..."}]} -``` - -Block `ref` values are opaque request tokens tied to the snapshot/baseToken. Re-fetch `/snapshot` for fresh refs before another `/edit/v2` call if any writes have landed since the last snapshot. Full successful `/edit/v2` responses include a fresh `mutationBase.token` and, unless `?return=minimal` was used, a fresh snapshot for chaining. - -**Bulk mechanical sweep — prefer `find_replace_in_doc` when the rule is literal.** For terminology renames, punctuation swaps, or other literal doc-wide replacements, use one `/edit/v2` operation: - -```json -{"op":"find_replace_in_doc","find":"old term","replace":"new term","occurrence":"all"} -``` - -Run the same payload through `/edit/v2?dryRun=1` first for large sweeps; dry-run returns `valid`, `appliedCount`, and per-op `results[]` without writing. For the real write, use `/edit/v2?return=minimal` when you only need `ok`, `revision`, `appliedCount`, and the next `mutationBase.token`. Responses with `operationResults` include per-block match counts; treat those refs as reporting/display data and re-read `/snapshot` before follow-up block-ref mutations. - -When the edit is semantic rather than literal, batch `replace_block`, `insert_*`, `delete_block`, or `replace_range` operations in one `/edit/v2` call. Use `suggestion.add` + `accepted` when edits are distinct and each deserves its own visible reject-to-revert trail. - -**Use pending `suggestion.add` (no status)** when the change is judgment-sensitive enough that the agent wants explicit user approval before commit — rare in HITL, since the point of auto-applied edits is to reduce round-trips. Most judgment-sensitive cases are better handled by leaving the thread open with a clarifying question. - -**`rewrite.apply` is not needed during a live review.** It's blocked by `LIVE_CLIENTS_PRESENT` anyway. - -**Mutation requirements (every write, including replies and resolves):** - -- Top-level field is `type` on single `/ops` writes; top-level `operations` on `/ops` comment batches; `operations[].op` on `/edit/v2`. Do not mix `/ops` `type` entries with `/edit/v2` `op` entries. -- Include `baseToken` from `/state.mutationBase.token` (or `/snapshot.mutationBase.token` for `/edit/v2`). -- Set `by: "ai:compound-engineering"` and header `X-Agent-Id: ai:compound-engineering`. -- Include an `Idempotency-Key` header. Reuse the same key only for an exact same-body resend; if you rebuild the body with a fresh `baseToken`, mint a new key. -- Successful mutation responses include the next `mutationBase.token`; reuse it for the next write instead of re-reading only to get a token. -- Reply and resolve together when done: `{"type":"comment.reply","markId":"","text":"...","resolve":true}` inside a `/ops` batch. Reopen if needed: `{"type":"comment.unresolve", ...}`. - -**Retry after any error is verify-first, not retry-first.** The Proof API can commit canonically and still return a non-2xx or a 202 with `collab.status: "pending"`; network timeouts can hit after the server has already written. Retrying without verifying is the most common cause of duplicate marks (same comment twice, same suggestion twice) that then need a manual cleanup pass. - -- On `STALE_BASE` / `BASE_TOKEN_REQUIRED` / `MISSING_BASE` / `INVALID_BASE_TOKEN`: pre-commit, token-related. Re-read `/state`, rebuild the request body with a fresh `baseToken`, and retry once with a new `Idempotency-Key`. The `mutate()` helper below auto-retries these. -- On `ANCHOR_NOT_FOUND` / `ANCHOR_AMBIGUOUS`: pre-commit, but the `quote` no longer matches uniquely. Re-read is not enough; the caller must tighten or regenerate the anchor before retrying. The helper surfaces the error instead of auto-retrying. -- On `INVALID_OPERATIONS` / `INVALID_REQUEST` / `INVALID_REF` / `INVALID_BLOCK_MARKDOWN` / `INVALID_RANGE` / `INVALID_MARKDOWN` / 422: the payload is wrong. Do not retry — fix the payload and send a new write. -- On `COLLAB_SYNC_FAILED` / `REWRITE_BARRIER_FAILED` / `PROJECTION_STALE` / `INTERNAL_ERROR` / 5xx / network error / timeout / **202 with `collab.status: "pending"`**: the write may have landed. Re-read `/state`, diff against the intended change (mark exists? suggestion applied? quote replaced?), and only retry if the server did not actually commit it. If the diff shows the write did land, treat the call as successful even though the response said otherwise. - -**When the loop breaks.** If a mutation keeps failing after a fresh read and a verified-needed retry, or two reads disagree about state, call `POST https://www.proofeditor.ai/api/bridge/report_bug` with the request ID, slug, and raw response body before falling back. Don't silently skip — that loses the audit trail the user is relying on. - ---- - -## Phase 3: Terminal Report - -Exception-based. Don't replay what the user can already see in the Proof doc — the full reasoning for each thread lives there. The terminal is for the decisions the user needs to make next. - -Every report covers three things, phrased naturally for the current state: - -- **What got handled** (e.g., how many comments resolved, any edits auto-applied) -- **What's still open** — if any escalations remain, each one gets one line of anchored quote plus one line of the agent's reply or question. Fuller context stays in the Proof thread -- **The doc URL** — always include it; the user may have closed the tab - -Keep the whole report scannable at a glance. Three common shapes fall out of this naturally: - -- A clean pass with everything handled collapses to a single line plus the doc URL -- An escalation pass lists the open threads compactly after a one-line summary of what was handled -- A pass with no new feedback just notes that and points to the doc - -Phrase them in whatever voice matches the situation rather than matching a template — "handled 4, 1 still needs you" and "all 5 addressed, doc's ready" are both fine. - ---- - -## Phase 4: Next-Signal Prompt - -Ask the user with the platform's blocking question tool: `AskUserQuestion` in Claude Code (call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded), `request_user_input` in Codex, `ask_user` in Gemini, `ask_user` in Pi (requires the `pi-ask-user` extension). Fall back to presenting options in chat only when no blocking tool exists in the harness or the call errors (e.g., Codex edit modes) — not because a schema load is required. Never silently skip the question. - -**Question:** "Proof review pass done. What's next?" - -Offer options that cover these intents — use concrete user-facing labels, not agent-internal jargon (no "end-sync", "ingest pass", etc.). Only include the options that fit the current state. Keep labels imperative and third-person (no "I'll" / "I'm" — it is ambiguous in a tool-mediated menu whether the speaker is the user or the agent) and keep the `[short label] — [description]` shape consistent across every option. A "still working, come back later" option is not offered: the blocking question already waits, so that option would be a no-op wrapper. - -- **Discuss** → `Discuss — walk through the open threads in terminal` - Talk through open threads in the terminal; the agent echoes decisions back to Proof threads. Only useful when escalations are open. -- **Proceed** → `Save — save the reviewed doc back to the local file` - Go to Phase 5 end-sync. If escalations are still open, name that in the label (e.g., `Save with 3 threads still open`) so the user is accepting the tradeoff explicitly instead of via a nested confirm. -- **Another pass** → `Re-check — look for new comments in Proof` - Re-read state and re-ingest. Worth offering even after a clean pass, since the user may have added comments while the report rendered. -- **Done for now** → `Pause — stop without saving` - Stop without syncing; return to caller with `status: done_for_now`, no end-sync. - -The sync confirmation happens in Phase 5 regardless of whether threads are open — this step only asks what the user wants next, not whether to overwrite the local file. - ---- - -## Phase 5: End-Sync - -Runs when the user selects **Proceed**. Before prompting anything, check whether the Proof content actually diverged from what was uploaded — if not, there's nothing to sync and no reason to ask. - -1. Fetch current state: `GET /api/agent/{slug}/state` with `x-share-token: `. Save the full response body to a temp file (`$STATE_TMP`) so the markdown bytes can later be streamed to disk without passing through `$(...)` (which would strip trailing newlines). Extract `state.revision` from that file into `$REVISION`. Read `state.markdown` from that file for the comparison in step 2. - -2. Compare `state.markdown` to `uploadedMarkdown` (captured in Phase 1). - - **If identical** — no content changes happened during the session. Skip the sync prompt entirely. Display: - - ``` - No changes to sync. Local file is unchanged. - Doc: - ``` - - Set presence `status: completed`, summary `"Review complete, no changes"`. Return to the caller with `status: proceeded`, `localSynced: true` (local matches Proof — no write needed, local is not stale), `revision: `, and the rest of the standard fields. - - **If different** — continue to step 3. - -3. Ask with the platform's blocking question tool: `AskUserQuestion` in Claude Code (call `ToolSearch` with `select:AskUserQuestion` first if its schema isn't loaded), `request_user_input` in Codex, `ask_user` in Gemini, `ask_user` in Pi (requires the `pi-ask-user` extension). Fall back to presenting options in chat only when no blocking tool exists in the harness or the call errors (e.g., Codex edit modes) — not because a schema load is required. Never silently skip the question. - - **Question:** "Sync the reviewed doc back to ``? Proof has your review changes; local still has the pre-review copy." - - **Options:** - - **Yes, sync now** (default, recommended) - - **Not yet, I'll pull it later** (returns to caller with `localSynced: false`) - - Why the extra prompt: the user may have started review hours ago and lost track of the local file at stake. A brief confirm makes the file write visible rather than a silent side-effect of clicking Proceed earlier. The caller signals via `localSynced` so downstream workflows can warn that local is stale. - -4. On **Yes, sync now**, write the fetched markdown to local — see `Workflow: Pull a Proof Doc to Local` in `SKILL.md`: - - ```bash - # $STATE_TMP is the temp file holding the /state response from step 1. - TMP="${SOURCE}.proof-sync.$$" - jq -jr '.markdown' "$STATE_TMP" > "$TMP" && mv "$TMP" "$SOURCE" - rm "$STATE_TMP" - ``` - - Stream `.markdown` bytes directly from the saved state file with `jq -jr` — do not capture the markdown into a shell variable, since `$(...)` would strip trailing newlines and corrupt the write. `$REVISION` (extracted separately in step 1) is safe to keep as a variable; it's an opaque scalar. - - On **Not yet**, skip the write (still clean up `$STATE_TMP`). - -5. Set presence `status: completed`, summary `"Review synced to "` (or `"Review complete, local not updated"` if sync was declined) so the Proof UI shows the loop has finished. - -6. Display one of: - - Synced: - ``` - Doc synced to (revision ). - Doc: - ``` - - Declined: - ``` - Review complete. Local file kept as-is — pull from Proof when ready. - Doc: - ``` - -7. Return to the caller with: - ``` - status: proceeded - localPath: - localSynced: true | false - docUrl: - openThreadCount: - revision: - ``` - -Do **not** delete the Proof doc. It remains the durable review record; the caller's workflow may want to link back to it. - ---- - -## Recipes - -### BaseToken-aware mutation - -Seed `baseToken` from the most recent `/state` or `/snapshot` read, then update it from each successful mutation response's `mutationBase.token`. Only re-read on `STALE_BASE` / `BASE_TOKEN_REQUIRED` or when you need fresh document/comment/snapshot content. For an ingest pass this means one comment-filtered `/state` read, one `/edit/v2` batch if content changes are needed, and one `/ops` comment batch for replies/resolutions. - -Two retry classes, and they behave differently. The helper below only covers the safe class; the ambiguous class needs a caller-supplied verifier because "did this write land?" depends on what the payload was (look for a markId, a quote replacement, a thread reply, etc.). - -```bash -SLUG= -TOKEN= -AGENT_ID=ai:compound-engineering -BASE= - -mutate() { - local PAYLOAD="$1" # jq template without baseToken - local IDEM_KEY BODY RESP CODE NEXT_BASE - # Fresh key for this request body. If the body changes, including because - # baseToken changes after STALE_BASE, the retry below mints a new key. - IDEM_KEY=$(uuidgen) - BODY=$(jq -n --arg base "$BASE" --argjson payload "$PAYLOAD" '$payload + {baseToken: $base}') - RESP=$(curl -s -X POST "https://www.proofeditor.ai/api/agent/$SLUG/ops" \ - -H "Content-Type: application/json" \ - -H "x-share-token: $TOKEN" \ - -H "X-Agent-Id: $AGENT_ID" \ - -H "Idempotency-Key: $IDEM_KEY" \ - -d "$BODY") - CODE=$(printf '%s' "$RESP" | jq -r '.code // .error // empty') - # Pre-commit token-related errors — safe to auto-retry with the same - # payload and a fresh baseToken. Anchor errors (ANCHOR_NOT_FOUND, - # ANCHOR_AMBIGUOUS) are also pre-commit but require a tighter quote, - # so they are surfaced instead of auto-retried. - if [ "$CODE" = "STALE_BASE" ] \ - || [ "$CODE" = "BASE_TOKEN_REQUIRED" ] \ - || [ "$CODE" = "MISSING_BASE" ] \ - || [ "$CODE" = "INVALID_BASE_TOKEN" ]; then - BASE=$(curl -s "https://www.proofeditor.ai/api/agent/$SLUG/state" \ - -H "x-share-token: $TOKEN" | jq -r '.mutationBase.token') - BODY=$(jq -n --arg base "$BASE" --argjson payload "$PAYLOAD" '$payload + {baseToken: $base}') - IDEM_KEY=$(uuidgen) - RESP=$(curl -s -X POST "https://www.proofeditor.ai/api/agent/$SLUG/ops" \ - -H "Content-Type: application/json" \ - -H "x-share-token: $TOKEN" \ - -H "X-Agent-Id: $AGENT_ID" \ - -H "Idempotency-Key: $IDEM_KEY" \ - -d "$BODY") - fi - NEXT_BASE=$(printf '%s' "$RESP" | jq -r '.mutationBase.token // empty') - if [ -n "$NEXT_BASE" ]; then - BASE="$NEXT_BASE" - fi - printf '%s' "$RESP" -} -``` - -The `Idempotency-Key` is minted for the exact request body being sent. If a retry rebuilds the body with a fresh `baseToken`, that is a different payload hash, so it needs a new key; reusing the previous key would trigger `IDEMPOTENCY_KEY_REUSED`. Reuse the same key only for a transport-level resend of the exact same body. Minting outside the function would make unrelated writes share one key, and the server would treat later payloads as invalid key reuse. - -**Ambiguous failures (anything outside the pre-commit set above — `COLLAB_SYNC_FAILED`, `INTERNAL_ERROR`, 5xx, network timeout, 202 with `collab.status: "pending"`):** do not retry from this helper. Re-read `/state` in the caller, diff the marks/content against the intended change, and only re-issue the write if the diff proves nothing landed. Pattern: - -```bash -# After an ambiguous failure on comment.add with quote "X" and text "Y": -STATE=$(curl -s "https://www.proofeditor.ai/api/agent/$SLUG/state" \ - -H "x-share-token: $TOKEN") -LANDED=$(printf '%s' "$STATE" | jq --arg q "X" --arg t "Y" \ - '[.marks[]? | select(.by == "ai:compound-engineering" and .quote == $q and (.thread[0].text // .text) == $t)] | length') -if [ "$LANDED" -gt 0 ]; then - echo "Already applied — skipping retry." -else - # Safe to retry with a fresh BASE. - ... -fi -``` - -Match on a payload-identifying field (quote + text for `comment.add`; quote + content for `suggestion.add`; markId + text for `comment.reply`; block ordinal + markdown for `/edit/v2`). When no such invariant is available, prefer leaving the write undone and surfacing it in the terminal report over risking a duplicate. - -### jq gotcha when inspecting responses - -When extracting fields from API responses with jq's `//` alternative operator, parenthesize inside object constructors — jq parses `{markId: .markId // .result.markId}` as a syntax error. Use `{markId: (.markId // .result.markId)}`, or pull the value outside the object: `jq -r '.markId // .result.markId'`. - -### Identity - -All ops must include: -- `by: "ai:compound-engineering"` in the request body -- `X-Agent-Id: ai:compound-engineering` in headers (required for presence; recommended for ops for consistent attribution) - -Display name `Compound Engineering` is bound via `POST /presence` with `{"name":"Compound Engineering", ...}`. Set this once after upload; it carries across subsequent ops. diff --git a/dist/skills/lfg/SKILL.md b/dist/skills/lfg/SKILL.md index bf5ff49..5c7ad99 100644 --- a/dist/skills/lfg/SKILL.md +++ b/dist/skills/lfg/SKILL.md @@ -10,25 +10,33 @@ When invoking any skill referenced below, resolve its name against the available 1. Invoke the `ce-plan` skill with `$ARGUMENTS`. - GATE: STOP. If ce-plan reported the task is non-software and cannot be processed in pipeline mode, stop the pipeline and inform the user that LFG requires software tasks. Otherwise, verify that the `ce-plan` workflow produced a plan file in `docs/plans/`. If no plan file was created, invoke `ce-plan` again with `$ARGUMENTS`. Do NOT proceed to step 2 until a written plan exists. **Record the plan file path** — it will be passed to ce-code-review in step 3. + GATE: STOP. If ce-plan reported the task is non-software and cannot be processed in pipeline mode, stop the pipeline and inform the user that LFG requires software tasks. Otherwise, verify that the `ce-plan` workflow produced a plan file in `docs/plans/`. If no plan file was created, invoke `ce-plan` again with `$ARGUMENTS`. Do NOT proceed to step 2 until a written plan exists. **Record the plan file path** — it will be passed to ce-code-review in step 4. 2. Invoke the `ce-work` skill. GATE: STOP. Verify that implementation work was performed - files were created or modified beyond the plan. Do NOT proceed to step 3 if no code changes were made. -3. Invoke the `ce-code-review` skill with `mode:agent plan:`. +3. Invoke the `ce-simplify-code` skill on the branch diff. + + This runs before review so the code-review in step 4 covers the simplified code. **Skip** this step when the change is docs-only (only markdown/docs paths changed) or trivial (roughly under 10 changed lines). Otherwise let `ce-simplify-code` resolve the branch-diff scope itself; it preserves behavior and runs the test suite. + + Do not commit in this step. `ce-simplify-code` leaves its changes in the working tree; step 4's review scopes the working tree (uncommitted changes included), and step 8's `ce-commit-push-pr` commits whatever remains. Committing here would sweep any still-uncommitted `ce-work` edits into a misleading `refactor` commit and could stall on a tree that never goes clean. + +4. Invoke the `ce-code-review` skill with `mode:agent plan:`. Pass the plan file path from step 1 so ce-code-review can verify requirements completeness. Read the **Actionable Findings** summary the skill emits. -4. **Apply and persist review fixes** (REQUIRED after step 3, before residual handoff) + `mode:agent` is report-only **by design** — it surfaces findings but never edits the tree; LFG applies the eligible ones in step 5. When narrating progress to the user, frame this as "review found X → applied X in step 5," not as "code review did not auto-fix." A report-only review followed by an LFG-applied fix is the intended contract, not a gap. + +5. **Apply and persist review fixes** (REQUIRED after step 4, before residual handoff) - Load `references/review-followup.md` and execute step 4 there (mechanical apply + commit/push when changes exist). Do not proceed to step 5, run browser tests, or output DONE while eligible review fixes remain only in the working tree uncommitted. + Load `references/review-followup.md` and execute its apply step (mechanical apply + commit/push when changes exist). Do not proceed to the residual handoff, run browser tests, or output DONE while eligible review fixes remain only in the working tree uncommitted. -5. **Autonomous residual handoff** (only when step 3 reported one or more actionable `downstream-resolver` findings not applied in step 4; skip when it reported `Actionable findings: none.`) +6. **Autonomous residual handoff** (only when step 4 reported one or more actionable `downstream-resolver` findings not applied in step 5; skip when it reported `Actionable findings: none.`) Do not prompt the user. This step embraces the autopilot contract: residuals must become durable before DONE, but the agent never stops to ask. - 1. Load `references/tracker-defer.md` in **non-interactive mode**. Pass the residual actionable findings from step 3/4 (or the run artifact when the summary was truncated). + 1. Load `references/tracker-defer.md` in **non-interactive mode**. Pass the residual actionable findings from step 4/5 (or the run artifact when the summary was truncated). 2. Collect the structured return: `{ filed: [...], failed: [...], no_sink: [...] }`. 3. Compose a `## Residual Review Findings` markdown section from the structured return: - For each item in `filed`: a bullet with severity, file:line, title, and a link to the tracker ticket URL. @@ -50,15 +58,15 @@ When invoking any skill referenced below, resolve its name against the available Never block DONE on tracker filing failures once residuals have been durably recorded. A `no_sink` outcome is success only when the findings are present in the PR body or in the pushed fallback file. -6. Invoke the `ce-test-browser` skill with `mode:pipeline`. +7. Invoke the `ce-test-browser` skill with `mode:pipeline`. -7. Invoke the `ce-commit-push-pr` skill. +8. Invoke the `ce-commit-push-pr` skill. - This commits any remaining changes, pushes the branch, and opens a pull request. If step 5 already opened a PR (check with `gh pr view --json number,url,state 2>/dev/null`), skip PR creation but still commit and push any uncommitted changes. + This commits any remaining changes, pushes the branch, and opens a pull request. If step 6 already opened a PR (check with `gh pr view --json number,url,state 2>/dev/null`), skip PR creation but still commit and push any uncommitted changes. -8. **CI watch and autofix loop** (only when an open PR exists for the current branch) +9. **CI watch and autofix loop** (only when an open PR exists for the current branch) - Detect the PR; if none exists or `gh` is unavailable, skip this step entirely and proceed to step 9. + Detect the PR; if none exists or `gh` is unavailable, skip this step entirely and proceed to step 10. ```bash gh pr view --json number,url,state @@ -72,7 +80,7 @@ When invoking any skill referenced below, resolve its name against the available gh pr checks --watch ``` - If the command exits 0, all checks passed. Break out of the loop and proceed to step 9. + If the command exits 0, all checks passed. Break out of the loop and proceed to step 10. If it exits non-zero, one or more checks failed. Continue to (2). @@ -105,8 +113,8 @@ When invoking any skill referenced below, resolve its name against the available gh pr edit PR_NUMBER --body-file BODY_FILE ``` - - Do NOT continue looping. The autopilot contract is "make residuals durable, then exit." Proceed to step 9. + - Do NOT continue looping. The autopilot contract is "make residuals durable, then exit." Proceed to step 10. -9. Output `DONE` when complete +10. Output `DONE` when complete Start with step 1 now. Remember: plan FIRST, then work. Never skip the plan. diff --git a/dist/skills/lfg/references/review-followup.md b/dist/skills/lfg/references/review-followup.md index e6d4a5a..54c0efb 100644 --- a/dist/skills/lfg/references/review-followup.md +++ b/dist/skills/lfg/references/review-followup.md @@ -1,8 +1,8 @@ -# Review followup (LFG step 3–4) +# Review followup (LFG step 4–5) `ce-code-review` is review-only. LFG applies eligible fixes itself, then commits. -## Step 3 — invoke review +## Step 4 — invoke review ``` ce-code-review mode:agent plan: @@ -12,7 +12,7 @@ Read the **Actionable Findings** summary and artifact path. Do not pass `mode:au Capture parsed JSON (`status`, `actionable_findings`, `findings`, `artifact_path`, `run_id`) or the markdown Actionable Findings section. If `status` is `failed`, stop and surface `reason`. -## Step 4 — apply and persist review fixes +## Step 5 — apply and persist review fixes ### What to apply @@ -37,8 +37,8 @@ Do not treat `autofix_class` as permission to auto-apply. 1. Filter `actionable_findings` (or markdown Actionable Findings) with the bar above. 2. Apply eligible fixes in the working tree in severity order (`#` stable from the review). 3. Run targeted tests when `requires_verification: true` on any applied finding. -4. If `git status --short` shows changes, stage only review-driven files, commit `fix(review): apply review findings`, and push before step 5. To push: if an upstream exists, run `git push`. If no upstream exists (common on a fresh feature branch, since step 7's `ce-commit-push-pr` has not run yet), resolve a writable remote dynamically: prefer `origin` when present, otherwise use `git remote` and choose the first configured remote. Then run `git push --set-upstream HEAD`. If no eligible fixes were applied, note explicitly and skip commit. +4. If `git status --short` shows changes, stage only review-driven files, commit `fix(review): apply review findings`, and push before step 6. To push: if an upstream exists, run `git push`. If no upstream exists (common on a fresh feature branch, since step 8's `ce-commit-push-pr` has not run yet), resolve a writable remote dynamically: prefer `origin` when present, otherwise use `git remote` and choose the first configured remote. Then run `git push --set-upstream HEAD`. If no eligible fixes were applied, note explicitly and skip commit. -## Step 5 — residual handoff +## Step 6 — residual handoff -Residuals are actionable findings **not** applied in step 4 — not leftovers from in-skill autofix. Use the Actionable Findings summary / artifact from step 3. +Residuals are actionable findings **not** applied in step 5 — not leftovers from in-skill autofix. Use the Actionable Findings summary / artifact from step 4.