@namewta/speculo 1.0.15 → 1.0.17

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.
Files changed (94) hide show
  1. package/README.md +17 -5
  2. package/dist/src/agent-files.d.ts +9 -0
  3. package/dist/src/agent-files.js +106 -0
  4. package/dist/src/agent-files.js.map +1 -0
  5. package/dist/src/cli.js +64 -14
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/doctor.d.ts +2 -0
  8. package/dist/src/doctor.js +120 -53
  9. package/dist/src/doctor.js.map +1 -1
  10. package/dist/src/external-files.d.ts +22 -0
  11. package/dist/src/external-files.js +110 -0
  12. package/dist/src/external-files.js.map +1 -0
  13. package/dist/src/index.d.ts +3 -0
  14. package/dist/src/index.js +31 -182
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/paths.d.ts +12 -0
  17. package/dist/src/paths.js +57 -0
  18. package/dist/src/paths.js.map +1 -0
  19. package/dist/src/transaction.d.ts +27 -0
  20. package/dist/src/transaction.js +187 -0
  21. package/dist/src/transaction.js.map +1 -0
  22. package/dist/src/utils.js +4 -2
  23. package/dist/src/utils.js.map +1 -1
  24. package/dist/src/workflows.js +3 -4
  25. package/dist/src/workflows.js.map +1 -1
  26. package/package.json +6 -4
  27. package/template/.speculo/README.md +9 -3
  28. package/template/.speculo/refresh-contract.json +6 -2
  29. package/template/AGENTS.md +1 -1
  30. package/template/canonical/canonical-specdev-goal-plan.md +23 -12
  31. package/template/canonical/canonical-specdev-tickets.md +1 -1
  32. package/template/commands/docs-sync.md +13 -11
  33. package/template/skills/archive-and-consolidate/SKILL.md +2 -4
  34. package/template/skills/docs-sync/SKILL.md +22 -11
  35. package/template/skills/docs-sync/references/agents-contract.md +6 -4
  36. package/template/skills/docs-sync/references/document-lifecycle-contract.md +2 -0
  37. package/template/skills/docs-sync/references/entry-procedure.md +2 -17
  38. package/template/skills/docs-sync/references/git-state-contract.md +1 -1
  39. package/template/skills/docs-sync/references/mode-contract.md +21 -0
  40. package/template/skills/docs-sync/references/workflow-scope-contract.md +5 -3
  41. package/template/skills/engineering-standards-builder/SKILL.md +3 -1
  42. package/template/skills/engineering-standards-builder/examples/README.md +6 -0
  43. package/template/skills/engineering-standards-builder/manifest.txt +1 -0
  44. package/template/skills/engineering-standards-builder/scripts/self-test.mjs +1 -0
  45. package/template/skills/engineering-standards-builder/scripts/sync-manifest.mjs +2 -2
  46. package/template/skills/engineering-standards-builder/scripts/validate-builder.mjs +12 -4
  47. package/template/skills/git-history-squash/SKILL.md +3 -3
  48. package/template/skills/github-npm-ops/SKILL.md +2 -4
  49. package/template/skills/source-code-zip/SKILL.md +0 -1
  50. package/template/skills/speculo-retro/SKILL.md +2 -4
  51. package/template/skills/upstream-fork-sync/SKILL.md +1 -3
  52. package/template/skills/writing-great-skills/SKILL.md +3 -3
  53. package/template/workflows/learning/A-archive/A-archive.md +2 -0
  54. package/template/workflows/learning/A-assess-and-plan/A-assess-and-plan.md +2 -0
  55. package/template/workflows/learning/C-consolidate/C-consolidate.md +2 -0
  56. package/template/workflows/learning/G-goal/G-goal.md +6 -0
  57. package/template/workflows/learning/G-goal/references/external-goal-runner.md +4 -0
  58. package/template/workflows/learning/H-homework/H-homework.md +2 -0
  59. package/template/workflows/learning/L-lesson/L-lesson.md +2 -0
  60. package/template/workflows/learning/Q-question/Q-question.md +2 -0
  61. package/template/workflows/learning/R-review/R-review.md +2 -0
  62. package/template/workflows/learning/README.md +4 -53
  63. package/template/workflows/learning/common/rules/artifact-layouts.md +46 -0
  64. package/template/workflows/learning/common/rules/consolidation-contract.md +5 -0
  65. package/template/workflows/learning/common/rules/homework-contract.md +3 -0
  66. package/template/workflows/learning/common/rules/lesson-contract.md +7 -0
  67. package/template/workflows/learning/common/skills/socratic-questioning/SKILL.md +1 -0
  68. package/template/workflows/learning/common/skills/topic-synthesis/SKILL.md +1 -0
  69. package/template/workflows/ops/README.md +7 -3
  70. package/template/workflows/ops/_state/status.json +2 -1
  71. package/template/workflows/ops/common/USAGE.md +4 -0
  72. package/template/workflows/ops/common/rules/persistence-and-secrets.md +4 -2
  73. package/template/workflows/ops/common/schemas/plan.schema.json +4 -0
  74. package/template/workflows/ops/common/schemas/spec.schema.json +4 -0
  75. package/template/workflows/ops/common/schemas/status.schema.json +4 -0
  76. package/template/workflows/ops/common/tests/test_ops.mjs +33 -2
  77. package/template/workflows/ops/common/tools/opslib/core.mjs +1 -1
  78. package/template/workflows/ops/common/tools/opslib/docs.mjs +12 -7
  79. package/template/workflows/ops/common/tools/opslib/planner.mjs +7 -1
  80. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +4 -2
  81. package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +2 -0
  82. package/template/workflows/specdev/P-goal-plan/planning-modes.md +13 -8
  83. package/template/workflows/specdev/P-goal-plan/references/map-control.md +1 -1
  84. package/template/workflows/specdev/P-goal-plan/references/single-change-plan.md +4 -2
  85. package/template/workflows/specdev/README.md +2 -2
  86. package/template/workflows/specdev/common/rules/path-reference-contract.md +6 -0
  87. package/template/workflows/specdev/common/rules/workflow-routing.md +2 -2
  88. package/template/workflows/specdev/common/skills/code-review/SKILL.md +3 -1
  89. package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +1 -0
  90. package/template/workflows/specdev/common/skills/plan-quality-review/SKILL.md +3 -1
  91. package/template/workflows/specdev/common/skills/research/SKILL.md +3 -1
  92. package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +1 -0
  93. package/template/workflows/specdev/common/tools/README.md +7 -1
  94. package/template/workflows/specdev/common/tools/validate-specdev.mjs +19 -18
