@minhduydev/mdpi 0.3.2 → 0.4.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/README.md CHANGED
@@ -38,6 +38,7 @@ npx mdpi init
38
38
  | Command | What it does |
39
39
  |---------|--------------|
40
40
  | `mdpi init` | Scaffold the curated `.pi/` kit into the current repo + write `.version` + `.template-manifest.json` (SHA-256 file map). Idempotent; `--force` overwrites template files (preserves user files), `--quiet` for CI. `--only <cats>` installs only the listed category dirs (`agents,prompts,skills,templates,workflows,context,extensions`) and trims settings.json to match. |
41
+ | `mdpi install` | Install the kit's declared npm packages — core (`.pi/settings.json:packages`) + optional (`.pi/packages.json`). Shells out to `pi install npm:<pkg>` (idempotent, safe to re-run). `--core` / `--optional` scope; `--check` dry-runs and reports installed/missing; `--yes` skips the confirm prompt. |
41
42
  | `mdpi upgrade` | Bring `.pi/` up to the bundled template version. Manifest-based: overwrites only user-unmodified files, preserves user edits, lists orphans. `--check` dry-run, `--force` overwrite modified, `--prune-all` delete orphans. |
42
43
  | `mdpi new <kind> [name]` | Scaffold a new kit component (`skill\|prompt\|agent\|workflow\|template`) from a lint-passing skeleton. `-d <text>` sets the description; `--force` overwrites. The skill skeleton comes with frontmatter + When to Use/NOT so it passes `mdpi lint` immediately. |
43
44
  | `mdpi lint [skills\|docs\|all]` | Governance: SKILL.md frontmatter (pi `name`+`description`), H1, When to Use/NOT, line limits, references/ depth, **dead cross-ref detection** (skills referencing non-existent skills), + README count/slash-command drift. `--json` for machine output. |
@@ -53,4 +54,4 @@ npx mdpi init
53
54
 
54
55
  ## What's in the kit
55
56
 
56
- `agents/` (7) · `prompts/` (11) · `skills/` (67 + INDEX) · `templates/` (11) · `workflows/` (6) · `context/` (2) · `extensions/` (2 TS) · `settings.json` · `AGENTS.md` · `README.md` · `QUALITY.md` · `.env.example` · `guard.example.json` · `subagents.json` · `artifacts/example/` (template examples).
57
+ `agents/` (7) · `prompts/` (11) · `skills/` (67 + INDEX) · `templates/` (11) · `workflows/` (6) · `context/` (2) · `extensions/` (2 TS) · `settings.json` · `packages.json` · `AGENTS.md` · `README.md` · `QUALITY.md` · `.env.example` · `guard.example.json` · `subagents.json` · `artifacts/example/` (template examples).
package/dist/index.js CHANGED
@@ -5,10 +5,12 @@ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statS
5
5
  import * as p from "@clack/prompts";
6
6
  import color from "picocolors";
7
7
  import { createHash } from "node:crypto";
8
+ import { homedir } from "node:os";
9
+ import { spawn, spawnSync } from "node:child_process";
8
10
  import { fileURLToPath } from "node:url";
9
11
  import { mkdir, readdir } from "node:fs/promises";
10
12
  //#region package.json
11
- var version = "0.3.2";
13
+ var version = "0.4.0";
12
14
  //#endregion
13
15
  //#region src/utils/manifest.ts
