pi-dev 0.2.4 → 0.2.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 +9 -7
- package/dist/install.js +34 -2
- package/dist/paths.js +9 -1
- package/extensions/pi-flow/README.md +40 -0
- package/extensions/pi-flow/index.ts +65 -0
- package/extensions/pi-flow/package.json +9 -0
- package/package.json +5 -4
- package/skills/do/SKILL.md +4 -31
- package/skills/improve-skill-flow/SKILL.md +91 -28
- package/skills/to-issues/SKILL.md +1 -18
- package/skills/triage/SKILL.md +0 -6
package/README.md
CHANGED
|
@@ -35,21 +35,22 @@ You ask. It classifies. It executes. It reports.
|
|
|
35
35
|
- **A migration gate that won't let you cheat.** `/do` refuses to touch an un-migrated repo. `/migrate` audits `AGENTS.md`, `CLAUDE.md`, scoped agent dirs, handoff systems, and ADR layouts; archives the noise; stamps a marker; and on every re-entry runs drift probes so banned conventions can't sneak back in.
|
|
36
36
|
- **No handoff files. Ever.** State of work lives in three places only — code (git), the issue tracker, and merged preferences. No `docs/handoff/`, no `.scratch/flow/`, no SESSION_*.md littering your repo.
|
|
37
37
|
- **Local-live verification the agent owns.** A one-time playbook captures how to boot your stack. From then on the agent boots it, drives it, and quotes the evidence in the summary. You are not the test runner.
|
|
38
|
-
- **Vertical-slice issues
|
|
38
|
+
- **Vertical-slice issues that read like a spec.** `/to-issues` produces independently-grabbable tickets — each with acceptance criteria, allowed-touch-set, and out-of-scope — written as plain spec so the next worker agent picks them up as input, not as a meta-tagged AI artefact.
|
|
39
|
+
- **One minimal plugin where prose is provably not enough.** Ships `pi-flow`: a single pi extension whose only job is to catch `/do` ending a turn with `follow-up: ... run /do ...` mid-chain (the hand-back pattern that turns one prompt into ten "진행해" replies) and steer back into the next phase. Toggle in `~/.pi/agent/settings.json` → `piFlow.enabled`. We add a new guard only when an audit shows a rule the model demonstrably can't see itself drift past.
|
|
39
40
|
|
|
40
41
|
## Install
|
|
41
42
|
|
|
42
43
|
Requires Node ≥ 20 and the [pi runtime](https://github.com/badlogic/pi).
|
|
43
44
|
|
|
44
45
|
```bash
|
|
45
|
-
# Interactive: pick global vs project-local, then install + seed preferences
|
|
46
|
+
# Interactive: pick global vs project-local, then install skills + extensions + seed preferences
|
|
46
47
|
npx pi-dev@latest install
|
|
47
48
|
|
|
48
49
|
# Or be explicit:
|
|
49
|
-
npx pi-dev@latest install --global # ~/.pi/agent/skills/ (every repo)
|
|
50
|
-
npx pi-dev@latest install --local # ./.pi/skills/ (this repo only)
|
|
50
|
+
npx pi-dev@latest install --global # ~/.pi/agent/{skills,extensions}/ (every repo)
|
|
51
|
+
npx pi-dev@latest install --local # ./.pi/{skills,extensions}/ (this repo only)
|
|
51
52
|
|
|
52
|
-
# Refresh skills (auto-detects scope from disk; preferences are kept)
|
|
53
|
+
# Refresh skills + extensions (auto-detects scope from disk; preferences are kept)
|
|
53
54
|
npx pi-dev@latest update
|
|
54
55
|
|
|
55
56
|
# See what's installed under each scope
|
|
@@ -64,10 +65,11 @@ npx pi-dev doctor
|
|
|
64
65
|
| | global | local |
|
|
65
66
|
| --- | --- | --- |
|
|
66
67
|
| Skills | `~/.pi/agent/skills/` | `<repo>/.pi/skills/` |
|
|
68
|
+
| Extensions | `~/.pi/agent/extensions/` | `<repo>/.pi/extensions/` |
|
|
67
69
|
| Preferences | `~/.pi/agent/preferences.md` | `<repo>/.pi/preferences.md` |
|
|
68
70
|
| Pi sessions see it from | every cwd | only this repo |
|
|
69
|
-
| Goes in the repo's git? | no | yes (commit `.pi/skills/`, gitignore `.pi/sessions/`) |
|
|
70
|
-
| Use when | the
|
|
71
|
+
| Goes in the repo's git? | no | yes (commit `.pi/skills/` + `.pi/extensions/`, gitignore `.pi/sessions/`) |
|
|
72
|
+
| Use when | the framework is part of *your* engineering taste | the framework is part of *the project's* contract |
|
|
71
73
|
|
|
72
74
|
Non-interactive runs (CI, piped input) default to `--global` silently. Pass `-y` to skip the prompt and accept the default.
|
|
73
75
|
|
package/dist/install.js
CHANGED
|
@@ -3,7 +3,19 @@ import { execSync } from "node:child_process";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { createInterface } from "node:readline";
|
|
5
5
|
import { SKILLS, CONSUMER_SKILLS } from "./manifest.js";
|
|
6
|
-
import { PKG_SKILLS_DIR, PKG_GLOBAL_PREFS_PRESET, destFor, } from "./paths.js";
|
|
6
|
+
import { PKG_SKILLS_DIR, PKG_EXTENSIONS_DIR, PKG_GLOBAL_PREFS_PRESET, destFor, } from "./paths.js";
|
|
7
|
+
/**
|
|
8
|
+
* Extensions shipped with pi-dev. Each is a subdirectory under `extensions/`
|
|
9
|
+
* that pi auto-discovers from `~/.pi/agent/extensions/<name>/` (global) or
|
|
10
|
+
* `.pi/extensions/<name>/` (local). The directory name is the install name
|
|
11
|
+
* verbatim — no prefix, no transform.
|
|
12
|
+
*
|
|
13
|
+
* Keep this list short. A new entry is justified only by an audit signal
|
|
14
|
+
* showing prose alone has ≥60% miss rate on a mechanically checkable rule.
|
|
15
|
+
*/
|
|
16
|
+
const EXTENSIONS = [
|
|
17
|
+
{ name: "pi-flow", summary: "Steer mid-chain hand-backs back into the next phase." },
|
|
18
|
+
];
|
|
7
19
|
function ask(question) {
|
|
8
20
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
9
21
|
return new Promise((res) => {
|
|
@@ -39,8 +51,9 @@ async function resolveScope(opts) {
|
|
|
39
51
|
}
|
|
40
52
|
export async function install(opts = {}) {
|
|
41
53
|
const scope = await resolveScope(opts);
|
|
42
|
-
const { agentDir, skillsDir, prefsFile } = destFor(scope);
|
|
54
|
+
const { agentDir, skillsDir, extensionsDir, prefsFile } = destFor(scope);
|
|
43
55
|
mkdirSync(skillsDir, { recursive: true });
|
|
56
|
+
mkdirSync(extensionsDir, { recursive: true });
|
|
44
57
|
const skillsToInstall = opts.includeMaintainer ? SKILLS : CONSUMER_SKILLS;
|
|
45
58
|
let copied = 0;
|
|
46
59
|
for (const skill of skillsToInstall) {
|
|
@@ -59,6 +72,25 @@ export async function install(opts = {}) {
|
|
|
59
72
|
copied++;
|
|
60
73
|
}
|
|
61
74
|
console.log(`Installed ${copied} skill(s) into ${skillsDir} [${scope}]`);
|
|
75
|
+
let extsCopied = 0;
|
|
76
|
+
for (const ext of EXTENSIONS) {
|
|
77
|
+
const src = join(PKG_EXTENSIONS_DIR, ext.name);
|
|
78
|
+
const dst = join(extensionsDir, ext.name);
|
|
79
|
+
if (!existsSync(src)) {
|
|
80
|
+
console.warn(` skip extension ${ext.name} (source not found in package)`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (existsSync(dst) && !opts.force) {
|
|
84
|
+
cpSync(src, dst, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
cpSync(src, dst, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
extsCopied++;
|
|
90
|
+
}
|
|
91
|
+
if (extsCopied > 0) {
|
|
92
|
+
console.log(`Installed ${extsCopied} extension(s) into ${extensionsDir} [${scope}]`);
|
|
93
|
+
}
|
|
62
94
|
if (opts.skipPrefs) {
|
|
63
95
|
console.log("Skipped preferences (pass --include-prefs on update to merge in new keys).");
|
|
64
96
|
return;
|
package/dist/paths.js
CHANGED
|
@@ -4,23 +4,31 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
export const HOME = homedir();
|
|
5
5
|
export const PI_AGENT_DIR = join(HOME, ".pi", "agent");
|
|
6
6
|
export const PI_SKILLS_DIR = join(PI_AGENT_DIR, "skills");
|
|
7
|
+
export const PI_EXTENSIONS_DIR = join(PI_AGENT_DIR, "extensions");
|
|
7
8
|
export const PI_GLOBAL_PREFS = join(PI_AGENT_DIR, "preferences.md");
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
10
11
|
/** Resolve the package root regardless of whether we run from src/ or dist/. */
|
|
11
12
|
export const PKG_ROOT = resolve(__dirname, "..");
|
|
12
13
|
export const PKG_SKILLS_DIR = join(PKG_ROOT, "skills");
|
|
14
|
+
export const PKG_EXTENSIONS_DIR = join(PKG_ROOT, "extensions");
|
|
13
15
|
export const PKG_PRESETS_DIR = join(PKG_ROOT, "presets");
|
|
14
16
|
export const PKG_GLOBAL_PREFS_PRESET = join(PKG_PRESETS_DIR, "preferences.md");
|
|
15
17
|
/** Compute install destinations for a given scope. `local` resolves against `cwd`. */
|
|
16
18
|
export function destFor(scope, cwd = process.cwd()) {
|
|
17
19
|
if (scope === "global") {
|
|
18
|
-
return {
|
|
20
|
+
return {
|
|
21
|
+
agentDir: PI_AGENT_DIR,
|
|
22
|
+
skillsDir: PI_SKILLS_DIR,
|
|
23
|
+
extensionsDir: PI_EXTENSIONS_DIR,
|
|
24
|
+
prefsFile: PI_GLOBAL_PREFS,
|
|
25
|
+
};
|
|
19
26
|
}
|
|
20
27
|
const agentDir = join(cwd, ".pi");
|
|
21
28
|
return {
|
|
22
29
|
agentDir,
|
|
23
30
|
skillsDir: join(agentDir, "skills"),
|
|
31
|
+
extensionsDir: join(agentDir, "extensions"),
|
|
24
32
|
prefsFile: join(agentDir, "preferences.md"),
|
|
25
33
|
};
|
|
26
34
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# pi-flow
|
|
2
|
+
|
|
3
|
+
The default plugin that ships with `pi-dev`. One job: stop `/do` from
|
|
4
|
+
quietly handing the chain back to you between phases.
|
|
5
|
+
|
|
6
|
+
## What it does
|
|
7
|
+
|
|
8
|
+
Watches the end of every assistant turn. If the last visible text contains
|
|
9
|
+
a `follow-up: ... run /do ...` line **without** a preceding
|
|
10
|
+
`chain complete — no further action.` line, it queues a follow-up steer
|
|
11
|
+
that prompts the next phase. Your next turn is the next `[flow N/M]`
|
|
12
|
+
status line, not "진행해".
|
|
13
|
+
|
|
14
|
+
## Why one guard, not five
|
|
15
|
+
|
|
16
|
+
`pi-flow` is intentionally minimal. Each new guard taxes every tool call,
|
|
17
|
+
slows iteration, and tempts everyone to disable the whole plugin. So:
|
|
18
|
+
|
|
19
|
+
- We add a guard only when a real audit shows ≥60% violation on a rule
|
|
20
|
+
the model can't see itself drift past.
|
|
21
|
+
- We remove a guard when the underlying root cause is gone (e.g. an
|
|
22
|
+
`.gitignore` lockout makes a path-write guard redundant).
|
|
23
|
+
- Everything else stays in `SKILL.md` prose where the cost is zero.
|
|
24
|
+
|
|
25
|
+
The hugn 2026-05 audit produced exactly one such finding (mid-chain
|
|
26
|
+
hand-back, 8/13 sessions). That is what this guard exists for.
|
|
27
|
+
|
|
28
|
+
## Toggle
|
|
29
|
+
|
|
30
|
+
`~/.pi/agent/settings.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"piFlow": {
|
|
35
|
+
"enabled": false
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Default: on.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-flow
|
|
3
|
+
*
|
|
4
|
+
* Minimal runtime plugin that keeps /do on-chain.
|
|
5
|
+
*
|
|
6
|
+
* One guard, one event: when an assistant turn ends with a
|
|
7
|
+
* `follow-up: ... run /do ...` line that is *not* preceded by the canonical
|
|
8
|
+
* `chain complete — no further action.` terminator, the chain is being
|
|
9
|
+
* handed back mid-flight. The plugin queues a steer reminder so the next
|
|
10
|
+
* turn re-enters the chain at the next phase instead of waiting for the user
|
|
11
|
+
* to type "진행해" / "go" / "다음".
|
|
12
|
+
*
|
|
13
|
+
* Rationale: the hugn 2026-05 audit showed 8/13 /do sessions ending with
|
|
14
|
+
* chain-depth 0 and 82% of user messages being short re-entry nudges. Every
|
|
15
|
+
* other candidate guard had near-zero ROI — the taboo-path writes were already
|
|
16
|
+
* stopped by a .gitignore lockout, and other rules were taken out of policy.
|
|
17
|
+
* One predicate, one steer.
|
|
18
|
+
*
|
|
19
|
+
* Toggle:
|
|
20
|
+
* ~/.pi/agent/settings.json → "piFlow": { "enabled": false }
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
24
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
25
|
+
import { homedir } from "node:os";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
|
|
28
|
+
const HANDBACK = /^follow-up:\s.*\brun\s+`?\/?do\b/m;
|
|
29
|
+
const TERMINATOR = /chain complete\s+\u2014\s+no further action/;
|
|
30
|
+
|
|
31
|
+
function isEnabled(): boolean {
|
|
32
|
+
const settingsPath = join(homedir(), ".pi", "agent", "settings.json");
|
|
33
|
+
if (!existsSync(settingsPath)) return true;
|
|
34
|
+
try {
|
|
35
|
+
const raw = JSON.parse(readFileSync(settingsPath, "utf-8")) as Record<string, unknown>;
|
|
36
|
+
const cfg = (raw["piFlow"] ?? {}) as { enabled?: boolean };
|
|
37
|
+
return cfg.enabled !== false;
|
|
38
|
+
} catch {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default function piFlow(pi: ExtensionAPI) {
|
|
44
|
+
if (!isEnabled()) return;
|
|
45
|
+
|
|
46
|
+
pi.on("message_end", async (event) => {
|
|
47
|
+
if (event.message.role !== "assistant") return;
|
|
48
|
+
const text = event.message.content
|
|
49
|
+
.filter((b): b is { type: "text"; text: string } => b.type === "text")
|
|
50
|
+
.map((b) => b.text)
|
|
51
|
+
.join("\n");
|
|
52
|
+
if (!text || !HANDBACK.test(text) || TERMINATOR.test(text)) return;
|
|
53
|
+
|
|
54
|
+
pi.sendMessage(
|
|
55
|
+
{
|
|
56
|
+
customType: "pi-flow",
|
|
57
|
+
content:
|
|
58
|
+
"[pi-flow] mid-chain hand-back detected. `follow-up: … run /do …` is the Step-7 terminator, " +
|
|
59
|
+
"not a phase boundary. Print the next `[flow N/M]` status line and continue the chain.",
|
|
60
|
+
display: true,
|
|
61
|
+
},
|
|
62
|
+
{ triggerTurn: true, deliverAs: "followUp" },
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-dev",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "An autonomous engineering skill framework for the pi runtime — built on Matt Pocock's skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"skills",
|
|
12
|
+
"extensions",
|
|
12
13
|
"presets",
|
|
13
14
|
"README.md",
|
|
14
15
|
"LICENSE"
|
|
@@ -39,10 +40,10 @@
|
|
|
39
40
|
},
|
|
40
41
|
"repository": {
|
|
41
42
|
"type": "git",
|
|
42
|
-
"url": "git+https://github.com/jason2077/pi-
|
|
43
|
+
"url": "git+https://github.com/jason2077/pi-flow.git"
|
|
43
44
|
},
|
|
44
45
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/jason2077/pi-
|
|
46
|
+
"url": "https://github.com/jason2077/pi-flow/issues"
|
|
46
47
|
},
|
|
47
|
-
"homepage": "https://github.com/jason2077/pi-
|
|
48
|
+
"homepage": "https://github.com/jason2077/pi-flow#readme"
|
|
48
49
|
}
|
package/skills/do/SKILL.md
CHANGED
|
@@ -26,38 +26,9 @@ The point: **one request → one finished outcome**, with as few user interrupti
|
|
|
26
26
|
- a phase's terminal predicate fails twice and the failure cannot be characterised, OR
|
|
27
27
|
- the Ambiguity protocol fires (preferences truly silent on a one-shot decision), OR
|
|
28
28
|
- user interrupts.
|
|
29
|
-
5. **No handoff files.** State of work lives in three places only: **code (git), issue tracker, merged preferences**. Do not create `.scratch/flow/`, `docs/handoff/`, or any session-log file. Phase outputs are remembered in-context; persistent decisions are committed to code or filed as issues.
|
|
29
|
+
5. **No handoff files.** State of work lives in three places only: **code (git), issue tracker, merged preferences**. Do not create `.scratch/flow/`, `docs/handoff/`, `.handoff/`, or any session-log file (`SESSION_*.md`, `HANDOFF_*.md`). Phase outputs are remembered in-context; persistent decisions are committed to code or filed as issues.
|
|
30
30
|
6. **Side-effect gates respect prefs literally.** `auto-create-issues`, `auto-apply-labels`, `auto-commit-per-slice`, `auto-pr` follow merged prefs without reinterpretation.
|
|
31
31
|
7. **Status line per phase.** `[flow N/M] <phase-name> — <one-sentence what>`.
|
|
32
|
-
8. **Issue-write rule (no exceptions).** Every issue body written from a `/do` flow — whether you invoke `/to-issues`, `/triage`, or call `gh issue create` / `gh issue edit` directly from a bash tool — MUST start with this disclaimer as the first non-blank line:
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
> *This was generated by AI during triage.*
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
This rule is global and binding regardless of which skill you think you are in. Before publishing any issue body:
|
|
39
|
-
|
|
40
|
-
- Build the body with `--body-file <path>` or a heredoc, never with inline `--body "..."` (heredocs make the disclaimer visible in the diff and the file is auditable).
|
|
41
|
-
- The first non-blank line of the body file must be the disclaimer literal above.
|
|
42
|
-
- Immediately after **every** `gh issue create` / `gh issue edit` returns, the **very next tool call** must be this self-check on the resulting body. Not "sometime later", not "once at the end of the batch":
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
gh issue view <num> --json body --jq '.body' | awk 'NF{print; exit}' | grep -q 'generated by AI' \
|
|
46
|
-
|| { echo "AI disclaimer missing on issue #<num>"; exit 1; }
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
- **If the self-check fails, the immediately following tool call MUST be a corrective `gh issue edit <num> --body-file <fixed>` that prepends the disclaimer literal, followed by a re-run of the self-check.** Do not create the next slice, do not call any other tool, and do not summarise progress until a self-check on that issue returns success. A failed self-check that is not followed by an edit-then-recheck pair is itself a Hard-rule #8 violation — equivalent to never having run the check.
|
|
50
|
-
- The `awk 'NF{print; exit}'` form is mandatory: it selects the first **non-blank** line, which is what the rule actually constrains. `head -1` is not equivalent and will pass false positives on bodies with a leading blank line.
|
|
51
|
-
|
|
52
|
-
**Anti-patterns** (delete and redo if you catch any in your own draft):
|
|
53
|
-
|
|
54
|
-
- `gh issue create --title "…" --body "..."` (inline body, no disclaimer check)
|
|
55
|
-
- First line of issue body being `## Goal`, `## Scope`, `## Problem Statement`, `## Context`, `**Parent epic:**`, or any heading other than the disclaimer.
|
|
56
|
-
- Skipping the post-create `gh issue view ... | grep generated by AI` self-check because "I included the disclaimer in the heredoc".
|
|
57
|
-
- Running the self-check, seeing it fail, and *continuing to the next slice anyway* — "I'll fix the disclaimers in a batch at the end" is the failure mode that this rule is named after. Fix the one issue you just created, then move on.
|
|
58
|
-
- Batching N `gh issue create` calls in a row and then a single self-check at the end. The self-check is per-issue, and it gates the next `create`.
|
|
59
|
-
|
|
60
|
-
Skills `/to-issues` and `/triage` repeat this rule for the case where you do enter them. This Hard rule is the binding statement for the case where you do not.
|
|
61
32
|
|
|
62
33
|
## Process
|
|
63
34
|
|
|
@@ -160,6 +131,8 @@ Then for each phase:
|
|
|
160
131
|
- Ending the turn with `follow-up: <next planned phase> — run /do …` when N < M. The `follow-up:` line is reserved for *post-chain* deferred work (push, manual ops live, prefs refresh). Using it to describe the *next planned phase of this chain* is a disguised hand-back — start the phase instead.
|
|
161
132
|
- Treating a short user nudge ("진행해", "다음", "계속", "ㄱㄱ", "go", "이어서") as a new request. If the planned chain has unfinished phases, those nudges are noise — re-enter the chain at the next phase, do not re-classify and re-inject `/do`.
|
|
162
133
|
|
|
134
|
+
The `pi-flow` plugin (installed by default) watches the end of each assistant turn: a `follow-up: ... run /do ...` line *not* preceded by `chain complete — no further action.` is treated as a mid-chain hand-back and steered back into the next phase automatically. The prose above is still the canonical contract; the plugin is the safety net.
|
|
135
|
+
|
|
163
136
|
The only place a wrap-up belongs is **Step 7 — Final summary**, after the last phase has met its terminal predicate.
|
|
164
137
|
|
|
165
138
|
### Step 5 — Live verification
|
|
@@ -224,7 +197,7 @@ If you emitted anything that looks like a wrap-up ("All set!", "Done.", "Let me
|
|
|
224
197
|
| `grill-with-docs` / `grill-lite` | every open question answered, deferred with rationale, or escalated; relevant CONTEXT/ADR updates committed |
|
|
225
198
|
| `to-prd` | PRD published to issue tracker with `needs-triage` (per `auto-create-issues`) |
|
|
226
199
|
| `to-issues` | all slices created on tracker; each is independently grabbable; labels applied per `auto-apply-labels` |
|
|
227
|
-
| `triage` | issue carries exactly one state label
|
|
200
|
+
| `triage` | issue carries exactly one state label |
|
|
228
201
|
| `diagnose` | reproducible pass/fail loop exists AND root cause identified AND regression test exists |
|
|
229
202
|
| `tdd` | new test red→green; project's check command clean; commit per `auto-commit-per-slice` |
|
|
230
203
|
| `improve-codebase-architecture` | proposed deepening either applied or recorded as a follow-up issue |
|
|
@@ -7,9 +7,9 @@ description: MAINTAINER-ONLY. Analyse real pi-runtime session telemetry from any
|
|
|
7
7
|
|
|
8
8
|
**Audience: pi-dev maintainers only.** Consumers do not get this skill installed. Consumers improve their own setup by editing `docs/agents/preferences.md` (per project) or `~/.pi/agent/preferences.md` (per machine), not by editing SKILL.md bodies. The framework is fixed for them; only the maintainer changes it.
|
|
9
9
|
|
|
10
|
-
The pi-dev
|
|
10
|
+
The pi-dev workflow is not just markdown. It is a layered control system: SKILL.md prose, repo preferences, pi-runtime lifecycle events, tools, commands, TUI surfaces, session persistence, compaction hooks, and extensions. This skill reads what real sessions did across consumer repos, compares that to what the workflow contract said *should* happen, then chooses the lightest effective intervention.
|
|
11
11
|
|
|
12
|
-
The point: **never
|
|
12
|
+
The point: **never improve the framework from gut feeling, and never collapse every fix into a "guard".** Edit because session N showed phase P violated predicate Q on M occasions, then decide whether the right response is clearer prose, repo-local preferences, a runtime steer, a custom tool, a command, a TUI affordance, state persistence, compaction/context shaping, or — only when the evidence calls for it — a blocking gate.
|
|
13
13
|
|
|
14
14
|
## Pre-flight (hard gate)
|
|
15
15
|
|
|
@@ -50,22 +50,49 @@ Always from inside the pi-dev checkout (see Pre-flight).
|
|
|
50
50
|
- **Consumer repo path** (or its sessions directory) to audit. The maintainer names a repo on this machine; you resolve its sessions dir.
|
|
51
51
|
- Optional: a specific skill name to focus the audit on (`do`, `migrate`, `triage`, …).
|
|
52
52
|
- Optional: a date range.
|
|
53
|
-
- **Fix scope** per finding — `framework` or `consumer-prefs`. Defaults set in Step 5.5; maintainer can flip individual rows before applying.
|
|
53
|
+
- **Fix scope** per finding — `framework`, `extension`, or `consumer-prefs`. Defaults set in Step 5.5; maintainer can flip individual rows before applying.
|
|
54
54
|
|
|
55
55
|
## Fix scopes
|
|
56
56
|
|
|
57
|
-
pi-runtime
|
|
57
|
+
pi-runtime loads three artefact kinds the framework can ship:
|
|
58
|
+
|
|
59
|
+
- **Skill bodies** — `~/.pi/agent/skills/<name>/SKILL.md` (global) or `<repo>/.pi/skills/<name>/SKILL.md` (local). Pure prose.
|
|
60
|
+
- **Runtime interventions** — extensions under `~/.pi/agent/extensions/<name>/` (global) or `<repo>/.pi/extensions/<name>/` (local). TypeScript modules auto-loaded via jiti. They can subscribe to lifecycle/session/agent/model/tool events, inject context in `before_agent_start`, reshape model context, observe `message_end`, intercept or modify tool calls/results, register custom tools/commands/shortcuts/flags, prompt via `ctx.ui`, render custom TUI widgets, persist state with `pi.appendEntry()`, and customize compaction/session behavior. pi-dev ships **one** extension by default — `pi-flow` — and the bar to add a second package remains high.
|
|
61
|
+
- **Preferences** — `docs/agents/preferences.md` (per repo) and `~/.pi/agent/preferences.md` (per machine). 3-layer override on prose-level decisions.
|
|
62
|
+
|
|
63
|
+
A finding lands in exactly one of:
|
|
58
64
|
|
|
59
65
|
| scope | lands in | reaches | propagation | when to pick |
|
|
60
66
|
| --- | --- | --- | --- | --- |
|
|
61
|
-
| **framework** | this repo's `skills/<name>/SKILL.md` | every consumer after the next `npx pi-dev update` | release-please → npm publish | the SKILL.md wording
|
|
62
|
-
| **
|
|
67
|
+
| **framework** | this repo's `skills/<name>/SKILL.md` | every consumer after the next `npx pi-dev update` | release-please → npm publish | the SKILL.md wording is wrong; gap shows up generically; prose alone is plausibly enough |
|
|
68
|
+
| **extension** | this repo's `extensions/pi-flow/index.ts` (extend) or a new `extensions/<name>/` (rare) | every consumer after `npx pi-dev update` | release-please → npm publish | a real audit shows prose / prefs cannot reliably preserve the workflow, AND pi-runtime has an event/tool/UI/state hook that can make the desired path easier, more observable, or safer |
|
|
69
|
+
| **consumer-prefs** | the audited consumer repo's `docs/agents/preferences.md` | only that repo, on every `/do` bootstrap | regular consumer-repo commit | gap is the consumer repo's domain / paths / conventions, not the SKILL.md |
|
|
63
70
|
|
|
64
71
|
Notes:
|
|
65
72
|
|
|
66
73
|
- A `framework` apply is **always** mirrored into `~/.pi/agent/skills/<name>/` on this machine so the next session picks it up immediately, without waiting for npm.
|
|
74
|
+
- An `extension` apply is **always** mirrored into `~/.pi/agent/extensions/<name>/` on this machine for the same reason. The package directory name is the install name verbatim (no `pi-dev-` prefix).
|
|
67
75
|
- A `consumer-prefs` apply touches no pi-dev files. It is committed to the consumer repo only.
|
|
68
|
-
- A single audit may produce a mix of
|
|
76
|
+
- A single audit may produce a mix of all three. Decide scope per finding, not per audit.
|
|
77
|
+
|
|
78
|
+
**Extension scope is the most expensive option, but it is not synonymous with "guards".** Runtime interventions can be passive observability, progress/status UI, context injection, command shortcuts, structured tools, state checkpoints, compaction shaping, soft steers, confirmations, or hard blocks. Default to `framework` / `consumer-prefs` when prose or repo-local convention plausibly fixes the gap; reach for `extension` when the audit shows the workflow needs runtime support.
|
|
79
|
+
|
|
80
|
+
Intervention ladder, from lightest to strongest:
|
|
81
|
+
|
|
82
|
+
1. **Observe** — collect counters / emit low-noise status so the next audit can see what happened.
|
|
83
|
+
2. **Make the right path easier** — custom command, custom tool, context injection, remembered state, or TUI affordance.
|
|
84
|
+
3. **Steer** — inject a follow-up message or system/context nudge when the model is drifting but no irreversible action happened.
|
|
85
|
+
4. **Confirm** — ask the user only for genuinely risky or preference-silent operations.
|
|
86
|
+
5. **Block** — refuse a tool call only for destructive, costly, or repeatedly proven workflow violations.
|
|
87
|
+
|
|
88
|
+
The bar for extension work:
|
|
89
|
+
|
|
90
|
+
- The failure is repeated or high-cost, and the expected workflow was available in-context via SKILL.md / prefs / repo docs.
|
|
91
|
+
- The runtime intervention can be described as a small event-driven mechanism over pi's lifecycle/session/agent/tool/UI/state surfaces; no hidden LLM call unless the finding is explicitly about a summarizer/evaluator extension.
|
|
92
|
+
- The success metric is measurable in the next audit: fewer user nudges, higher `/do` phase completion, fewer corrections, better issue shape, shorter stalled intervals, or clearer live evidence.
|
|
93
|
+
- A simpler remedy (docs wording, prefs, `.gitignore` lockout, issue-template fix) does **not** plausibly close the gap. If it does, take the simpler remedy.
|
|
94
|
+
|
|
95
|
+
External research posture (DECAY): before proposing a new class of runtime intervention, do a quick current-source pass. 2025–2026 agent-reliability literature emphasizes trajectory monitoring, workflow-level observability, recovery orchestration, and textual feedback from traces — not just pre-execution blocking. Use that as a check against over-fitting on "guards"; cite the sources in the audit notes when they shape the proposal.
|
|
69
96
|
|
|
70
97
|
## Session-data location & format
|
|
71
98
|
|
|
@@ -159,12 +186,16 @@ Run a single pass over every targeted `.jsonl` and tally:
|
|
|
159
186
|
- top Edit / Write targets (hotspot files)
|
|
160
187
|
- bash commands matching domain-specific danger / smell patterns
|
|
161
188
|
|
|
162
|
-
**
|
|
163
|
-
- After each `<skill name="do">` injection, did another skill get injected within the same session? **This measures `/do` chain depth.** Single-step chains are a red flag.
|
|
189
|
+
**Workflow-compliance specific:**
|
|
190
|
+
- After each `<skill name="do">` injection, did another skill get injected within the same session? **This measures `/do` chain depth.** Single-step chains are a red flag, but not the whole story.
|
|
191
|
+
- Did `/do` emit `[flow plan]`? Count planned phases and observed `[flow N/M]` status lines. Flag: plan missing, N/M skipped, final summary before all phases, or terminal predicate not evidenced.
|
|
164
192
|
- Count user messages shorter than ~80 chars — these are usually nudges ("진행해", "다음은?", "끝났어?"). High proportion = `/do` is handing the flow back too often.
|
|
165
|
-
- Count user messages containing correction markers (`아니`, `wait`, `stop`, `취소`, `다시`, `그만`, `undo`, `revert
|
|
193
|
+
- Count user messages containing correction markers (`아니`, `wait`, `stop`, `취소`, `다시`, `그만`, `undo`, `revert`, `왜`, `??`, `제대로`). These mark interventions.
|
|
194
|
+
- Detect stalled intervals: long gaps between assistant text / tool calls, repeated identical commands, or repeated failed live probes beyond the repo's wait budget.
|
|
195
|
+
- Count local-live / ops-live evidence when runtime behavior changed: command run, observed output, log/screenshot/evidence embedded in summary.
|
|
196
|
+
- Count side-effect gates: commits, pushes, PRs, issue creates/edits/closes vs. merged prefs (`auto-*`) and tracker docs.
|
|
166
197
|
- Count `<!-- migrated: ... -->` marker date vs. any post-marker `docs/handoff/` / `.scratch/flow/` / `SESSION_*.md` writes. Drift = handoff lockout failed.
|
|
167
|
-
- Count tracker writes (`gh issue create`, `gh pr create`) and
|
|
198
|
+
- Count tracker writes (`gh issue create`, `gh pr create`) and inspect the bodies; the bodies are plain spec consumed by future worker agents, so look for issues with shape problems (missing parent, no acceptance criteria, wrong state labels, wrong parent topology, etc.) rather than meta tags.
|
|
168
199
|
|
|
169
200
|
Use a deterministic Python or shell script you write once and check into `/tmp` for the duration of the run. Do not eyeball big JSONLs by hand.
|
|
170
201
|
|
|
@@ -191,7 +222,7 @@ Produce a small table per audited skill. Each row:
|
|
|
191
222
|
| signal | observed | expected (predicate / rule) | severity |
|
|
192
223
|
| ------------------------------ | -------- | ---------------------------------- | -------- |
|
|
193
224
|
| /do → next-skill chain depth | 1/5 | ≥1 per chain step (M phases) | 🔴 |
|
|
194
|
-
|
|
|
225
|
+
| /do hand-back via follow-up | 8/13 | 0 mid-chain hand-backs | 🔴 |
|
|
195
226
|
| post-marker handoff writes | 9 | 0 | 🟡 |
|
|
196
227
|
| ... | | | |
|
|
197
228
|
```
|
|
@@ -207,7 +238,7 @@ For every 🔴 / 🟡 row, quote the smallest piece of evidence that makes the g
|
|
|
207
238
|
|
|
208
239
|
- a user message timestamp + first 80 chars,
|
|
209
240
|
- a tool-call command that violates a taboo,
|
|
210
|
-
-
|
|
241
|
+
- the first 80 chars of an issue body that violates the slice template.
|
|
211
242
|
|
|
212
243
|
If a finding cannot be backed by an excerpt, it is not actionable yet — demote to a TODO and keep digging.
|
|
213
244
|
|
|
@@ -215,9 +246,19 @@ If a finding cannot be backed by an excerpt, it is not actionable yet — demote
|
|
|
215
246
|
|
|
216
247
|
For each 🔴 / 🟡 finding, pick a default scope using the heuristic below, then show the table once and let the maintainer flip individual rows before applying.
|
|
217
248
|
|
|
249
|
+
Before assigning scope, write one sentence answering: **what would have made the correct workflow easier to follow at the moment of failure?** Do not jump straight to a blocking guard.
|
|
250
|
+
|
|
251
|
+
Default to `extension` if the finding matches **any** of:
|
|
252
|
+
|
|
253
|
+
- The expected behavior was already in SKILL.md / prefs / repo docs at the time of the violating session **and** the session still drifted repeatedly or expensively.
|
|
254
|
+
- The fix needs runtime affordance rather than prose: observe counters, inject context, add a command/tool, show TUI status, persist/checkpoint state, shape compaction/context, steer after a message, confirm a risky action, or block an unsafe tool call.
|
|
255
|
+
- The success condition can be measured in the next session from telemetry, not merely hoped for from stronger wording.
|
|
256
|
+
|
|
257
|
+
When defaulting to `extension`, classify the intervention type: `observe`, `affordance`, `context`, `state`, `render`, `steer`, `confirm`, or `block`.
|
|
258
|
+
|
|
218
259
|
Default to `framework` if the finding matches **any** of:
|
|
219
260
|
|
|
220
|
-
- Cites SKILL.md wording / phase / predicate / rule numbers.
|
|
261
|
+
- Cites SKILL.md wording / phase / predicate / rule numbers, and the rule was not yet in place.
|
|
221
262
|
- The proposed fix is a generic anti-pattern string, a terminator literal, a runway line, or a lockout that any repo would benefit from.
|
|
222
263
|
- The same gap would plausibly show up in two or more consumer repos.
|
|
223
264
|
|
|
@@ -230,12 +271,12 @@ Default to `consumer-prefs` if the finding matches **any** of:
|
|
|
230
271
|
Present the scope-decision table:
|
|
231
272
|
|
|
232
273
|
```
|
|
233
|
-
| # | finding (short) | default scope | target file
|
|
234
|
-
| - | ---------------------------------------- | ---------------- |
|
|
235
|
-
| 1 | /do hands flow back between phases |
|
|
236
|
-
| 2 |
|
|
237
|
-
| 3 |
|
|
238
|
-
| 4 | smoke command name changed in S058 | consumer-prefs | hugn:docs/agents/preferences.md
|
|
274
|
+
| # | finding (short) | default scope | target file | flip? |
|
|
275
|
+
| - | ---------------------------------------- | ---------------- | ---------------------------------------------------- | ----- |
|
|
276
|
+
| 1 | /do hands flow back between phases | extension:steer | pi-dev:extensions/pi-flow/index.ts (message_end) | |
|
|
277
|
+
| 2 | long live-smoke silence causes user nudges | extension:render/observe | pi-dev:extensions/pi-flow/index.ts or project extension | |
|
|
278
|
+
| 3 | post-marker handoff writes | framework | pi-dev:skills/migrate/SKILL.md (gitignore lockout) | |
|
|
279
|
+
| 4 | smoke command name changed in S058 | consumer-prefs | hugn:docs/agents/preferences.md | |
|
|
239
280
|
```
|
|
240
281
|
|
|
241
282
|
Ask once: "OK to proceed with these scopes? Reply with row numbers to flip, or `go`." Apply the flips and move on.
|
|
@@ -251,6 +292,16 @@ For each 🔴 / 🟡 finding, draft the smallest possible edit that, **if it had
|
|
|
251
292
|
- Prefer **terminal markers** ("the summary's last line must be one of these two literals: …") over qualitative descriptions of "good wrap-up".
|
|
252
293
|
- Update **at most three skills per run.** More than that means findings aren't anchored well enough.
|
|
253
294
|
|
|
295
|
+
**Extension findings (target: pi-dev `extensions/pi-flow/index.ts`, or rarely a new `extensions/<name>/`):**
|
|
296
|
+
|
|
297
|
+
- Start from pi's actual extension surface, not from the word "guard": lifecycle/session/agent/model/tool events, `before_agent_start` context injection, `context` shaping, `tool_call` / `tool_result` interception, registered tools, registered commands, `ctx.ui` notifications/widgets/custom UI, custom renderers, `pi.appendEntry()` state, and compaction/session hooks.
|
|
298
|
+
- Prefer extending `pi-flow` when the concern is generic workflow compliance. Create a new extension only when the concern is large enough to be independently named, toggled, installed, and audited.
|
|
299
|
+
- Pick the weakest intervention that would have changed the session outcome: observe → affordance → context/state/render → steer → confirm → block.
|
|
300
|
+
- Determinism is mandatory for `confirm` and `block`; it is desirable but not sufficient for softer interventions. A progress widget, command shortcut, or state checkpoint can be valuable even when it does not block anything.
|
|
301
|
+
- Runtime behavior must be toggleable via `~/.pi/agent/settings.json` when it can alter turns or tool execution. Default on only if the audit shows broad benefit.
|
|
302
|
+
- Keep the corresponding SKILL.md prose as the human-readable contract: one-line *why*, the expected behavior, and a pointer to the runtime support. Do not delete the why — the model still needs to know the intent when the extension is off.
|
|
303
|
+
- Update **at most one runtime mechanism per run** unless the second is pure observability. Two behavior changes at once destroys the next audit's ability to attribute movement.
|
|
304
|
+
|
|
254
305
|
**Consumer-prefs findings (target: that repo's `docs/agents/preferences.md`):**
|
|
255
306
|
|
|
256
307
|
- Pick the *narrowest* existing section that fits before adding a new one. Mapping:
|
|
@@ -265,10 +316,10 @@ For each 🔴 / 🟡 finding, draft the smallest possible edit that, **if it had
|
|
|
265
316
|
| glossary / context term clarification | `## Glossary alignment` |
|
|
266
317
|
| rationale that doesn't fit elsewhere | `## Free notes` (one paragraph max, dated) |
|
|
267
318
|
|
|
268
|
-
- One bullet per finding. Reference the evidence ticket ("S058 smoke name", "#103 missing
|
|
319
|
+
- One bullet per finding. Reference the evidence ticket ("S058 smoke name", "#103 missing parent ref") so the line stays auditable.
|
|
269
320
|
- Do **not** invent new top-level sections unless three findings legitimately share one.
|
|
270
321
|
|
|
271
|
-
Show all drafts as one unified diff per target file before applying. Group by target file: pi-dev's `skills/<name>/SKILL.md`
|
|
322
|
+
Show all drafts as one unified diff per target file before applying. Group by target file: pi-dev's `extensions/pi-flow/index.ts` first (extension), then `skills/<name>/SKILL.md` (framework), then the consumer's `docs/agents/preferences.md` (consumer-prefs).
|
|
272
323
|
|
|
273
324
|
### 7 — Apply, release, verify (branches on scope)
|
|
274
325
|
|
|
@@ -281,6 +332,16 @@ Run both branches if the audit produced mixed-scope findings. Each branch has it
|
|
|
281
332
|
3. `git push origin main`; release-please opens the version-bump PR; merge it; npm publish runs automatically.
|
|
282
333
|
4. Confirm `npm view pi-dev@latest version` matches the bumped tag.
|
|
283
334
|
|
|
335
|
+
**7a′. Extension branch** — only if any finding was approved as `extension`:
|
|
336
|
+
|
|
337
|
+
1. Edit `extensions/pi-flow/index.ts` (or, only if justified by Step 5.5 bar, add a new `extensions/<name>/` directory with `index.ts`, `package.json`, `README.md`).
|
|
338
|
+
2. If a new extension was added, register it in `src/install.ts` `EXTENSIONS` array so `pi-dev install` and `pi-dev update` propagate it.
|
|
339
|
+
3. `npm run build` to ensure `install.ts` still compiles.
|
|
340
|
+
4. Smoke-test with `node dist/cli.js install --local --skip-prefs -y` in `/tmp/<fresh-dir>`. Verify the extension landed under `.pi/extensions/<name>/`.
|
|
341
|
+
5. `git add extensions/<name>/ src/install.ts src/paths.ts && git commit -m "feat(pi-flow): <one-liner anchoring the evidence>"`. Commit body must cite the signal.
|
|
342
|
+
6. Mirror to live: `cp -r extensions/<name> ~/.pi/agent/extensions/<name>` so the **next** session picks up the change without waiting for npm.
|
|
343
|
+
7. `git push origin main`; release-please → npm publish as usual.
|
|
344
|
+
|
|
284
345
|
**7b. Consumer-prefs branch** — only if any finding was approved as `consumer-prefs`:
|
|
285
346
|
|
|
286
347
|
1. In the audited consumer repo: edit `docs/agents/preferences.md` per the drafts from Step 6. Keep the migration marker at the very end of the file undisturbed.
|
|
@@ -291,7 +352,7 @@ Run both branches if the audit produced mixed-scope findings. Each branch has it
|
|
|
291
352
|
**Verification (both branches).** After the next pi session in the affected repo:
|
|
292
353
|
|
|
293
354
|
1. Re-run **this skill** scoped to the last 24 h.
|
|
294
|
-
2. Confirm each previously-🔴 signal has moved (chain depth up, intervention rate down, taboo writes gone,
|
|
355
|
+
2. Confirm each previously-🔴 signal has moved (chain depth up, intervention rate down, taboo writes gone, etc.).
|
|
295
356
|
3. If a signal did not move, the fix wording was too weak — file a follow-up audit, do not re-write from scratch.
|
|
296
357
|
|
|
297
358
|
## Terminal predicate
|
|
@@ -299,9 +360,9 @@ Run both branches if the audit produced mixed-scope findings. Each branch has it
|
|
|
299
360
|
This skill is done when **all four** are true:
|
|
300
361
|
|
|
301
362
|
1. A signal table with severities and evidence excerpts has been presented.
|
|
302
|
-
2. Each finding has an approved scope (`framework` / `consumer-prefs` / `defer`) on record, defaulted by Step 5.5 and confirmed by the maintainer.
|
|
363
|
+
2. Each finding has an approved scope (`framework` / `extension` / `consumer-prefs` / `defer`) on record, defaulted by Step 5.5 and confirmed by the maintainer.
|
|
303
364
|
3. Either (a) zero 🔴 findings — flow is healthy, recorded as "no change this cycle", OR (b) each 🔴 finding has landed in its scope's target file.
|
|
304
|
-
4. For any landed change: if `framework`, the npm version has bumped (`npm view pi-dev@latest version`); if `consumer-prefs`, the consumer repo has the commit on its push-stream. Either way, the next-session re-audit plan is stated.
|
|
365
|
+
4. For any landed change: if `framework` or `extension`, the npm version has bumped (`npm view pi-dev@latest version`) and the live mirror is in place; if `consumer-prefs`, the consumer repo has the commit on its push-stream. Either way, the next-session re-audit plan is stated.
|
|
305
366
|
|
|
306
367
|
The summary's **last line** must be one of:
|
|
307
368
|
|
|
@@ -323,10 +384,12 @@ audit complete — framework v<X.Y.Z> released, consumer-prefs commit <sha>, nex
|
|
|
323
384
|
## Heuristics
|
|
324
385
|
|
|
325
386
|
- **One screenful of signals beats a dashboard.** Most of the time three or four numbers tell the whole story.
|
|
326
|
-
- **
|
|
327
|
-
- **Short user messages are the cheapest interruption proxy.** Count them.
|
|
387
|
+
- **Judge `/do` by workflow completion, not skill injection alone.** Chain depth is useful, but the stronger metric is: plan emitted → phases accounted for → terminal predicates evidenced → side effects match prefs → user did not need to re-enter the chain.
|
|
388
|
+
- **Short user messages are the cheapest interruption proxy.** Count them, then inspect the preceding assistant turn to classify why the user had to nudge.
|
|
328
389
|
- **A taboo without a `.gitignore` lockout will resurrect.** If the same taboo file shows up across two audits, the fix belongs in `/migrate`, not `/do`.
|
|
329
|
-
- **
|
|
390
|
+
- **Do not overfit on guards.** The intervention may be an observability counter, status widget, custom command, context injection, state checkpoint, prompt/compaction shaping, soft steer, confirmation, or block. Pick by evidence and measured failure cost.
|
|
391
|
+
- **Trajectory beats scalar success.** A task that eventually shipped after five corrections is not healthy; use the session trace to find where workflow support was missing.
|
|
392
|
+
- **Refresh external reliability patterns when designing new runtime support.** Current agent-reliability work emphasizes trajectory monitoring, recovery orchestration, and trace-derived textual feedback; use that to challenge pi-flow designs before coding.
|
|
330
393
|
|
|
331
394
|
## Why this skill exists
|
|
332
395
|
|
|
@@ -55,11 +55,7 @@ For each approved slice, publish a new issue to the issue tracker. Use the issue
|
|
|
55
55
|
|
|
56
56
|
Publish issues in dependency order (blockers first) so you can reference real issue identifiers in the "Blocked by" field.
|
|
57
57
|
|
|
58
|
-
**Every issue body MUST start with the AI disclaimer** (same wording as `/triage`). This is a hard requirement — no exceptions, including auto-generated slices. After writing the body, grep your own draft for the disclaimer string; if missing, do not publish. This duplicates `/do` Hard rule #8 — the per-issue self-check below is part of the contract, not an optional verification step.
|
|
59
|
-
|
|
60
58
|
<issue-template>
|
|
61
|
-
> *This was generated by AI during triage.*
|
|
62
|
-
|
|
63
59
|
## Parent
|
|
64
60
|
|
|
65
61
|
A reference to the parent issue on the issue tracker (if the source was an existing issue, otherwise omit this section).
|
|
@@ -82,15 +78,13 @@ Or "None - can start immediately" if no blockers.
|
|
|
82
78
|
|
|
83
79
|
</issue-template>
|
|
84
80
|
|
|
85
|
-
**Publishing pattern (GitHub).** Use `--body-file -` with a heredoc, never inline `--body "..."`, so
|
|
81
|
+
**Publishing pattern (GitHub).** Use `--body-file -` with a heredoc, never inline `--body "..."`, so markdown structure survives shell quoting verbatim:
|
|
86
82
|
|
|
87
83
|
```bash
|
|
88
84
|
gh issue create \
|
|
89
85
|
--title "[Slice N] <title>" \
|
|
90
86
|
--label needs-triage \
|
|
91
87
|
--body-file - <<'EOF'
|
|
92
|
-
> *This was generated by AI during triage.*
|
|
93
|
-
|
|
94
88
|
## Parent
|
|
95
89
|
#<parent>
|
|
96
90
|
|
|
@@ -99,15 +93,4 @@ gh issue create \
|
|
|
99
93
|
EOF
|
|
100
94
|
```
|
|
101
95
|
|
|
102
|
-
After **each** `gh issue create` returns, the **very next tool call** must verify the disclaimer landed on that specific issue, before creating the next slice:
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
gh issue view <n> --json body --jq '.body' | awk 'NF{print; exit}' | grep -q 'generated by AI' \
|
|
106
|
-
|| { echo "FAIL: disclaimer missing on #<n>"; exit 1; }
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Use `awk 'NF{print; exit}'` (first non-blank line), not `head -1` — a leading blank line will pass `head -1` and hide a missing disclaimer.
|
|
110
|
-
|
|
111
|
-
**If the self-check fails**, the next tool call MUST be `gh issue edit <n> --body-file <fixed>` to prepend the disclaimer, followed by a re-run of the self-check. Do not proceed to the next slice until the self-check on the current issue passes. Batching all the creates first and then running checks at the end is a Hard-rule #8 violation — the check gates the *next* create.
|
|
112
|
-
|
|
113
96
|
Do NOT close or modify any parent issue.
|
package/skills/triage/SKILL.md
CHANGED
|
@@ -7,12 +7,6 @@ description: Triage issues through a state machine driven by triage roles. Use w
|
|
|
7
7
|
|
|
8
8
|
Move issues on the project issue tracker through a small state machine of triage roles.
|
|
9
9
|
|
|
10
|
-
Every comment or issue posted to the issue tracker during triage **must** start with this disclaimer:
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
> *This was generated by AI during triage.*
|
|
14
|
-
```
|
|
15
|
-
|
|
16
10
|
## Reference docs
|
|
17
11
|
|
|
18
12
|
Before acting on the issue tracker, read the repo-local setup docs if they exist:
|