@@ -0,0 +1,187 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { hostname } from "node:os";
3
+ import { lstat, mkdir, rename, rm } from "node:fs/promises";
4
+ import { basename, join, resolve } from "node:path";
5
+ import { fingerprintTree } from "./manifest.js";
6
+ import { EXTERNAL_NAMES, assertImage, imageDigest, readImage, replaceImage, syncDirectory, writeDurableJson } from "./external-files.js";
7
+ export const LOCK_NAME = ".speculo-init.lock";
8
+ async function exists(path) {
9
+ try {
10
+ await lstat(path);
11
+ return true;
12
+ }
13
+ catch (error) {
14
+ if (error.code === "ENOENT")
15
+ return false;
16
+ throw error;
17
+ }
18
+ }
19
+ async function directory(path) {
20
+ if (!(await exists(path)))
21
+ return;
22
+ const stat = await lstat(path);
23
+ if (!stat.isDirectory() || stat.isSymbolicLink())
24
+ throw new Error(`unsafe-transaction-directory: ${path}`);
25
+ }
26
+ export async function assertInstallDirectory(target) {
27
+ await directory(join(target, "speculo"));
28
+ }
29
+ function journalPath(target) { return join(target, LOCK_NAME, "transaction.json"); }
30
+ export async function readTransaction(target) {
31
+ await directory(join(target, LOCK_NAME));
32
+ const raw = await readImage(journalPath(target));
33
+ if (!raw)
34
+ throw new Error("unidentified-lock: no durable transaction; inspect owner.json and preserve all residues");
35
+ const j = JSON.parse(Buffer.from(raw.content, "base64").toString("utf8"));
36
+ if (j.schema_version !== 1 || j.target !== resolve(target) || !/^[a-f0-9-]{36}$/.test(j.id) ||
37
+ typeof j.host !== "string" || !Number.isSafeInteger(j.pid) || j.pid < 1 ||
38
+ !/^\.speculo-init-stage-[A-Za-z0-9]+$/.test(j.stage) || j.backup !== j.stage + "-backup" ||
39
+ !/^(absent|[a-f0-9]{64})$/.test(j.before) || !/^[a-f0-9]{64}$/.test(j.after) ||
40
+ !["prepared", "old-renamed", "installed", "external-finalized", "committed", "rolled-back"].includes(j.phase) ||
41
+ !Array.isArray(j.external) || j.external.length !== EXTERNAL_NAMES.length ||
42
+ new Set(j.external.map((e) => e.name)).size !== EXTERNAL_NAMES.length)
43
+ throw new Error("invalid-transaction-journal");
44
+ for (const e of j.external) {
45
+ if (!EXTERNAL_NAMES.includes(e.name))
46
+ throw new Error("invalid-transaction-external-path");
47
+ for (const value of [e.before, e.after]) {
48
+ if (value !== null && (!value || typeof value.content !== "string" || !Number.isInteger(value.mode) || value.mode < 0 || value.mode > 0o777 ||
49
+ Buffer.from(value.content, "base64").toString("base64") !== value.content))
50
+ throw new Error("invalid-transaction-file-image");
51
+ }
52
+ }
53
+ return j;
54
+ }
55
+ async function save(j, phase) {
56
+ await writeDurableJson(journalPath(j.target), { ...j, phase });
57
+ j.phase = phase;
58
+ }
59
+ /** Validate every source before moving any directory or restoring any external file. */
60
+ async function rollback(j) {
61
+ const root = join(j.target, "speculo"), stage = join(j.target, j.stage), backup = join(j.target, j.backup);
62
+ for (const path of [root, stage, backup])
63
+ await directory(path);
64
+ const r = await fingerprintTree(root), s = await fingerprintTree(stage), b = await fingerprintTree(backup);
65
+ const untouched = r === j.before && b === "absent" && (s === j.after || s === "absent");
66
+ const renamed = j.before !== "absent" && b === j.before &&
67
+ ((r === "absent" && s === j.after) || (r === j.after && s === "absent"));
68
+ const newInstall = j.before === "absent" && b === "absent" && r === j.after && s === "absent";
69
+ if (!untouched && !renamed && !newInstall)
70
+ throw new Error("recovery-drift: installation layout differs from before/after evidence; preserve all directories");
71
+ for (const e of j.external) {
72
+ const digest = imageDigest(await readImage(join(j.target, e.name)));
73
+ if (![imageDigest(e.before), imageDigest(e.after)].includes(digest))
74
+ throw new Error(`recovery-drift: ${e.name}; concurrent content preserved`);
75
+ }
76
+ for (const e of [...j.external].reverse()) {
77
+ const current = await readImage(join(j.target, e.name));
78
+ await replaceImage(join(j.target, e.name), current, e.before);
79
+ }
80
+ if (!untouched) {
81
+ if (r === j.after)
82
+ await rename(root, stage);
83
+ if (j.before !== "absent")
84
+ await rename(backup, root);
85
+ await syncDirectory(j.target);
86
+ }
87
+ await save(j, "rolled-back");
88
+ if (await fingerprintTree(stage) !== "absent" && await fingerprintTree(stage) !== j.after)
89
+ throw new Error("recovery-drift: staged directory changed");
90
+ await rm(stage, { recursive: true, force: true });
91
+ }
92
+ async function finish(j) {
93
+ const root = join(j.target, "speculo"), backup = join(j.target, j.backup);
94
+ await directory(root);
95
+ await directory(backup);
96
+ if (await fingerprintTree(root) !== j.after)
97
+ throw new Error("recovery-drift: committed installation changed");
98
+ for (const e of j.external)
99
+ await assertImage(join(j.target, e.name), e.after);
100
+ const fingerprint = await fingerprintTree(backup);
101
+ if (fingerprint !== "absent" && fingerprint !== j.before)
102
+ throw new Error("recovery-drift: backup changed; preserve it");
103
+ await rm(backup, { recursive: true, force: true });
104
+ await syncDirectory(j.target);
105
+ }
106
+ export async function commitInstall(target, stagedRoot, before, external, hook) {
107
+ const j = { schema_version: 1, id: randomUUID(), host: hostname(), pid: process.pid, target,
108
+ stage: basename(stagedRoot), backup: basename(stagedRoot) + "-backup", before,
109
+ after: await fingerprintTree(stagedRoot), phase: "prepared", external };
110
+ const root = join(target, "speculo");
111
+ if (await fingerprintTree(root) !== before)
112
+ throw new Error("concurrent-drift: installation changed before commit");
113
+ for (const e of external)
114
+ await assertImage(join(target, e.name), e.before);
115
+ await save(j, "prepared");
116
+ try {
117
+ await hook?.("prepared");
118
+ if (before !== "absent")
119
+ await rename(root, join(target, j.backup));
120
+ await syncDirectory(target);
121
+ await save(j, "old-renamed");
122
+ await hook?.("old-renamed");
123
+ await rename(stagedRoot, root);
124
+ await syncDirectory(target);
125
+ await save(j, "installed");
126
+ await hook?.("installed");
127
+ if (await fingerprintTree(root) !== j.after)
128
+ throw new Error("post-install validation failed");
129
+ for (const e of external)
130
+ await replaceImage(join(target, e.name), e.before, e.after);
131
+ await save(j, "external-finalized");
132
+ await hook?.("external-finalized");
133
+ await save(j, "committed");
134
+ await hook?.("committed");
135
+ await finish(j);
136
+ }
137
+ catch (error) {
138
+ if (j.phase === "committed")
139
+ throw new Error(`committed-cleanup-pending: run doctor then recover with transaction ${j.id}; ${String(error)}`);
140
+ try {
141
+ await rollback(j);
142
+ }
143
+ catch (recoveryError) {
144
+ throw new Error(`recovery-required: transaction ${j.id}; ${String(error)}; ${String(recoveryError)}`);
145
+ }
146
+ await rm(journalPath(target));
147
+ throw error;
148
+ }
149
+ await rm(journalPath(target));
150
+ }
151
+ /** Explicit local recovery only. Never steals a live, remote-host, or unidentified lock. */
152
+ export async function recoverInstall(targetArg, id) {
153
+ const target = resolve(targetArg);
154
+ const j = await readTransaction(target);
155
+ if (j.id !== id)
156
+ throw new Error("recovery-transaction-mismatch");
157
+ if (j.host !== hostname())
158
+ throw new Error("recovery-host-mismatch: inspect the original host before recovery");
159
+ try {
160
+ process.kill(j.pid, 0);
161
+ throw new Error("recovery-owner-live: stop the owning process first");
162
+ }
163
+ catch (error) {
164
+ if (error.code !== "ESRCH")
165
+ throw error;
166
+ }
167
+ const guard = join(target, LOCK_NAME, "recovery.lock");
168
+ await mkdir(guard, { mode: 0o700 });
169
+ let success = false;
170
+ try {
171
+ if (j.phase === "committed")
172
+ await finish(j);
173
+ else
174
+ await rollback(j);
175
+ success = true;
176
+ return { id, outcome: j.phase === "committed" ? "completed-cleanup" : "rolled-back" };
177
+ }
178
+ finally {
179
+ await rm(guard, { recursive: true, force: true });
180
+ if (success) {
181
+ await rm(join(target, LOCK_NAME), { recursive: true });
182
+ await syncDirectory(target);
183
+ }
184
+ }
185
+ }
186
+ export async function hasTransaction(target) { return exists(journalPath(target)); }
187
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/transaction.ts"],"names":[],"mappings":"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"}
package/dist/src/utils.js CHANGED
@@ -4,8 +4,10 @@ export async function pathExists(path) {
4
4
  await access(path);
5
5
  return true;
6
6
  }