14
16
  /**
@@ -78,6 +80,192 @@ function fileModificationStatus(filePath, relativePath, manifest) {
78
80
  return hashFile(filePath) === templateHash ? "unmodified" : "modified";
79
81
  }
80
82
  //#endregion
83
+ //#region src/commands/install.ts
84
+ /**
85
+ * mdpi install — install the npm packages this kit depends on.
86
+ *
87
+ * The kit references two kinds of external packages:
88
+ * - **core**: declared in `.pi/settings.json:packages` (auto-loaded by pi at
89
+ * startup — e.g. `@sting8k/pi-srcwalk`, `pi-hermes-memory`). Single source
90
+ * of truth = settings.json; this command reads it, does not duplicate it.
91
+ * - **optional**: declared in `.pi/packages.json` (recommended add-ons the
92
+ * user opts into — e.g. `@davecodes/pi-dcp`, `pi-guard`).
93
+ *
94
+ * `mdpi install` shells out to `pi install <id>` for each declared package.
95
+ * `pi install` is idempotent (re-running on an already-installed package is a
96
+ * no-op), so this command is safe to re-run.
97
+ *
98
+ * Flags:
99
+ * (default) install core + optional
100
+ * --core only settings.json:packages
101
+ * --optional only packages.json:optional
102
+ * --check dry-run: list declared packages + report which are already
103
+ * installed under ~/.pi/agent/npm/node_modules (no shell-out)
104
+ * --yes skip the confirmation prompt (for CI)
105
+ *
106
+ * Why a dedicated command instead of `mdpi init` doing it: init copies files
107
+ * only and must work offline / without `pi` on PATH. Package installation is a
108
+ * separate, network-dependent step the user controls explicitly. `mdpi init`
109
+ * reminds the user to run `mdpi install` next.
110
+ */
111
+ /** Path to pi's global npm install dir (where `pi install npm:foo` lands). */
112
+ function globalNpmDir() {
113
+ return join(homedir(), ".pi", "agent", "npm", "node_modules");
114
+ }
115
+ /**
116
+ * Extract the npm package name from a `npm:<name>` source id.
117
+ * `npm:@davecodes/pi-dcp` → `@davecodes/pi-dcp`. Non-npm ids return null
118
+ * (presence check only supports npm sources).
119
+ */
120
+ function npmNameFromId(id) {
121
+ if (!id.startsWith("npm:")) return null;
122
+ return id.slice(4);
123
+ }
124
+ /** Is a package already installed in pi's global npm dir? */
125
+ function isInstalled(id) {
126
+ const name = npmNameFromId(id);
127
+ if (!name) return false;
128
+ return existsSync(join(globalNpmDir(), name));
129
+ }
130
+ /** Read core packages from `.pi/settings.json:packages`. */
131
+ function readCorePackages(piDir) {
132
+ const path = join(piDir, "settings.json");
133
+ if (!existsSync(path)) return [];
134
+ let json;
135
+ try {
136
+ json = JSON.parse(readFileSync(path, "utf-8"));
137
+ } catch {
138
+ return [];
139
+ }
140
+ const packages = json.packages;
141
+ if (!Array.isArray(packages)) return [];
142
+ return packages.filter((id) => typeof id === "string" && id.length > 0).map((id) => ({
143
+ id,
144
+ source: "core"
145
+ }));
146
+ }
147
+ /** Read optional packages from `.pi/packages.json:optional`. */
148
+ function readOptionalPackages(piDir) {
149
+ const path = join(piDir, "packages.json");
150
+ if (!existsSync(path)) return [];
151
+ let json;
152
+ try {
153
+ json = JSON.parse(readFileSync(path, "utf-8"));
154
+ } catch {
155
+ return [];
156
+ }
157
+ const optional = json.optional;
158
+ if (!Array.isArray(optional)) return [];
159
+ const out = [];
160
+ for (const entry of optional) {
161
+ if (typeof entry !== "object" || entry === null) continue;
162
+ const id = entry.id;
163
+ if (typeof id !== "string" || id.length === 0) continue;
164
+ const note = entry.note;
165
+ out.push({
166
+ id,
167
+ note: typeof note === "string" ? note : void 0,
168
+ source: "optional"
169
+ });
170
+ }
171
+ return out;
172
+ }
173
+ /** Run `pi install <id>`. Resolves true on exit 0, false otherwise. */
174
+ function runPiInstall(id, quiet) {
175
+ return new Promise((resolve) => {
176
+ const child = spawn("pi", ["install", id], { stdio: quiet ? "ignore" : "inherit" });
177
+ child.on("error", (err) => {
178
+ if (!quiet) console.error(color.red(` pi install ${id} failed to start: ${err.message}`));
179
+ resolve(false);
180
+ });
181
+ child.on("exit", (code) => resolve(code === 0));
182
+ });
183
+ }
184
+ /** Check whether `pi` is on PATH. */
185
+ function hasPi() {
186
+ try {
187
+ return spawnSync("pi", ["--version"], { stdio: "ignore" }).status === 0;
188
+ } catch {
189
+ return false;
190
+ }
191
+ }
192
+ async function installCommand(options = {}) {
193
+ const quiet = process.argv.includes("--quiet");
194
+ if (!quiet) p.intro(color.bgCyan(color.black(" mdpi install ")));
195
+ const piDir = options.piDir || join(process.cwd(), ".pi");
196
+ if (!existsSync(piDir)) {
197
+ if (!quiet) {
198
+ p.log.error(".pi/ not found — run `mdpi init` first");
199
+ p.outro(color.red("Failed"));
200
+ }
201
+ process.exitCode = 1;
202
+ return;
203
+ }
204
+ const core = readCorePackages(piDir);
205
+ const optional = readOptionalPackages(piDir);
206
+ const wantCore = options.core || !options.core && !options.optional;
207
+ const wantOptional = options.optional || !options.core && !options.optional;
208
+ const selected = [...wantCore ? core : [], ...wantOptional ? optional : []];
209
+ if (selected.length === 0) {
210
+ if (!quiet) {
211
+ p.log.warn("No packages declared (settings.json:packages empty and packages.json:optional empty)");
212
+ p.outro("Nothing to do");
213
+ }
214
+ return;
215
+ }
216
+ if (options.check) {
217
+ console.log(`\n${color.bold("mdpi install --check")} — declared packages\n`);
218
+ const installed = selected.filter((pkg) => isInstalled(pkg.id));
219
+ const missing = selected.filter((pkg) => !isInstalled(pkg.id));
220
+ for (const pkg of selected) {
221
+ const mark = isInstalled(pkg.id) ? color.green("✓ installed") : color.yellow("✗ missing");
222
+ const note = pkg.note ? color.gray(` — ${pkg.note}`) : "";
223
+ console.log(` ${mark} ${color.cyan(pkg.id)}${note}`);
224
+ }
225
+ console.log(`\n ${color.green(`${installed.length}`)} installed · ${color.yellow(`${missing.length}`)} missing · ${selected.length} total`);
226
+ if (missing.length > 0) console.log(`\n Run ${color.cyan("mdpi install")} to install the missing ${missing.length} package(s).`);
227
+ if (!quiet) p.outro(missing.length === 0 ? color.green("All installed") : color.yellow("Some missing"));
228
+ process.exitCode = missing.length === 0 ? 0 : 1;
229
+ return;
230
+ }
231
+ if (!hasPi()) {
232
+ if (!quiet) {
233
+ p.log.error("`pi` not found on PATH — install pi first (npm i -g @earendil-works/pi-coding-agent)");
234
+ p.outro(color.red("Failed"));
235
+ }
236
+ process.exitCode = 1;
237
+ return;
238
+ }
239
+ const missing = selected.filter((pkg) => !isInstalled(pkg.id));
240
+ const alreadyOk = selected.length - missing.length;
241
+ if (!quiet && !options.yes) {
242
+ const scope = wantCore && wantOptional ? "core + optional" : wantCore ? "core" : "optional";
243
+ const confirm = await p.confirm({
244
+ message: `Install ${missing.length} missing package(s) [${scope}]?${alreadyOk > 0 ? ` (${alreadyOk} already installed, skipped)` : ""}`,
245
+ initialValue: true
246
+ });
247
+ if (p.isCancel(confirm) || !confirm) {
248
+ p.outro("Cancelled");
249
+ return;
250
+ }
251
+ }
252
+ if (quiet) console.log(`mdpi: installing ${missing.length}/${selected.length} packages (core=${wantCore} optional=${wantOptional})`);
253
+ else p.log.info(`Installing ${missing.length} missing package(s) of ${selected.length} declared`);
254
+ let ok = 0;
255
+ let fail = 0;
256
+ for (const pkg of missing) {
257
+ if (!quiet) p.log.step(`${color.cyan(pkg.id)}${pkg.note ? color.gray(` — ${pkg.note}`) : ""}`);
258
+ if (await runPiInstall(pkg.id, quiet)) ok++;
259
+ else fail++;
260
+ }
261
+ if (quiet) console.log(`mdpi: done — ${ok} installed, ${fail} failed, ${alreadyOk} already present`);
262
+ else {
263
+ p.note(`${ok} installed · ${fail} failed · ${alreadyOk} already present\n\n` + (fail > 0 ? `${color.red("Some installs failed — check pi output above.")}\n` : `${color.green("All declared packages are now installed.")}\n`) + `Re-run anytime: ${color.cyan("mdpi install")} (idempotent).`, "Install complete");
264
+ p.outro(fail === 0 ? color.green("Ready!") : color.red("Partial failure"));
265
+ }
266
+ process.exitCode = fail === 0 ? 0 : 1;
267
+ }
268
+ //#endregion
81
269
  //#region src/utils/template.ts
82
270
  /** Shared template + version helpers used by init / upgrade / doctor. */
