gentle-pi 3.1.1 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/orchestrator-delegation.md +18 -11
- package/assets/orchestrator.md +2 -2
- package/docs/gentle-shell.md +15 -5
- package/docs/readme-reference.md +43 -18
- package/docs/review-integration.md +15 -6
- package/extensions/gentle-agents.ts +22 -1
- package/extensions/gentle-ai.ts +103 -143
- package/extensions/gentle-shell.ts +29 -7
- package/lib/background-subagents-policy.ts +148 -0
- package/lib/model-routing-authority.ts +1 -1
- package/lib/native-review-cli.ts +18 -0
- package/lib/opaque-pi-reviewer-adapter.ts +130 -10
- package/lib/review-candidate-view.ts +27 -6
- package/lib/review-host-relay.ts +95 -2
- package/lib/shell-bar.ts +63 -9
- package/lib/shell-usage.ts +226 -10
- package/package.json +2 -1
- package/runtime/native-review-cli.mjs +18 -0
- package/scripts/gentle-ai-installer.mjs +10 -10
- package/scripts/mirror-odd-routing.mjs +242 -0
- package/scripts/verify-package-files.mjs +3 -3
- package/skills/chained-pr/SKILL.md +2 -1
- package/skills/work-unit-commits/SKILL.md +9 -0
- package/tests/background-subagents-default-mode.test.ts +105 -0
- package/tests/gentle-agents.test.ts +14 -1
- package/tests/gentle-ai-binary.test.ts +1 -1
- package/tests/gentle-ai-installer.test.ts +47 -47
- package/tests/gentle-shell.test.ts +109 -3
- package/tests/native-review-capability-contract.test.ts +27 -1
- package/tests/odd-routing-canonical-ratchet.test.ts +293 -0
- package/tests/odd-routing-contract.test.ts +101 -2
- package/tests/opaque-pi-reviewer-adapter.test.ts +153 -9
- package/tests/package-manifest.test.ts +6 -6
- package/tests/review-base-ref-hint.test.ts +39 -0
- package/tests/review-candidate-view.test.ts +55 -0
- package/tests/review-controller-native-routing.test.ts +60 -1
- package/tests/review-host-relay.test.ts +83 -14
- package/tests/review-relay-transport-agent.test.ts +86 -1
- package/tests/shell-bar.test.ts +153 -3
- package/tests/shell-usage-view.test.ts +3 -2
- package/tests/shell-usage.test.ts +254 -6
|
@@ -79,7 +79,7 @@ Investigation, explanation, review, comparison, and proposal-only requests remai
|
|
|
79
79
|
|
|
80
80
|
Small, understood work creates no durable task artifacts. Substantial means coordinated steps or progress worth recovering, not a line threshold. For substantial authorized implementation, automatically create the feature document after exploration, without a task or storage permission prompt. Follow `orchestrator-memory.md` for the file and full Engram recovery copy, automatic updates, truthful checkoffs, and resume. Keep the parent responsible for reconciliation; bounded workers receive the document locator, relevant intent, task IDs, authorized scope and checks, not authority over unrelated tasks; they read the document before edits.
|
|
81
81
|
|
|
82
|
-
Use about 400 authored changed lines per ODD task only as a planning heuristic, counting additions plus deletions. Keep the smallest coherent behavior with its tests and docs. This is not a task acceptance criterion, hard cap, counter-trigger, automatic stop, forced split, or RDD trigger. If the correct clear solution naturally exceeds it, briefly explain why and continue without size-only rework loops. Never delete spaces, blank lines, or comments for cosmetic line savings; never omit tests, minify, add gratuitous abstractions, or split artificially to fit the heuristic. Forward this same advisory-only instruction when delegating tasks to subagents. Existing PR size gates remain unchanged; follow repository policy.
|
|
82
|
+
Use about 400 authored changed lines per ODD task only as a planning heuristic, counting additions plus deletions. Keep the smallest coherent behavior with its tests and docs. This is not a task acceptance criterion, hard cap, counter-trigger, automatic stop, forced split, or RDD trigger. If the correct clear solution naturally exceeds it, briefly explain why and continue without size-only rework loops. Never delete spaces, blank lines, or comments for cosmetic line savings; never omit tests, minify, add gratuitous abstractions, or split artificially to fit the heuristic. Forward this same advisory-only instruction when delegating tasks to subagents. The delivery budget below reads the accumulated branch, not this per-task heuristic. Existing PR size gates remain unchanged; follow repository policy.
|
|
83
83
|
|
|
84
84
|
#### Research depth without a new phase
|
|
85
85
|
|
|
@@ -95,9 +95,11 @@ Use at most one scoped independent read-only assumption challenge for a high-con
|
|
|
95
95
|
|
|
96
96
|
Resolve effective TDD on/off from existing project/session configuration or explicit user choice; retain its source and exact test runner. Record resolved mode, source, and runner in the feature document when present. Tests or frameworks being present does not enable TDD. Forward mode, source, and runner on every implementation delegation; refresh on resume. When enabled, require observed RED before implementation, GREEN, then REFACTOR; never invent evidence. When disabled, run ordinary functional checks, not no checks. If mode is unknown/conflicting or the runner is missing, disclose and resolve only the ambiguity affecting the next action; never invent precedence or a command, and never invoke sdd-init to determine ODD TDD.
|
|
97
97
|
|
|
98
|
-
Run applicable functional checks per task
|
|
98
|
+
Run applicable functional checks per task; a TODO checkbox never triggers a review cycle. The native review candidate is a work-unit commit or a PR slice, never a TODO checkbox and never the accumulated feature branch, and native review runs at that work-unit commit or PR slice boundary, not every task update. Checklists grant no approval or receipt and never skip an existing delivery gate.
|
|
99
99
|
|
|
100
|
-
When RDD is enabled, first use native candidate risk assessment through `gentle_review` with `{"operation":"assess"}`. Passive/low
|
|
100
|
+
When RDD is enabled, first use native candidate risk assessment through `gentle_review` with `{"operation":"assess"}`; after each work-unit commit, assess it with that same call and `{"baseRef":"<last reviewed boundary>","committedOnly":true}`. Passive/low: silent structural checks, no reviewer or consent ceremony, and the boundary advances. High, or an unavailable or failed assessment: the commit itself is the candidate; start native review on it right away at that base with `gentle_review` `{"operation":"start"}` and the same `baseRef`/`committedOnly: true` input. Medium: defer to the PR slice, the commits accumulated since the last reviewed boundary, bounded by the delivery budget of about 400 authored changed lines, and review at slice close; native review runs only on grant, and a decline continues under ordinary policy. The first boundary is the branch point, and every reviewed boundary becomes the next base. Record per task the assessed tier and outcome: granted, declined, passive, deferred to slice, or unavailable. Do not substitute model judgment, task size, or defect severity for prospective candidate risk; never infer low risk from a failed assessment. Follow the mirrored provider contract and native continuations; this paragraph introduces no lifecycle route. When RDD is disabled, do not start or prompt for RDD; ordinary checks remain. A checklist or assumption challenge never enables RDD, replaces its refuter, or answers consent.
|
|
101
|
+
|
|
102
|
+
Delivery follows work units. At feature-document creation, forecast authored changed lines (additions plus deletions, generated files excluded) from the task list, and keep a running count from work-unit commits. Choose one delivery strategy per feature: `ask-on-risk` (default), `auto-chain`, `single-pr`, or `exception-ok`. When the forecast or the running count exceeds about 400 authored changed lines, apply the chosen strategy before the next commit: `ask-on-risk` asks once for the chain strategy, `stacked-to-main` or `feature-branch-chain`; `auto-chain` asks only for a missing chain strategy and slices automatically. Cache both choices, and record slice boundaries, which commits each pull request holds, in the feature document. Resolve the `work-unit-commits` and `chained-pr` skills by registry name, never hardcode their paths.
|
|
101
103
|
|
|
102
104
|
### Delegation Rules
|
|
103
105
|
|
|
@@ -121,14 +123,19 @@ Keep one writer and a short synthesized handoff. Delegation is mandatory at the
|
|
|
121
123
|
|
|
122
124
|
#### Mandatory Delegation Triggers
|
|
123
125
|
|
|
124
|
-
These are parent-orchestrator routing boundaries.
|
|
126
|
+
These are parent-orchestrator routing boundaries; do not pass these rules to child agents as permission to orchestrate. These triggers are mandatory, not advisory. When one fires, stop and delegate through the runtime's subagent mechanism before continuing; executing past a fired trigger inline is a routing defect even if the work succeeds. Delegation keeps the parent context thin enough to orchestrate; it does not slow the work down.
|
|
127
|
+
|
|
128
|
+
1. **Mapping trigger (4-file rule):** when understanding the work requires 4 or more files, delegate one narrow exploration or mapping task before deciding or writing anything.
|
|
129
|
+
2. **Writer trigger (Multi-file write rule):** when implementation touches 2 or more non-trivial files, delegate one bounded writer instead of editing them inline.
|
|
130
|
+
3. **Incident rule:** after wrong `cwd`, accidental repository/worktree mutation, failed merge recovery, confusing test command, or environment workaround, stop and diagnose the incident separately before resuming.
|
|
131
|
+
4. **Long-session backstop (Long-session rule):** after about 20 tool calls, 5 exploratory reads, or 2 non-mechanical edits without any delegation, pause and delegate the next bounded unit of work.
|
|
132
|
+
5. **Verification rule** (gentle-pi#661/#662, RDD-aware): executing or delegating verification commands goes to `gentle-ai-verify`; only the 1–3-file read-only check stays inline. The normative on/off/unknown routing is stated once under Pi Trigger Runtime Bindings below; reference it, do not restate it.
|
|
133
|
+
|
|
134
|
+
**Preparation trigger:** reading that prepares a write, and broad research or context compression, delegate together with or ahead of the write instead of filling the parent context.
|
|
135
|
+
|
|
136
|
+
**Route declaration:** for substantial work, record the chosen route per task (inline or delegated) and the trigger evidence in the feature document, so skipped delegation is observable instead of silent.
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
2. **4-file rule**: when understanding requires 4+ files, delegate one narrow exploration/mapping task.
|
|
128
|
-
3. **Write rule**: keep one mechanical, already-understood file inline only when it needs no research or unresolved design work; delegate one writer for 2+ non-trivial files.
|
|
129
|
-
4. **Context rule**: delegate reading that prepares a write and broad research/context compression.
|
|
130
|
-
5. **Per-action rule**: tests, builds, and installs may use fresh workers without changing the implementation route or creating SDD state.
|
|
131
|
-
6. **Optional SDD rule**: retain SDD only after an explicit request or accepted proposal. Resolve organic uncertainty with optional research and a concise proposal only for a real decision; risk alone never forces SDD.
|
|
138
|
+
These triggers never select SDD and never create SDD artifacts; they only choose between direct inline and delegated direct inside the organic flow.
|
|
132
139
|
|
|
133
140
|
For bounded multi-file writes, prefer the installed package-owned `gentle-ai-worker`, then a user-configured `worker`. If neither worker definition exists, fall back to the native `Agent` even when `subagent_*` tools are available. If no delegation mechanism is available, stop and explain the blocker. Judgment Day phase roles are never generic fallbacks. If the generic writer chain is unavailable, use the documented native generic fallback or stop.
|
|
134
141
|
|
|
@@ -194,7 +201,7 @@ Background execution is policy-gated: the always-on orchestrator prompt renders
|
|
|
194
201
|
|
|
195
202
|
When the policy is on and `subagent_run` is available:
|
|
196
203
|
|
|
197
|
-
-
|
|
204
|
+
- The runtime already defaults `subagent_run` to `mode: "background"` under this policy in interactive and RPC sessions, so omit `mode` for ordinary delegation. It returns a task id at once; the terminal stays free and the human keeps typing. Pass a `label` of three to six words naming the work.
|
|
198
205
|
- A child `agent_end` retains its latest answer but is not completion: Pi may still retry, compact, or run a queued follow-up. Treat the task as finished only at `agent_settled`; only then release its queue slot, publish its background result, or terminate it. If it exits first, report failure with its retained answer as diagnostics.
|
|
199
206
|
- When a background task settles, its result arrives as a message in this session (custom type `gentle-agents.result`, one per task) and starts a new turn if you are idle. Wait for it: end the turn once launches and any non-overlapping work are done. Never poll, sleep, or call `subagent_status`/`subagent_result` for completion.
|
|
200
207
|
- Do not claim an implementation ready or RDD-ready while its required verification or correction follow-up remains queued. Run the required focused verification before that claim, and retain legitimate post-correction verification. This does not invent a universal full-suite requirement or make a receipt a delivery gate.
|
package/assets/orchestrator.md
CHANGED
|
@@ -56,8 +56,8 @@ Mandatory Delegation Triggers — once fired, delegate through the best availabl
|
|
|
56
56
|
1. **4-file rule** — 4+ files to understand → delegate a scout/mapping task.
|
|
57
57
|
2. **Multi-file write rule** — 2+ non-trivial files touched → delegate one writer.
|
|
58
58
|
3. **Incident rule** — diagnose wrong cwd/worktree/git/tooling incidents separately before resuming work.
|
|
59
|
-
4. **
|
|
60
|
-
5. **
|
|
59
|
+
4. **Long-session rule** — ~20 tool calls, 5 exploratory reads, or 2 non-mechanical edits without delegation → pause and delegate.
|
|
60
|
+
5. **Verification rule** — executing/delegating verification commands → `gentle-ai-verify`; only the 1-3-file read-only check stays inline.
|
|
61
61
|
|
|
62
62
|
{{GENTLE_PI_BACKGROUND_POLICY}}; rules: the background-subagents block in the delegation contract.
|
|
63
63
|
|
package/docs/gentle-shell.md
CHANGED
|
@@ -15,7 +15,7 @@ The [v2.6.0 release](https://github.com/Gentleman-Programming/gentle-pi/releases
|
|
|
15
15
|
- The Agents List and Details views preserve the orchestrator/session hierarchy and completion, abort, and lost-exit history. Parent-child queries and notifications have an explicit handoff path, while model, effort, and usage stay observable per task.
|
|
16
16
|
- Named `/gentle:profiles` atomically route the orchestrator separately from packaged and review roles; see the [technical reference](readme-reference.md#agent-model-profiles) for the profile model.
|
|
17
17
|
|
|
18
|
-
The source checkout currently prepares `gentle-pi` `3.1
|
|
18
|
+
The source checkout currently prepares `gentle-pi` `3.2.1` with a package-local Gentle AI `v3.2.1` pin; this is not a claim that `3.2.1` is published.
|
|
19
19
|
|
|
20
20
|
## Shell interactions and runtime behavior
|
|
21
21
|
|
|
@@ -30,7 +30,7 @@ The sidebar Status card also shows `Profile` in its Model section when the profi
|
|
|
30
30
|
The status bar replaces pi's three-line footer with a single line of segments:
|
|
31
31
|
|
|
32
32
|
```text
|
|
33
|
-
✿ gentle
|
|
33
|
+
✿ gentle shell ⟡ ~/work/gentle-pi main ⟡ gpt-5.5 · medium ⟡ ctx ▰▰▰▰▱▱▱▱ 45% ⟡ $9.49 sub ⟡ MCP: 3 servers enabled Release notes
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
- Context is a gauge, not a number. It turns amber at 80% and red at 95%; after compaction it shows `?%` until the next response.
|
|
@@ -90,15 +90,25 @@ The separate `session_worktree_register` tool still registers canonical same-clo
|
|
|
90
90
|
|
|
91
91
|
To use `ctrl+p` like OpenCode, rebind Pi's `app.model.cycleForward` in `~/.pi/agent/keybindings.json` (Pi reserves that action, so an extension cannot take `ctrl+p` while it holds it) and set `GENTLE_PI_COMMANDS_KEY=ctrl+p`.
|
|
92
92
|
|
|
93
|
-
Subscription usage shows in the bar after the cost, and `/gentle:usage` opens a panel with
|
|
93
|
+
Subscription usage shows in the bar after the cost, and `/gentle:usage` opens a panel with one row per window of every provider: the limit name, its meter, its percentage and, when that window reports one, its reset, all on one line. Codex, Claude and NaN all read the same way:
|
|
94
94
|
|
|
95
95
|
```text
|
|
96
|
-
✿ gentle
|
|
96
|
+
✿ gentle shell ⟡ … ⟡ $9.49 sub ⟡ codex 5h ▰▰▰▰▰▱▱▱ 62% · week 31%
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The panel rows a provider reports its windows with:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
✿ nan · updated just now
|
|
103
|
+
deepseek-v4-flash ▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱ 26% · resets in 12d 17h
|
|
104
|
+
glm5.3-flash ▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱▱ 11% · resets in 12d 17h
|
|
97
105
|
```
|
|
98
106
|
|
|
99
107
|
- For Codex, usage comes from the same account usage endpoint the Codex CLI reads, using the OAuth token pi already holds. It is fetched at session start, at most every 5 minutes after a turn, and on `r` in the panel. Rate-limit headers on SSE responses are picked up too.
|
|
100
108
|
- For Claude Pro/Max, usage arrives in the rate-limit headers of every response, so the 5h and weekly windows appear after the first turn.
|
|
101
|
-
-
|
|
109
|
+
- For NaN Cloud, usage comes from the quota endpoint the official dashboard reads, with the same API key pi already holds. Each metered model reports one allowance for the billing period, and that window carries no label: the model id names it in the bar and the reset text says what it is in the panel. A model that also reports a rolling window shows that one labeled next to it (`4h`), which today's payload does not send; percentages are tokens used over the allowance, exactly as the dashboard draws them, and the allowance is the full-period cap (`fullCap`) whenever the model reports a positive one, because `cap` alone is the prorated allowance of the period in progress. It is fetched under the same 5-minute rule as Codex, counted per provider so a switch fetches the provider it switched to, refuses redirects so the bearer cannot be replayed to another origin, and keeps no cached copy. The endpoint sits outside NaN's published OpenAPI, so the parser reads it defensively: a model that reports no allowance is skipped, as the dashboard skips it, while a metered model whose usage cannot be read fails the whole read, so a partial payload never replaces a complete snapshot with a cheaper-looking one. A session that already has a snapshot keeps the last valid one through a malformed payload or a failed fetch, and the pending note appears only while there is nothing to draw.
|
|
110
|
+
- The bar names the subscription it shows (`codex`, `claude`, a NaN model) and always follows the active model. A provider with per-model allowances draws the session model's own meter, falling back to its family and then to the account total, never to whichever model the payload happens to list first — and that holds for a payload that reports a single metered model too, because one allowance is still per-model data rather than a reason to echo the first entry. The panel puts the active provider first, marked with the petal, and says why it has no data when it does not: API-key providers have no subscription windows, Claude reports after the first response, Codex and NaN wait for a fetch. A provider without per-model allowances keeps its single aggregate line in the sidebar, unchanged.
|
|
111
|
+
- A provider with per-model allowances is ordered by family on both surfaces: a family stays together, the family that consumes most comes first, and the models inside it follow the same rule, most used first. There are no `total` rows anywhere — an aggregate nobody can act on only costs space — so the account and family totals survive only as the bar's fallback name when the session model holds no allowance of its own (`nan total`). An allowance row leaves the window label empty and prints `name meter percent`, while a labeled sub-window (`4h`) keeps its column, and the reset a window reports rides that same line after a `·`; a window without one ends at its percentage, never on a dangling separator. The sidebar's Usage group prints those same rows in that same order, so the breakdown does not require opening the panel, and stops at the percentage: the reset dates stay in the panel. A row whose windows all round to `0%` is dropped from that group — an allowance nobody has touched yet tells the reader nothing the missing row does not — and the same rule retires the aggregate line of a provider without raw allowances once every window it shows sits at `0%`; the bar and the panel keep printing it, so a zeroed subscription is still verifiable there.
|
|
102
112
|
- Only the plan name and the windows are kept; account details in the payload are discarded.
|
|
103
113
|
- Gauges turn amber at 80% and red at 95%, like the context gauge.
|
|
104
114
|
|
package/docs/readme-reference.md
CHANGED
|
@@ -18,8 +18,8 @@ ODD is the predefined workflow: it runs by default on every request, without the
|
|
|
18
18
|
3. **Resolve uncertainty** — optional research or one focused product question only for a real unresolved decision.
|
|
19
19
|
4. **Classify** — substantial when exploration yields two or more meaningful implementation steps; small work stays small.
|
|
20
20
|
5. **Track before the first write** — create the feature document and Engram mirror automatically for substantial work, and tell the user in one line.
|
|
21
|
-
6. **Implement task by task** — route each task through the smallest safe workflow, with configured TDD and applicable checks.
|
|
22
|
-
7. **Close** — report the verified outcome, failed/pending checks, and the next step.
|
|
21
|
+
6. **Implement task by task** — route each task through the smallest safe workflow, with configured TDD and applicable checks. Every task closes with at least one work-unit commit on the feature branch (branch first when on the default branch), with tests and docs alongside the behavior, using a Conventional Commit message; the feature document records the commit identity as evidence.
|
|
22
|
+
7. **Close** — report the verified outcome, failed/pending checks, and the next step. The native review candidate is a work-unit commit or a PR slice, never a TODO checkbox and never the accumulated feature branch.
|
|
23
23
|
|
|
24
24
|
- **One feature document:** `odd/tasks/<feature-name>.md` holds objective, problem, why, scope, constraints, actionable checklist with stable IDs and acceptance criteria, verification evidence, progress, and next step. Project-scoped Engram topic `odd/<feature-name>/tasks` mirrors the full document and repository-relative locator. Keep concise rationale for meaningful accepted changes here, not a separate plan or exhaustive journal. Accepted user, review, or verification changes update intent and tasks together; preserve valid completed work, add new tasks or reopen invalidated items with reasons. Findings alone do not authorize expansion or acceptance. Routine corrections stay with their tasks; checkoffs require observed proof.
|
|
25
25
|
- **Recovery:** write local progress first and read back both copies; writes are not atomic. Unavailable Engram leaves an explicit pending mirror, not invented success or a block on unrelated safe work. Before implementation or resume, the parent reads full feature memory and the actual task file, reconciles code and evidence, and preserves conflicting versions. Pass the locator and relevant context; workers read the document before edits. The existing Todo UI is a projection, not another authority.
|
|
@@ -27,7 +27,8 @@ ODD is the predefined workflow: it runs by default on every request, without the
|
|
|
27
27
|
- **Research:** optional research addresses a named uncertainty. Establish problem, intended outcome, constraints, and current evidence; inspect code and adapt depth to consequence, not fixed questionnaires or rounds. The parent asks one focused product question only when needed, then waits; workers return gaps. Use available authorized documentation/web tools, prefer primary sources, and attribute claims to URLs/code locations. Distinguish facts, assumptions, contradictions, freshness, and gaps; return a recommendation, tradeoffs, open questions, and implementation implications. Forward these instructions to an existing fresh general worker, not a specialized agent or `sdd-research`. Unavailable evidence pauses only unsafe dependent decisions. Research stays read-only with no new persistence/readiness machinery; a brief proposal is needed only for a real decision.
|
|
28
28
|
- **Assumptions:** at most one scoped independent read-only challenge for a high-consequence unproven premise, including a small security-critical change. Deterministic failures need fixes, not debate. Native RDD claims stay with its refuter.
|
|
29
29
|
- **TDD:** resolve on/off from existing project/session configuration or explicit user choice; retain source and exact runner in the feature document when present and forward all three on every implementation delegation, refreshing on resume. Test presence does not enable TDD. Enabled requires observed RED before implementation → GREEN → REFACTOR; disabled still requires ordinary functional checks. Unknown/conflicting mode or a missing runner needs only the clarification affecting the next action, never invented precedence, commands, or `sdd-init`.
|
|
30
|
-
- **Checks:** functional checks run per task
|
|
30
|
+
- **Checks:** functional checks run per task; a TODO checkbox never triggers a review cycle. The native review candidate is a work-unit commit or a PR slice, never a TODO checkbox and never the accumulated feature branch. After each work-unit commit, when RDD is enabled, assess it with `gentle_review` `{"operation":"assess"}` and `{"baseRef":"<last reviewed boundary>","committedOnly":true}`. Passive or low stays silent and the boundary advances. High, or an unavailable or failed assessment, reviews the commit itself right away at that base. Medium defers to the PR slice, the commits accumulated since the last reviewed boundary, bounded by the delivery budget of about 400 authored changed lines, and reviews at slice close. The first boundary is the branch point, and every reviewed boundary becomes the next base. Record the assessed tier and outcome per task: granted, declined, passive, deferred to slice, or unavailable. Existing risk, consent, and authority stay unchanged; never infer low risk from a failed assessment. Never skip an existing delivery gate.
|
|
31
|
+
- **Delivery:** at feature-document creation, forecast authored changed lines (additions plus deletions, generated files excluded) from the task list, and keep a running count from work-unit commits. Choose one delivery strategy per feature: `ask-on-risk` (default), `auto-chain`, `single-pr`, or `exception-ok`. When the forecast or running count exceeds about 400 authored changed lines, apply the chosen strategy before the next commit. `ask-on-risk` asks once for the chain strategy (`stacked-to-main` or `feature-branch-chain`); `auto-chain` asks only for a missing chain strategy and slices automatically. Cache both choices, and record slice boundaries (which commits each PR holds) in the feature document. Resolve the `work-unit-commits` and `chained-pr` skills by registry name before planning or creating any PR.
|
|
31
32
|
|
|
32
33
|
```mermaid
|
|
33
34
|
flowchart TD
|
|
@@ -49,20 +50,25 @@ flowchart TD
|
|
|
49
50
|
TC --> M[Implement next authorized task]
|
|
50
51
|
M --> N[Applicable functional checks]
|
|
51
52
|
N --> O[Record truthful results; update tracked intent, tasks and mirror]
|
|
52
|
-
O -->
|
|
53
|
+
O --> OC[Close task with a work-unit commit]
|
|
54
|
+
OC --> P{Authorized work remains?}
|
|
53
55
|
P -->|Yes| M
|
|
54
|
-
P -->|No| Q{RDD enabled at
|
|
56
|
+
P -->|No| Q{RDD enabled at work-unit commit boundary?}
|
|
55
57
|
Q -->|No| R[Ordinary checks and policy]
|
|
56
|
-
Q -->|Yes| S{Native candidate risk}
|
|
57
|
-
S -->|Passive or low| T[Silent structural checks;
|
|
58
|
-
S -->|Medium
|
|
59
|
-
S -->|
|
|
58
|
+
Q -->|Yes| S{Native candidate risk per commit}
|
|
59
|
+
S -->|Passive or low| T[Silent structural checks; boundary advances]
|
|
60
|
+
S -->|Medium| U{Existing candidate consent for PR slice}
|
|
61
|
+
S -->|High or unavailable| V[Review the commit now at that base]
|
|
60
62
|
U -->|Granted| W[Native review plan and authority]
|
|
61
63
|
U -->|Declined| R
|
|
62
|
-
|
|
63
|
-
T --> X
|
|
64
|
+
V --> X[Existing delivery gates]
|
|
64
65
|
W --> X
|
|
65
|
-
|
|
66
|
+
T --> X
|
|
67
|
+
R --> X
|
|
68
|
+
X --> AG{Running authored lines over 400?}
|
|
69
|
+
AG -->|Yes| AH[Apply delivery strategy: chained PR slice]
|
|
70
|
+
AG -->|No| Y[Deliver]
|
|
71
|
+
AH --> Y
|
|
66
72
|
Z[Resume] --> AA[Full feature memory and actual task file]
|
|
67
73
|
AA --> AB[Reconcile requirements, code, proof and conflicts]
|
|
68
74
|
AB --> TC
|
|
@@ -99,7 +105,7 @@ This is guidance through existing tools, not a new CLI, phase, state engine, or
|
|
|
99
105
|
| **Skill creation workflow** | Provides the `gentle-ai-skill-creator`/`gentle-ai-skill-improver` skills, `/skill-creation` prompt, and packaged style guide for LLM-first skills. |
|
|
100
106
|
| **Delivery skills** | Includes issue-first PRs, chained PRs, work-unit commits, cognitive docs, comment writing, and Judgment Day review. |
|
|
101
107
|
| **Bounded native review** | Freezes one candidate, dispatches only controller-selected lenses, and records native authority. Review outcomes are informational; delivery follows ordinary repository policy. |
|
|
102
|
-
| **Verified native runtime** | The current source checkout provisions the exact package-local Gentle AI v3.
|
|
108
|
+
| **Verified native runtime** | The current source checkout provisions the exact package-local Gentle AI v3.2.1 runtime: signed, SHA-256-pinned release archives on Darwin/Linux and a Go SumDB-verified source build on Windows x64/arm64. It validates package-local integrity and rejects PATH, global, sibling, symlink, and mode fallbacks. |
|
|
103
109
|
| **Runtime safety** | Blocks destructive shell commands, asks for confirmation for sensitive operations, and blocks direct read/write/edit access to sensitive paths. |
|
|
104
110
|
|
|
105
111
|
## Native pointer regions
|
|
@@ -136,7 +142,7 @@ The stable release is [`v2.6.0`](https://github.com/Gentleman-Programming/gentle
|
|
|
136
142
|
|
|
137
143
|
### Source checkout
|
|
138
144
|
|
|
139
|
-
This checkout prepares `gentle-pi` `3.1
|
|
145
|
+
This checkout prepares `gentle-pi` `3.2.1`; it is source state, not a published release. Its package-local native runtime pin is Gentle AI `v3.2.1`, distinct from the published `v2.6.0` pairing.
|
|
140
146
|
|
|
141
147
|
The native SDD status consumer accepts both the pinned producer's legacy
|
|
142
148
|
`apply`/`verify`/`remediate`/`archive` instruction record and the classical
|
|
@@ -147,7 +153,7 @@ Unknown or incomplete instruction records still fail closed.
|
|
|
147
153
|
The Pi runtime now uses native status exclusively for SDD and retires standalone
|
|
148
154
|
sync. The full chain follows completed apply to archive, where applicable delta
|
|
149
155
|
specs are composed; verification remains explicitly invokable. With the current
|
|
150
|
-
3.
|
|
156
|
+
3.2.1 pin, native still requires verification and its emitted evidence requirements;
|
|
151
157
|
a plain practical PASS report does not satisfy that legacy native gate. Pi forwards
|
|
152
158
|
those exact instructions without overriding readiness or inventing legacy evidence.
|
|
153
159
|
Classical direct-archive behavior is compatibility-tested with an identified
|
|
@@ -181,7 +187,7 @@ pi install npm:gentle-pi@2.6.0
|
|
|
181
187
|
|
|
182
188
|
RDD remains opt-in. Enable it only through an explicit user decision with `/gentle:review-mode enable`; `status` lets you inspect the mode without changing it.
|
|
183
189
|
|
|
184
|
-
The source checkout's RDD integration installs Gentle AI only into its private `.gentle-ai/` directory. Darwin and Linux use pinned release assets with asset and executable SHA-256 verification (signed archives for source pin `v3.
|
|
190
|
+
The source checkout's RDD integration installs Gentle AI only into its private `.gentle-ai/` directory. Darwin and Linux use pinned release assets with asset and executable SHA-256 verification (signed archives for source pin `v3.2.1`; raw prerelease binaries only under a prerelease pin). Windows x64 and arm64 build the exact `v3.2.1` source tag with a local Go 1.25.10+ toolchain, a sealed Go environment, `GOTOOLCHAIN=local`, and `GOSUMDB=sum.golang.org`; it does not download Go automatically. Windows provenance is Go-toolchain plus SumDB evidence and postinstall tamper detection, **not** Authenticode or protection against a malicious joint binary-and-manifest replacement. Package-private locks coordinate cooperative concurrent or crashed installers; their tombstones fail closed. A malicious same-user process with write access to package-private `node_modules` is outside that protocol because it can already replace package code, binary, or manifest, and portable Node has no pathname-delete CAS. It never uses `PATH` or a global `gentle-ai` installation. For development or offline installs only, set `GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1`; native review operations then fail closed with an actionable `package-local-binary-missing` error. To recover explicitly, if `GENTLE_PI_SKIP_GENTLE_AI_INSTALL` is set, remove or unset it before changing to the installed `gentle-pi` package directory. Then run `node scripts/install-gentle-ai.mjs`. This invokes the package-owned installer without relying on a global binary or npm configuration change. A missing binary can result from skipped lifecycle scripts, but does not prove that lifecycle scripts were disabled.
|
|
185
191
|
|
|
186
192
|
Recommended companion packages:
|
|
187
193
|
|
|
@@ -201,6 +207,23 @@ pi
|
|
|
201
207
|
|
|
202
208
|
`gentle-pi` installs delegation and review agents at startup. SDD agents, chains, and support are global Pi runtime assets installed on demand, not per-project setup. The first SDD flow in a session runs a one-time SDD preflight for preferences and managed-asset refresh; natural-language SDD requests or accepted proposals select that workflow, then run its preflight. Ordinary ODD does not run SDD initialization.
|
|
203
209
|
|
|
210
|
+
### Base references for review
|
|
211
|
+
|
|
212
|
+
An explicit `baseRef` accepts one of these forms:
|
|
213
|
+
|
|
214
|
+
- `HEAD`.
|
|
215
|
+
- A full 40- or 64-character commit id.
|
|
216
|
+
- A ref name: a branch, a tag, a remote-tracking ref, or an explicit `refs/...` path.
|
|
217
|
+
|
|
218
|
+
Abbreviated commit ids are rejected as `base-ref-unresolvable`; a rejected `baseRef` names its accepted forms in the response. Explicit tree ids are not accepted today.
|
|
219
|
+
|
|
220
|
+
Under the ODD contract, the orchestrator passes the last reviewed boundary as `baseRef` for each work-unit commit or slice, so base refs are routine input, not an edge case.
|
|
221
|
+
|
|
222
|
+
An orphan branch with commits and no parent has no branch point to name as `baseRef`. Before the first work-unit commit, either:
|
|
223
|
+
|
|
224
|
+
- Create an empty root commit to open the branch: `git commit --allow-empty -m "chore: open the feature branch"`. The next commit can then use that root commit as its `baseRef`.
|
|
225
|
+
- Omit `baseRef` while the branch is still unborn (no commits yet); the review uses Git's empty tree as the base automatically.
|
|
226
|
+
|
|
204
227
|
## Quick start
|
|
205
228
|
|
|
206
229
|
```text
|
|
@@ -338,13 +361,13 @@ flowchart TD
|
|
|
338
361
|
|
|
339
362
|
VALIDATE is informational. Commit, push, PR, and release commands follow ordinary repository policy; RDD never authorizes, rewrites, consumes review state for, or blocks them. Dangerous-command safety and destructive-review consent remain independent.
|
|
340
363
|
|
|
341
|
-
For the source checkout, native contract pairing is exact: this adapter resolves only the integrity-verified package-local Gentle AI v3.
|
|
364
|
+
For the source checkout, native contract pairing is exact: this adapter resolves only the integrity-verified package-local Gentle AI v3.2.1 executable, independently hashes it, then negotiates `gentle-ai.review-integration/v2` outside the repository. Capabilities are cached by that executable digest. Every START, target status, FINALIZE, validate, and BIND-SDD request passes the same contract identifier. Negotiated envelopes decode exactly against the vendored schemas; `recover` routes only the provider-selected `action_disposition`, and optional additions require a future compatible schema/minor that the provider explicitly advertises and the consumer negotiates.
|
|
342
365
|
|
|
343
366
|
Contract `/v2` replaces the Base64 `candidate_diff` reviewer transport of `/v1` with immutable `base_tree`/`candidate_tree` plus an ordered `changed_path_manifest` and never an inline patch. `gentle-pi` negotiates `/v2` only, with no dual-lane fallback; the cutover landed as one atomic commit against gentle-ai v2.2.2 (tracked by the `migrate-review-integration-v2` change), and the `/v1` schemas stay packaged because the `/v2` schemas `$ref` into their fragments. This provider contract version is unrelated to Pi's own internal "compact-v2" review-authority naming used below — the shared digit is coincidental, not a version pairing.
|
|
344
367
|
|
|
345
368
|
Target status owns `current_target`, `unrelated`, `ambiguous`, and `corrupted` applicability and returns one native action. Pi does not reconstruct ordinary authority from provider-private files or choose a lineage from repository-wide history. Restart recovery rebuilds only the derived candidate view from the native Git/content projection, including intended-untracked paths, symlinks, and immutable gitlink identities. Native failure envelopes retain their exact mutation outcome, replayability, required inputs, request digest, and next action. After an unknown or lost mutating result, Pi calls target status before any replay decision and returns only the provider-declared action.
|
|
346
369
|
|
|
347
|
-
Once the source checkout's pinned gentle-ai runtime (currently v3.
|
|
370
|
+
Once the source checkout's pinned gentle-ai runtime (currently v3.2.1) has written review authority, rollback MUST preserve every native store and receipt and MUST NOT run a downgraded binary against that repository. Disable the Pi route or roll forward to a compatible authority-aware release instead; deleting authority data or reinstalling an older binary is not a rollback path.
|
|
348
371
|
|
|
349
372
|
### FINALIZE wrapper input
|
|
350
373
|
|
|
@@ -819,6 +842,8 @@ Startup installs and refreshes only delegation and review assets. SDD assets are
|
|
|
819
842
|
|
|
820
843
|
Background delegation requires a live interactive/RPC parent and is rejected in `pi -p`, even when the policy is on. Use task mode for bounded print-mode work.
|
|
821
844
|
|
|
845
|
+
With the policy `on`, `subagent_run` defaults to `mode: "background"` at the runtime level in interactive and RPC sessions; print mode keeps `task` regardless of the policy, since `pi -p` exits before a parent session can receive a background result. `mode: "task"` remains available as an explicit opt-in for work that must ask the human mid-flight, such as a dialog-driven task or one the caller wants to wait on.
|
|
846
|
+
|
|
822
847
|
Background delegation is off unless you turn it on. The policy is user-owned: only an explicit `/gentle:background-subagents enable` or `disable` writes it, and Pi automation never toggles it.
|
|
823
848
|
|
|
824
849
|
```text
|
|
@@ -8,8 +8,8 @@ Gentle Pi is a transport consumer, not a review authority. Gentle AI generates t
|
|
|
8
8
|
|
|
9
9
|
| Component | Responsibility |
|
|
10
10
|
| --- | --- |
|
|
11
|
-
| Pi reviewer adapter | A pure opaque adapter: `Buffer → Buffer/error`. It accepts a Go-materialized prompt as bytes, invokes Pi, and returns
|
|
12
|
-
| Host coordinator | Executes the exact Go-issued materialize/submission tokens, launches the adapter, and submits its
|
|
11
|
+
| Pi reviewer adapter | A pure opaque adapter: `Buffer → Buffer/error`. It accepts a Go-materialized prompt as bytes, invokes Pi in JSON event mode, and returns the event stream's final assistant text or a typed transport error carrying what the child's own stream revealed. |
|
|
12
|
+
| Host coordinator | Executes the exact Go-issued materialize/submission tokens, launches the adapter, and submits its result only through the supplied token. It validates and forwards two optional caller-owned launch selections: the lens's reviewer model (`--model`) and an explicit extension allowlist (`-e` paths). |
|
|
13
13
|
| Gentle AI (Go) | Go owns worktree, lineage, candidate freeze, lens selection, correction, validator, approval burn, and review semantics. Delivery commands remain ordinary repository-policy operations. |
|
|
14
14
|
|
|
15
15
|
The adapter does not parse bindings, select work, rebuild prompts, inspect repository state, retry, classify results, or create authority. The coordinator does not infer a command or replace a provider-issued token. The package has no durable receipt or policy authority.
|
|
@@ -18,10 +18,17 @@ The adapter does not parse bindings, select work, rebuild prompts, inspect repos
|
|
|
18
18
|
|
|
19
19
|
1. Gentle AI emits an opaque materialization or submission token for the selected Pi runtime.
|
|
20
20
|
2. The host coordinator executes that exact token and gives only the materialized bytes to the adapter.
|
|
21
|
-
3. The adapter returns
|
|
21
|
+
3. The adapter runs the child with `--mode json`, extracts the final assistant text from the pi event stream, and returns those bytes to the coordinator. A run that produced no assistant text fails typed with evidence: the stream kind, the reviewer selection the child itself reported, and whether a tool call was attempted (a text-mode run used to exit 0 with zero bytes and no diagnosable cause).
|
|
22
22
|
4. The coordinator sends those bytes only through the exact Go-issued submission token.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## Reviewer launch selection (user-owned)
|
|
25
|
+
|
|
26
|
+
The default reviewer launch is selection-free: no model flag, no extensions, no ambient inheritance of the session's model. Two optional, user-owned selections ride the request and are validated before any process launches; a broken value is refused typed as `reviewer-config-invalid`, never a mid-review transport failure:
|
|
27
|
+
|
|
28
|
+
- **Lens model** — the capture path reads the lens's entry from the agent model routing config (`review-risk`, `review-resilience`, `review-readability`, `review-reliability`) and forwards it as `--model <provider/id>`.
|
|
29
|
+
- **Extension allowlist** — `GENTLE_PI_REVIEW_RELAY_EXTENSIONS` holds absolute extension file paths separated by the platform path delimiter. They are loaded through explicit `-e` paths, which pi honors even under `--no-extensions`; this is how a subscription provider's OAuth billing adapter rides along without re-enabling extension discovery.
|
|
30
|
+
|
|
31
|
+
A typed Pi transport refusal fails closed. The coordinator reports the refusal — including the reviewer evidence and a bounded stderr excerpt on an empty-output failure — without an agentless lifecycle fallback, local retry policy, synthetic result, or alternate approval path.
|
|
25
32
|
|
|
26
33
|
## Dynamic contract delivery
|
|
27
34
|
|
|
@@ -29,16 +36,18 @@ Package static assets intentionally omit lifecycle instructions, candidate routi
|
|
|
29
36
|
|
|
30
37
|
## Integration constraints
|
|
31
38
|
|
|
32
|
-
- Keep Pi transport opaque: raw prompt bytes in,
|
|
39
|
+
- Keep Pi transport opaque: raw prompt bytes in, the event stream's assistant text or a typed, evidenced error out.
|
|
33
40
|
- Preserve Go-issued materialize and submission tokens exactly; they are the only authority-bearing inputs the host may execute.
|
|
41
|
+
- Keep the reviewer launch selection user-owned: the relay never invents a model and never enables extension discovery; it only forwards the validated caller-owned selections.
|
|
34
42
|
- Treat a transport failure as unavailable evidence, never as an approval, completion, or permission to substitute a local workflow.
|
|
35
43
|
- Keep command safety and user interaction in the host, without interpreting provider authority state.
|
|
36
44
|
- Keep durable review state, admissions, correction accounting, and approvals in Gentle AI. Keep delivery decisions in ordinary repository policy.
|
|
37
45
|
|
|
38
46
|
## Review checklist
|
|
39
47
|
|
|
40
|
-
- [ ] The adapter surface is still `Buffer → Buffer/error
|
|
48
|
+
- [ ] The adapter surface is still `Buffer → Buffer/error` (the output is the pi event stream's assistant text; failures carry typed evidence).
|
|
41
49
|
- [ ] The coordinator executes only exact Go-issued materialize/submission tokens.
|
|
50
|
+
- [ ] The reviewer launch stays selection-free unless the caller-owned selection and extension allowlist validate.
|
|
42
51
|
- [ ] Typed transport refusal remains fail-closed.
|
|
43
52
|
- [ ] No package code or static prompt uses review authority to decide, authorize, rewrite, or block delivery commands.
|
|
44
53
|
|
|
@@ -17,6 +17,7 @@ import { sidebarPart } from "../lib/shell-sidebar.ts";
|
|
|
17
17
|
import { invalidateSidebar } from "../lib/shell-sidebar-layout.ts";
|
|
18
18
|
import { createCompletionQueue } from "../lib/agents-completion-delivery.ts";
|
|
19
19
|
import { AGENT_MODE, discoverAgents, parseAgentDefinition, loadAgentsConfig, resolveAgentProfile, withPinnedModelProfiles, type AgentDefinition, type AgentMode } from "../lib/agents-config.ts";
|
|
20
|
+
import { resolveBackgroundSubagentsPolicy } from "../lib/background-subagents-policy.ts";
|
|
20
21
|
import { isFinished, TASK_STATUS, TaskStore, type AskRequest, type TaskRecord } from "../lib/agents-protocol.ts";
|
|
21
22
|
import { AgentRunner, piCommand, abortReasonText, plannedCommands, type RemediationPlan, type RemediationScope, REMEDIATION_PLAN_ENV, parseRemediationPlan, type AskAnswer, type RunnerDeps, type SddChangeSelection, type TaskRequest } from "../lib/agents-runner.ts";
|
|
22
23
|
import { ChildMessenger, type IpcEndpoint } from "../lib/agents-messaging.ts";
|
|
@@ -341,6 +342,22 @@ function expandHint(expanded: boolean): string {
|
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
// The default mode for a subagent_run request that named neither an explicit
|
|
346
|
+
// mode nor an agent-defined one. Background is a runtime default only when
|
|
347
|
+
// the background-subagents policy is on AND the parent can receive results:
|
|
348
|
+
// print mode exits before a parent session exists to deliver them to (see
|
|
349
|
+
// the `ctx.mode === "print"` guard in `launch` below), so it must keep the
|
|
350
|
+
// configured default (normally task) even when the policy is on.
|
|
351
|
+
export function resolveDefaultSubagentMode(input: {
|
|
352
|
+
configuredDefault: AgentMode;
|
|
353
|
+
policy: "on" | "off";
|
|
354
|
+
parentMode: string | undefined;
|
|
355
|
+
}): AgentMode {
|
|
356
|
+
return input.policy === "on" && input.parentMode !== "print"
|
|
357
|
+
? AGENT_MODE.BACKGROUND
|
|
358
|
+
: input.configuredDefault;
|
|
359
|
+
}
|
|
360
|
+
|
|
344
361
|
// What the model reads when a background task ends: the outcome first, then
|
|
345
362
|
// the answer itself. The card renderer shows the same text.
|
|
346
363
|
export function completionText(task: TaskRecord): string {
|
|
@@ -1248,7 +1265,11 @@ export default function gentleAgents(pi: ExtensionAPI, env: NodeJS.ProcessEnv =
|
|
|
1248
1265
|
const { agents } = discoverAgents(roots(ctx));
|
|
1249
1266
|
const agent = agents.find((candidate) => candidate.name === params.agent);
|
|
1250
1267
|
if (!agent) return text(`Error: no subagent named "${String(params.agent)}". Known: ${agents.map((candidate) => candidate.name).join(", ") || "none"}`, { error: "unknown agent" });
|
|
1251
|
-
const mode = (params.mode as AgentMode | undefined) ?? agent.mode ??
|
|
1268
|
+
const mode = (params.mode as AgentMode | undefined) ?? agent.mode ?? resolveDefaultSubagentMode({
|
|
1269
|
+
configuredDefault: loadAgentsConfig(roots(ctx)).defaultMode,
|
|
1270
|
+
policy: resolveBackgroundSubagentsPolicy(ctx.cwd).policy,
|
|
1271
|
+
parentMode: ctx.mode,
|
|
1272
|
+
});
|
|
1252
1273
|
let sddChange: SddChangeSelection | undefined;
|
|
1253
1274
|
try { sddChange = parseSddChange(params.sdd_change, agent.name); }
|
|
1254
1275
|
catch (error) { return text(`Error: ${error instanceof Error ? error.message : String(error)}`, { error: "invalid sdd_change" }); }
|