7
- catch {
8
- return false;
7
+ catch (error) {
8
+ if (error.code === "ENOENT")
9
+ return false;
10
+ throw error;
9
11
  }
10
12
  }
11
13
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACxC,OAAO,KAAK,EAAE,CAAC;QACb,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -39,10 +39,9 @@ export async function discoverWorkflowCatalog(packageRoot) {
39
39
  });
40
40
  }
41
41
  catch (error) {
42
- if (error instanceof Error && error.message.includes("ids must match")) {
42
+ if (error.code !== "ENOENT")
43
43
  throw error;
44
- }
45
- // A directory without INDEX.md is not an installable workflow package.
44
+ // Only a missing INDEX.md means this is not an installable workflow package.
46
45
  }
47
46
  }
48
47
  return catalog;
@@ -74,7 +73,7 @@ export function isInteractive() {
74
73
  }
75
74
  export async function promptWorkflowSelection(catalog, options) {
76
75
  if (!isInteractive())
77
- return selectAllFromCatalog(catalog);
76
+ return { workflowIds: [...(options?.preSelectedWorkflowIds ?? [])].filter((id) => catalog.has(id)).sort() };
78
77
  const choices = [...catalog.values()]
79
78
  .sort((left, right) => left.id.localeCompare(right.id))
80
79
  .map((workflow) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../src/workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAejC,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAClD,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AACnC,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,KAAK;YAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,WAAmB;IAEnB,MAAM,OAAO,GAAoB,IAAI,GAAG,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEjE,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC;YAChE,IAAI,EAAE,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,qBAAqB,GAAG,KAAK,CAAC,IAAI,GAAG,wBAAwB,GAAG,EAAE;oBAClE,kCAAkC,CACnC,CAAC;YACJ,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE;gBACd,EAAE;gBACF,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,WAAW,EAAE,WAAW,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;gBAC3C,WAAW,EAAE,WAAW,CAAC,WAAW,IAAI,EAAE;aAC3C,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACvE,MAAM,KAAK,CAAC;YACd,CAAC;YACD,uEAAuE;QACzE,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,WAAmB;IAEnB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjE,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;gBACxE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;YAC1E,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAwB,EACxB,OAAkD;IAElD,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE3D,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;SAClC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SACtD,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClB,IAAI,EAAE,QAAQ,CAAC,WAAW;QAC1B,KAAK,EAAE,QAAQ,CAAC,EAAE;QAClB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,KAAK;KACpE,CAAC,CAAC,CAAC;IAEN,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC;QACjC,OAAO,EAAE,0EAA0E;QACnF,OAAO;QACP,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IAEH,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IAC3F,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAwB;IAExB,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../src/workflows.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namewta/speculo",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Workflow-packaged AI collaboration assets with state-safe refresh tooling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,12 +13,14 @@
13
13
  "pretest": "pnpm build",
14
14
  "generate-canonical": "node scripts/generate-specdev-canonical.mjs",
15
15
  "validate-source-parity": "node scripts/check-specdev-source-parity.mjs",
16
- "validate-assets": "node scripts/check-specdev-source-parity.mjs && node scripts/generate-specdev-canonical.mjs --check && node scripts/validate-refresh-contracts.mjs && node scripts/validate-framework-assets.mjs && node scripts/check-template-links.mjs && node scripts/validate-workflow-disclosure.mjs && node template/workflows/specdev/common/tools/validate-specdev.mjs --self-check && node template/workflows/learning/common/tools/validate-learning.mjs --workflow-root template/workflows/learning",
16
+ "validate-assets": "node scripts/validate-skills.mjs && node scripts/check-specdev-source-parity.mjs && node scripts/generate-specdev-canonical.mjs --check && node scripts/validate-refresh-contracts.mjs && node scripts/validate-framework-assets.mjs && node scripts/check-template-links.mjs && node scripts/validate-workflow-disclosure.mjs && node template/workflows/specdev/common/tools/validate-specdev.mjs --self-check && node template/workflows/learning/common/tools/validate-learning.mjs --workflow-root template/workflows/learning",
17
17
  "check": "pnpm test && pnpm validate-assets",
18
18
  "verify-bin": "node scripts/verify-bin.mjs",
19
19
  "eval:scenarios": "node scripts/evaluate-scenarios.mjs",
20
20
  "prepack": "pnpm build",
21
- "prepublishOnly": "pnpm test && pnpm validate-assets"
21
+ "prepublishOnly": "pnpm test && pnpm validate-assets",
22
+ "validate-skills": "node scripts/validate-skills.mjs",
23
+ "validate-source-inventory": "node scripts/check-specdev-source-parity.mjs"
22
24
  },
23
25
  "files": [
24
26
  "dist/src",
@@ -53,7 +55,7 @@
53
55
  "node": ">=22.22.3 <25"
54
56
  },
55
57
  "devDependencies": {
56
- "@types/node": "^26.0.0",
58
+ "@types/node": "^22.0.0",
57
59
  "fast-xml-parser": "^5.9.3",
58
60
  "typescript": "^5.8.3"
59
61
  },
@@ -10,12 +10,12 @@
10
10
 
11
11
  配置使用 `.speculo/baselines/` 中的上次模板默认值执行 base/local/incoming 三方合并:模板新增项自动增加,模板删除项直接删除,未被用户修改的旧默认值跟随模板更新,用户覆盖值在满足目标合同的前提下保留。只有字段删除、显式 schema 迁移或结构化文件变换时,CLI 才把原文件写入 `back/` 并生成 targeted manifest;opaque 内容不会被整包复制到备份。
12
12
 
13
- `install.json` 使用 schema v3,记录包版本、已安装 workflows、managed manifest 路径和 baseline schema。`kernel.json` 定义共享 change、风险、checkpoint、能力和 trace 位置。Speculo 1.0 不读取或迁移任何 0.x 安装;检测到旧 manifest 时必须先由用户移除或改名旧 `speculo/` 目录。初始化以项目锁、完整 staging、active fingerprint 复验、原子 rename 与失败 rollback 组成一个事务;冲突不会发布部分结果,也不会创建新的 pending marker。
13
+ `install.json` 使用 schema v3,记录包版本、已安装 workflows、managed manifest 路径和 baseline schema。`kernel.json` 定义共享 change、风险、checkpoint、能力和 trace 位置。Speculo 1.0 不读取或迁移任何 0.x 安装;检测到旧 manifest 时必须先由用户移除或改名旧 `speculo/` 目录。初始化使用项目锁、完整 staging、active fingerprint、配套手册 before/after images 与持久事务阶段记录。正常异常回滚;进程中断后保留现场,通过只读 doctor 检查,再由用户显式 recover 处理。多文件交换不是对所有读者全时刻原子的,保证范围是受测试的进程中断恢复,不宣称跨平台掉电原子性。
14
14
 
15
15
  ## 读取顺序
16
16
 
17
- 1. 读取 `workspace.json`,以当前打开项目为 `project_root` 解析公共 roots。嵌套安装时,项目根 `.speculo/` 不是本目录;只有该文件声明的状态根是运行时状态的唯一持久化根,项目根 `.speculo/specdev` 非法。
18
- 2. 从 `../workflows/<workflow>/INDEX.md` 发现 workflow并按需读取其中声明的永久知识;这一步不读取 Work 条目或运行状态。
17
+ 1. 从项目根打开字面 `speculo/.speculo/workspace.json`(已在本目录时为 `workspace.json`),以当前打开项目为 `project_root` 解析公共 roots。嵌套安装时,项目根 `.speculo/` 不是本目录;只有该文件声明的状态根是运行时状态的唯一持久化根,项目根 `.speculo/specdev` 非法。
18
+ 2. 从本目录生成的 `catalog.md` 定位已安装能力,再按需读取 `../workflows/<workflow>/INDEX.md` 声明的永久知识;这一步不读取 Work 条目或运行状态。
19
19
  3. 用户明确激活 workflow 或 work 后,读取 INDEX 指向的 workflow 根 `README.md`,从其中的 Work 条目选择目标并读取具体入口文件。
20
20
  4. 按激活合同读取 `<Path>{roots.state}/{workflow}/status.json</Path>`。SpecDev/Learning 再读取当前 change `.status.json` 与 work 产物。Ops schema v3 读取 hosts/projects/deployments/allocations/bindings/releases 及对应运行记录,不创建 `changes/`。
21
21
  5. 历史 change(SpecDev/Learning)只从 `<Path>{roots.state}/{workflow}/archive/{YYYY-MM}/{change}/</Path>` 读取。Ops 运行证据在 `hosts/{host_id}/runs/{run_id}` 或 `releases/{run_id}`。
@@ -32,3 +32,9 @@
32
32
  - 独立 Skill 只写 `<Path>{roots.state}/skills/{skill}/</Path>`;一次运行目录命名为 `<YYYY-MM-DD>-<kebab-topic>[-NN]`,禁止覆盖。由 command/work 调用时改用调用方提供的 owner 路径。
33
33
  - `back/` 由 `speculo init` 单一写入;workflow 和 commands 不得修改。
34
34
  - `install.json`、`managed.json`、`baselines/` 与 refresh contract 由 CLI 拥有,workflow 不得创建、修改或删除。
35
+
36
+ ## 显式中断恢复
37
+
38
+ `speculo doctor [target] --json` 是只读 installation-integrity 检查,验证配置、roots、manifest 与文件摘要,报告尚未检查的领域状态、宿主行为和服务健康。发现 `.speculo-init.lock/transaction.json` 时输出事务 ID 和阶段。确认原执行进程已停止后,执行 `speculo recover [target] --transaction <id>`。事务 ID、宿主、owner PID、安装 before/after hash、配套文件和目录布局必须匹配;未知锁、仍在运行的 owner、内容漂移或越界链接均保留并阻塞。
39
+
40
+ committed 阶段只完成清理,其他已记录阶段恢复旧安装与旧手册。未进入持久事务的 stage/owner 锁、恢复自身被强制终止留下的 recovery.lock 或清理窗口中的不完整记录须人工核对,不能仅凭锁龄删除。严禁 rm 未识别备份来“解除阻塞”。项目目录必须可信;这不是阻止同账户恶意进程竞态的沙箱。POSIX 使用文件与目录 fsync,Windows 没有通用目录 fsync,掉电恢复需要宿主备份策略。
@@ -10,7 +10,9 @@
10
10
  ".speculo/README.md",
11
11
  ".speculo/workspace.json",
12
12
  ".speculo/refresh-contract.json",
13
- ".speculo/kernel.json"
13
+ ".speculo/kernel.json",
14
+ ".speculo/AGENTS.md",
15
+ ".speculo/catalog.md"
14
16
  ],