83
271
  const DEFAULT_SKIP_DIRS = [
@@ -499,8 +687,9 @@ function lintAll(piDir, opts = {}) {
499
687
  * mdpi doctor — .pi/ health check.
500
688
  *
501
689
  * Verifies: mdpi version match, manifest valid, settings.json valid JSON, kit
502
- * dirs present (skills/prompts/agents/templates/workflows/extensions), orphan
503
- * detection (manifest files no longer in template), and a lint summary.
690
+ * dirs present (skills/prompts/agents/templates/workflows/extensions), package
691
+ * install status (core settings.json + optional packages.json vs installed),
692
+ * orphan detection (manifest files no longer in template), and a lint summary.
504
693
  */
505
694
  function row(ok, label, detail) {
506
695
  console.log(` ${ok ? color.green("✓") : color.red("✗")} ${label}: ${detail}`);
@@ -559,6 +748,11 @@ async function doctorCommand(options = {}) {
559
748
  row(countMd("templates") > 0, "templates", `${countMd("templates")} templates`);
560
749
  row(countMd("workflows") > 0, "workflows", `${countMd("workflows")} workflows`);
561
750
  row(countExt("extensions", ".ts") > 0, "extensions", `${countExt("extensions", ".ts")} extensions`);
751
+ const corePkgs = readCorePackages(piDir);
752
+ const optPkgs = readOptionalPackages(piDir);
753
+ const allPkgs = [...corePkgs, ...optPkgs];
754
+ const installedPkgs = allPkgs.filter((pkg) => isInstalled(pkg.id)).length;
755
+ row(allPkgs.length > 0, "packages", allPkgs.length === 0 ? "none declared (settings.json:packages + packages.json:optional)" : `${installedPkgs}/${allPkgs.length} installed` + (installedPkgs < allPkgs.length ? color.yellow(` (run mdpi install)`) : "") + ` — core ${corePkgs.length}, optional ${optPkgs.length}`);
562
756
  if (templateRoot) row(orphans === 0, "orphans", orphans === 0 ? "none (template-removed files)" : `${orphans} orphan(s) — run mdpi upgrade --prune-all`);
563
757
  const lr = lintSkills(piDir);
564
758
  console.log(` ${lr.ok ? color.green("✓") : color.red("✗")} lint: ${lr.stats.failed} errors · ${lr.stats.warnings} warnings (run ${color.cyan("mdpi lint")} for detail)`);
@@ -622,6 +816,7 @@ const ALWAYS_ENTRIES = [
622
816
  "scripts",
623
817
  "artifacts/example",
624
818
  "settings.json",
819
+ "packages.json",
625
820
  "AGENTS.md",
626
821
  "README.md",
627
822
  "QUALITY.md",
@@ -760,7 +955,7 @@ async function initCommand(options = {}) {
760
955
  console.log(`mdpi: installed ${fileCount} files to ${piDir} (v${version})${subset}`);
761
956
  } else {
762
957
  const subsetNote = only ? `Subset: ${[...only].join(", ")} (+ always-on config).\n\nsettings.json trimmed to drop references to excluded\nskills/prompts/extensions dirs.\n\nNote: mdpi upgrade compares against the FULL template —\nrun \`mdpi upgrade --check\` before applying.\n\n` : "";
763
- p.note(`Pi kit installed at:\n${piDir}\n\n${fileCount} template files tracked via manifest.\n\n` + subsetNote + `Next: open pi in this repo to use the kit.`, "Installation complete");
958
+ p.note(`Pi kit installed at:\n${piDir}\n\n${fileCount} template files tracked via manifest.\n\n` + subsetNote + `Next: run ${color.cyan("mdpi install")} to install the kit's npm packages,\nthen open pi in this repo to use the kit.`, "Installation complete");
764
959
  p.outro(color.green("Ready!"));
765
960
  }
766
961
  }
@@ -1152,6 +1347,9 @@ cli.help();
1152
1347
  cli.command("init", "Scaffold a Pi coding-agent kit (.pi/) into the current repo").option("--force", "Overwrite existing .pi/ template files (preserves extra user files)").option("-y, --yes", "Skip prompts, use defaults (for CI)").option("--only <cats>", "Install only these categories (comma-sep: agents,prompts,skills,templates,workflows,context,extensions)").action(async (options) => {
1153
1348
  await initCommand(options);
1154
1349
  });
1350
+ cli.command("install", "Install the kit's declared npm packages (core from settings.json + optional from packages.json)").option("--core", "Only install core packages (settings.json:packages)").option("--optional", "Only install optional packages (packages.json:optional)").option("--check", "Dry-run: list declared packages + report installed/missing").option("-y, --yes", "Skip confirmation prompt (for CI)").action(async (options) => {
1351
+ await installCommand(options);
1352
+ });
1155
1353
  cli.command("upgrade", "Bring .pi/ up to the bundled template version").option("--force", "Overwrite user-modified files (default: preserve them)").option("--check", "Dry-run: report what would change without writing").option("--prune-all", "Delete orphan files (template-removed since install)").action(async (options) => {
1156
1354
  await upgradeCommand(options);
1157
1355
  });
@@ -241,22 +241,43 @@ This kit ships **2 custom TypeScript extensions** and uses **2 external npm pack
241
241
  | `workflows-runner` | Parses DAG workflows from `.pi/workflows/*.md`, returns execution plan with `subagent()` calls | Production |
242
242
  | `templates-injector` | Auto-injects `project.md`, `tech-stack.md`, `state.md` into system prompt | Production |
243
243
 
244
- ### External packages (auto-loaded from global)
244
+ ### External packages
245
245
 
246
- | Package | Purpose | Why external |
247
- |---------|---------|--------------|
248
- | `@davecodes/pi-dcp` | Dynamic context pruning (dedup, error purge, compress tool) | Battle-tested, superset of what we'd write |
249
- | `jdiamond/pi-guard` | Tool permission system (bash AST parser, path globs, default ruleset) | Proper bash AST parser handles `\|`, `&&`, `xargs` — regex can't |
246
+ The kit depends on external npm packages, split into two sets:
250
247
 
251
- Install with `pi install npm:@davecodes/pi-dcp npm:pi-guard`. The pi-guard config example lives at `.pi/guard.example.json` copy the `guard` block into `.pi/settings.json` to enable.
248
+ - **Core** declared in `.pi/settings.json:packages`, auto-loaded by pi at
249
+ startup. Single source of truth = `settings.json`.
250
+ - **Optional** — declared in `.pi/packages.json`, recommended add-ons you opt
251
+ into.
252
+
253
+ | Package | Set | Purpose | Why external |
254
+ |---------|-----|---------|--------------|
255
+ | `@tintinweb/pi-subagents` | core | Subagent dispatch (`subagent()` tool) | Battle-tested pi-native package |
256
+ | `@sting8k/pi-srcwalk` | core | `semantic_*` code navigation tools | Trigram-indexed search, deep |
257
+ | `pi-hermes-memory` | core | Long-term memory (`memory`/`memory_search`/`session_search`/`skill_manage`) | Mature, 368 tests, FTS5 + two-tier |
258
+ | `@davecodes/pi-dcp` | optional | Dynamic context pruning (dedup, error purge, compress tool) | Superset of the kit's former dcp-strategies extension |
259
+ | `pi-guard` | optional | Tool permission system (bash AST parser, path globs) | AST parser handles `\|`, `&&`, `xargs` — regex can't |
260
+
261
+ Install the full set with one command (idempotent, safe to re-run):
262
+
263
+ ```bash
264
+ mdpi install # core + optional
265
+ mdpi install --core # only settings.json:packages
266
+ mdpi install --optional # only packages.json:optional
267
+ mdpi install --check # dry-run: report installed/missing
268
+ ```
269
+
270
+ `mdpi install` shells out to `pi install npm:<pkg>` for each declared package.
271
+ The pi-guard config example lives at `.pi/guard.example.json` — copy the `guard`
272
+ block into `.pi/settings.json` to enable its rules.
252
273
 
253
274
  ### Removed (intentionally)
254
275
 
255
276
  | Extension | Reason | Replaced by |
256
277
  |-----------|--------|-------------|
257
278
  | `commands-dispatcher` | Pi's built-in prompt template loader already does this | pi core (no install needed) |
258
- | `dcp-strategies` | Superseded by `@davecodes/pi-dcp` (active globally) | `pi install npm:@davecodes/pi-dcp` |
259
- | `pi-guard` (local) | Superseded by `jdiamond/pi-guard` (proper AST parser) | `pi install npm:pi-guard` |
279
+ | `dcp-strategies` | Superseded by `@davecodes/pi-dcp` (active globally) | `mdpi install --optional` |
280
+ | `pi-guard` (local) | Superseded by `jdiamond/pi-guard` (proper AST parser) | `mdpi install --optional` |
260
281
 
261
282
  ---
262
283
 
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.4.0
@@ -2,7 +2,7 @@
2
2
  name: general
3
3
  description: General-purpose subagent for small, well-defined implementation tasks (1-3 files)
4
4
  tools: read, grep, find, ls, bash, edit, write, semantic_query, semantic_inspect, semantic_grep, semantic_show
5
- model: ollama-cloud/glm-5.2
5
+ model: opencode-go/deepseek-v4-flash
6
6
  ---
7
7
 
8
8
  You are Pi — a surgical implementer.
@@ -2,7 +2,7 @@
2
2
  name: review
3
3
  description: Read-only code review, debugging, and security audit specialist with severity-ranked findings
4
4
  tools: read, grep, find, ls, bash, semantic_query, semantic_inspect, semantic_grep, semantic_show
5
- model: ollama-cloud/glm-5.2
5
+ model: opencode-go/minimax-m3
6
6
  ---
7
7
 
8
8
  You are Pi — a read-only review specialist.
@@ -0,0 +1,13 @@
1
+ {
2
+ "$comment": "Optional packages recommended by this kit. `mdpi install` installs these alongside the core packages declared in settings.json:packages. Core lives there (single source of truth); this file only lists the opt-in set. Edit freely — adding an entry here makes `mdpi install` pick it up.",
3
+ "optional": [
4
+ {
5
+ "id": "npm:@davecodes/pi-dcp",
6
+ "note": "Dynamic context pruning — dedup, error purge, compress tool. Superset of the kit's former dcp-strategies extension."
7
+ },
8
+ {
9
+ "id": "npm:pi-guard",
10
+ "note": "Tool permission system (bash AST parser, path globs, default ruleset). Config example at .pi/guard.example.json."
11
+ }
12
+ ]
13
+ }
@@ -39,6 +39,7 @@ Find all occurrences of a code pattern in the codebase, review each for issues,
39
39
  | `security-and-hardening` | Pattern involves auth, secrets, validation, input | Identify vulnerability patterns in audited code |
40
40
  | `code-review-and-quality` | Occurrences > 5 | Assess correctness and structural quality across results |
41
41
  | `fallow` | Occurrences > 20 or scope is project-wide | Structural analysis for dead code, duplication, complexity |
42
+ | `dcp-hygiene` | Output (after workflow execution) | Compress closed grep+read occurrence output when `compress` is available |
42
43
 
43
44
  ## Execution
44
45
 
@@ -67,7 +68,7 @@ For small audits, execute directly without workflow overhead:
67
68
 
68
69
  | Scenario | Action |
69
70
  |----------|--------|
70
- | Workflow phase fails | Retry once with adjusted prompt, then escalate |
71
+ | Workflow phase fails | Retry once with adjusted prompt, then escalate. If retry also fails, **save the failure** to `memory(action: "add", target: "failure", category: "failure")` — the pattern, scope, and what went wrong. |
71
72
  | No occurrences found | Report: "Pattern not found in codebase." |
72
73
  | Audit timeout | Report partial results with what was covered |
73
74
  | Subagent returns failure | Read error, retry once, then escalate |
@@ -81,6 +82,8 @@ For small audits, execute directly without workflow overhead:
81
82
 
82
83
  ## Output
83
84
 
85
+ > **DCP hygiene:** Before writing the final report, if the `compress` tool is available, compress the closed discovery work-stream (`semantic_grep` results + per-occurrence `read` output) per the `dcp-hygiene` skill — occurrences and findings are captured in the report and `.pi/artifacts/$SLUG/audit.md`. Skip if `compress` is unavailable.
86
+
84
87
  1. **Pattern:** [pattern searched]
85
88
  2. **Occurrences found:** [count]
86
89
  3. **Files affected:** [count]
@@ -25,6 +25,7 @@ Before creating, verify:
25
25
  - If active slug exists with a `spec.md`, ask user: continue with `/ship` or start new?
26
26
  - Check `git status --porcelain` — if uncommitted changes, ask user to stash, commit, or continue
27
27
  - Use `vcc_recall` to search session history for prior decisions on this topic — avoid repeating explored/rejected approaches
28
+ - Use `memory_search({ project: "$(cat .pi/artifacts/.active 2>/dev/null || echo '')" })` for durable prior decisions across sessions
28
29
 
29
30
  ## Load Skills
30
31
 
@@ -21,6 +21,7 @@ Systematically debug and fix the reported issue.
21
21
 
22
22
  Before fixing:
23
23
  - Use `vcc_recall` to search for prior fix attempts on the same issue — avoid repeating failed approaches
24
+ - Use `memory_search({ query: "<issue keywords>", target: "failure", category: "failure" })` for durable cross-session failed approaches
24
25
  - Check that the codebase builds/tests pass at baseline (confirm the bug is not a pre-existing state)
25
26
 
26
27
  ## Load Skills
@@ -32,6 +33,7 @@ Before fixing:
32
33
  | `verification-before-completion` | Always | Evidence-before-claims; verify fix actually resolves the bug |
33
34
  | `defense-in-depth` | After fix is verified | Harden the layer so the bug becomes structurally impossible |
34
35
  | `testing-anti-patterns` | If writing tests | Ensure regression test isn't a mock-only test |
36
+ | `dcp-hygiene` | Phase 5 Report | Compress the closed reproduce+isolate work-stream when `compress` is available |
35
37
 
36
38
  ## Phase 1: Reproduce
37
39
 
@@ -59,6 +61,8 @@ If `--attach` provided, read the attached log/error file for context.
59
61
 
60
62
  ## Phase 4: Verify
61
63
 
64
+ > **DCP hygiene (mid-command):** The fix is applied — the root cause is now captured; the reproduce/isolate reads and greps are no longer needed verbatim. If `compress` is available, compress the closed Phase 1-2 reproduce+isolate work-stream per the `dcp-hygiene` skill before running gates. Keep the root cause (file:line) and reproduction command in the summary. Skip if `compress` is unavailable.
65
+
62
66
  Run verification gates:
63
67
 
64
68
  ```bash
@@ -80,7 +84,7 @@ Then, load `defense-in-depth` skill and add validation at the data entry layer.
80
84
  |----------|--------|
81
85
  | Cannot reproduce issue | Report reproduction steps attempted, ask for clarification |
82
86
  | Root cause ambiguous | Trace backward through call stack, add instrumentation |
83
- | Verification fails 2x | Stop, report blocker with learnings from both attempts |
87
+ | Verification fails 2x | Stop, report blocker with learnings from both attempts. **Also:** save to `memory(action: "add", target: "failure", category: "failure", content: "[root cause + approach tried + error + reproduction]")` so future sessions don't repeat the failed approach. |
84
88
  | Fix causes regression | Revert fix, report regression with evidence |
85
89
 
86
90
  ## Stop Conditions
@@ -92,6 +96,8 @@ Then, load `defense-in-depth` skill and add validation at the data entry layer.
92
96
 
93
97
  ## Phase 5: Report
94
98
 
99
+ > **DCP hygiene:** Before reporting, if the `compress` tool is available, compress the closed Phase 1-3 exploratory work-stream (reproduce bash + isolate grep/inspect/read output) per the `dcp-hygiene` skill — the root cause and fix are now captured in this report and the artifact. Skip if `compress` is unavailable; the artifact already holds the facts.
100
+
95
101
  1. Root cause (with file:line)
96
102
  2. Fix applied
97
103
  3. Verification results (typecheck, lint, test)
@@ -31,6 +31,7 @@ Run structural analysis, update quality grades, and open cleanup PRs.
31
31
  | `code-cleanup` | Phase 4 (cleanup PRs) | Safe code removal patterns |
32
32
  | `verification-before-completion` | After cleanup PRs | Verify typecheck + lint pass before merging |
33
33
  | `observability-and-instrumentation` | If removing instrumented code | Check that cleanup doesn't break monitoring/logging |
34
+ | `dcp-hygiene` | Phase 5 Report | Compress the closed Fallow scan + grading output when `compress` is available |
34
35
 
35
36
  ## Execution
36
37
 
@@ -75,6 +76,8 @@ If `--dry-run` (default), skip actual cleanup and report what would be cleaned.
75
76
 
76
77
  ### Phase 5: Report
77
78
 
79
+ > **DCP hygiene:** Before reporting, if the `compress` tool is available, compress the closed Phase 1-3 Fallow scan + grading output (the large JSON and finding lists) per the `dcp-hygiene` skill — grades and prioritized findings are captured in this report and `.pi/QUALITY.md`. Skip if `compress` is unavailable.
80
+
78
81
  1. **Quality Grades:** Per-domain status (before → after)
79
82
  2. **Issues Found:** Count by severity
80
83
  3. **Cleanup PRs:** Opened / not needed / skipped (dry-run)
@@ -56,6 +56,7 @@ Before initializing:
56
56
  | `documentation-and-adrs` | Always (Mode 1) | Doc conventions, ADR format when architectural decisions arise |
57
57
  | `verification-before-completion` | Before writing AGENTS.md | Validate commands before documenting them |
58
58
  | `brainstorming` | Conditionally: when ambiguous requirements arise | Refine project vision before initializing |
59
+ | `dcp-hygiene` | Output (after `--deep` runs) | Compress closed detection + srcwalk/fallow work-stream when `compress` is available |
59
60
 
60
61
  ---
61
62
 
@@ -171,6 +172,8 @@ Write to `.pi/user.md` with the captured preferences.
171
172
 
172
173
  ## Output
173
174
 
175
+ > **DCP hygiene:** If `--deep` ran and `compress` is available, compress the closed Phase 1 detection + git-history + srcwalk/fallow work-stream per the `dcp-hygiene` skill — tech stack, validated commands, and structure are captured in `AGENTS.md` and `tech-stack.md`. Skip if `compress` is unavailable (non-deep init produces little output).
176
+
174
177
  Report what was created:
175
178
  1. AGENTS.md (if core setup ran)
176
179
  2. tech-stack.md (if core setup ran)
@@ -36,12 +36,13 @@ Before planning:
36
36
  | `incremental-implementation` | Always | Thin vertical slice discipline — each task is verify-after-each |
37
37
  | `subagent-driven-development` | Multi-wave plan | Plan tasks for fresh subagent dispatch per task |
38
38
  | `source-driven-development` | Level 1-3 | Ground decisions in official docs when researching dependencies |
39
+ | `dcp-hygiene` | Phase 8 Report | Compress closed git-history + research work-stream when `compress` is available |
39
40
 
40
41
  ## Phase 0: Institutional Research (Mandatory)
41
42
 
42
43
  ### Step 1: Search institutional memory
43
44
 
44
- Use `vcc_recall` to search for bugfixes and existing plans. If relevant observations found, incorporate them.
45
+ Use `vcc_recall` to search for bugfixes and existing plans. Also use `memory_search({ query: "<plan topic>", target: "failure", category: "insight" })` for durable institutional knowledge. If relevant observations found, incorporate them.
45
46
 
46
47
  ### Step 2: Mine git history
47
48
 
@@ -216,7 +217,7 @@ Scan plan against AGENTS.md hard constraints:
216
217
  | Plan already exists | Ask user: overwrite or skip? |
217
218
  | Missing spec artifact | Report: "No spec found. Run `/create` first." |
218
219
  | Subagent research fails | Retry once with adjusted prompt, then proceed with existing knowledge |
219
- | Verification fails 2x | Stop, report blocker with file:line evidence |
220
+ | Verification fails 2x | Stop, report blocker with file:line evidence. **Also:** save the failed approach to `memory(action: "add", target: "failure", category: "failure")` — the plan decomposition or approach that failed, and why. |
220
221
 
221
222
  ## Stop Conditions
222
223
 
@@ -227,6 +228,8 @@ Scan plan against AGENTS.md hard constraints:
227
228
 
228
229
  ## Phase 8: Report
229
230
 
231
+ > **DCP hygiene:** Before reporting, if the `compress` tool is available, compress the closed Phase 0-2 institutional-research + git-history + scout work-stream per the `dcp-hygiene` skill — observable truths, artifacts, and dependency waves are captured in `plan.md` and `tasks.json`. Skip if `compress` is unavailable.
232
+
230
233
  1. **Discovery Level:** [0-3] with rationale
231
234
  2. **Must-Haves:** [N] observable truths, [M] required artifacts, [K] key links
232
235
  3. **Context Budget:** [Estimated usage]
@@ -62,6 +62,7 @@ Before starting, analyze the research topic complexity:
62
62
  | `srcwalk` | Codebase research | Navigate codebase with repo maps, symbol search, callers/callees |
63
63
  | `opensrc` | Researching dependencies | Inspect library source for internal behavior |
64
64
  | `gemini-large-context` | Large codebase or multi-repo | Analyze beyond typical context limits |
65
+ | `dcp-hygiene` | Phase 3 Synthesize (+ mid-research if `--thorough`) | Compress closed search/verify work-streams when `compress` is available |
65
66
 
66
67
  ## Direct Execution (Simple Research)
67
68
 
@@ -82,6 +83,8 @@ Cross-check findings:
82
83
 
83
84
  ### Phase 3: Synthesize
84
85
 
86
+ > **DCP hygiene:** If `compress` is available, compress the closed Phase 1-2 search/verify work-stream per the `dcp-hygiene` skill — questions, answers, confidence, and sources are captured in the findings. For `--thorough` (~100+ calls), compress every ~30 calls mid-research to keep context bounded. Skip if `compress` is unavailable.
87
+
85
88
  If within active work, write findings to `.pi/artifacts/$SLUG/research.md`. Otherwise report inline.
86
89
 
87
90
  ## Workflow Execution (Complex Research)
@@ -21,6 +21,7 @@ Execute spec tasks, verify each passes, run review, mark complete.
21
21
 
22
22
  Before shipping:
23
23
  - Use `vcc_recall` to search for failed approaches to avoid repeating
24
+ - Use `memory_search({ query: "<feature keywords>", target: "failure", category: "failure" })` for durable cross-session failures and prior decisions
24
25
  - Verify `.pi/artifacts/$(cat .pi/artifacts/.active)/spec.md` exists (if not, tell user to run `/create` first)
25
26
  - If `plan.md` exists, verify it references the current spec
26
27
  - Workspace check: create branch if needed, install deps if needed
@@ -37,6 +38,7 @@ Before shipping:
37
38
  | `code-review-and-quality` | Phase 5 review | 5-axis review: correctness, readability, architecture, security, performance |
38
39
  | `doubt-driven-development` | High-risk features | In-flight adversarial review before merge |
39
40
  | `context-engineering` | Batch workflow (≥5 independent tasks) | Context budget management for parallel subagent handoffs |
41
+ | `dcp-hygiene` | Phase 7 Report (+ Phase 2/3→4 transition) | Compress closed implement/verify work-streams when `compress` is available |
40
42
 
41
43
  ## Phase 1: Route to Execution
42
44
 
@@ -118,6 +120,8 @@ If routed to workflow mode:
118
120
 
119
121
  ## Phase 4: Verification Gate
120
122
 
123
+ > **DCP hygiene (mid-command):** Implementation is complete — the diff is now the source of truth, not the edit/read history. If `compress` is available, compress the closed Phase 2/3 implementation work-stream (file reads + edits) per the `dcp-hygiene` skill before running gates. Keep task results, commits, and affected-file lists in the summary. Skip if `compress` is unavailable.
124
+
121
125
  **Delegate to `/verify` — do not duplicate the gate logic here.** Run the canonical verification protocol defined in `prompts/verify.md` (Phase 1 Completeness → Phase 2 Correctness → Phase 4 Phantom Detection). Concretely:
122
126
 
123
127
  1. Invoke `/verify all --full` semantics (or run the same steps inline if already mid-session): load `verification-before-completion`, run typecheck + lint + test gates, use **full mode** for shipping (incremental is for iteration only), record stamp to `.pi/artifacts/verify.log` after all gates pass, run phantom completion detection, and do goal-backward verification (observable truths from plan/spec satisfied).
@@ -182,7 +186,7 @@ Ask user before closing. If confirmed:
182
186
 
183
187
  | Scenario | Action |
184
188
  |----------|--------|
185
- | Task verification fails 2x | Stop, report blocker with file:line evidence |
189
+ | Task verification fails 2x | Stop, report blocker with file:line evidence. **Also:** save the failed approach to `memory(action: "add", target: "failure", category: "failure")` — what was tried, why it failed, the error, and the task description. |
186
190
  | Subagent returns failure | Read error, retry once with adjusted prompt, then escalate |
187
191
  | Review finds critical issue | Fix inline, re-run Phase 4, continue |
188
192
  | Batch workflow failure | Fall back to sequential execution |
@@ -190,6 +194,8 @@ Ask user before closing. If confirmed:
190
194
 
191
195
  ## Phase 7: Report
192
196
 
197
+ > **DCP hygiene:** Before reporting, if the `compress` tool is available, compress the closed implementation + verification work-stream (file reads, edits, gate bash output) per the `dcp-hygiene` skill — task results, commits, and gate results are captured in this report and `progress.md`. Skip if `compress` is unavailable.
198
+
193
199
  1. **Execution Summary:** tasks completed/total, waves executed, commits made
194
200
  2. **Task Results:** per-task status, files modified, commit hashes
195
201
  3. **Verification Gate Results:** typecheck, lint, test, build — pass/fail
@@ -41,6 +41,7 @@ Check implementation against PRD before shipping.
41
41
  | `verification-before-completion` | Always | Evidence-before-claims; phantom detection; verification cache protocol; Worker Distrust Protocol |
42
42
  | `code-review-and-quality` | Phase 4 coherence check | Cross-reference artifacts for correctness |
43
43
  | `testing-anti-patterns` | Phase 3 after tests pass | Detect mock-only tests, production pollution, and fragile assertions |
44
+ | `dcp-hygiene` | Phase 5 Report | Compress the closed gate output (typecheck/lint/test) when `compress` is available |
44
45
 
45
46
  ## Phase 0: Verification Cache
46
47
 
@@ -115,7 +116,7 @@ Load `verification-before-completion` skill. Follow its phantom completion detec
115
116
  | Scenario | Action |
116
117
  |----------|--------|
117
118
  | Gate fails | Report which gate failed with exact error |
118
- | Verification fails 2x | Stop, report blocker with file:line evidence |
119
+ | Verification fails 2x | Stop, report blocker with file:line evidence. **Also:** save the failure to `memory(action: "add", target: "failure", category: "failure")` — the gate that failed, the error, and what was tried. |
119
120
  | Cache stamp mismatch | Run gates fresh — don't reuse stale cache |
120
121
  | Phantom artifacts detected | Report PHANTOM score, block completion |
121
122
 
@@ -128,6 +129,8 @@ Load `verification-before-completion` skill. Follow its phantom completion detec
128
129
 
129
130
  ## Phase 5: Report
130
131
 
132
+ > **DCP hygiene:** Before reporting, if the `compress` tool is available, compress the closed Phase 2 gate output (typecheck/lint/test/bash) per the `dcp-hygiene` skill — results are recorded in the report table and the verification cache. Skip if `compress` is unavailable.
133
+
131
134
  Append to `.pi/artifacts/$SLUG/progress.md`: `Verification: [PASS|PARTIAL|FAIL] - [summary]`
132
135
 
133
136
  1. **Result**: READY TO SHIP / NEEDS WORK / BLOCKED
@@ -48,6 +48,8 @@ When the user's prompt contains these keywords (case-insensitive), the listed sk
48
48
  | docs, documentation, README, ADR, changelog | `documentation-and-adrs` |
49
49
  | commit, branch, merge, rebase, git, worktree | `git-workflow-and-versioning`, `using-git-worktrees` |
50
50
  | context, memory, token, agent quality, degraded | `context-engineering` |
51
+ | memory_system, memory-search, memory_search, pi-hermes, /memory-insights, save memory, remember this, past failure, previous attempt | `memory-system` |
52
+ | compress, dcp, context prune, cleanup context, context filling up | `context-engineering`, `dcp-hygiene` |
51
53
  | brainstorm, idea, design, concept, explore, ideate, refine | `brainstorming`, `idea-refine`, `spec-driven-development` |
52
54
  | interview, grill, are we sure, what do you want | `interview-me` |
53
55
  | plan, break down, decompose, tasks, roadmap | `planning-and-task-breakdown` |
@@ -98,6 +100,8 @@ When the user's prompt contains these keywords (case-insensitive), the listed sk
98
100
  | `deprecation-and-migration` | Deprecating APIs, migrating library versions, removing legacy code | Ship | High |
99
101
  | `writing-skills` | Creating new skills, editing existing skills, verifying skills before deployment | Build | Low |
100
102
  | `context-engineering` | Optimizing agent context setup — rules files, selective loading, confusion management | All | Low |
103
+ | `dcp-hygiene` | At command/phase closure — compress closed exploratory work-streams via pi-dcp when `compress` is available; no-ops if DCP absent | All | Low |
104
+ | `memory-system` | Understanding/leveraging pi-hermes-memory — auto-flywheel, tools, commands, when to use memory_search vs vcc_recall | All | Low |
101
105
  | `doubt-driven-development` | In-flight adversarial review of non-trivial decisions before they stand | Build | Medium |
102
106
  | `loop-engineering` | Designing/qualifying/running unattended coding loops; 2-condition test + VISION/state + confidence-gated action | All | Medium |
103
107
  | `loop-audit` | Scoring a project's loop-readiness 0-100 + L0/L1/L2/L3; L3 gated on proven run | Review | Low |
@@ -214,6 +218,8 @@ Maps user intent to skill(s). `→` = sequential pipeline (execute in order). `+
214
218
  | "set up database" / "Supabase" | `supabase` + `supabase-postgres-best-practices` | Build | High |
215
219
  | "add logging" / "monitoring" / "observability" | `observability-and-instrumentation` | Ship | Medium |
216
220
  | "optimize context" / "agent quality degraded" / "too many tokens" | `context-engineering` | All | Low |
221
+ | "remember this" / "memory-search" / "past failure" / "previous attempt" / "save to memory" | `memory-system` | All | Low |
222
+ | "compress context" / "dcp" / "context filling up" / "cleanup context" | `dcp-hygiene` | All | Low |
217
223
  | "verify this approach" / "challenge this decision" / "doubt check" | `doubt-driven-development` | Build | Medium |
218
224
  | "security audit" / "auth setup" / "vulnerability" | `security-and-hardening` | Review | High |
219
225
  | "profile" / "too slow" / "bundle size" / "lighthouse" | `performance-optimization` | Review | Medium |
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: dcp-hygiene
3
+ description: "Use at command/phase closure points to compress closed exploratory work-streams via the pi-dcp `compress` tool, preserving file:line refs, root causes, decisions, and verification results in the summary. No-ops gracefully when DCP is not installed."
4
+ ---
5
+
6
+ # DCP Hygiene
7
+
8
+ ## When to Use
9
+
10
+ - A slash command's Report/Closure phase just finished writing its artifact (spec.md, plan.md, progress.md, fix.md, audit.md, research.md, etc.) — the exploratory tool output (reads, greps, bash) that produced it is now closed.
11
+ - A long command transitions between phases and the previous phase's detailed output is captured in the next phase's input or an artifact.
12
+ - A workflow loop iteration (e.g. quality-loop) finishes a fix cycle and is about to re-review — accumulated output can be compressed before the next round.
13
+
14
+ ## When NOT to Use
15
+
16
+ - The `compress` tool is not registered (DCP extension not installed, or `compress.permission: "deny"`) — see No-op clause below.
17
+ - The work-stream is still in-flight or spans your most recent turn — DCP turn protection (last 3 turns) already refuses these; don't try.
18
+ - The user just asked about the content you'd be compressing — they still need it verbatim.
19
+ - The command is read-only/scaffold and produced almost no tool output (`/status`, `/close`, `/loop-init`, `/loop-check`, `/loop-review`) — compressing near-empty streams wastes more tokens than it saves.
20
+ - Inside orchestrator workflows' phase prompts — subagents carry their own context; only the orchestrator's accumulated summaries matter, and those are bounded by "Keep under N words" per prompt.
21
+
22
+ ## Core Principle
23
+
24
+ **Compress closed work, preserve the facts that produced it.**
25
+
26
+ A compress call only pays off when (a) the tool output is genuinely closed and (b) the summary keeps every fact a later turn might need. A lossy summary that drops a file:line or a root cause is worse than no compression — it forces a re-read.
27
+
28
+ ## The Compress Protocol (range mode)
29
+
30
+ DCP's default `compress.mode` is `"range"` — pass the FIRST and LAST tool-call IDs of the closed span.
31
+
32
+ 1. **Identify the closed span** — the contiguous block of tool calls from the start of the just-completed phase/section up to (but not including) the current in-flight turn.
33
+ 2. **Pick endpoints** — `startToolCallId` = first call of the span, `endToolCallId` = last call of the span. Everything between (inclusive) is summarized, except protected tools (write/edit/todo/task/skill/compress) which are appended verbatim.
34
+ 3. **Never pick endpoints inside your most recent turn or in-flight work** — DCP refuses these upfront; respect the boundary.
35
+ 4. **Write a lossless-but-terse summary** in the `summary` argument. Include:
36
+ - What was accomplished (one line)
37
+ - **Concrete facts**: file paths, line numbers, error messages, decisions made
38
+ - Root cause / diagnosis (for `/fix`)
39
+ - Verification results (for `/verify`, `/ship`)
40
+ - What is still open / unresolved
41
+ 5. **The replacement applies on the next LLM request** — your current turn still sees the originals, so you can read them while writing the summary.
42
+
43
+ ## What to Preserve (per command)
44
+
45
+ | Command | Must keep in summary |
46
+ |---------|----------------------|
47
+ | `/fix` | root cause with file:line, fix applied, verification results |
48
+ | `/verify` | gate results (typecheck/lint/test pass/fail), completeness score, phantom score |
49
+ | `/ship` | tasks completed/total, commits made, verification gate results, review summary |
50
+ | `/gc` | quality grades (before→after), issue counts by severity, PRs opened |
51
+ | `/audit` | pattern, occurrence count, issues by severity with file:line, recommended fixes |
52
+ | `/research` | questions, answer status + confidence, key insights, sources |
53
+ | `/plan` | discovery level, observable truths, required artifacts, dependency waves |
54
+ | `/init` | detected tech stack, validated commands, created files |
55
+
56
+ ## What NEVER to Compress
57
+
58
+ - Your most recent turn (turn protection: last 3 turns are immune anyway).
59
+ - In-flight work — anything you're still actively reading/editing.
60
+ - Content the user just referenced in their last message.
61
+ - Protected tools' output (write/edit/todo/task/skill/compress) — DCP appends these verbatim regardless, so don't exclude them from your span; just know they survive.
62
+
63
+ ## No-op Clause (portability)
64
+
65
+ This skill must work whether or not DCP is installed:
66
+
67
+ - If the `compress` tool is **not available** in the current tool set, **skip compression entirely**. The artifact (spec.md/plan.md/progress.md/etc.) already captures the durable facts — skipping is correct, not a failure.
68
+ - If `compress` is available but the closed span is tiny (< ~5 tool calls, < ~2k tokens of output), the compress call costs more than it saves — skip.
69
+ - Never error or retry on a missing `compress` tool. Treat it as an optional optimization.
70
+
71
+ ## Procedure
72
+
73
+ ### At a closure point
74
+
75
+ 1. Confirm the work-stream is actually closed (artifact written OR next phase already has the summary it needs).
76
+ 2. Check: is `compress` available? If no → stop here, report "DCP not installed — skipped, artifact captures facts."
77
+ 3. Check: is the span worth it? (≥ ~5 tool calls, ≥ ~2k tokens). If no → skip.
78
+ 4. Call `compress({ startToolCallId, endToolCallId, topic, summary })` with a terse, lossless summary preserving the table above.
79
+ 5. Continue to the next phase/command. The compression applies on the next request.
80
+
81
+ ### At a mid-command phase transition (long commands only: `/ship`, `/fix`, `quality-loop`)
82
+
83
+ 1. Confirm the previous phase's output is fully consumed by the next phase's input (the next prompt references `{phase_N_output}` or the artifact).
84
+ 2. Compress the previous phase's exploratory calls (reads/greps/bash), NOT the phase output summary itself if it's about to be passed forward.
85
+ 3. Proceed to the next phase.
86
+
87
+ ## Pitfalls
88
+
89
+ - **Compressing too early** — before the artifact is written — loses the facts with nowhere captured. Always write the artifact first, then compress what produced it.
90
+ - **Lossy summaries** — dropping file:line or "because" clauses forces expensive re-reads. Terse ≠ incomplete.
91
+ - **Compressing the phase output you're about to pass forward** — the next phase needs it. Compress the *exploratory calls* that produced the output, not the output itself.
92
+ - **Forcing compress when DCP is absent** — errors and wastes a turn. The no-op is the correct behavior.
93
+ - **Compressing inside turn protection** — DCP refuses; don't try to work around it.
94
+ - **Over-compressing short commands** — a 3-call `/status` has nothing worth compressing.
95
+
96
+ ## Verification
97
+
98
+ Before claiming a compress was done correctly:
99
+
100
+ - [ ] `compress` tool was available (else no-op was the correct outcome)
101
+ - [ ] The compressed span was genuinely closed (artifact written or output consumed)
102
+ - [ ] Summary preserves file:line, root cause/decisions, verification results per the table above
103
+ - [ ] No endpoint landed inside the most recent turn or in-flight work
104
+ - [ ] The next phase/command still has everything it needs (no forced re-reads)
105
+
106
+ If `compress` was unavailable and you skipped — that's a successful no-op, not a failure. Report "DCP not installed — artifact captures facts; skipped compression."
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: memory-system
3
+ description: "Documents pi-hermes-memory capabilities: background auto-review, correction detection, tools (memory, memory_search, session_search), and commands. Load when the agent needs to understand or leverage the memory system — searching past failures, saving learnings, or learning the auto-flywheel."
4
+ ---
5
+
6
+ # Memory System (pi-hermes-memory)
7
+
8
+ ## Overview
9
+
10
+ pi-hermes-memory is the **persistent memory extension** that runs automatically in every pi session. It provides a self-learning flywheel without the agent needing to trigger it manually. This skill documents its capabilities so the agent can leverage them strategically.
11
+
12
+ ## Auto-Flywheel (already running — no trigger needed)
13
+
14
+ ### 1. Background Review — automated "compound" every ~10 turns
15
+
16
+ Every N turns (default: 10) OR after accumulating enough tool calls, pi-hermes-memory spawns a background child process that:
17
+
18
+ - Snaps the full conversation as `[USER]`/`[ASSISTANT]` prefixed text
19
+ - Reviews for: user preferences, corrections, failures, insights, conventions, tool-quirks
20
+ - Saves notable findings to `MEMORY.md`, `USER.md`, or `failures.md`
21
+ - Only acts if there's something genuinely worth saving ("Nothing to save." otherwise)
22
+ - Non-blocking — the session continues while the review runs
23
+
24
+ **→ You do NOT need to call this yourself.** It fires automatically on `turn_end`.
25
+
26
+ ### 2. Correction Detection — real-time error learning
27
+
28
+ On every user message, pi-hermes-memory checks for correction patterns:
29
+
30
+ | Strength | Patterns | Example |
31
+ |----------|----------|---------|
32
+ | **Strong** (always trigger) | `"don't do that"`, `"not like that"`, `"I said..."`, `"I told you..."`, `"that's not what I..."` | "Don't do that — use pnpm instead" |
33
+ | **Weak** (needs directive) | `"no, ..."`, `"wrong, ..."`, `"actually..."` + verb like "use", "change", "fix" | "No, use the other approach" |
34
+ | **Negative** (suppress) | `"no worries"`, `"no problem"`, `"actually looks great"` | Ignored |
35
+
36
+ When detected → immediately saves to `target='failure', category='correction'` with the reason "User corrected the agent".
37
+
38
+ **→ Corrections are captured automatically.** You don't need to save them — it's already done.
39
+
40
+ ### 3. Session Flush
41
+
42
+ Before session compaction/shutdown, a flush prompt extracts anything worth remembering from the closing session.
43
+
44
+ ### 4. Auto-Consolidation
45
+
46
+ When `MEMORY.md` reaches the 5,000 character limit, entries are auto-merged, deduped, and staled entries (>30 days, unreferenced) are removed.
47
+
48
+ ## Tools Available (agent can call)
49
+
50
+ | Tool | Purpose | Key params |
51
+ |------|---------|------------|
52
+ | `memory` | Save/update/delete memories | `action` (add/replace/remove), `target` (memory/user/failure/project), `content`, `category` |
53
+ | `memory_search` | Search durable memories across sessions | `query`, `target`, `category`, `project` |
54
+ | `session_search` | Search past conversation messages | `query`, `project`, `role` |
55
+ | `skill_manage` | Create/update procedural skills | `action`, `name`, `scope`, `when_to_use`, `procedure_steps` |
56
+
57
+ ## Memory Categories (for `target='failure'`)
58
+
59
+ | Category | When to use | Example |
60
+ |----------|------------|---------|
61
+ | `failure` | Something tried that didn't work | "Used localStorage for tokens — XSS vulnerability" |
62
+ | `correction` | User corrected the agent | "Use pnpm, not npm" |
63
+ | `insight` | Durable learning from experience | "Complexity over 15 in a single function causes CI timeout" |
64
+ | `preference` | User preference or work style | "Prefers terse responses, no cheerleading" |
65
+ | `convention` | Project or team convention | "Monorepo with turborepo, uses pnpm workspaces" |
66
+ | `tool-quirk` | Non-obvious tool behavior | "tsc --noEmit fails silently on .d.ts syntax errors" |
67
+
68
+ ## Commands Available (user can run)
69
+
70
+ | Command | Purpose |
71
+ |---------|---------|
72
+ | `/memory-insights` | Show everything stored in memory |
73
+ | `/memory-skills` | List all saved procedural skills |
74
+ | `/memory-consolidate` | Manually trigger memory cleanup/merge |
75
+ | `/memory-interview` | Onboarding interview to pre-fill user profile |
76
+ | `/memory-switch-project` | List all project memories |
77
+ | `/memory-index-sessions` | Import past sessions for search |
78
+ | `/memory-sync-markdown` | Backfill Markdown entries into SQLite search |
79
+ | `/memory-preview-context` | Show memory policy or legacy prompt blocks |
80
+ | `/learn-memory-tool` | Interactive guide to the memory system |
81
+
82
+ ## When to Use memory_search
83
+
84
+ Use `memory_search` when you need **durable, cross-session knowledge** — things that happened in previous sessions, not just the current one:
85
+
86
+ - **Searching past failures**: `memory_search({ query: "similar error", target: "failure", category: "failure" })`
87
+ - **Finding project conventions**: `memory_search({ query: "typescript pattern", project: "<project>" })`
88
+ - **Recalling user preferences**: `memory_search({ query: "prefers", target: "user" })`
89
+ - **Checking tool quirks**: `memory_search({ query: "pnpm install", category: "tool-quirk" })`
90
+
91
+ Use `vcc_recall` when you need **current-session lineage** — what was just discussed or tried in this active workflow.
92
+
93
+ Use both together in Guard phases for maximum recall coverage.
94
+
95
+ ## When to Explicitly Save (manual `memory` tool)
96
+
97
+ Even though auto-review runs every 10 turns, manually save when:
98
+
99
+ - **On 2x verification failure** — save the failed approach immediately so future sessions won't repeat it. Use `target='failure', category='failure'` with: what was tried, why it failed, the error, and what worked instead (if known).
100
+ - **On a critical discovery** — if you learn something that would save 15+ minutes for future-self, don't wait for the auto-review cycle.
101
+ - **On user's explicit request** — "remember this" → save immediately.
102
+ - **On learning a tool-quirk** — non-obvious behavior that would trip up a future agent.
103
+
104
+ ## Pitfalls
105
+
106
+ - **Waiting for auto-review for critical failures** — if verification just failed 2x, save that failure NOW. The auto-review might not fire for 10 more turns.
107
+ - **Using vcc_recall for cross-session knowledge** — vcc_recall is lineage-scoped (active session); it may not find failures from a closed session. Use `memory_search` instead.
108
+ - **Over-saving** — don't save task progress, session outcomes, or temporary state. The auto-review already captures durable learnings. Manual saves are for URGENT or USER-REQUESTED facts only.
109
+ - **Assuming memory_search has everything** — if the SQLite sync is broken (the memory-sync-markdown command can fix this), older Markdown entries may not appear in search. The `/memory-sync-markdown` command backfills them.
110
+
111
+ ## Verification
112
+
113
+ Before relying on memory_search:
114
+
115
+ - [ ] Check if the SQLite sync is healthy (`/memory-insights` shows recent entries)
116
+ - [ ] If search returns nothing but you KNOW the info was saved, run `/memory-sync-markdown`
117
+ - [ ] Use both `memory_search` AND `vcc_recall` in Guard phases for dual coverage
118
+ - [ ] When saving a failure, include: what was tried, why it failed, the error message, reproduction steps
@@ -170,6 +170,8 @@ Score-gated, review-driven feedback loop for high-risk features. Runs iterative
170
170
  - **Concurrency:** 1
171
171
  - **Depends on:** Phase 6
172
172
  - **Prompt:**
173
+ > **DCP hygiene (loop iteration):** This loop runs up to 5 rounds — context accumulates across iterations. Before re-reviewing, if `compress` is available, compress this iteration's closed Phase 6 fix work-stream (file reads + edits) per the `dcp-hygiene` skill. Keep the finding fixed (file:line), the fix applied, and the verification result in the summary; drop the exploratory reads. Skip if `compress` is unavailable.
174
+
173
175
  Loop back to Phase 2. The implementation has been updated based on review findings. Spawn a fresh review agent with the updated diff and spec.
174
176
 
175
177
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhduydev/mdpi",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "CLI to scaffold and manage a Pi coding-agent kit (.pi/) in any repo",
5
5
  "keywords": [
6
6
  "pi",