@hobin/developer 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -48,10 +48,10 @@ Unify the duplicate schedule types and conversion logic without changing existin
48
48
  | Command | Effect |
49
49
  | --- | --- |
50
50
  | `/develop` | Open the interactive Developer control menu |
51
- | `/develop on` | Enable adaptive routing without restricting Pi's existing tools |
52
- | `/develop strict` | Enable routing and withhold Pi's built-in mutation tools until a direct route is active |
51
+ | `/develop on` | Enable adaptive routing; tools stay active unless a `before-direct` question gate is open |
52
+ | `/develop strict` | Gate shell execution behind an active route and structured artifact mutation behind a direct route |
53
53
  | `/develop status` | Inspect current branch state in a read-only panel |
54
- | `/develop questions` | Choose an unresolved question and prepare an editable revisit prompt |
54
+ | `/develop questions` | Choose an unresolved question, answer it or request investigation, and submit it to Pi |
55
55
  | `/develop off` | Disable the protocol and clear current protocol state |
56
56
 
57
57
  Explicit command arguments participate in Pi's completion UI. In interactive
@@ -71,14 +71,18 @@ pi --develop-mode strict
71
71
 
72
72
  | Mode | Routing | Built-in mutation tools | Best fit |
73
73
  | --- | --- | --- | --- |
74
- | `on` | Adaptive | Unchanged | Normal product development |
75
- | `strict` | Adaptive | Pi built-in `edit`, `write`, and `bash` require an active `direct` route | High-risk changes and workflow-discipline experiments |
74
+ | `on` | Adaptive | Unchanged except while a `before-direct` question gate is open | Normal product development |
75
+ | `strict` | Adaptive | `bash` is available during skill/direct routes; Pi built-in `edit` and `write` require an active `direct` route and no `before-direct` gate | High-risk changes and workflow-discipline experiments |
76
76
  | `off` | Disabled | Developer makes no changes to the active set | Normal Pi behavior without the protocol |
77
77
 
78
- Strict mode is a workflow-integrity gate, not a security sandbox. It recognizes
79
- Pi built-ins from their provenance and does not claim to classify or block
80
- mutation-capable tools registered by other extensions. It also preserves
81
- unrelated active tools and does not force-enable read tools the user disabled.
78
+ Strict mode and question gates are workflow-integrity controls, not a security
79
+ sandbox. A skill route receives the shell execution lane needed for repository
80
+ inspection and verifier execution, while structured `edit`/`write` mutation
81
+ remains direct-only. Shell commands are not parsed as a security language; skill
82
+ contracts prohibit artifact mutation, and adversarial evaluation checks the
83
+ workspace boundary. Developer recognizes Pi built-ins from their provenance,
84
+ preserves unrelated active tools, and does not force-enable tools the user
85
+ disabled.
82
86
 
83
87
  ## How a request runs
84
88
 
@@ -93,6 +97,10 @@ Developer adds two model-facing protocol tools:
93
97
  4. `developer_record_judgment` closes the route with a status, result, evidence,
94
98
  artifacts, and any newly opened questions. Developer then routes again from
95
99
  the stable landing before another movement.
100
+ 5. Consecutive direct routes remain valid. To prevent routing by momentum, a
101
+ direct route that follows a direct judgment must cite the previous landing
102
+ evidence and record the plausible skill routes reconsidered plus why they add
103
+ no useful judgment at that point.
96
104
 
97
105
  The conditional default topology is:
98
106
 
@@ -121,12 +129,28 @@ Developer uses different Pi surfaces for different information:
121
129
 
122
130
  - The footer contains only global mode, protocol state, and current route target.
123
131
  - A compact widget appears only while a route or unresolved question exists.
