continuous-improvement 3.9.2 → 3.11.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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +61 -0
- package/QUICKSTART.md +13 -8
- package/README.md +84 -153
- package/bin/backfill.mjs +0 -0
- package/bin/check-doc-runtime-claims.mjs +0 -0
- package/bin/check-docs-substrings.mjs +73 -0
- package/bin/check-everything-mirror.mjs +0 -0
- package/bin/check-routing-targets.mjs +0 -0
- package/bin/check-scripts-citation-drift.mjs +210 -0
- package/bin/check-skill-count.mjs +110 -0
- package/bin/check-skill-law-tag.mjs +0 -0
- package/bin/check-skill-mirror.mjs +0 -0
- package/bin/check-skill-tiers.mjs +0 -0
- package/bin/check-test-imports-only.mjs +126 -0
- package/bin/check-third-party-shape.mjs +0 -0
- package/bin/companion-preference-status.mjs +231 -0
- package/bin/gateguard-clear.mjs +53 -0
- package/bin/generate-plugin-manifests.mjs +7 -1
- package/bin/harvest-friction.mjs +0 -0
- package/bin/hook-stats.mjs +0 -0
- package/bin/install.mjs +182 -26
- package/bin/lint-transcript.mjs +0 -0
- package/bin/mcp-server.mjs +215 -2
- package/bin/observe.mjs +0 -0
- package/bin/pre-commit-block-strays.sh +0 -0
- package/bin/refresh-third-party.mjs +315 -313
- package/bin/unified-cli.mjs +0 -0
- package/commands/audit.md +34 -0
- package/commands/companion-preference.md +58 -0
- package/commands/discipline.md +14 -0
- package/commands/distill.md +39 -0
- package/commands/goal-check.md +53 -0
- package/commands/grill-me.md +40 -0
- package/commands/grill-with-docs.md +38 -0
- package/commands/handoff.md +42 -0
- package/commands/proceed-with-the-recommendation.md +20 -0
- package/commands/recall.md +49 -0
- package/commands/reconcile.md +47 -0
- package/commands/superpowers.md +2 -2
- package/commands/verify-install.md +55 -0
- package/hooks/companion-preference.mjs +190 -0
- package/hooks/gateguard.mjs +60 -25
- package/hooks/goal-drift-stop.mjs +183 -0
- package/hooks/observe.sh +15 -1
- package/hooks/route-prompt.mjs +180 -0
- package/hooks/route-table.json +35 -0
- package/hooks/three-section-close.mjs +134 -132
- package/lib/cli-anything.mjs +0 -0
- package/lib/compound-engineering.mjs +0 -0
- package/lib/gateguard-state.mjs +54 -2
- package/lib/goal-drift-gate.mjs +50 -0
- package/lib/goal-state.mjs +285 -0
- package/lib/observe-event.mjs +0 -0
- package/lib/plugin-metadata.mjs +126 -12
- package/lib/pm-marketplace.mjs +0 -0
- package/lib/pm-skills.mjs +0 -0
- package/lib/recall-index.mjs +175 -0
- package/lib/resolve-home-dir.mjs +0 -0
- package/lib/skill-distill.mjs +222 -0
- package/lib/skill-tiers.mjs +0 -0
- package/lib/unified-plugin.mjs +0 -0
- package/llms.txt +1 -1
- package/package.json +11 -7
- package/plugins/beginner.json +8 -3
- package/plugins/continuous-improvement/.claude-plugin/marketplace.json +2 -2
- package/plugins/continuous-improvement/.claude-plugin/plugin.json +2 -2
- package/plugins/continuous-improvement/agents/README.md +2 -2
- package/plugins/continuous-improvement/bin/backfill.mjs +0 -0
- package/plugins/continuous-improvement/bin/gateguard-clear.mjs +53 -0
- package/plugins/continuous-improvement/bin/mcp-server.mjs +215 -2
- package/plugins/continuous-improvement/bin/observe.mjs +0 -0
- package/plugins/continuous-improvement/commands/audit.md +34 -0
- package/plugins/continuous-improvement/commands/companion-preference.md +58 -0
- package/plugins/continuous-improvement/commands/discipline.md +14 -0
- package/plugins/continuous-improvement/commands/distill.md +39 -0
- package/plugins/continuous-improvement/commands/goal-check.md +53 -0
- package/plugins/continuous-improvement/commands/grill-me.md +40 -0
- package/plugins/continuous-improvement/commands/grill-with-docs.md +38 -0
- package/plugins/continuous-improvement/commands/handoff.md +42 -0
- package/plugins/continuous-improvement/commands/proceed-with-the-recommendation.md +20 -0
- package/plugins/continuous-improvement/commands/recall.md +49 -0
- package/plugins/continuous-improvement/commands/reconcile.md +47 -0
- package/plugins/continuous-improvement/commands/superpowers.md +2 -2
- package/plugins/continuous-improvement/commands/verify-install.md +55 -0
- package/plugins/continuous-improvement/hooks/companion-preference.mjs +190 -0
- package/plugins/continuous-improvement/hooks/gateguard.mjs +60 -25
- package/plugins/continuous-improvement/hooks/goal-drift-stop.mjs +183 -0
- package/plugins/continuous-improvement/hooks/hooks.json +18 -2
- package/plugins/continuous-improvement/hooks/observe.sh +15 -1
- package/plugins/continuous-improvement/hooks/route-prompt.mjs +180 -0
- package/plugins/continuous-improvement/hooks/route-table.json +35 -0
- package/plugins/continuous-improvement/hooks/three-section-close.mjs +134 -132
- package/plugins/continuous-improvement/lib/gateguard-state.mjs +137 -0
- package/plugins/continuous-improvement/lib/goal-drift-gate.mjs +50 -0
- package/plugins/continuous-improvement/lib/goal-state.mjs +285 -0
- package/plugins/continuous-improvement/lib/observe-event.mjs +0 -0
- package/plugins/continuous-improvement/lib/plugin-metadata.mjs +126 -12
- package/plugins/continuous-improvement/lib/recall-index.mjs +175 -0
- package/plugins/continuous-improvement/lib/resolve-home-dir.mjs +0 -0
- package/plugins/continuous-improvement/lib/skill-distill.mjs +222 -0
- package/plugins/continuous-improvement/skills/README.md +8 -0
- package/plugins/continuous-improvement/skills/audit/SKILL.md +73 -0
- package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +13 -17
- package/plugins/continuous-improvement/skills/gateguard/SKILL.md +36 -17
- package/plugins/continuous-improvement/skills/goal-monitor/SKILL.md +81 -0
- package/plugins/continuous-improvement/skills/grill-me/SKILL.md +66 -0
- package/plugins/continuous-improvement/skills/grill-with-docs/SKILL.md +252 -0
- package/plugins/continuous-improvement/skills/handoff/SKILL.md +59 -0
- package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +1 -1
- package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +82 -6
- package/plugins/continuous-improvement/skills/ralph/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/recall/SKILL.md +50 -0
- package/plugins/continuous-improvement/skills/reconcile/SKILL.md +80 -0
- package/plugins/continuous-improvement/skills/recovery-classification/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/skill-distillation/SKILL.md +57 -0
- package/plugins/continuous-improvement/skills/state-reconciliation/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/superpowers/SKILL.md +76 -2
- package/plugins/continuous-improvement/skills/token-budget-advisor/SKILL.md +1 -1
- package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +28 -20
- package/plugins/continuous-improvement/skills/wild-risa-balance/SKILL.md +1 -0
- package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +1 -1
- package/plugins/continuous-improvement/skills/worktree-safety/SKILL.md +3 -2
- package/plugins/expert.json +27 -2
- package/skills/README.md +3 -0
- package/skills/audit.md +73 -0
- package/skills/deploy-receipt.md +13 -17
- package/skills/gateguard.md +36 -17
- package/skills/goal-monitor.md +81 -0
- package/skills/grill-me.md +66 -0
- package/skills/grill-with-docs.md +252 -0
- package/skills/handoff.md +59 -0
- package/skills/para-memory-files.md +1 -1
- package/skills/proceed-with-the-recommendation.md +82 -6
- package/skills/ralph.md +1 -0
- package/skills/recall.md +50 -0
- package/skills/reconcile.md +80 -0
- package/skills/recovery-classification.md +1 -0
- package/skills/safety-guard.md +1 -0
- package/skills/skill-distillation.md +57 -0
- package/skills/state-reconciliation.md +1 -0
- package/skills/strategic-compact.md +1 -0
- package/skills/superpowers.md +76 -2
- package/skills/token-budget-advisor.md +1 -1
- package/skills/verification-loop.md +28 -20
- package/skills/wild-risa-balance.md +1 -0
- package/skills/workspace-surface-audit.md +1 -1
- package/skills/worktree-safety.md +3 -2
|
@@ -11,13 +11,17 @@
|
|
|
11
11
|
* node bin/mcp-server.mjs --mode beginner # explicit beginner
|
|
12
12
|
*/
|
|
13
13
|
import { execSync } from "node:child_process";
|
|
14
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
16
|
import { basename, dirname, join } from "node:path";
|
|
17
17
|
import { createInterface } from "node:readline";
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
19
|
import { createHash } from "node:crypto";
|
|
20
20
|
import { PACKAGE_NAME, VERSION, getToolDefinitions, isPluginMode, } from "../lib/plugin-metadata.mjs";
|
|
21
|
+
import { formatDriftReport, parseGoalFromPlan, scoreObservations, } from "../lib/goal-state.mjs";
|
|
22
|
+
import { buildIndex, formatRecallHits, parseSince, query as queryRecall, } from "../lib/recall-index.mjs";
|
|
23
|
+
import { draftFromCandidate, extractTrajectories, findCandidates, formatCandidates, serializeDraft, } from "../lib/skill-distill.mjs";
|
|
24
|
+
import { MAX_CLEARED_FILES, clearFiles, resolveSessionDir, } from "../lib/gateguard-state.mjs";
|
|
21
25
|
function getHomeDir() {
|
|
22
26
|
return process.env.HOME || process.env.USERPROFILE || homedir();
|
|
23
27
|
}
|
|
@@ -32,6 +36,12 @@ function getString(value, fallback = "") {
|
|
|
32
36
|
function getNumber(value, fallback = 0) {
|
|
33
37
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
34
38
|
}
|
|
39
|
+
// Draft ids are derived from slugified tool n-grams (src/lib/skill-distill.mts)
|
|
40
|
+
// and are joined into a filesystem path, so a caller-supplied id must match the
|
|
41
|
+
// safe shape before it is used to read/write/delete a draft file.
|
|
42
|
+
function isSafeDraftId(id) {
|
|
43
|
+
return /^draft-[a-z0-9-]+$/.test(id);
|
|
44
|
+
}
|
|
35
45
|
function getBoolean(value, fallback = false) {
|
|
36
46
|
return typeof value === "boolean" ? value : fallback;
|
|
37
47
|
}
|
|
@@ -174,6 +184,12 @@ function countObservations(projectHash) {
|
|
|
174
184
|
}
|
|
175
185
|
}
|
|
176
186
|
function getRecentObservations(projectHash, limit = 50) {
|
|
187
|
+
// Clamp a non-positive or non-integer limit to the default. slice(-0) would
|
|
188
|
+
// otherwise return the ENTIRE history (the limit:0 boundary), and a negative
|
|
189
|
+
// limit would drop rows from the front instead of taking the tail. ci_goal_check
|
|
190
|
+
// pre-rejects bad limits with a clear error(); this guards ci_observations and
|
|
191
|
+
// any other caller that passes a user-supplied limit straight through.
|
|
192
|
+
const cappedLimit = Number.isInteger(limit) && limit > 0 ? limit : 50;
|
|
177
193
|
const observationsFile = join(INSTINCTS_DIR, projectHash, "observations.jsonl");
|
|
178
194
|
if (!existsSync(observationsFile)) {
|
|
179
195
|
return [];
|
|
@@ -182,7 +198,7 @@ function getRecentObservations(projectHash, limit = 50) {
|
|
|
182
198
|
const lines = readFileSync(observationsFile, "utf8")
|
|
183
199
|
.split("\n")
|
|
184
200
|
.filter((line) => line.trim().length > 0);
|
|
185
|
-
return lines.slice(-
|
|
201
|
+
return lines.slice(-cappedLimit).flatMap((line) => {
|
|
186
202
|
try {
|
|
187
203
|
return [JSON.parse(line)];
|
|
188
204
|
}
|
|
@@ -195,6 +211,16 @@ function getRecentObservations(projectHash, limit = 50) {
|
|
|
195
211
|
return [];
|
|
196
212
|
}
|
|
197
213
|
}
|
|
214
|
+
function readDistillObservations(projectHash) {
|
|
215
|
+
return getRecentObservations(projectHash, 100000).map((observation) => ({
|
|
216
|
+
ts: getString(observation.ts),
|
|
217
|
+
session: getString(observation.session),
|
|
218
|
+
session_id: getString(observation.session_id),
|
|
219
|
+
tool: getString(observation.tool),
|
|
220
|
+
input_summary: getString(observation.input_summary),
|
|
221
|
+
output_summary: getString(observation.output_summary),
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
198
224
|
function detectLevel(projectHash) {
|
|
199
225
|
const observationCount = countObservations(projectHash);
|
|
200
226
|
const instincts = readInstincts(projectHash);
|
|
@@ -480,6 +506,33 @@ function handleTool(name, params) {
|
|
|
480
506
|
].join("\n");
|
|
481
507
|
return text(reflection);
|
|
482
508
|
}
|
|
509
|
+
case "ci_gateguard_clear": {
|
|
510
|
+
// Beginner-available on purpose: the GateGuard hook fires for every
|
|
511
|
+
// install, so the clearance action must too. Resolves the session dir via
|
|
512
|
+
// gateguard-state (canonical), the same way the hook does, so the marker
|
|
513
|
+
// lands where the hook looks regardless of how each process spelled the
|
|
514
|
+
// project root.
|
|
515
|
+
const rawList = Array.isArray(params.file_paths) ? params.file_paths : [];
|
|
516
|
+
const listPaths = rawList.filter((value) => typeof value === "string" && value.length > 0);
|
|
517
|
+
const single = getString(params.file_path).trim();
|
|
518
|
+
const paths = single ? [...listPaths, single] : listPaths;
|
|
519
|
+
if (paths.length === 0) {
|
|
520
|
+
return error("file_paths is required — pass the file path(s) named in the GateGuard block reason, e.g. { file_paths: [\"src/x.ts\"] }.");
|
|
521
|
+
}
|
|
522
|
+
const sessionDir = resolveSessionDir();
|
|
523
|
+
const { cleared, skippedForCap } = clearFiles(sessionDir, paths);
|
|
524
|
+
const lines = [
|
|
525
|
+
"## GateGuard clearance",
|
|
526
|
+
"",
|
|
527
|
+
`**State file:** ${join(sessionDir, "gateguard-session.json")}`,
|
|
528
|
+
`**Cleared (${cleared.length}):** ${cleared.length > 0 ? cleared.join(", ") : "(none — already cleared)"}`,
|
|
529
|
+
];
|
|
530
|
+
if (skippedForCap.length > 0) {
|
|
531
|
+
lines.push(`**Skipped — session cap of ${MAX_CLEARED_FILES} reached (${skippedForCap.length}):** ${skippedForCap.join(", ")}`, "Start a new session to reset the gate.");
|
|
532
|
+
}
|
|
533
|
+
lines.push("", "Retry the Edit/Write now — it will pass.");
|
|
534
|
+
return text(lines.join("\n"));
|
|
535
|
+
}
|
|
483
536
|
case "ci_reinforce": {
|
|
484
537
|
if (MODE !== "expert") {
|
|
485
538
|
return error("ci_reinforce requires expert mode. Start server with --mode expert");
|
|
@@ -665,6 +718,166 @@ function handleTool(name, params) {
|
|
|
665
718
|
}
|
|
666
719
|
return text(lines.join("\n"));
|
|
667
720
|
}
|
|
721
|
+
case "ci_goal_check": {
|
|
722
|
+
if (MODE !== "expert") {
|
|
723
|
+
return error("ci_goal_check requires expert mode");
|
|
724
|
+
}
|
|
725
|
+
const limit = getNumber(params.limit, 30);
|
|
726
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
727
|
+
return error(`limit must be a positive integer; got ${limit}. Omit it to score the default 30 most recent observations.`);
|
|
728
|
+
}
|
|
729
|
+
const explicit = getString(params.goal_file).trim();
|
|
730
|
+
const workspaceRoot = getWorkspaceRoot();
|
|
731
|
+
const candidates = explicit
|
|
732
|
+
? [explicit]
|
|
733
|
+
: [
|
|
734
|
+
join(workspaceRoot, PLANNING_FILES.taskPlan),
|
|
735
|
+
join(INSTINCTS_DIR, project.hash, "goal.md"),
|
|
736
|
+
];
|
|
737
|
+
let goalContent = "";
|
|
738
|
+
let goalSource = "";
|
|
739
|
+
for (const candidate of candidates) {
|
|
740
|
+
if (!existsSync(candidate)) {
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
goalContent = readFileSync(candidate, "utf8");
|
|
745
|
+
goalSource = candidate;
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
catch {
|
|
749
|
+
// try the next candidate
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (!goalContent) {
|
|
753
|
+
return text(`No goal source found. Looked for: ${candidates.join(", ")}.\nRun ci_plan_init (or /planning-with-files) to create ${PLANNING_FILES.taskPlan} with a '## Goal' section.`);
|
|
754
|
+
}
|
|
755
|
+
const goal = parseGoalFromPlan(goalContent);
|
|
756
|
+
if (!goal) {
|
|
757
|
+
return text(`Found ${goalSource} but it has no '## Goal' section. Add one — ci_plan_init seeds it. Optional '## Goal Keywords' and '## Goal Scope' sections sharpen the drift signal.`);
|
|
758
|
+
}
|
|
759
|
+
const goalObservations = getRecentObservations(project.hash, limit).map((observation) => ({
|
|
760
|
+
ts: getString(observation.ts),
|
|
761
|
+
tool: getString(observation.tool),
|
|
762
|
+
input_summary: getString(observation.input_summary),
|
|
763
|
+
output_summary: getString(observation.output_summary),
|
|
764
|
+
}));
|
|
765
|
+
const report = scoreObservations(goalObservations, goal, { window: limit });
|
|
766
|
+
return text(`## Goal Check\n\n**Goal source:** ${goalSource}\n\n${formatDriftReport(report)}`);
|
|
767
|
+
}
|
|
768
|
+
case "ci_recall": {
|
|
769
|
+
if (MODE !== "expert") {
|
|
770
|
+
return error("ci_recall requires expert mode");
|
|
771
|
+
}
|
|
772
|
+
const queryString = getString(params.query).trim();
|
|
773
|
+
if (!queryString) {
|
|
774
|
+
return error("query is required");
|
|
775
|
+
}
|
|
776
|
+
const k = getNumber(params.k, 5);
|
|
777
|
+
const since = getString(params.since).trim();
|
|
778
|
+
if (since && parseSince(since, Date.now()) === null) {
|
|
779
|
+
return error(`Could not parse since="${since}". Use an ISO timestamp (e.g. 2026-05-01) or a relative window like 7d, 24h, or 30m.`);
|
|
780
|
+
}
|
|
781
|
+
// Recall searches the full history, not just the recent window.
|
|
782
|
+
const recallObservations = getRecentObservations(project.hash, 100000).map((observation) => ({
|
|
783
|
+
ts: getString(observation.ts),
|
|
784
|
+
session: getString(observation.session),
|
|
785
|
+
session_id: getString(observation.session_id),
|
|
786
|
+
tool: getString(observation.tool),
|
|
787
|
+
input_summary: getString(observation.input_summary),
|
|
788
|
+
output_summary: getString(observation.output_summary),
|
|
789
|
+
}));
|
|
790
|
+
if (recallObservations.length === 0) {
|
|
791
|
+
return text("No observations yet. Hooks capture tool calls automatically; recall searches that history.");
|
|
792
|
+
}
|
|
793
|
+
const index = buildIndex(recallObservations);
|
|
794
|
+
const hits = queryRecall(index, queryString, { k, since: since || undefined });
|
|
795
|
+
return text(formatRecallHits(hits, queryString));
|
|
796
|
+
}
|
|
797
|
+
case "ci_distill_candidates": {
|
|
798
|
+
if (MODE !== "expert") {
|
|
799
|
+
return error("ci_distill_candidates requires expert mode");
|
|
800
|
+
}
|
|
801
|
+
const distillObservations = readDistillObservations(project.hash);
|
|
802
|
+
const candidates = findCandidates(extractTrajectories(distillObservations));
|
|
803
|
+
return text(formatCandidates(candidates));
|
|
804
|
+
}
|
|
805
|
+
case "ci_distill_propose": {
|
|
806
|
+
if (MODE !== "expert") {
|
|
807
|
+
return error("ci_distill_propose requires expert mode");
|
|
808
|
+
}
|
|
809
|
+
const id = getString(params.id).trim();
|
|
810
|
+
if (!id) {
|
|
811
|
+
return error("id is required — run ci_distill_candidates to list current candidate ids");
|
|
812
|
+
}
|
|
813
|
+
if (!isSafeDraftId(id)) {
|
|
814
|
+
return error(`Invalid draft id "${id}". Draft ids look like draft-<slug> (lowercase letters, digits, hyphens).`);
|
|
815
|
+
}
|
|
816
|
+
const distillObservations = readDistillObservations(project.hash);
|
|
817
|
+
const candidate = findCandidates(extractTrajectories(distillObservations)).find((entry) => entry.id === id);
|
|
818
|
+
if (!candidate) {
|
|
819
|
+
return error(`No candidate "${id}". Run ci_distill_candidates to list current ids.`);
|
|
820
|
+
}
|
|
821
|
+
const draft = serializeDraft(draftFromCandidate(candidate));
|
|
822
|
+
const draftsDir = join(INSTINCTS_DIR, project.hash, "drafts");
|
|
823
|
+
mkdirSync(draftsDir, { recursive: true });
|
|
824
|
+
const draftPath = join(draftsDir, `${id}.yaml`);
|
|
825
|
+
writeFileSync(draftPath, draft);
|
|
826
|
+
return text([
|
|
827
|
+
"## Draft written",
|
|
828
|
+
"",
|
|
829
|
+
`**Path:** ${draftPath}`,
|
|
830
|
+
"",
|
|
831
|
+
"Edit the body to capture the real recipe (preconditions, concrete steps, gotchas), then promote with:",
|
|
832
|
+
"",
|
|
833
|
+
` ci_distill_promote id=${id}`,
|
|
834
|
+
"",
|
|
835
|
+
"```yaml",
|
|
836
|
+
draft.trimEnd(),
|
|
837
|
+
"```",
|
|
838
|
+
].join("\n"));
|
|
839
|
+
}
|
|
840
|
+
case "ci_distill_promote": {
|
|
841
|
+
if (MODE !== "expert") {
|
|
842
|
+
return error("ci_distill_promote requires expert mode");
|
|
843
|
+
}
|
|
844
|
+
const id = getString(params.id).trim();
|
|
845
|
+
if (!id) {
|
|
846
|
+
return error("id is required");
|
|
847
|
+
}
|
|
848
|
+
if (!isSafeDraftId(id)) {
|
|
849
|
+
return error(`Invalid draft id "${id}". Draft ids look like draft-<slug> (lowercase letters, digits, hyphens).`);
|
|
850
|
+
}
|
|
851
|
+
const draftPath = join(INSTINCTS_DIR, project.hash, "drafts", `${id}.yaml`);
|
|
852
|
+
if (!existsSync(draftPath)) {
|
|
853
|
+
return error(`No draft at ${draftPath}. Run ci_distill_propose id=${id} first.`);
|
|
854
|
+
}
|
|
855
|
+
let parsed = null;
|
|
856
|
+
try {
|
|
857
|
+
parsed = parseYamlInstinct(readFileSync(draftPath, "utf8"));
|
|
858
|
+
}
|
|
859
|
+
catch {
|
|
860
|
+
parsed = null;
|
|
861
|
+
}
|
|
862
|
+
if (!parsed) {
|
|
863
|
+
return error(`Draft ${draftPath} could not be parsed as an instinct. Check the YAML shape.`);
|
|
864
|
+
}
|
|
865
|
+
const promoted = {
|
|
866
|
+
...parsed,
|
|
867
|
+
confidence: 0.5,
|
|
868
|
+
source: "distilled",
|
|
869
|
+
scope: "project",
|
|
870
|
+
observation_count: 1,
|
|
871
|
+
};
|
|
872
|
+
writeInstinct(project.hash, promoted);
|
|
873
|
+
try {
|
|
874
|
+
rmSync(draftPath);
|
|
875
|
+
}
|
|
876
|
+
catch {
|
|
877
|
+
// best-effort cleanup; the live instinct is already written
|
|
878
|
+
}
|
|
879
|
+
return text(`Promoted **${promoted.id}** to a project instinct at confidence ${promoted.confidence} (SUGGEST tier). The draft has been consumed.`);
|
|
880
|
+
}
|
|
668
881
|
case "ci_dashboard": {
|
|
669
882
|
if (MODE !== "expert") {
|
|
670
883
|
return error("ci_dashboard requires expert mode");
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit
|
|
3
|
+
description: Audit a window of recent commits for real defects, confirm each finding before fixing, verify every surface a fix touches, then report confirmed/dismissed/no-op with evidence. Enforces Law 4 (Verify Before Reporting).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /audit — Confirm Recent Commits Before You Trust Them
|
|
7
|
+
|
|
8
|
+
Run the audit-driven loop over recent work: a merged commit with green CI is a claim, not a proof.
|
|
9
|
+
|
|
10
|
+
## What it does
|
|
11
|
+
|
|
12
|
+
Takes a commit window, hunts for real defects one concern at a time, proves each finding against the actual code (false positives die before any edit), fixes on a branch with the smallest diff, verifies every surface the fix touches, and reports honestly. Backed by the `audit` skill.
|
|
13
|
+
|
|
14
|
+
## The loop
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
1. Scope git log to pick the window (e.g. HEAD~10..HEAD, or main since last release)
|
|
18
|
+
2. Find one pass per dimension: value/economy drift, concurrency, surface coverage, type/contract
|
|
19
|
+
3. Confirm read the actual lines; state in one sentence why it is real, or dismiss it
|
|
20
|
+
4. Fix one concern per commit; prefer a failing test first, then green
|
|
21
|
+
5. Verify exercise EVERY surface (backend, frontend, admin, cache, migration), not just the edited one
|
|
22
|
+
6. Report confirmed (with the proof), dismissed (with why), no-op (in scope, nothing to change)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Default skeptical
|
|
26
|
+
|
|
27
|
+
Findings are hypotheses. Default each to a false positive until the code proves the bug — defaulting to "real" is how plausible-but-wrong fixes ship. For a thorough audit, fan the find pass out across dimensions with parallel reviewers, then verify each survivor adversarially.
|
|
28
|
+
|
|
29
|
+
## Pairs with
|
|
30
|
+
|
|
31
|
+
- **`audit`** skill — the discipline this command runs.
|
|
32
|
+
- **`code-review`** / **`security-review`** — the per-dimension passes.
|
|
33
|
+
- **`reconcile`** — the safe branch→PR path once the audit produces a fix.
|
|
34
|
+
- **`recall`** — check whether a finding was already hit and fixed before.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: companion-preference
|
|
3
|
+
description: Inspect companion-preference hook telemetry — counts by CI skill, action breakdown, and companion-installed%.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /companion-preference
|
|
7
|
+
|
|
8
|
+
Read and aggregate the JSONL telemetry written by `hooks/companion-preference.mjs`. Reports per-skill totals, action breakdown (`observation`, `advisory`, `block`, `block-not-installed`), and the share of events where the companion plugin was installed at the time.
|
|
9
|
+
|
|
10
|
+
The dataset is the evidence base for a future `companions-first` default-flip decision — once a 7-day shadow shows the `companions-first` path firing on a meaningful share of routed Skill calls, with companions installed in the majority of them, the flip is grounded.
|
|
11
|
+
|
|
12
|
+
## Trigger phrases
|
|
13
|
+
|
|
14
|
+
- `/companion-preference`
|
|
15
|
+
- `/companion-preference status`
|
|
16
|
+
- "show companion preference stats"
|
|
17
|
+
- "what does the companion-preference hook see"
|
|
18
|
+
|
|
19
|
+
## What happens
|
|
20
|
+
|
|
21
|
+
1. Run `node bin/companion-preference-status.mjs` from the repo root with the operator's chosen window. Default `--days 7`. Pass `--all` for the entire file or `--days N` for a different window.
|
|
22
|
+
2. Render the table the CLI emits to the user verbatim. Do not paraphrase the numbers — the JSONL is authoritative.
|
|
23
|
+
3. If the CLI prints "no telemetry recorded yet," check three things in order: (a) `~/.claude/settings.json` has `continuous_improvement.companion_preference` set (otherwise the hook is a no-op and writes nothing); (b) the user has invoked at least one mapped CI skill (`tdd-workflow`, `verification-loop`, `context-budget`, `ralph`, `learn-eval`) since the hook landed; (c) the hook's PreToolUse registration is intact in `plugins/continuous-improvement/hooks/hooks.json`.
|
|
24
|
+
4. Offer one decision-ready next step based on the totals — e.g., "ratio of `observation` rows with `companion_installed=true` suggests `companions-first` is safe to flip for X but not Y."
|
|
25
|
+
|
|
26
|
+
## Subcommands
|
|
27
|
+
|
|
28
|
+
### `/companion-preference status` (default)
|
|
29
|
+
|
|
30
|
+
Same as `/companion-preference`.
|
|
31
|
+
|
|
32
|
+
### `/companion-preference status --json`
|
|
33
|
+
|
|
34
|
+
Emit the machine-readable JSON report. Useful when you want to pipe the output into another tool or write your own aggregator.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node bin/companion-preference-status.mjs --json --all
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## CLI flags
|
|
41
|
+
|
|
42
|
+
| Flag | Effect |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `--days N` | Only count events from the last N days (default 7). |
|
|
45
|
+
| `--all` | Ignore the window; count every row in the file. |
|
|
46
|
+
| `--json` | Emit a machine-readable JSON report. |
|
|
47
|
+
| `--path <file>` | Override the default JSONL path. Used by the test suite; rarely needed in practice. |
|
|
48
|
+
| `-h`, `--help` | Print CLI help and exit. |
|
|
49
|
+
|
|
50
|
+
## Path resolution
|
|
51
|
+
|
|
52
|
+
By default the CLI reads `~/.claude/instincts/<project-hash>/companion-preference.jsonl`, where the hash is the same `sha256(projectRoot).slice(0, 12)` that the hook itself uses. The project root resolves via `CLAUDE_PROJECT_DIR` env var if set, else `git rev-parse --show-toplevel`, else the literal `"global"`. Hash and path scheme are reused verbatim from `hooks/companion-preference.mjs` to keep the read side aligned with the write side.
|
|
53
|
+
|
|
54
|
+
## Companion skills
|
|
55
|
+
|
|
56
|
+
- `hooks/companion-preference.mjs` — the writer that produces the JSONL this command reads.
|
|
57
|
+
- `skills/superpowers.md` § "Companion-Preference Override" — the broader contract for the setting this command's dataset measures.
|
|
58
|
+
- `commands/dashboard.md` — the broader continuous-improvement status surface; this command is the dispatcher-bias-specific narrower view.
|
|
@@ -33,6 +33,20 @@ The Laws above are the *how*. These five principles are the *why*: code ships fr
|
|
|
33
33
|
|
|
34
34
|
Code is a liability, not an asset. Speed without these five turns into someone else's incident at 3am — except the someone is you.
|
|
35
35
|
|
|
36
|
+
## Goal-Driven Execution maps onto the Laws
|
|
37
|
+
|
|
38
|
+
"Goal-Driven Execution" is the operator's global principle #4 — tie every change to a stated goal, refuse scope creep, stop when the goal is met. It is not a separate Law here; it is the spine of four existing Laws:
|
|
39
|
+
|
|
40
|
+
| Sub-rule of Goal-Driven Execution | Lives in |
|
|
41
|
+
|---|---|
|
|
42
|
+
| Tie work to a stated goal; if none, ask | Law 2 — the `## Goal` in `task_plan.md` is the single source of truth |
|
|
43
|
+
| Catch drift away from that goal mid-session | Law 2 — the `goal-monitor` skill / `/goal-check` scores recent activity against the goal |
|
|
44
|
+
| Finish one thing; refuse "while I'm here" scope creep | Law 3 |
|
|
45
|
+
| Commit messages lead with the outcome, not the mechanism | Law 4 — "done" is an observed outcome |
|
|
46
|
+
| Iterate one change at a time toward the goal | Law 6 |
|
|
47
|
+
|
|
48
|
+
The `goal-monitor` primitive (`/goal-check`, `ci_goal_check`) is the measurable arm of this principle: it reads the `## Goal` section and reports ON GOAL / DRIFT / NO DATA. Run it at phase boundaries to confirm the work and the plan still agree.
|
|
49
|
+
|
|
36
50
|
## The Loop
|
|
37
51
|
|
|
38
52
|
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: distill
|
|
3
|
+
description: Distill repeated successful tool sequences from the observation log into reusable draft instincts, with an explicit propose-edit-promote ladder. Enforces Law 7 (Learn From Every Session).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /distill — Trajectory Distillation
|
|
7
|
+
|
|
8
|
+
Mine this project's observation log for tool sequences that recurred across multiple successful sessions, and turn the good ones into reusable instincts.
|
|
9
|
+
|
|
10
|
+
## What it does
|
|
11
|
+
|
|
12
|
+
Groups observations into trajectories, keeps the ones that ended in a passing verification, and finds tool-sequence n-grams that recurred across distinct sessions. Backed by the `ci_distill_candidates` / `ci_distill_propose` / `ci_distill_promote` MCP tools (expert mode) and the `skill-distillation` skill.
|
|
13
|
+
|
|
14
|
+
## The ladder
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
ci_distill_candidates # list patterns that qualify (read-only)
|
|
18
|
+
ci_distill_propose id=<id> # write a DRAFT (placeholder body) to drafts/<id>.yaml
|
|
19
|
+
# ... edit the draft body to capture the real recipe ...
|
|
20
|
+
ci_distill_promote id=<id> # promote to a live instinct at 0.5 confidence (SUGGEST)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Drafts never affect behavior until promoted. The draft starts at 0.4 confidence in a `drafts/` subdirectory the instinct loader ignores; promotion writes a live instinct at 0.5 (SUGGEST tier).
|
|
24
|
+
|
|
25
|
+
## Candidate criteria
|
|
26
|
+
|
|
27
|
+
- The trajectory must have ended in success (`verify-exit-0` or `reflection-pass`).
|
|
28
|
+
- The tool sequence must have recurred at least 3 times across at least 2 distinct sessions.
|
|
29
|
+
- A pattern repeated only within one session is rejected — that is repetition, not a reusable skill.
|
|
30
|
+
|
|
31
|
+
## Why the human edit step
|
|
32
|
+
|
|
33
|
+
A tool sequence is evidence, not a recipe. `Read → Edit → Bash → Edit → Bash` is a TDD loop, but the value is in the preconditions and concrete steps. Editing the draft body before promotion is the guard against fabricating confident skills from coincidental call ordering.
|
|
34
|
+
|
|
35
|
+
## Pairs with
|
|
36
|
+
|
|
37
|
+
- **`skill-distillation`** skill — the discipline this command runs.
|
|
38
|
+
- **`continuous-improvement`** (core SKILL.md, Law 7 — Learn From Every Session).
|
|
39
|
+
- **`recall`** — before promoting, check whether an existing instinct already covers the pattern.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: goal-check
|
|
3
|
+
description: Check whether recent tool activity still relates to the stated goal in task_plan.md, reporting a drift score and the top off-goal tool calls. Enforces Law 2 (Plan Is Sacred).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /goal-check — Goal Drift Check
|
|
7
|
+
|
|
8
|
+
Score this session's recent tool activity against the stated goal and report whether the work is still ON GOAL or has DRIFTed.
|
|
9
|
+
|
|
10
|
+
## What it does
|
|
11
|
+
|
|
12
|
+
Reads the `## Goal` section of `task_plan.md` (plus optional `## Goal Keywords` and `## Goal Scope` sections), scores the most recent observations from `~/.claude/instincts/<project-hash>/observations.jsonl`, and reports a drift score with the top off-goal tool calls. Backed by the `ci_goal_check` MCP tool (expert mode) and the `goal-monitor` skill.
|
|
13
|
+
|
|
14
|
+
## How to invoke
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
ci_goal_check # last 30 observations vs task_plan.md
|
|
18
|
+
ci_goal_check limit=50 # widen the observation window
|
|
19
|
+
ci_goal_check goal_file=docs/x.md # score against a specific plan file
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Goal source resolution order: `task_plan.md` in the project root, then `~/.claude/instincts/<project-hash>/goal.md`, then an explicit `goal_file`.
|
|
23
|
+
|
|
24
|
+
## Output shape
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
## Goal Check
|
|
28
|
+
|
|
29
|
+
**Goal source:** /home/me/repo/task_plan.md
|
|
30
|
+
|
|
31
|
+
**Status:** DRIFT
|
|
32
|
+
**Score:** 12% (1/8 matched, threshold 30%)
|
|
33
|
+
**Reason:** Only 1/8 recent observations relate to the goal (threshold 0.3).
|
|
34
|
+
**Goal keywords:** oauth, jwt, login, session
|
|
35
|
+
|
|
36
|
+
**Top off-goal activity (most recent 5):**
|
|
37
|
+
- [2026-05-28T12:01:00Z] Edit — src/marketing/landing.ts
|
|
38
|
+
- ...
|
|
39
|
+
|
|
40
|
+
_Drift detected. Either steer back to the goal, or update the `## Goal` section in your plan if the goal has legitimately changed._
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Acting on the result
|
|
44
|
+
|
|
45
|
+
- **ON GOAL** — the plan and the work agree; proceed.
|
|
46
|
+
- **DRIFT** — steer back to the goal, or update `## Goal` if it has legitimately changed. Keeping the plan and the work in disagreement is the Law 2 violation this command catches.
|
|
47
|
+
- **NO DATA** — the observation window is still filling; keep working.
|
|
48
|
+
|
|
49
|
+
## Pairs with
|
|
50
|
+
|
|
51
|
+
- **`goal-monitor`** skill — the discipline this command runs.
|
|
52
|
+
- **`continuous-improvement`** (core SKILL.md, Law 2 — Plan Is Sacred).
|
|
53
|
+
- **`planning-with-files`** — creates the `task_plan.md` whose `## Goal` section this command reads.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grill-me
|
|
3
|
+
description: "Interview the user relentlessly about a plan or design until shared understanding is reached. Ported from mattpocock/skills under MIT."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /grill-me
|
|
7
|
+
|
|
8
|
+
Stress-test the current plan or design by interviewing the user one question at a time, walking every branch of the decision tree, and recommending an answer for each.
|
|
9
|
+
|
|
10
|
+
## Trigger phrases
|
|
11
|
+
|
|
12
|
+
- `/grill-me`
|
|
13
|
+
- "grill me"
|
|
14
|
+
- "stress-test this plan"
|
|
15
|
+
- "interview me about this"
|
|
16
|
+
- "what am I missing?"
|
|
17
|
+
|
|
18
|
+
## What happens
|
|
19
|
+
|
|
20
|
+
1. Identify the current plan or design from the conversation — the high-level goal, the assumptions in play, the decisions already made.
|
|
21
|
+
2. Walk the decision tree top-down. For each unresolved branch, ask exactly **one question** with a **recommended answer**.
|
|
22
|
+
3. Before asking, check whether the codebase already answers the question (`grep`, `ls`, file reads). If it does, use that and skip the question.
|
|
23
|
+
4. Resolve dependencies in order — do not ask about deployment before the data model is pinned.
|
|
24
|
+
5. Stop when the plan is shippable cold to a fresh agent. Do not interview past the point of usefulness.
|
|
25
|
+
|
|
26
|
+
## Five interview rules
|
|
27
|
+
|
|
28
|
+
1. **One question at a time.** Never multi-question; force depth on every branch.
|
|
29
|
+
2. **Always recommend.** Every question carries "my answer would be X because Y".
|
|
30
|
+
3. **Explore before asking.** Code answers beat user-attention answers.
|
|
31
|
+
4. **Walk the tree, do not jump.** Order matters.
|
|
32
|
+
5. **Stop when shippable.** End state is a plan a fresh agent could execute, not an infinite interview.
|
|
33
|
+
|
|
34
|
+
## Skill file
|
|
35
|
+
|
|
36
|
+
Full behavior is defined in [`skills/grill-me.md`](../skills/grill-me.md). The verbatim upstream cold-storage copy lives at [`third-party/mattpocock-skills/skills/productivity/grill-me/SKILL.md`](../third-party/mattpocock-skills/skills/productivity/grill-me/SKILL.md); SHA pin in [`third-party/MANIFEST.md`](../third-party/MANIFEST.md).
|
|
37
|
+
|
|
38
|
+
## Attribution
|
|
39
|
+
|
|
40
|
+
Ported from [mattpocock/skills `productivity/grill-me`](https://github.com/mattpocock/skills/blob/main/skills/productivity/grill-me/SKILL.md) (MIT, © 2026 Matt Pocock).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grill-with-docs
|
|
3
|
+
description: "Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates CONTEXT.md + ADRs inline as decisions crystallise. Ported from mattpocock/skills under MIT."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /grill-with-docs
|
|
7
|
+
|
|
8
|
+
Stress-test the current plan or design by interviewing the user one question at a time AND updating the project's domain-language doc (`CONTEXT.md`) and architecture decision records (`docs/adr/`) inline as decisions land.
|
|
9
|
+
|
|
10
|
+
## Trigger phrases
|
|
11
|
+
|
|
12
|
+
- `/grill-with-docs`
|
|
13
|
+
- "grill me and update the docs"
|
|
14
|
+
- "stress-test this against our domain model"
|
|
15
|
+
- "let's nail down the language and ADR this"
|
|
16
|
+
|
|
17
|
+
## What happens
|
|
18
|
+
|
|
19
|
+
1. Read `CONTEXT.md` (or `CONTEXT-MAP.md` + per-context `CONTEXT.md`) and `docs/adr/` if they exist. Use them as the source of truth for project language and prior decisions.
|
|
20
|
+
2. Walk the decision tree top-down. One question at a time with a recommended answer.
|
|
21
|
+
3. Challenge fuzzy terms against the glossary. Sharpen vague language. Stress-test relationships with concrete scenarios. Cross-reference user statements against the code.
|
|
22
|
+
4. When a term is resolved, update `CONTEXT.md` immediately (lazy-create if missing). Use the format in the skill's Appendix A.
|
|
23
|
+
5. Offer an ADR only when all three are true: hard to reverse, surprising without context, result of a real trade-off. Use the format in Appendix B.
|
|
24
|
+
|
|
25
|
+
## When to fire this instead of `/grill-me`
|
|
26
|
+
|
|
27
|
+
| Skill | Use when |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `/grill-me` | Conversation-only grilling; no project to update yet, or no docs convention. |
|
|
30
|
+
| `/grill-with-docs` | Project has `CONTEXT.md` or is ready to start one; decisions should persist past the session. |
|
|
31
|
+
|
|
32
|
+
## Skill file
|
|
33
|
+
|
|
34
|
+
Full behavior, format specs, and 7 Laws fit are defined in [`skills/grill-with-docs.md`](../skills/grill-with-docs.md). The verbatim upstream cold-storage copies live at [`third-party/mattpocock-skills/skills/engineering/grill-with-docs/`](../third-party/mattpocock-skills/skills/engineering/grill-with-docs/) (`SKILL.md`, `CONTEXT-FORMAT.md`, `ADR-FORMAT.md`); SHA pin in [`third-party/MANIFEST.md`](../third-party/MANIFEST.md).
|
|
35
|
+
|
|
36
|
+
## Attribution
|
|
37
|
+
|
|
38
|
+
Ported from [mattpocock/skills `engineering/grill-with-docs`](https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/SKILL.md) (MIT, © 2026 Matt Pocock). Mattpocock calls this his most powerful skill: "It's hard to explain how powerful this is. It might be the single coolest technique in this repo."
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: handoff
|
|
3
|
+
description: "Compact the current conversation into a handoff document for another agent to pick up. Ported from mattpocock/skills under MIT."
|
|
4
|
+
argument-hint: "What will the next session be used for?"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /handoff
|
|
8
|
+
|
|
9
|
+
Hand the current session off to a fresh agent by writing a brief, mktemp-backed markdown summary they can pick up cold.
|
|
10
|
+
|
|
11
|
+
## Trigger phrases
|
|
12
|
+
|
|
13
|
+
- `/handoff`
|
|
14
|
+
- `/handoff <what the next session will focus on>`
|
|
15
|
+
- "write a handoff doc"
|
|
16
|
+
- "compact this into a handoff"
|
|
17
|
+
|
|
18
|
+
## What happens
|
|
19
|
+
|
|
20
|
+
1. Read the current conversation (and the user's argument, if given) to identify the goal, current state, decisions made, open questions, next concrete step, and skills to load.
|
|
21
|
+
2. Generate a unique path with `mktemp -t handoff-XXXXXX.md` and read it (it will be empty).
|
|
22
|
+
3. Write the handoff doc to that path. Reference PRDs, plans, ADRs, issues, commits, and diffs by path or URL — do not duplicate their content.
|
|
23
|
+
4. Suggest the skills the next session should load.
|
|
24
|
+
|
|
25
|
+
## What goes in the doc
|
|
26
|
+
|
|
27
|
+
A one-screen brief, in this order:
|
|
28
|
+
|
|
29
|
+
1. **Goal** — one sentence on the outcome the user is steering toward.
|
|
30
|
+
2. **Current state** — what is actually true on disk / in the system right now.
|
|
31
|
+
3. **Decisions made this session** — only what is not already captured in commits or other artifacts.
|
|
32
|
+
4. **Open questions** — blocking choices the next agent needs the user to answer.
|
|
33
|
+
5. **Next concrete step** — the single action the next agent should take first.
|
|
34
|
+
6. **Skills to load** — names of the skills the next session should activate.
|
|
35
|
+
|
|
36
|
+
## Skill file
|
|
37
|
+
|
|
38
|
+
Full behavior is defined in [`skills/handoff.md`](../skills/handoff.md). The verbatim upstream cold-storage copy lives at [`third-party/mattpocock-skills/skills/in-progress/handoff/SKILL.md`](../third-party/mattpocock-skills/skills/in-progress/handoff/SKILL.md); SHA pin in [`third-party/MANIFEST.md`](../third-party/MANIFEST.md).
|
|
39
|
+
|
|
40
|
+
## Attribution
|
|
41
|
+
|
|
42
|
+
Ported from [mattpocock/skills `in-progress/handoff`](https://github.com/mattpocock/skills/blob/main/skills/in-progress/handoff/SKILL.md) (MIT, © 2026 Matt Pocock).
|
|
@@ -18,6 +18,26 @@ Invoke immediately after the agent has offered a numbered list of recommendation
|
|
|
18
18
|
- "execute the recommendations"
|
|
19
19
|
- "yes do it" / "all of them"
|
|
20
20
|
|
|
21
|
+
## Fast-path: `--once` mode
|
|
22
|
+
|
|
23
|
+
For a single-item, `safe`-tagged confirmation, append `--once` to skip P-MAG, Plan, Reflect, and the three-section close. Runs Phase 1 + Phase 3 + Phase 4 only and ends with one line: `Done: <item>. Verified: <check + output>.`
|
|
24
|
+
|
|
25
|
+
Trigger phrases:
|
|
26
|
+
|
|
27
|
+
- `/proceed-with-the-recommendation --once`
|
|
28
|
+
- `/proceed --once`
|
|
29
|
+
- "proceed once with that" / "just do that one"
|
|
30
|
+
- Any standard trigger phrase plus the literal `--once` suffix
|
|
31
|
+
|
|
32
|
+
Hard preconditions (the skill refuses `--once` and falls back to the full flow if any fail):
|
|
33
|
+
|
|
34
|
+
- Recommendation list has exactly one item
|
|
35
|
+
- Item is tagged `safe` (not `caution`, not `needs-approval`)
|
|
36
|
+
- Item touches ≤3 files, ≤150 LOC, and none of `.github/`, `bin/`, `lib/`, `src/`, `third-party/`
|
|
37
|
+
- Item is not destructive (no deploy, force-push, DB drop, secret rotation)
|
|
38
|
+
|
|
39
|
+
Full behavior is defined in [`skills/proceed-with-the-recommendation.md`](../skills/proceed-with-the-recommendation.md) under § "Fast-Path: `--once` Mode".
|
|
40
|
+
|
|
21
41
|
## What happens
|
|
22
42
|
|
|
23
43
|
1. **Pre-flight (Law 1)** — restate the recommendation list in original order, tag each `safe` / `caution` / `needs-approval`
|