@davidorex/pi-project-workflows 0.9.2 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidorex/pi-project-workflows",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Pi extensions for structured project state, workflow orchestration, and behavior monitoring — single install for all three",
5
5
  "license": "MIT",
6
6
  "author": "David Ryan",
@@ -29,8 +29,8 @@
29
29
  ]
30
30
  },
31
31
  "dependencies": {
32
- "@davidorex/pi-project": "^0.9.2",
33
- "@davidorex/pi-workflows": "^0.9.2",
34
- "@davidorex/pi-behavior-monitors": "^0.9.2"
32
+ "@davidorex/pi-project": "^0.10.0",
33
+ "@davidorex/pi-workflows": "^0.10.0",
34
+ "@davidorex/pi-behavior-monitors": "^0.10.0"
35
35
  }
36
36
  }
@@ -63,16 +63,20 @@ List patterns for a behavior monitor.
63
63
  </tools_reference>
64
64
 
65
65
  <commands_reference>
66
+ <command name="/work-quality">
67
+ On-demand work quality analysis
68
+ </command>
69
+
66
70
  <command name="/monitors">
67
71
  Manage behavior monitors
68
72
 
69
- Subcommands: `on`, `off`, `help`, `fragility`, `response-style`
73
+ Subcommands: `on`, `off`, `help`, `fragility`, `hedge`, `work-quality`
70
74
  </command>
71
75
 
72
76
  </commands_reference>
73
77
 
74
78
  <events>
75
- `session_start`, `session_switch`, `agent_end`, `turn_start`, `message_end`
79
+ `session_start`, `agent_end`, `turn_start`, `message_end`, `turn_end`
76
80
  </events>
77
81
 
78
82
  <bundled_resources>
@@ -111,7 +115,7 @@ Built-in placeholders (always available, not in `classify.context`):
111
115
  - `every(N)` — Fire every Nth activation (counter resets when user text changes)
112
116
  - `tool(name)` — Fire only if specific named tool called since last user message
113
117
 
114
- **Events:** `message_end`, `turn_end`, `agent_end`, `command`
118
+ **Events:** `message_end`, `turn_end`, `agent_end`, `command`, `tool_call`
115
119
 
116
120
  **Verdict Types:** `clean`, `flag`, `new`
117
121
 