124
- - `/develop` uses a `SelectList` action menu.
125
- - `/develop status` opens a branch-grounded, read-only status panel.
126
- - `/develop questions` uses stable question IDs and only prepares editor text;
127
- selection alone never mutates protocol state.
128
- - Protocol tool rows show compact status by default and evidence details when
129
- expanded with the user's configured Pi keybinding.
132
+ - `/develop` uses a `SelectList` action menu that exposes pending questions directly instead of hiding them behind a second question menu.
133
+ - `/develop status` opens a branch-grounded, read-only status panel with recent
134
+ route/judgment history and the alternatives recorded for consecutive direct work.
135
+ - `/develop questions` uses stable internal question IDs. A sole question opens
136
+ directly; multiple questions use one selector before the answer/evidence editor.
137
+ Editor Escape returns to the previous root or multi-question selector; a sole
138
+ direct editor closes because it has no parent selector. Cancelling leaves
139
+ protocol state unchanged, while submitting sends the resolution request to Pi.
140
+ - A newly opened, answerable user question that gates direct work is pushed to the
141
+ TUI immediately. The user can answer now or leave it open. When the question
142
+ supplies a `choice-form` `responseSpec`, Answer now renders every required
143
+ decision as an individual option control, collects option-specific detail, and
144
+ provides a review/edit step before submission. The answer still requires a
145
+ focused judgment and explicit `question_updates` resolution.
146
+ - Selection and status overlays use most of the terminal, keep a stable rendered
147
+ height while navigating or scrolling, and remain bounded on small terminals.
148
+ They support mouse-wheel/trackpad scrolling, arrow keys, Page Up/Down, and
149
+ Home/End. Terminal mouse reporting is enabled only while the overlay is open
150
+ and is released when it closes.
151
+ - Protocol tool rows show compact status by default and higher-contrast evidence
152
+ details when expanded with the user's configured Pi keybinding. They render
153
+ without Pi's default full tool-row background.
130
154
 
131
155
  RPC, JSON, and print modes keep the same protocol semantics without depending on
132
156
  terminal components.
@@ -137,8 +161,11 @@ terminal components.
137
161
  | --- | --- |
138
162
  | `idle` | No active route and no unresolved Developer question |
139
163
  | `needs-judgment` | One route is active and must be closed with a judgment |
140
- | `needs-evidence` | At least one question remains open for evidence |
141
- | `blocked` | At least one pending question carries a recorded blocker |
164
+ | `needs-evidence` | At least one agent- or environment-owned evidence question remains open |
165
+ | `needs-answer` | At least one user-owned answer or decision remains open |
166
+ | `needs-routing` | A direct stable landing must be re-observed and routed again |
167
+ | `needs-verification` | Changed artifacts still need a resolved verify judgment |
168
+ | `blocked` | A question is unavailable or explicitly gates direct work |
142
169
 
143
170
  These are routing states, not product-completion claims. In particular:
144
171
 
@@ -146,12 +173,50 @@ These are routing states, not product-completion claims. In particular:
146
173
  - A resolved `specify` judgment is not user acceptance.
147
174
  - A resolved `verify` judgment is not timeless proof after later changes.
148
175
 
149
- Pending questions receive stable internal IDs, but users do not type them.
150
- Selecting `/develop questions` focuses the question in branch state; the next
151
- route automatically associates that focus. A sole pending question or an exact
152
- question match is also associated automatically. Resolved and not-applicable
153
- judgments remove the associated question immediately; needs-evidence and blocked
154
- judgments retain the same identity.
176
+ Pending questions receive stable internal IDs, but users do not type them. Each
177
+ question records:
178
+
179
+ - `resolutionOwner`: `agent`, `user`, or `environment`;
180
+ - `gate`: `none`, `before-direct`, or `before-completion`;
181
+ - `resolutionCriteria`: the observable evidence or answer that closes it;
182
+ - optional `context`: detailed Markdown choices, examples, or constraints shown
183
+ when the question is revisited without repeating that detail in every protocol prompt;
184
+ - optional user-owned `responseSpec`: a bounded `choice-form` with required
185
+ single-choice fields and optional per-option detail prompts.
186
+
187
+ A producer should use `response_spec` when a user must answer finite decisions
188
+ such as A, B1–B4, C, and so on. Each decision becomes one field; the TUI does not
189
+ infer controls by parsing Markdown. Options such as A3 or G3 that need additional
190
+ input declare `detail_prompt`. Missing or malformed replay data falls back to the
191
+ freeform editor without dropping the pending question.
192
+
193
+ Selecting `/develop questions` opens structured controls when a valid user
194
+ `responseSpec` exists. Otherwise it opens the owner-specific editor: user
195
+ questions ask for the required decision, agent questions ask Pi to investigate,
196
+ and environment questions request access or an external observation. Submitting
197
+ focuses the question in branch state; an explicit ID, focus, or exact question
198
+ match associates the next route. Selection alone never closes it.
199
+
200
+ Every judgment rechecks all pending questions. `question_updates` can resolve an
201
+ unfocused question when implementation, tests, inspection, user input, or an
202
+ environment observation naturally supplies its criteria. A focused question
203
+ must receive an explicit update: resolve or dismiss it with concrete basis,
204
+ retain it as open or blocked, or close the broad parent while opening narrower
205
+ children. Resolved and not-applicable updates remove the question with recorded
206
+ basis; open or blocked updates preserve its identity. A `before-direct` question blocks both direct
207
+ routes and Pi built-in mutation tools even in adaptive mode. A
208
+ `before-completion` question allows investigation and implementation but keeps
209
+ the protocol non-idle and prevents verification debt from being cleared as a
210
+ completion claim.
211
+
212
+ A resolved or not-applicable judgment may preserve a distinct follow-up question:
213
+ finishing the routed judgment does not imply that no later work was discovered.
214
+ It may not reopen its own normalized question under a resolved status; that route
215
+ must remain needs-evidence/blocked or explicitly refine a focused parent instead.
216
+
217
+ When a judgment replaces a broad unresolved question with more specific evidence
218
+ questions, only the actionable children remain. Equivalent question wording is
219
+ deduplicated while preserving the existing identity.
155
220
 