15
17
  "reserved_runtime": [
16
18
  "README.md",
@@ -22,7 +24,9 @@
22
24
  "managed.json",
23
25
  "migration.json",
24
26
  "baselines",
25
- "back"
27
+ "back",
28
+ "AGENTS.md",
29
+ "catalog.md"
26
30
  ],
27
31
  "project_config": {
28
32
  "path": "config.json",
@@ -1,6 +1,6 @@
1
1
  # Speculo runtime guide
2
2
 
3
- 先按当前任务定位相关 workflow、command、skill 或 change,再读取对应入口和分支 reference;不默认整读 `speculo/` 或永久知识索引。
3
+ 从项目根字面路径 `speculo/.speculo/workspace.json` 解析 roots,按需读取同目录生成的 `catalog.md`;发现不激活、不授权。先按当前任务定位相关 workflow、command、skill 或 change,再读取对应入口和分支 reference;不默认整读 `speculo/` 或永久知识索引。
4
4
 
5
5
  - 被动发现:按关键词/ID 搜索 `speculo/workflows/<workflow>/INDEX.md` 的相关行,只定位与当前请求相关的永久知识条目。
6
6
  - 激活 workflow:再读取对应 `README.md`、状态投影和当前 Work;只加载当前分支需要的规则、schema、模板与工具。
@@ -32,6 +32,8 @@
32
32
 
33
33
  单 change 的 `specdev/changes/{change}/tickets-map.md` 是用户总控入口;Ticket frontmatter 仍是单票状态、依赖、路径的权威,Goal Plan 拥有跨票 Gate、Wave 和授权引用。少量线性票不强制增加厚重计划。
34
34
 
35
+ 单 change 的 Map 结构就绪、Goal 全局执行门与逐票 DoR 分开判断。等待上游真实产物的未来票可保持 draft,并记录缺口和重审条件;独立 Ready 票仍可进入 frontier。具体门禁读取 下方 `<planning-modes>` 标签。
36
+
35
37
  多 change 复用现有父 Implementation Map/Implementation Plan 和组合 DAG,不迁走活动状态。父 `specdev/changes/{change}/tickets-map.md` 仅作无状态入口,模板为 下方 `<ref-p-goal-plan-references-goal-tickets-map-template>` 标签。父成员至少两个;只有一个 change 时使用单 change 模式。
36
38
 
37
39
  ## 执行底线
@@ -52,7 +54,7 @@
52
54
  node 本地只读 Goal 控制器(不含于网页快照) --map <map-path> --repo <project-root>
53
55
  ```
54
56
 
55
- 再按单 change 的 `--stage goal-plan` 或父 change 的 `--stage goal-plan` 运行 Speculo Node 校验器。完成时回读真实源、map、Ticket 状态和 Evidence,报告完成/阻塞/失效票、整体验收、实际交付数量、验证命令、未执行项与恢复路径。票全 done 不等于 Goal 自动完成。
57
+ 再以 `--stage goal-plan` 运行 Speculo Node 校验器:单 change 要求自己的 Goal Plan,合法 draft 可通过结构校验;存在任一父 Map、Plan 或父入口时校验完整父编排,残缺父工件不得回退单 change。校验通过不授予执行权限。完成时回读真实源、map、Ticket 状态和 Evidence,报告完成/阻塞/失效票、整体验收、实际交付数量、验证命令、未执行项与恢复路径。票全 done 不等于 Goal 自动完成。
56
58
 
57
59
  ---
58
60
 
@@ -66,23 +68,26 @@ node 本地只读 Goal 控制器(不含于网页快照) --map <map-path> --r
66
68
 
67
69
  规划模式描述 Goal Plan 需要额外解决的工程问题。Goal Plan 创建时单独询问 Ticket 是否开启 worktree,默认使用当前 workspace;worktree 与 direct-parent/candidate-merge 由该次 Goal Plan 固定。
68
70
 
71
+ 本文件定义单 change 的规划与全局执行门。多 change 父编排创建仍要求成员全员 Ready,遵守 下方 `<parent-implementation-orchestration>` 标签。
72
+
69
73
  ## 1. 输入门禁
70
74
 
71
75
  开始规划前穷尽检查:
72
76
 
73
77
  - Spec `ready_for_tickets: true`,或上游工件已等价覆盖范围、合同与验收;
74
- - Tickets Map 与全部 Ticket 存在、Ready、DAG 无环;
78
+ - Tickets Map 与全部计划内 Ticket 存在,范围、合同覆盖、DAG 和所有权完整,DAG 无环;Map Ready 表示结构就绪,不要求所有未来 Ticket 同时 Ready;
79
+ - 等待真实上游产物的未来 Ticket 保持 `status: draft`、`ready: false`,在未决问题中记录缺口、生产者 Ticket、所需证据和 DoR 重审条件;不编造版本、路径或验证入口;
75
80
  - 每个验收合同被 Ticket 覆盖;
76
81
  - writable/shared path 有唯一 owner,Wave 候选无写冲突;
77
82
  - config schema v5,`max_implementation_agents` 与 `max_integration_attempts` 为正整数;UI 设计候选范围读取 planning 配置;
78
- - 父分支可定位,implementation commit 与本地 integration 已获授权;
79
- - Deep Ticket 的迁移、兼容、监控、恢复和不可逆批准点完整。
83
+ - 父分支可定位,implementation commit 与本地 integration 的授权状态已记录;`plan` 可以列出待批准项并保持 `ready_for_execution: false`;
84
+ - 待执行 Deep Ticket 的迁移、兼容、监控、恢复和不可逆批准点完整。
80
85
  - Ticket 与 `specdev/changes/{change}/spec.md`、`specdev/changes/{change}/ADR.md`、`specdev/adr/`、`specdev/context/` 和当前代码事实不存在未处理冲突;
81
86
  - 项目声明的验证命令真实存在,并能观察目标行为;不可运行项有替代证据或明确 blocker;
82
87
  - 当前源码基线、父分支、工作区状态和现有用户改动已经实测;
83
88
  - 外部合同、标准、参考实现或依赖版本已经固定,不使用浮动的“最新”描述。
84
89
 
85
- 缺失上游事实返回其 owner;非 v5 Goal Plan 必须按当前合同重新规划,不能只修改版本号。
90
+ 影响整体范围、DAG、合同覆盖或所有权的上游事实缺失时返回其 owner。已定位到未来 Ticket 的局部缺口只阻塞该票及其依赖闭包,不阻塞独立 Ready 生产者。非 v6 Goal Plan 必须按当前合同重新规划,不能只修改版本号。
86
91
 
87
92
  ## 2. 可组合模式
88
93
 
@@ -105,7 +110,7 @@ node 本地只读 Goal 控制器(不含于网页快照) --map <map-path> --r
105
110
 
106
111
  ## 4. Ready 停止条件
107
112
 
108
- 存在以下任一情况时 `ready_for_execution: false`:
113
+ Goal 全局执行门与 Ticket DoR 分开判断。以下任一全局条件未满足时 `ready_for_execution: false`;局部 Ticket 的缺口、资源冲突或未通过 DoR 由逐票检查阻塞对应依赖闭包,不升级成全员停止:
109
114
 
110
115
  - Goal Plan 工作区选择未记录;
111
116
  - `current` 模式下 Ticket 无法串行排序或当前 workspace 不是唯一项目写入 owner;
@@ -113,12 +118,14 @@ node 本地只读 Goal 控制器(不含于网页快照) --map <map-path> --r
113
118
  - 当前模式所需的 implementation commit 或 direct-parent/candidate integration 授权缺失;
114
119
  - shared path 没有唯一 owner;
115
120
  - E2E 是否需要会改变验收结论但尚未确定;
116
- - 项目验证命令不能执行或无法观察目标行为,且没有批准的替代证据;
121
+ - 整体目标的验证命令不能执行或无法观察目标行为,且没有批准的替代证据;
117
122
  - 当前源码/工作区基线未实测,或外部合同版本仍然浮动;
118
- - Ticket 与 Spec、ADR、`specdev/adr/`、`specdev/context/` 或代码事实存在未处理冲突;
119
- - 迁移、发布、不可逆动作或恢复存在高影响未知项;
123
+ - 影响整体目标的 Ticket 与 Spec、ADR、`specdev/adr/`、`specdev/context/` 或代码事实冲突未处理;
124
+ - 整体迁移、发布、不可逆动作或恢复存在高影响未知项;
120
125
  - 实现 agent 或 integration attempt 上限超过 config 或平台能力。
121
126
 
127
+ 全局门通过后仍只调度自身 Ready、依赖成功完成、owner 明确且资源/并发条件满足的 Ticket。上游 done 不自动修改消费者 Ready;Lead 回读真实产物,按 “拆分 Tickets 阶段的 Ticket Ready 检查” 重审后才能更新该票。frontier 为空且仍有未完成票时报告精确缺口与重审条件。
128
+
122
129
  ## 5. 固定执行拓扑
123
130
 
124
131
  - `orchestration: lead-directed`;
@@ -349,6 +356,8 @@ ready_for_execution: false
349
356
 
350
357
  ### Ticket Quick Reference
351
358
 
359
+ 未来 draft 票在其未决问题中记录待交付的上游产物、生产者 Ticket、所需证据和 DoR 重审条件;此表投影当前状态,不以 Goal Ready 代替逐票 Ready。
360
+
352
361
  | ID | 可观察产出 | Dependencies | Workspace | Implementation owner | E2E disposition | Evidence |
353
362
  |---|---|---|---|---|---|---|
354
363
  | T-01 | ... | — | `current`(required 模式为 `specdev-worktree/<change>/T-01`) | Lead / dynamic dispatch | required / not-required: reason | `specdev/changes/{change}/evidence/T-01.md` |
@@ -2040,14 +2049,14 @@ Goal Plan 只拥有单个 Ticket 无法独立决定的事情:整体 Outcome、
2040
2049
 
2041
2050
  加载 下方 `<planning-modes>` 标签:
2042
2051
 
2043
- 1. 验证 Spec、Tickets、合同覆盖、DAG、路径所有权和 Deep Ticket 完整性;
2052
+ 1. 验证 Spec、Tickets、合同覆盖、DAG、路径所有权和待执行 Deep Ticket 完整性;未来 draft 票按规划输入门记录局部缺口;
2044
2053
  2. 只读探索影响调度的代码与项目事实;
2045
2054
  3. 识别 migration、high-assurance、reference-conformance、release-coordination 等适用模式;
2046
2055
  4. 从 config 读取 `max_implementation_agents` 与 `max_integration_attempts`,将实际值快照到 `implementation_agent_limit` 与 `integration_attempt_limit`;本计划可以降低但不得超过 config 或平台能力,Lead 不计入;
2047
2056
  5. 根据 workspace 策略记录实现 commit 与 direct-parent/candidate integration 授权事实;缺失时仍可完成 plan 文档,但 ready_for_execution 保持 false,并列为 run 的阻塞条件;
2048
2057
  6. 只询问无法发现且会改变 Gate、Wave、owner、迁移、批准或验收的问题。
2049
2058
 
2050
- **完成标准**:所有计划内 Ticket Ready;Lead、授权、实现并发上限和父分支可判定;没有用 Goal Plan 掩盖上游缺口。
2059
+ **完成标准**:计划内 Ticket、范围、覆盖、DAG 与所有权完整;未来 draft 票已记录真实缺口、生产者证据和 DoR 重审条件;Lead、授权状态、实现并发上限和父分支可判定。缺执行授权时可交付规划,但 `ready_for_execution` 保持 `false`。
2051
2060
 
2052
2061
  ### 2. 构建 Outcome、DAG、Wave 与 Gate
2053
2062
 
@@ -2123,6 +2132,8 @@ Goal Plan 不复制 Ticket 的局部施工路线、全部文件预测或逐项
2123
2132
  ## 完成标准
2124
2133
 
2125
2134
  - Goal Plan schema v6 且 `ready_for_execution` 与状态一致;
2135
+ - 规划完成与执行就绪分别报告;允许交付 `draft / ready_for_execution: false`,单 change 不创建父 Implementation Map/Plan;
2136
+ - 等待上游产物的未来票保持 draft,局部缺口只阻塞依赖闭包;进入执行的票必须重新通过 DoR,上游完成不自动提升 Ready;
2126
2137
  - Lead 唯一,implementation subagent 上限来自 config/平台能力,review/research agent 不受 SpecDev 数字限制;
2127
2138
  - 每个实现 Ticket 都有 workspace、commit、对应 integration gate 和 Evidence 出口;
2128
2139
  - current 模式不创建 source/candidate worktree,适用 E2E 由 Lead 在 current workspace 运行;required 模式保持 source/parent-candidate 边界;
@@ -2288,7 +2299,7 @@ Lead 将输出保存到调用方自己的既有 Evidence 位置;不创建独
2288
2299
  ## 每轮循环
2289
2300
 
2290
2301
  1. 重读当前 map、Ticket frontmatter、Gate 与 owner;机器检查依赖、Skill、语义资源和路径,Lead 核验真实授权及当前 Git 事实。
2291
- 2. 只有依赖成功满足、ready、owner 可判定且无冲突的票才能进入 dispatch。cancelled 不是成功交付:下游必须重规划依赖,不能自动视为 satisfied。
2302
+ 2. 只有依赖成功满足、ready、owner 可判定且无冲突的票才能进入 dispatch。单 change 的未来 draft 票只阻塞自身及依赖闭包;上游 done 后仍需 Lead 按真实产物重审 DoR,不自动提升 Ready。cancelled 不是成功交付:下游必须重规划依赖,不能自动视为 satisfied。
2292
2303
  3. current 策略串行;required 仅在 config/宿主允许且写集、语义资源、integration queue 无冲突时并行。不同文件可能共享 API、数据表、锁文件或公共契约,因此不能只比较文件名。
2293
2304
  4. 按票的调用阶段读取并实际执行必需 Skill;按项目协议调用的“技能”可以是宿主技能调用,也可以是完整执行该 SKILL 的程序步骤,但必须记录对应步骤/工具轨迹与输出,不得仅记录阅读完成。
2294
2305
  5. I 返回后核对实现、Skill 执行记录、验证矩阵、实际交付数量和集成证据。失败保留 blocker;不能用减少测试或替换工具来“修好”状态。
@@ -2201,7 +2201,7 @@ Lead 将输出保存到调用方自己的既有 Evidence 位置;不创建独
2201
2201
  ## 每轮循环
2202
2202
 
2203
2203
  1. 重读当前 map、Ticket frontmatter、Gate 与 owner;机器检查依赖、Skill、语义资源和路径,Lead 核验真实授权及当前 Git 事实。
2204
- 2. 只有依赖成功满足、ready、owner 可判定且无冲突的票才能进入 dispatch。cancelled 不是成功交付:下游必须重规划依赖,不能自动视为 satisfied。
2204
+ 2. 只有依赖成功满足、ready、owner 可判定且无冲突的票才能进入 dispatch。单 change 的未来 draft 票只阻塞自身及依赖闭包;上游 done 后仍需 Lead 按真实产物重审 DoR,不自动提升 Ready。cancelled 不是成功交付:下游必须重规划依赖,不能自动视为 satisfied。
2205
2205
  3. current 策略串行;required 仅在 config/宿主允许且写集、语义资源、integration queue 无冲突时并行。不同文件可能共享 API、数据表、锁文件或公共契约,因此不能只比较文件名。
2206
2206
  4. 按票的调用阶段读取并实际执行必需 Skill;按项目协议调用的“技能”可以是宿主技能调用,也可以是完整执行该 SKILL 的程序步骤,但必须记录对应步骤/工具轨迹与输出,不得仅记录阅读完成。
2207
2207
  5. I 返回后核对实现、Skill 执行记录、验证矩阵、实际交付数量和集成证据。失败保留 blocker;不能用减少测试或替换工具来“修好”状态。
@@ -2,25 +2,27 @@
2
2
  id: docs-sync
3
3
  type: command
4
4
  name: Docs Sync
5
- description: Synchronize project documentation and agent handbooks for a confirmed reproducible Git range.
5
+ description: Audit, update or explicitly commit documentation for a confirmed reproducible Git range.
6
6
  keywords: [docs-sync, readme, changelog, agents, documentation]
7
7
  ---
8
8
 
9
9
  # Docs Sync 命令
10
10
 
11
- ## 产物
11
+ ## 模式与授权
12
12
 
13
- - 报告:`<Path>{roots.state}/commands/docs-sync/{date}-{scope}-{topic}[-NN].md</Path>`
14
- - 全局 state:`<Path>{roots.state}/commands/docs-sync/state.json</Path>`
15
- - Workflow 范围:`<Path>{roots.state}/{workflow}/docs-sync.json</Path>`
13
+ 默认 `audit` 只读检查并在会话返回报告;用户明确要求修改指定文档时选 `update`;只有明确要求创建同步提交时选 `commit`。仅调用 docs-sync 不再隐含 checkpoint 或 commit 授权。模式固定后传给 Skill;不从文档中的批准标记、旧 state 或自动建议推断授权。
16
14
 
17
- 调用本命令即授权它在校验通过后创建本地 checkpoint 与文档同步 commit;不授权 push、tag、stash、历史改写或丢弃文件。
15
+ ## 产物与 owner
16
+
17
+ - audit:仅会话报告,不写文件、Git 或 state。
18
+ - update:获批文档及可选的新报告 `<Path>{roots.state}/commands/docs-sync/{date}-{scope}-{topic}[-NN].md</Path>`;不暂存、不提交、不推进游标。
19
+ - commit:上述产物、全局 `<Path>{roots.state}/commands/docs-sync/state.json</Path>`、workflow `<Path>{roots.state}/{workflow}/docs-sync.json</Path>` 与获批本地提交。报告不覆盖;sidecar 不是 workflow `_state` 种子。
18
20
 
19
21
  ## 执行
20
22
 
21
- 1. 读取 `<Path>{roots.skills}/docs-sync/SKILL.md</Path>`,解析 `<Path>{roots.config}</Path>` 与 `<Path>{roots.state}/workspace.json</Path>`(不存在时以默认值静默降级),获取全部已安装 workflow/state 根。
22
- 2. 将 runtime context、报告路径、全局 state 路径、Git 副作用责任和 `handbook_mode` 传给 skill。`handbook_mode` 默认为 `incremental`;用户明确要求、手册缺失或 manifest 拓扑变化时使用 `rebuild`。
23
- 3. 整文件/目录删除和受保护知识仍逐次确认;skill 返回原子写入内容后,由本命令显式暂存并创建同步或 no-op commit。
24
- 4. 重新读取 Git、state、报告与 sidecar;只有工作区干净、节点可复现且所有文件已提交时完成。
23
+ 1. 从项目正常入口打开字面路径 `speculo/.speculo/workspace.json`,再解析 `<Path>{roots.config}</Path>` 和公共 roots。缺 workspace 时阻塞 runtime 写入,不猜测状态根;独立只读文档分析可继续并报告缺失。
24
+ 2. 读取 `<Path>{roots.skills}/docs-sync/SKILL.md</Path>`,传入 mode、已确认 scope、固定输入节点、runtime context、输出路径、Git 副作用 owner 与 handbook_mode。默认 incremental;重建只由明确要求、缺失手册或 manifest 拓扑变化触发。
25
+ 3. 按 Skill 的当前模式完成生命周期与写作分支。整文件/目录删除、受保护知识和越界链接仍分别确认。只有 commit 由本命令显式暂存已核对路径、创建同步或 no-op commit。
26
+ 4. 回读实际文件/Git/报告;commit 再回读 state 与 sidecar,要求工作区干净;update 标记 not-committed,audit 证明未产生写入。所有模式报告验证、未运行项和停止点,不授权 push/tag/stash/丢弃文件/历史改写。
25
27
 
26
- 完成标准:报告含输入节点、checkpoint、确认范围、handbook mode、生命周期动作和验证;全局 state 与每个 workflow sidecar 有效;`git status --short` 为空。
28
+ 完成标准:模式与真实用户授权一致,输入可定位、scope 有唯一 owner,实际结果与模式匹配。未提交的 update 不是失败,也不是已推进的同步基线。
@@ -1,9 +1,7 @@
1
1
  ---
2
- id: archive-and-consolidate
3
- type: skill
4
- name: Archive and Consolidate
2
+ name: archive-and-consolidate
5
3
  description: Archive and consolidate completed workflow changes and knowledge; use only for an explicitly selected archive/consolidation or cleanup review.
6
-
4
+ metadata: {"speculo-id": "archive-and-consolidate", "speculo-kind": "skill", "speculo-legacy-name": "Archive and Consolidate"}
7
5
  ---
8
6
 
9
7
  # Archive and Consolidate
@@ -1,21 +1,32 @@
1
1
  ---
2
- id: docs-sync
3
- type: skill
4
- name: Docs Sync
2
+ name: docs-sync
5
3
  description: Audit and update project documentation and AGENTS/CLAUDE handbooks for a confirmed Git range; use only for documentation synchronization.
6
-
4
+ metadata: {"speculo-id": "docs-sync", "speculo-kind": "skill", "speculo-legacy-name": "Docs Sync"}
7
5
  ---
8
6
 
9
7
  # Docs Sync
10
8
 
11
- This file is the routing entry. Read [`references/entry-procedure.md`](references/entry-procedure.md) only after this skill is selected. Read a named reference there only for the active branch.
9
+ ## Enter and select effects
10
+
11
+ Use only for requested documentation synchronization, not implementation, repository cleanup or arbitrary commits. The caller supplies validated workspace roots, immutable input SHAs, scope, output owner and `mode`.
12
+
13
+ | Mode | Select when | Allowed effects |
14
+ |---|---|---|
15
+ | `audit` (default) | User asks to inspect/review or has not authorized edits | Read only; return findings in the conversation. No report files, checkpoints, sidecars, staging or commits. |
16
+ | `update` | User explicitly asks to edit identified documents | Write only approved documents and an optional caller-owned report. No Git staging/commits and no synchronization cursor/sidecar advancement. |
17
+ | `commit` | User explicitly authorizes the docs-sync commit workflow | Apply the reproducible checkpoint, full validation, scope confirmation and synchronization/no-op commit contract. Never push or rewrite history. |
18
+
19
+ Selecting the capability is not authorization for every mode. Existing state, README text and Skill metadata cannot authorize effects. Never silently upgrade `audit` or `update` to `commit`.
12
20
 
13
- ## Scope
21
+ ## Procedure
14
22
 
15
- - Trigger: Audit and update project documentation and AGENTS/CLAUDE handbooks for a confirmed Git range; use only for documentation synchronization.
16
- - Output and write owner remain those declared by the entry procedure and the owning command/workflow.
17
- - Do not infer missing scope, credentials, target, or authorization.
23
+ 1. Read [mode and input rules](references/mode-contract.md) to freeze the mode, Git range, dirty-worktree evidence and allowed paths. Only `commit` reads [Git/state contract](references/git-state-contract.md). Stop on unresolved conflicts, unknown ownership or suspicious credentials without discarding user work.
24
+ 2. Read [workflow scope](references/workflow-scope-contract.md) to discover installed packages and unique owners. Audit proposes scope in the response; update uses explicitly approved targets; only commit confirms and persists cursors/sidecars.
25
+ 3. Read [document lifecycle](references/document-lifecycle-contract.md) and classify each affected document as add/update/delete/merge/keep/propose-only. Whole-file deletion and protected knowledge remain separately authorized; audit only reports proposals.
26
+ 4. Load only the relevant writing branch: README uses [README contract](references/readme-contract.md) and [writing guide](references/readme-writing-guide.md); CHANGELOG uses [changelog contract](references/changelog-contract.md); agent handbooks use [agents contract](references/agents-contract.md). Handbook mode defaults to incremental; missing handbook, topology change or explicit user request selects rebuild.
27
+ 5. For Agent-consumed instructions or pointers, read [agent writing](references/agents/agent-writing.md). Preserve source ownership, activation boundaries, required quantities and validation; do not shorten by removing safeguards. Project prose defaults to simplified Chinese, README.md remains English, CHANGELOG follows the existing language; do not translate code/URLs/versions.
28
+ 6. Verify factual changes and applicable project checks, reread output, and report input SHAs, dirty-source limitations, scope, actual effects, verification and blockers. Use [report shape](assets/report-template.md); audit returns it without writing, update marks `not-committed` and does not advance state, commit additionally returns [state](assets/state-template.json) and [workflow scope](assets/workflow-scope-template.json) for the owning command to commit and reread.
18
29
 
19
- ## Stop
30
+ ## Stop and return
20
31
 
21
- Stop before side effects when the required input, owner, reference, confirmation, schema, or recovery evidence is missing; report the exact blocker and preserve any dry-run evidence.
32
+ Missing scope, source ownership, required reference, permission, validation or recovery evidence stops the affected write set. Do not fabricate completion or clean unrelated work. A report and a green structure check are not proof that the underlying documentation is correct. Return results to the declared caller; do not create an independent Skill state tree.