@@ -205,9 +209,9 @@ A `.monitor.json` file conforms to `schemas/monitor.schema.json`:
205
209
  "on_flag": {
206
210
  "steer": "Fix the issue.",
207
211
  "write": {
208
- "path": ".workflow/gaps.json",
212
+ "path": ".project/issues.json",
209
213
  "merge": "append",
210
- "array_field": "gaps",
214
+ "array_field": "issues",
211
215
  "template": {
212
216
  "id": "monitor-{finding_id}",
213
217
  "description": "{description}",
@@ -238,7 +242,7 @@ A `.monitor.json` file conforms to `schemas/monitor.schema.json`:
238
242
  |-------|---------|-------------|
239
243
  | `name` | (required) | Monitor identifier. Must be unique across project and global. |
240
244
  | `description` | `""` | Human-readable description. Also used as command description for `event: command` monitors. |
241
- | `event` | `message_end` | When to fire: `message_end`, `turn_end`, `agent_end`, or `command`. |
245
+ | `event` | `message_end` | When to fire: `message_end`, `turn_end`, `agent_end`, `command`, or `tool_call`. `tool_call` fires pre-execution and can block the tool. |
242
246
  | `when` | `always` | Activation condition (see below). |
243
247
  | `ceiling` | `5` | Max consecutive steers before escalation. |
244
248
  | `escalate` | `ask` | At ceiling: `ask` (confirm with user) or `dismiss` (silence for session). |
@@ -272,7 +276,7 @@ Non-main scopes can still write findings to JSON files.
272
276
  | `steer` | Message to inject into conversation. `null` = no steering. Only effective for `scope.target: "main"`. |
273
277
  | `write.path` | JSON file to write findings to. Relative paths resolve from `process.cwd()`, not from the monitor directory. |
274
278
  | `write.merge` | `append` (add to array) or `upsert` (update by matching `id` field). |
275
- | `write.array_field` | Which field in target JSON holds the array (e.g. `"gaps"`, `"findings"`). |
279
+ | `write.array_field` | Which field in target JSON holds the array (e.g. `"issues"`, `"findings"`). |
276
280
  | `write.template` | Template mapping with `{finding_id}`, `{description}`, `{severity}`, `{monitor_name}`, `{timestamp}`. |
277
281
  | `write.schema` | Optional schema path for documentation. Not enforced at runtime. |
278
282
  | `learn_pattern` | If true, add new pattern to patterns file on `new` verdict. |
@@ -425,6 +429,14 @@ corrected response re-triggers monitors naturally for any remaining issues. Moni
425
429
  **Abort**: Classification calls are aborted when the agent ends (via `agent_end` event).
426
430
  Aborted classifications produce no verdict and no action.
427
431
 
432
+ **Pre-execution blocking (tool_call)**: Monitors with `event: "tool_call"` fire before a
433
+ tool executes. The handler receives the pending tool name and arguments, classifies them,
434
+ and can return `{ block: true, reason }` to prevent execution. This is fundamentally
435
+ different from post-hoc steering — the tool never runs. Classification failure is fail-open:
436
+ if the side-channel LLM call errors, the tool is allowed to proceed. The pending tool call
437
+ context (name + arguments) is available as `{{ tool_call_context }}` in classify templates.
438
+ Dedup is not applied to tool_call monitors since each tool call is a distinct event.
439
+
428
440
  **Write action**: Relative `write.path` values resolve from `process.cwd()`, not from the
429
441
  monitor directory. Parent directories are created automatically. If the target file doesn't
430
442
  exist or is unparseable, a fresh object is created. The `upsert` merge strategy matches on
@@ -455,14 +467,14 @@ for other extensions or workflows to invoke classification directly.
455
467
  </commands>
456
468
 
457
469
  <bundled_monitors>
458
- Four example monitors ship in `examples/` and are seeded on first run. Each has a
470
+ Five example monitors ship in `examples/` and are seeded on first run. Each has a
459
471
  Nunjucks classify template in `examples/<name>/classify.md` with iteration-aware
460
472
  acknowledgment support:
461
473
 
462
474
  **fragility** (`message_end`, `when: has_tool_results`)
463
475
  Watches for unaddressed fragilities after tool use — errors, warnings, or broken state the
464
476
  agent noticed but chose not to fix. Steers with "Fix the issue you left behind." Writes
465
- findings to `.workflow/gaps.json` under `category: "fragility"`. Excludes: none. Ceiling: 5.
477
+ findings to `.project/issues.json` under `category: "fragility"`. Excludes: none. Ceiling: 5.
466
478
  12 bundled patterns across categories: avoidance (dismiss-preexisting, not-my-change,
467
479
  blame-environment, workaround-over-root-cause, elaborate-workaround-for-fixable),
468
480
  error-handling (empty-catch, happy-path-only, early-return-on-unexpected,
@@ -480,7 +492,7 @@ deflection (ask-permission, qualify-yesno, counter-question).
480
492
 
481
493
  **work-quality** (`command`, `when: always`)
482
494
  On-demand work quality analysis invoked via `/work-quality`. Analyzes user request, tool
483
- calls, and assistant response for quality issues. Writes findings to `.workflow/gaps.json`
495
+ calls, and assistant response for quality issues. Writes findings to `.project/issues.json`
484
496
  under `category: "work-quality"`. Ceiling: 3.
485
497
  11 bundled patterns across categories: methodology (trial-and-error, symptom-fix,
486
498
  double-edit, edit-without-read, insanity-retry, no-plan), verification (no-verify),
@@ -493,6 +505,12 @@ generic or certainty-language message, steers to improve. Does not write finding
493
505
  are their own artifact. Ceiling: 3.
494
506
  6 bundled patterns across categories: missing-commit (no-commit), message-quality
495
507
  (generic-message, certainty-language, no-context), commit-safety (amend-not-new, force-push).
508
+
509
+ **unauthorized-action** (`tool_call`, `when: has_tool_results`)
510
+ Pre-execution blocker that classifies each pending tool call against user-directed scope.
511
+ If the agent is about to execute a tool the user did not direct, the monitor blocks the
512
+ tool call before execution rather than steering correction after the fact. Uses `tool_call`
513
+ event with `{ block: true, reason }` return to prevent execution. Ceiling: 3.
496
514
  </bundled_monitors>
497
515
 
498
516
  <disabling_monitors>
@@ -523,6 +541,7 @@ should trigger a flag? Translate the user's description into concrete, observabl
523
541
  - Response content issues (trailing questions, lazy options, tone) → `turn_end`, `when: always`
524
542
  - Tool use issues (no commit, no test, bad edits) → `agent_end`, `when: has_file_writes` or `has_tool_results`
525
543
  - Post-action fragility (ignoring errors) → `message_end`, `when: has_tool_results`
544
+ - Pre-execution blocking (unauthorized actions, dangerous commands) → `tool_call`, `when: has_tool_results` or `always`
526
545
  - On-demand analysis → `command`, `when: always`
527
546
 
528
547
  **Step 3: Choose context collectors.** What data does the classifier need to see?
@@ -11,12 +11,12 @@ description: >
11
11
  <tool name="append-block-item">
12
12
  Append an item to an array in a project block file. Schema validation is automatic.
13
13
 
14
- *Append items to project blocks (gaps, decisions, or any user-defined block)*
14
+ *Append items to project blocks (issues, decisions, or any user-defined block)*
15
15
 
16
16
  | Parameter | Type | Required | Description |
17
17
  |-----------|------|----------|-------------|
18
- | `block` | string | yes | Block name (e.g., 'gaps', 'decisions') |
19
- | `arrayKey` | string | yes | Array key in the block (e.g., 'gaps', 'decisions') |
18
+ | `block` | string | yes | Block name (e.g., 'issues', 'decisions') |
19
+ | `arrayKey` | string | yes | Array key in the block (e.g., 'issues', 'decisions') |
20
20
  | `item` | unknown | yes | Item object to append — must conform to block schema |
21
21
  </tool>
22
22
 
@@ -27,9 +27,9 @@ Update fields on an item in a project block array. Finds by predicate field matc
27
27
 
28
28
  | Parameter | Type | Required | Description |
29
29
  |-----------|------|----------|-------------|
30
- | `block` | string | yes | Block name (e.g., 'gaps', 'decisions') |
30
+ | `block` | string | yes | Block name (e.g., 'issues', 'decisions') |
31
31
  | `arrayKey` | string | yes | Array key in the block |
32
- | `match` | object | yes | Fields to match (e.g., { id: 'gap-123' }) |
32
+ | `match` | object | yes | Fields to match (e.g., { id: 'issue-123' }) |
33
33
  | `updates` | object | yes | Fields to update (e.g., { status: 'resolved' }) |
34
34
  </tool>
35
35
 
@@ -40,7 +40,7 @@ Read a project block file as structured JSON.
40
40
 
41
41
  | Parameter | Type | Required | Description |
42
42
  |-----------|------|----------|-------------|
43
- | `block` | string | yes | Block name (e.g., 'gaps', 'tasks', 'requirements') |
43
+ | `block` | string | yes | Block name (e.g., 'issues', 'tasks', 'requirements') |
44
44
  </tool>
45
45
 
46
46
  <tool name="write-block">
@@ -106,8 +106,8 @@ See references/bundled-resources.md for full inventory.
106
106
  | `conformance-reference` | Conformance Reference | `principles` | id, name, description?, rules (array) |
107
107
  | `decisions` | Decisions | `decisions` | id, decision, rationale, phase? (string|integer), status (string (decided|tentative|revisit|superseded)), context? |
108
108
  | `domain` | Domain Knowledge | `entries` | id, title, content, category (string (research|reference|domain-rule|prior-art|constraint)), source?, confidence? (string (high|medium|low)), related_requirements? (array), tags? (array) |
109
- | `gaps` | Gaps | `gaps` | id, description, status (string (open|resolved|deferred)), category (string (missing|incomplete|defect|improvement|technical-debt|question)), priority (string (low|medium|high|critical)), phase? (string|integer), resolved_by?, source? (string (human|agent|monitor|workflow)), details? |
110
109
  | `handoff` | Handoff | `current_tasks` | |
110
+ | `issues` | Issues | `issues` | id, title, body, location, status (string (open|resolved|deferred)), category (string (primitive|issue|cleanup|capability|composition)), priority (string (low|medium|high|critical)), package, source? (string (human|agent|monitor|workflow)), resolved_by? |
111
111
  | `phase` | Phase | `success_criteria` | criterion, verify_method (string (command|inspect|test)) |
112
112
  | `project` | Project Identity | `target_users` | |
113
113
  | `rationale` | Design Rationale | `rationales` | id, title, narrative, related_decisions? (array), phase? (string|integer), context? |
@@ -124,10 +124,10 @@ See references/bundled-resources.md for full inventory.
124
124
  | `decisions` | `status` | decided, tentative, revisit, superseded |
125
125
  | `domain` | `category` | research, reference, domain-rule, prior-art, constraint |
126
126
  | `domain` | `confidence` | high, medium, low |
127
- | `gaps` | `status` | open, resolved, deferred |
128
- | `gaps` | `category` | missing, incomplete, defect, improvement, technical-debt, question |
129
- | `gaps` | `priority` | low, medium, high, critical |
130
- | `gaps` | `source` | human, agent, monitor, workflow |
127
+ | `issues` | `status` | open, resolved, deferred |
128
+ | `issues` | `category` | primitive, issue, cleanup, capability, composition |
129
+ | `issues` | `priority` | low, medium, high, critical |
130
+ | `issues` | `source` | human, agent, monitor, workflow |
131
131
  | `phase` | `status` | planned, in-progress, completed |
132
132
  | `phase` | `verify_method` | command, inspect, test |
133
133
  | `phase` | `status` | planned, in-progress, completed |
@@ -5,7 +5,7 @@
5
5
  - `defaults/blocks/conformance-reference.json`
6
6
  - `defaults/blocks/decisions.json`
7
7
  - `defaults/blocks/domain.json`
8
- - `defaults/blocks/gaps.json`
8
+ - `defaults/blocks/issues.json`
9
9
  - `defaults/blocks/project.json`
10
10
  - `defaults/blocks/rationale.json`
11
11
  - `defaults/blocks/requirements.json`
@@ -16,8 +16,8 @@
16
16
  - `defaults/schemas/conformance-reference.schema.json`
17
17
  - `defaults/schemas/decisions.schema.json`
18
18
  - `defaults/schemas/domain.schema.json`
19
- - `defaults/schemas/gaps.schema.json`
20
19
  - `defaults/schemas/handoff.schema.json`
20
+ - `defaults/schemas/issues.schema.json`
21
21
  - `defaults/schemas/phase.schema.json`
22
22
  - `defaults/schemas/project.schema.json`
23
23
  - `defaults/schemas/rationale.schema.json`
@@ -34,7 +34,7 @@ Workflow orchestration extension for Pi
34
34
  Behavior monitors for pi that watch agent activity and steer corrections
35
35
 
36
36
  **Tools:** `monitors-status`, `monitors-inspect`, `monitors-control`, `monitors-rules`, `monitors-patterns`
37
- **Commands:** `/monitors`
37
+ **Commands:** `/work-quality`, `/monitors`
38
38
  </extension>
39
39
 
40
40
  </included_extensions>