156
221
  ## Skills
157
222
 
@@ -162,7 +227,7 @@ or the user may invoke one directly with `/skill:<name>`.
162
227
  | --- | --- |
163
228
  | `specify` | Product meaning, scope, invariants, risks, and blocking unknowns |
164
229
  | `model` | Condition spaces, contracts, replacement, transitions, guarantees, and verification targets |
165
- | `sketch` | Data-driven skeletons, abstraction and composition boundaries, state, responsibility, and variation |
230
+ | `sketch` | Inspectable code/pseudocode skeletons, case and interface tables, boundary/flow maps, state, responsibility, and variation |
166
231
  | `signal` | Evidence-backed structural movement and model-code mismatch |
167
232
  | `naming-judgment` | Domain sense, honest effects, and change-preserving names |
168
233
  | `abstraction-review` | Whether a candidate should be kept, revised, split, rejected, or deferred |
@@ -171,6 +236,19 @@ or the user may invoke one directly with `/skill:<name>`.
171
236
  | `visualize` | The smallest visual surface that lowers judgment cost |
172
237
  | `adversarial-eval` | Finite, escalating attempts to falsify a skill or implementation claim |
173
238
 
239
+ Each leaf chooses a surface that matches its inspection problem instead of
240
+ returning undifferentiated prose: contract and scope tables for `specify`, case
241
+ or transition models for `model`, code/interface/check surfaces for `sketch`,
242
+ artifact comparisons for `signal`, rename maps for `naming-judgment`, review
243
+ cards and boundaries for `abstraction-review`, timing matrices for `schedule`,
244
+ evidence matrices for `verify`, escalation matrices for `adversarial-eval`, and
245
+ a completed visual artifact for `visualize` when a visual is warranted. Simple
246
+ judgments may remain compact when prose is genuinely clearer.
247
+
248
+ Skill judgment results preserve those surfaces as Markdown. Expanded protocol
249
+ rows render tables and code blocks through Pi's Markdown component rather than
250
+ flattening them into dim text.
251
+
174
252
  Pi's loaded resource metadata is authoritative. If package configuration filters
175
253
  or disables a skill, Developer cannot route to it even if its file exists in the
176
254
  npm package.
@@ -200,19 +278,46 @@ disabled, or replaced through resource configuration.
200
278
  ## State, branches, and compaction
201
279
 
202
280
  Mode changes are stored as Pi custom session entries. Routes and judgments are
203
- stored in tool-result details. Developer reconstructs state from the current
204
- session branch on startup and tree navigation, so a fork inherits only the
205
- events on its branch.
281
+ stored in tool-result details. Developer replays the current branch through an
282
+ XState v5 machine on startup and tree navigation, so a fork inherits only the
283
+ events on its branch. Parallel machine regions keep mode, route, question gates,
284
+ framing debt, and verification debt explicit; transition guards reject a direct
285
+ route while a `before-direct` question remains.
206
286
 
207
- The current event contract is `developer/v3`. Legacy `developer/v1` and
208
- `developer/v2` routing history can be replayed, but new framing and verification
209
- obligations are not retroactively inferred.
287
+ ```text
288
+ developerMachine (parallel)
289
+ ├── mode: off | on | strict
290
+ ├── route: idle | judgment | direct
291
+ ├── questions: clear | open
292
+ ├── directGate: clear | blocked
293
+ ├── completionGate: clear | blocked
294
+ ├── checkpoint: ready | required
295
+ ├── framing: clear | required
296
+ └── verification: current | required
297
+ ```
210
298
 
