gentle-pi 3.1.0 → 3.2.0
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 +6 -4
- package/assets/orchestrator-memory.md +1 -1
- package/assets/sdd-orchestrator-workflow.md +1 -1
- package/docs/gentle-shell.md +1 -1
- package/docs/readme-reference.md +43 -18
- package/extensions/gentle-agents.ts +22 -1
- package/extensions/gentle-ai.ts +33 -138
- package/extensions/pi-pretty.ts +13 -1
- package/lib/background-subagents-policy.ts +148 -0
- package/lib/native-review-cli.ts +9 -0
- package/lib/review-candidate-view.ts +27 -6
- package/lib/sdd-preflight.ts +5 -19
- package/package.json +1 -1
- package/runtime/native-review-cli.mjs +9 -0
- package/scripts/gentle-ai-installer.mjs +10 -10
- package/scripts/verify-package-files.mjs +2 -2
- 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-theme.test.ts +2 -0
- package/tests/native-review-capability-contract.test.ts +14 -1
- package/tests/odd-routing-contract.test.ts +49 -2
- package/tests/package-manifest.test.ts +6 -6
- package/tests/pi-pretty.test.ts +5 -0
- package/tests/review-base-ref-hint.test.ts +39 -0
- package/tests/review-candidate-view.test.ts +55 -0
- package/tests/runtime-harness.mjs +12 -10
- package/tests/sdd-managed-runtime-settlement.test.ts +2 -2
- package/tests/sdd-preflight-rpc-input.test.ts +29 -29
- package/tests/sdd-preflight.test.ts +12 -7
- package/tests/windows-hidden-processes.test.ts +2 -2
- package/themes/Gentleman-Cute.json +1 -1
|
@@ -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
|
|
|
@@ -194,7 +196,7 @@ Background execution is policy-gated: the always-on orchestrator prompt renders
|
|
|
194
196
|
|
|
195
197
|
When the policy is on and `subagent_run` is available:
|
|
196
198
|
|
|
197
|
-
-
|
|
199
|
+
- 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
200
|
- 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
201
|
- 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
202
|
- 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.
|
|
@@ -14,7 +14,7 @@ On resume, use `mem_context`, then project/feature-scoped `mem_search`, and `mem
|
|
|
14
14
|
|
|
15
15
|
Before implementation or resume, the parent reads both the actual file and full observation, reconciles them, and passes the locator and relevant context; workers read the document before edits. Small work without a document still receives its authorized scope and checks.
|
|
16
16
|
|
|
17
|
-
The existing `todo` tool is
|
|
17
|
+
The existing `todo` tool is the required session/UI projection for substantial ODD, not a third authority. After reconciling and writing the durable file and Engram copy, create or rebuild the visible `todo` list from the same feature tasks before the first source write; after every task transition and material plan change, update both durable copies and the visible projection in the same turn; its replay or completed-list clearing must not delete or replace the durable file or Engram copy. If the projection is unavailable, record that limitation without pretending it is synchronized. Small/read-only work does not acquire an ODD artifact or todo list merely because the UI can display tasks.
|
|
18
18
|
|
|
19
19
|
### SDD phases
|
|
20
20
|
|
|
@@ -71,7 +71,7 @@ Do not guess the active change. If change selection is ambiguous, ask the user a
|
|
|
71
71
|
|
|
72
72
|
## Lazy SDD Preflight
|
|
73
73
|
|
|
74
|
-
Do not ask SDD setup questions on session start. The first time the user initiates an SDD process in a Pi session, run the SDD preflight once and keep those choices for the rest of that session. Runtime
|
|
74
|
+
Do not ask SDD setup questions on session start. The first time the user initiates an SDD process in a Pi session, run the SDD preflight once and keep those choices for the rest of that session. Runtime input detection is intentionally syntax-only: slash SDD flows and `/gentle-sdd-init` run preflight automatically; ordinary natural-language text never triggers preflight by itself. For natural-language requests, the parent/orchestrator decides semantically whether the user explicitly selected SDD. Only after that selection, when the parent is about to dispatch the first SDD operation or agent, the execution gate runs or reuses `/gentle:sdd-preflight` before allowing SDD work to start. Merely mentioning, asking about, explaining, comparing, auditing, or referencing SDD — including questions ("what is SDD?"), negatives ("don't use SDD for this"), conditionals ("could we use SDD?"), bug reports about SDD itself, and passing references — stays in the normal read-only flow without preflight, the init guard, or any SDD phase. When a message is ambiguous between discussing SDD and requesting it, ask one clarification and remain read-only until answered.
|
|
75
75
|
|
|
76
76
|
**Hard gate:** `openspec/config.yaml`, existing SDD changes, installed `.pi`/global SDD assets, or a todo named "preflight" are not session preflight. They are project context only. Do not mark SDD preflight complete, start `sdd-init`, launch SDD subagents/chains, or move to explore/proposal/spec/design/tasks until this session has an injected `## SDD Session Preflight` block or an equivalent resolution from the canonical authority order below.
|
|
77
77
|
|
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.
|
|
18
|
+
The source checkout currently prepares `gentle-pi` `3.2.0` with a package-local Gentle AI `v3.1.0` pin; this is not a claim that `3.2.0` is published.
|
|
19
19
|
|
|
20
20
|
## Shell interactions and runtime behavior
|
|
21
21
|
|
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.0
|
|
108
|
+
| **Verified native runtime** | The current source checkout provisions the exact package-local Gentle AI v3.1.0 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.
|
|
145
|
+
This checkout prepares `gentle-pi` `3.2.0`; it is source state, not a published release. Its package-local native runtime pin is Gentle AI `v3.1.0`, 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.0
|
|
156
|
+
3.1.0 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.0
|
|
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.1.0`; raw prerelease binaries only under a prerelease pin). Windows x64 and arm64 build the exact `v3.1.0` 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.0
|
|
364
|
+
For the source checkout, native contract pairing is exact: this adapter resolves only the integrity-verified package-local Gentle AI v3.1.0 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.0
|
|
370
|
+
Once the source checkout's pinned gentle-ai runtime (currently v3.1.0) 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
|
|
@@ -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" }); }
|
package/extensions/gentle-ai.ts
CHANGED
|
@@ -34,6 +34,15 @@ import type {
|
|
|
34
34
|
} from "@earendil-works/pi-coding-agent";
|
|
35
35
|
import { Key, isKeyRelease, matchesKey, truncateToWidth, type KeybindingsManager, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
|
|
36
36
|
import { resolveGentlePiAgentHome, gentlePiConfigHome } from "../lib/agent-home.ts";
|
|
37
|
+
import {
|
|
38
|
+
BACKGROUND_SUBAGENTS_FILE,
|
|
39
|
+
BACKGROUND_SUBAGENTS_SCHEMA,
|
|
40
|
+
loadBackgroundSubagentsPolicy,
|
|
41
|
+
parseBackgroundSubagentsPolicyFile,
|
|
42
|
+
resolveBackgroundSubagentsPolicy,
|
|
43
|
+
type BackgroundSubagentsPolicy,
|
|
44
|
+
type BackgroundSubagentsResolution,
|
|
45
|
+
} from "../lib/background-subagents-policy.ts";
|
|
37
46
|
import {
|
|
38
47
|
ensureSddPreflight,
|
|
39
48
|
getSddPreflightPreferences,
|
|
@@ -158,7 +167,7 @@ import {
|
|
|
158
167
|
} from "../lib/review-snapshot.ts";
|
|
159
168
|
import { renderGentleAiLifecycleCall, renderGentleAiResult, type GentleAiRenderContext } from "../lib/gentle-ai-renderer.ts";
|
|
160
169
|
import { sanitizeTerminalText, stripAnsi } from "../lib/terminal-theme.ts";
|
|
161
|
-
import { CandidateViewError, CandidateViewRegistry, injectReviewCandidateView, readCandidateContextManifestPage, resolveCanonicalCandidateBase, type CandidateView } from "../lib/review-candidate-view.ts";
|
|
170
|
+
import { BASE_REF_ACCEPTED_FORMS, CandidateViewError, CandidateViewRegistry, injectReviewCandidateView, readCandidateContextManifestPage, resolveCanonicalCandidateBase, type CandidateView } from "../lib/review-candidate-view.ts";
|
|
162
171
|
import {
|
|
163
172
|
GentleAiDevBinaryOverrideError,
|
|
164
173
|
GENTLE_AI_INSTALL_RECOVERY_COMMAND,
|
|
@@ -349,9 +358,16 @@ function localAgentOverrideCount(cwd: string, owner: PackageAssetOwner): number
|
|
|
349
358
|
|
|
350
359
|
// ---------------------------------------------------------------------------
|
|
351
360
|
// Background subagents policy — project > global > env > default off
|
|
361
|
+
//
|
|
362
|
+
// The pure resolver (parseBackgroundSubagentsPolicyFile,
|
|
363
|
+
// resolveBackgroundSubagentsPolicy, loadBackgroundSubagentsPolicy, and their
|
|
364
|
+
// types/constants) lives in lib/background-subagents-policy.ts so the
|
|
365
|
+
// runtime side (extensions/gentle-agents.ts) can read the effective policy
|
|
366
|
+
// without importing the pi extension surface. Everything below this point
|
|
367
|
+
// (capability probing, report rendering, the global-file writer) stays here
|
|
368
|
+
// because it is specific to this extension's UI-facing surface.
|
|
352
369
|
// ---------------------------------------------------------------------------
|
|
353
370
|
|
|
354
|
-
type BackgroundSubagentsPolicy = "on" | "off";
|
|
355
371
|
type BackgroundSubagentsCapability = "ready" | "absent";
|
|
356
372
|
|
|
357
373
|
interface BackgroundSubagentsRendering {
|
|
@@ -359,142 +375,11 @@ interface BackgroundSubagentsRendering {
|
|
|
359
375
|
capability: BackgroundSubagentsCapability;
|
|
360
376
|
}
|
|
361
377
|
|
|
362
|
-
/** Which of the four sources decided the effective policy. */
|
|
363
|
-
type BackgroundSubagentsSource =
|
|
364
|
-
| "project_file"
|
|
365
|
-
| "global_file"
|
|
366
|
-
| "environment"
|
|
367
|
-
| "default";
|
|
368
|
-
|
|
369
|
-
interface BackgroundSubagentsResolution {
|
|
370
|
-
policy: BackgroundSubagentsPolicy;
|
|
371
|
-
source: BackgroundSubagentsSource;
|
|
372
|
-
/** The deciding file was present but failed the strict decode. */
|
|
373
|
-
malformed: boolean;
|
|
374
|
-
projectFile: string;
|
|
375
|
-
globalFile: string;
|
|
376
|
-
projectFileExists: boolean;
|
|
377
|
-
globalFileExists: boolean;
|
|
378
|
-
/** The raw env value, reported even when it is unrecognized and inert. */
|
|
379
|
-
envValue: string | undefined;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
interface LoadBackgroundSubagentsOptions {
|
|
383
|
-
/** Override the config home directory (used in tests to avoid touching ~/.pi). */
|
|
384
|
-
gentlePiConfigHome?: string;
|
|
385
|
-
/** Override the environment lookup (used in tests). */
|
|
386
|
-
env?: Record<string, string | undefined>;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const BACKGROUND_SUBAGENTS_SCHEMA = "gentle-pi.background-subagents/v1";
|
|
390
|
-
const BACKGROUND_SUBAGENTS_FILE = "background-subagents.json";
|
|
391
|
-
|
|
392
378
|
const DEFAULT_BACKGROUND_SUBAGENTS_RENDERING: BackgroundSubagentsRendering = {
|
|
393
379
|
policy: "off",
|
|
394
380
|
capability: "absent",
|
|
395
381
|
};
|
|
396
382
|
|
|
397
|
-
/**
|
|
398
|
-
* Strict decode of {"schema":"gentle-pi.background-subagents/v1","policy":"on"|"off"}.
|
|
399
|
-
* Any malformed shape (bad JSON, wrong schema, unknown keys, invalid policy)
|
|
400
|
-
* returns undefined so the caller fails closed to "off".
|
|
401
|
-
*/
|
|
402
|
-
function parseBackgroundSubagentsPolicyFile(
|
|
403
|
-
raw: string,
|
|
404
|
-
): BackgroundSubagentsPolicy | undefined {
|
|
405
|
-
let parsed: unknown;
|
|
406
|
-
try {
|
|
407
|
-
parsed = JSON.parse(raw);
|
|
408
|
-
} catch {
|
|
409
|
-
return undefined;
|
|
410
|
-
}
|
|
411
|
-
if (!isRecord(parsed)) return undefined;
|
|
412
|
-
if (parsed.schema !== BACKGROUND_SUBAGENTS_SCHEMA) return undefined;
|
|
413
|
-
if (parsed.policy !== "on" && parsed.policy !== "off") return undefined;
|
|
414
|
-
if (Object.keys(parsed).length !== 2) return undefined;
|
|
415
|
-
return parsed.policy;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Resolve the background-subagents policy AND the source that decided it.
|
|
420
|
-
*
|
|
421
|
-
* Resolution order (first hit wins, mirroring loadRuntimeGuardrailsConfig):
|
|
422
|
-
* 1. Project file `${cwd}/.pi/gentle-ai/background-subagents.json`
|
|
423
|
-
* 2. Global file `${configHome}/background-subagents.json`
|
|
424
|
-
* (configHome honors GENTLE_PI_CONFIG_HOME, default ~/.pi/gentle-ai)
|
|
425
|
-
* 3. Env var GENTLE_PI_BACKGROUND_SUBAGENTS ("on" | "off")
|
|
426
|
-
* 4. Default "off"
|
|
427
|
-
*
|
|
428
|
-
* A present-but-malformed file fails closed to "off" instead of falling
|
|
429
|
-
* through to a lower-priority source, and it stays attributed to that file:
|
|
430
|
-
* "off decided by a broken project file" and "off by default" are different
|
|
431
|
-
* situations, and only the first one is a mistake to fix.
|
|
432
|
-
*
|
|
433
|
-
* Four sources with first-hit-wins is exactly the shape that makes an edit
|
|
434
|
-
* look like it did nothing, so the deciding source is part of the result
|
|
435
|
-
* rather than something a caller has to re-derive.
|
|
436
|
-
*/
|
|
437
|
-
function resolveBackgroundSubagentsPolicy(
|
|
438
|
-
cwd: string,
|
|
439
|
-
options: LoadBackgroundSubagentsOptions = {},
|
|
440
|
-
): BackgroundSubagentsResolution {
|
|
441
|
-
const env = options.env ?? process.env;
|
|
442
|
-
const envValue = env.GENTLE_PI_BACKGROUND_SUBAGENTS;
|
|
443
|
-
let projectFile = "";
|
|
444
|
-
let globalFile = "";
|
|
445
|
-
try {
|
|
446
|
-
const configHome = options.gentlePiConfigHome ?? gentleAiConfigHome();
|
|
447
|
-
projectFile = join(cwd, ".pi", "gentle-ai", BACKGROUND_SUBAGENTS_FILE);
|
|
448
|
-
globalFile = join(configHome, BACKGROUND_SUBAGENTS_FILE);
|
|
449
|
-
const projectFileExists = existsSync(projectFile);
|
|
450
|
-
const globalFileExists = existsSync(globalFile);
|
|
451
|
-
const locations = { projectFile, globalFile, projectFileExists, globalFileExists, envValue };
|
|
452
|
-
for (const [source, path, present] of [
|
|
453
|
-
["project_file", projectFile, projectFileExists],
|
|
454
|
-
["global_file", globalFile, globalFileExists],
|
|
455
|
-
] as const) {
|
|
456
|
-
if (!present) continue;
|
|
457
|
-
let decoded: BackgroundSubagentsPolicy | undefined;
|
|
458
|
-
try {
|
|
459
|
-
decoded = parseBackgroundSubagentsPolicyFile(readFileSync(path, "utf8"));
|
|
460
|
-
} catch {
|
|
461
|
-
// Unreadable is indistinguishable from unusable at this layer, and
|
|
462
|
-
// both must fail closed on the file that claimed the decision.
|
|
463
|
-
decoded = undefined;
|
|
464
|
-
}
|
|
465
|
-
return decoded === undefined
|
|
466
|
-
? { policy: "off", source, malformed: true, ...locations }
|
|
467
|
-
: { policy: decoded, source, malformed: false, ...locations };
|
|
468
|
-
}
|
|
469
|
-
if (envValue === "on" || envValue === "off") {
|
|
470
|
-
return { policy: envValue, source: "environment", malformed: false, ...locations };
|
|
471
|
-
}
|
|
472
|
-
return { policy: "off", source: "default", malformed: false, ...locations };
|
|
473
|
-
} catch {
|
|
474
|
-
return {
|
|
475
|
-
policy: "off",
|
|
476
|
-
source: "default",
|
|
477
|
-
malformed: false,
|
|
478
|
-
projectFile,
|
|
479
|
-
globalFile,
|
|
480
|
-
projectFileExists: false,
|
|
481
|
-
globalFileExists: false,
|
|
482
|
-
envValue,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* The effective policy alone, for callers that do not report a source.
|
|
489
|
-
* It delegates so the loader and the resolver can never disagree.
|
|
490
|
-
*/
|
|
491
|
-
function loadBackgroundSubagentsPolicy(
|
|
492
|
-
cwd: string,
|
|
493
|
-
options: LoadBackgroundSubagentsOptions = {},
|
|
494
|
-
): BackgroundSubagentsPolicy {
|
|
495
|
-
return resolveBackgroundSubagentsPolicy(cwd, options).policy;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
383
|
/** Write the global policy file, creating the config home when needed. */
|
|
499
384
|
function writeGlobalBackgroundSubagentsPolicy(
|
|
500
385
|
policy: BackgroundSubagentsPolicy,
|
|
@@ -1388,14 +1273,14 @@ Organic Driven Development (ODD) is the predefined workflow of this orchestrator
|
|
|
1388
1273
|
2. **Explore.** Explore existing code and requirements first, proportionately to the request, before proposing or writing anything.
|
|
1389
1274
|
3. **Resolve uncertainty.** Recommend optional research only for a named uncertainty; ask one focused user question only for a real unresolved product decision, then stop and wait; use at most one scoped read-only assumption challenge for a high-consequence unproven premise.
|
|
1390
1275
|
4. **Classify.** The work is substantial when exploration yields two or more meaningful implementation steps, or progress worth recovering after an interruption. Small, understood work stays small and creates no durable task artifacts.
|
|
1391
|
-
5. **Track before the first write.** For substantial authorized implementation, create \`odd/tasks/<feature-name>.md\` and its Engram mirror \`odd/<feature-name>/tasks\` automatically, before the first source write
|
|
1392
|
-
6. **Implement task by task.** Route each task through the orchestrator's Work Routing Ladder, with the configured TDD mode and applicable checks. Check an item off only after its outcome and checks were observed; update the file and
|
|
1393
|
-
7. **Close.** Report the verified outcome, every failed, skipped, or pending check, and the next step.
|
|
1276
|
+
5. **Track before the first write.** For substantial authorized implementation, create \`odd/tasks/<feature-name>.md\` and its Engram mirror \`odd/<feature-name>/tasks\` automatically, then create or rebuild the visible \`todo\` list from the reconciled feature tasks, all before the first source write and without asking permission for tasks or storage. Tell the user in one line which feature document was created and how many tasks it holds.
|
|
1277
|
+
6. **Implement task by task.** Route each task through the orchestrator's Work Routing Ladder, with the configured TDD mode and applicable checks. Check an item off only after its outcome and checks were observed; update the file, mirror, and visible \`todo\` projection after every task transition and material plan change. 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; record the commit identity in the feature document as evidence. Work-unit commits on the feature branch are part of authorized substantial ODD implementation; push, pull request creation, and merge remain the user's decisions.
|
|
1278
|
+
7. **Close.** Report the verified outcome, every failed, skipped, or pending check, 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; native review runs only under the user-owned RDD switch.
|
|
1394
1279
|
Resume an interrupted feature with \`mem_context\`, then project- and feature-scoped \`mem_search\`, then \`mem_get_observation\` for the full document, then the task file itself; reconcile before continuing the next unfinished task. Detail for steps 3–7: \`orchestrator-delegation.md\` and \`orchestrator-memory.md\`.
|
|
1395
1280
|
|
|
1396
1281
|
Harness principles:
|
|
1397
1282
|
- el Gentleman is not prompt engineering. It is runtime discipline around powerful agents.
|
|
1398
|
-
- Organic Driven Development (ODD) is the predefined workflow for every request: authorize, explore, resolve uncertainty, classify, track substantial work before the first write, implement task by task with proportionate checks, close. SDD is explicitly selected.
|
|
1283
|
+
- Organic Driven Development (ODD) is the predefined workflow for every request: authorize, explore, resolve uncertainty, classify, track substantial work before the first write, implement task by task with proportionate checks, close each task with a work-unit commit, and close. SDD is explicitly selected.
|
|
1399
1284
|
- Clarify scope, constraints, acceptance criteria, and non-goals before implementation.
|
|
1400
1285
|
- Use subagents when available for exploration, planning, implementation, and review, while keeping one parent session responsible for orchestration.
|
|
1401
1286
|
- Keep writes single-threaded unless the user explicitly approves parallel write isolation.
|
|
@@ -4805,7 +4690,7 @@ const REVIEW_CONTROLLER_PARAMETERS = {
|
|
|
4805
4690
|
},
|
|
4806
4691
|
input: {
|
|
4807
4692
|
type: "string",
|
|
4808
|
-
description: "A JSON-serialized object string, not a nested object. New native ordinary START uses {\"mode\":\"ordinary\"}; answer-consent uses exactly {\"consentBinding\":\"<opaque id>\",\"answer\":\"granted|declined\"}. Ordinary provider capture belongs only to gentle_review_capture. An explicit baseRef requires committedOnly: true and requests a committed range, while repository-local policyPath remains optional. ASSESS accepts an optional object with baseRef, committedOnly, writerModelId, writerEffort, and nativeReviewOutcome (gentle-pi#662/#668); omitting writerModelId and writerEffort assesses the ambient working tree and fails closed to a small writer profile (never large) because the writer's actual profile is unknown to this call. nativeReviewOutcome (one of closed, declined, unavailable, unknown) tells ASSESS whether the native review actually closed for this candidate: when Receipt-driven development reads on but the review was declined for this candidate, is unavailable, or its outcome is unknown, ASSESS falls back to the exact risk-gated plan it returns when RDD is off, re-enabling the separate verifier -- a decline is candidate-scoped and never lowers the bar below the RDD-off path. Omitting it lets ASSESS try to derive declined/unavailable from what this process itself recorded for this exact candidate (never a different one, and never from repository state alone), failing closed to unknown when it cannot; `closed` is never derived -- pass it explicitly, and only right after acknowledging the approved review for this same candidate. The returned outcome_source (explicit|derived|unknown) says which of these produced the value. Legacy controller input remains separate.",
|
|
4693
|
+
description: "A JSON-serialized object string, not a nested object. New native ordinary START uses {\"mode\":\"ordinary\"}; answer-consent uses exactly {\"consentBinding\":\"<opaque id>\",\"answer\":\"granted|declined\"}. Ordinary provider capture belongs only to gentle_review_capture. An explicit baseRef requires committedOnly: true and requests a committed range, while repository-local policyPath remains optional. baseRef must be HEAD, a full 40- or 64-character commit id, or a ref name; abbreviated commit ids are rejected as base-ref-unresolvable. ASSESS accepts an optional object with baseRef, committedOnly, writerModelId, writerEffort, and nativeReviewOutcome (gentle-pi#662/#668); omitting writerModelId and writerEffort assesses the ambient working tree and fails closed to a small writer profile (never large) because the writer's actual profile is unknown to this call. nativeReviewOutcome (one of closed, declined, unavailable, unknown) tells ASSESS whether the native review actually closed for this candidate: when Receipt-driven development reads on but the review was declined for this candidate, is unavailable, or its outcome is unknown, ASSESS falls back to the exact risk-gated plan it returns when RDD is off, re-enabling the separate verifier -- a decline is candidate-scoped and never lowers the bar below the RDD-off path. Omitting it lets ASSESS try to derive declined/unavailable from what this process itself recorded for this exact candidate (never a different one, and never from repository state alone), failing closed to unknown when it cannot; `closed` is never derived -- pass it explicitly, and only right after acknowledging the approved review for this same candidate. The returned outcome_source (explicit|derived|unknown) says which of these produced the value. Legacy controller input remains separate.",
|
|
4809
4694
|
},
|
|
4810
4695
|
outputPath: { type: "string", description: "Retired with legacy bundle export; ignored. Export returns legacy-operation-retired." },
|
|
4811
4696
|
inputPath: { type: "string", description: "Repository-local JSON input file for the separate legacy controller flow (alternative to input). Legacy bundle import is retired." },
|
|
@@ -5840,6 +5725,12 @@ function validateNativeStartUntrackedSelection(value: Record<string, unknown>):
|
|
|
5840
5725
|
};
|
|
5841
5726
|
}
|
|
5842
5727
|
|
|
5728
|
+
const BASE_REF_REJECTION_REASONS = new Set(["base-ref-unresolvable", "base-ref-ambiguous", "base-ref-moved", "base-ref-invalid"]);
|
|
5729
|
+
|
|
5730
|
+
function baseRefRejectionHint(reason: string): { hint?: string } {
|
|
5731
|
+
return BASE_REF_REJECTION_REASONS.has(reason) ? { hint: BASE_REF_ACCEPTED_FORMS } : {};
|
|
5732
|
+
}
|
|
5733
|
+
|
|
5843
5734
|
function nativeStartRejection(reason: string, field?: string): Record<string, unknown> {
|
|
5844
5735
|
return {
|
|
5845
5736
|
operation: REVIEW_CONTROLLER_OPERATION.START,
|
|
@@ -5861,6 +5752,7 @@ function nativeStartRejection(reason: string, field?: string): Record<string, un
|
|
|
5861
5752
|
: "native-start-policy-path-invalid",
|
|
5862
5753
|
reason,
|
|
5863
5754
|
...(field === undefined ? {} : { field }),
|
|
5755
|
+
...baseRefRejectionHint(reason),
|
|
5864
5756
|
...nativeStartPreAuthorityRejection(),
|
|
5865
5757
|
};
|
|
5866
5758
|
}
|
|
@@ -5872,6 +5764,7 @@ function nativeStatusInputRejection(reason: string, field?: string): Record<stri
|
|
|
5872
5764
|
outcome: "native-status-input-invalid",
|
|
5873
5765
|
reason,
|
|
5874
5766
|
...(field === undefined ? {} : { field }),
|
|
5767
|
+
...baseRefRejectionHint(reason),
|
|
5875
5768
|
mutation_performed: false,
|
|
5876
5769
|
mutation_outcome: "none",
|
|
5877
5770
|
};
|
|
@@ -8595,6 +8488,8 @@ export const __testing = {
|
|
|
8595
8488
|
loadRuntimeGuardrailsConfig,
|
|
8596
8489
|
buildGentlePrompt,
|
|
8597
8490
|
nativeStatusUnsupported,
|
|
8491
|
+
nativeStartRejection,
|
|
8492
|
+
nativeStatusInputRejection,
|
|
8598
8493
|
executeReviewControllerOperation,
|
|
8599
8494
|
executeReviewCaptureOperation,
|
|
8600
8495
|
executeReviewCaptureGroupOperation,
|
package/extensions/pi-pretty.ts
CHANGED
|
@@ -61,7 +61,19 @@ export default async function gentlePiPrettyExtension(
|
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
63
|
});
|
|
64
|
-
|
|
64
|
+
// pi-pretty's hidden-thinking API is global. Its best-effort private per-row
|
|
65
|
+
// patch can miss the host's actual component class and then animate every
|
|
66
|
+
// historical Thinking row. Gentle Shell chooses the robust presentation:
|
|
67
|
+
// keep collapsed labels static while preserving the separate working frame.
|
|
68
|
+
const previousThinkingIndicator = process.env.PRETTY_THINKING_INDICATOR;
|
|
69
|
+
process.env.PRETTY_THINKING_INDICATOR = "off";
|
|
70
|
+
let result: unknown;
|
|
71
|
+
try {
|
|
72
|
+
result = await extension(delegated, deps);
|
|
73
|
+
} finally {
|
|
74
|
+
if (previousThinkingIndicator === undefined) delete process.env.PRETTY_THINKING_INDICATOR;
|
|
75
|
+
else process.env.PRETTY_THINKING_INDICATOR = previousThinkingIndicator;
|
|
76
|
+
}
|
|
65
77
|
// GentlePromptEditor already carries the live working state in its frame.
|
|
66
78
|
// Hide Pi's separate loader row to avoid repeating Thinking above the input;
|
|
67
79
|
// transcript thinking blocks remain untouched as historical reasoning markers.
|