211
- Developer uses Pi's normal compaction. Each new agent turn receives current
212
- protocol state, and route results place identity and recovery metadata before
213
- potentially long skill instructions. Tool output is checked against Pi's standard size
214
- limits before state changes are committed. At most twenty pending questions may
215
- remain in current state.
299
+ Judgment routes carry the `execute` tag, direct routes carry `execute` and
300
+ `mutate`, and question/debt regions expose blocking tags. Every direct judgment
301
+ moves the checkpoint to `required`; the next accepted route returns it to
302
+ `ready`. Tool availability, runtime call guards, status, and direct-transition
303
+ eligibility are derived from the same machine snapshot.
304
+
305
+ The current event contract is `developer/v4`. Legacy `developer/v1` through
306
+ `developer/v3` routing history can be replayed. Legacy questions receive
307
+ conservative owner, gate, and resolution-criteria defaults rather than guessed
308
+ product decisions.
309
+
310
+ Developer deliberately leaves compaction ownership to Pi. It does not trigger,
311
+ cancel, or replace threshold/overflow compaction, so it cannot override the
312
+ user's Pi settings or race another extension. Configure earlier compaction with
313
+ Pi's `compaction.reserveTokens` and `compaction.keepRecentTokens` settings when
314
+ a large-context model reaches its limit too abruptly.
315
+
316
+ Each new agent turn receives current protocol state, and route results place
317
+ identity and recovery metadata before potentially long skill instructions. That
318
+ makes the active route recoverable after Pi compacts normally. Tool output is
319
+ checked against Pi's standard size limits before state changes are committed.
320
+ At most twenty pending questions may remain in current state.
216
321
 
217
322
  ## Update, configure, and remove
218
323
 
@@ -240,10 +345,11 @@ pinning, and security behavior.
240
345
  ```text
241
346
  extensions/
242
347
  ├── developer.ts # command, protocol tools, events, and Pi integration
348
+ ├── machine.ts # XState v5 parallel regions, guards, transitions, and tags
243
349
  ├── references/ # direct execution profiles loaded through tool results
244
- ├── state.ts # replayable developer/v2 branch state
350
+ ├── state.ts # developer/v4 event normalization and branch replay
245
351
  ├── skills.ts # loaded-skill filtering and instruction rendering
246
- ├── tool-policy.ts # strict-mode active-tool reconciliation
352
+ ├── tool-policy.ts # machine-derived execution and mutation access policy
247
353
  └── tui.ts # selectors, widget, status panel, and prompt preparation
248
354
  skills/ # ten independently loadable Pi skills
249
355
  SOURCES.md # source-to-capability maintenance trace
@@ -280,8 +386,37 @@ a model.
280
386
 
281
387
  `check` validates package structure and deterministic behavior. `eval` launches
282
388
  the real Pi RPC surface without a model and covers package resources, commands,
283
- mode state, and strict tool gating. Maintainers can use `eval:json` and the live
284
- fixtures for model-dependent scenarios.
389
+ mode state, and strict tool gating. These are release-gating checks.
390
+
391
+ Model-dependent runs are probabilistic evaluations rather than binary tests:
392
+
393
+ ```sh
394
+ PI_CODING_AGENT_DIR=~/.pi/agent \
395
+ DEVELOPER_EVAL_FIXTURE=agent-before-direct-evidence-gate \
396
+ DEVELOPER_EVAL_TRIALS=5 \
397
+ pnpm --filter @hobin/developer eval:live
398
+ ```
399
+
400
+ Use `eval:live:json` for the JSON transport. Each report separates the hard
401
+ admissibility envelope from routing quality: structurally valid runs must use an
402
+ admissible route, preserve mutation/question/completion invariants, satisfy
403
+ hidden artifact checks, include required semantic terms, and end in a declared
404
+ outcome. Among accepted runs, `preferredFirstOwners` measures better versus
405
+ merely admissible routing. Reports include acceptance and preference rates,
406
+ 95% Wilson intervals, inadmissible results, rejected protocol attempts, budget
407
+ exhaustion, and environment failures. Any accepted inadmissible result makes the
408
+ evaluation command fail; ordinary admissible preference variation remains a
409
+ rate. A single model sample is not release evidence.
410
+
411
+ Live fixtures classify terminal outcomes as `settled-unchanged`, `pending`,
412
+ `changed-paused`, or `changed-verified`. An eval-only observer compares
413
+ product-file snapshots around bash/edit/write calls and rejects artifact changes
414
+ outside a direct route. Dedicated fixtures sample a deliberately paused direct
415
+ landing and an agent-owned before-direct question resolved through a non-direct
416
+ bash evidence route; their structural guarantees also have deterministic machine,
417
+ extension, trace, filesystem, and outcome tests. RPC and JSON runners share
418
+ route, tool-call, tool-error, wall-clock, and no-progress budgets and preserve a
419
+ trace for diagnosis.
285
420
 
286
421
  ## License
287
422