@llblab/pi-actors 0.45.1 → 0.46.1

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 (228) hide show
  1. package/AGENTS.md +9 -7
  2. package/BACKLOG.md +582 -0
  3. package/CHANGELOG.md +17 -1
  4. package/README.md +27 -13
  5. package/dist/fixtures/protocol/recipe-summary.json +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/lib/async-runs.d.ts +5 -1
  8. package/dist/lib/async-runs.js +26 -24
  9. package/dist/lib/automatic-review-runtime.d.ts +2 -0
  10. package/dist/lib/automatic-review-runtime.js +12 -5
  11. package/dist/lib/draft-sleep.js +0 -1
  12. package/dist/lib/execution.d.ts +1 -0
  13. package/dist/lib/execution.js +1 -0
  14. package/dist/lib/extension-runtime.d.ts +1 -1
  15. package/dist/lib/extension-runtime.js +26 -4
  16. package/dist/lib/inspector.js +46 -7
  17. package/dist/lib/paths.d.ts +0 -1
  18. package/dist/lib/paths.js +0 -7
  19. package/dist/lib/prompts.d.ts +1 -1
  20. package/dist/lib/prompts.js +4 -4
  21. package/dist/lib/recipes-context.d.ts +12 -3
  22. package/dist/lib/recipes-context.js +30 -6
  23. package/dist/lib/recipes-discovery.d.ts +18 -0
  24. package/dist/lib/recipes-discovery.js +95 -22
  25. package/dist/lib/recipes-references.d.ts +42 -9
  26. package/dist/lib/recipes-references.js +248 -135
  27. package/dist/lib/registry.d.ts +14 -1
  28. package/dist/lib/registry.js +110 -87
  29. package/dist/lib/runtime.d.ts +30 -4
  30. package/dist/lib/runtime.js +74 -12
  31. package/dist/lib/tools-inspect.d.ts +3 -1
  32. package/dist/lib/tools-inspect.js +56 -9
  33. package/dist/lib/tools-local.d.ts +2 -0
  34. package/dist/lib/tools-local.js +5 -2
  35. package/dist/lib/tools-response.js +2 -0
  36. package/dist/lib/tools-spawn.d.ts +2 -0
  37. package/dist/lib/tools-spawn.js +24 -52
  38. package/dist/lib/tools.d.ts +4 -1
  39. package/dist/lib/tools.js +2 -0
  40. package/dist/scripts/build-dist.mjs +13 -4
  41. package/dist/skills/actors/SKILL.md +8 -8
  42. package/dist/skills/actors/recipes/recipe-validate.json +11 -0
  43. package/{recipes/utility-coordinator-lock-snapshot.json → dist/skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  44. package/dist/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  45. package/dist/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  46. package/dist/skills/actors/recipes/run-summary.json +9 -0
  47. package/dist/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  48. package/dist/skills/actors/scripts/run-utils.mjs +164 -0
  49. package/{scripts → dist/skills/actors/scripts}/validate-recipe.mjs +134 -17
  50. package/dist/skills/artifacts/SKILL.md +16 -0
  51. package/{recipes/pipeline-artifact-bundle.json → dist/skills/artifacts/recipes/bundle.json} +4 -4
  52. package/dist/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  53. package/dist/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  54. package/{recipes/pipeline-artifact-report.json → dist/skills/artifacts/recipes/report.json} +2 -2
  55. package/dist/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  56. package/dist/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  57. package/dist/skills/media/SKILL.md +16 -0
  58. package/dist/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  59. package/{recipes/music-player.json → dist/skills/media/recipes/player.json} +1 -3
  60. package/dist/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  61. package/dist/skills/media/scripts/media-utils.mjs +47 -0
  62. package/dist/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  63. package/dist/skills/project-work/SKILL.md +16 -0
  64. package/dist/skills/project-work/recipes/changelog-section.json +11 -0
  65. package/{recipes/pipeline-docs-maintenance.json → dist/skills/project-work/recipes/docs-maintenance.json} +4 -4
  66. package/dist/skills/project-work/recipes/package-summary.json +9 -0
  67. package/{recipes/pipeline-release-readiness.json → dist/skills/project-work/recipes/release-readiness.json} +6 -6
  68. package/dist/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  69. package/{recipes/pipeline-repo-health.json → dist/skills/project-work/recipes/repo-health.json} +6 -6
  70. package/{recipes/pipeline-async-run-ops.json → dist/skills/project-work/recipes/run-ops.json} +3 -3
  71. package/dist/skills/project-work/recipes/skill-summary.json +11 -0
  72. package/dist/skills/project-work/scripts/project-utils.mjs +89 -0
  73. package/dist/skills/recipe-memory/SKILL.md +16 -0
  74. package/dist/skills/swarm/SKILL.md +4 -4
  75. package/{recipes/pipeline-architect-coordinator.json → dist/skills/swarm/recipes/architect.json} +5 -5
  76. package/{recipes/pipeline-checkpoint-continuation.json → dist/skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  77. package/dist/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  78. package/dist/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  79. package/dist/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  80. package/{recipes/pipeline-research-synthesis.json → dist/skills/swarm/recipes/research-synthesis.json} +6 -6
  81. package/{recipes/pipeline-review-readiness.json → dist/skills/swarm/recipes/review-readiness.json} +1 -1
  82. package/{recipes/subagents-prompts.json → dist/skills/swarm/recipes/subagent-prompts.json} +1 -1
  83. package/{recipes → dist/skills/swarm/recipes}/subagent-quorum.json +1 -1
  84. package/dist/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  85. package/docs/actor-inspector.md +4 -3
  86. package/docs/async-runs.md +2 -2
  87. package/docs/recipe-library.md +23 -23
  88. package/docs/releasing.md +2 -2
  89. package/docs/template-recipes.md +32 -14
  90. package/docs/tool-registry.md +10 -4
  91. package/fixtures/protocol/recipe-summary.json +1 -1
  92. package/index.ts +2 -1
  93. package/lib/async-runs.ts +52 -25
  94. package/lib/automatic-review-runtime.ts +16 -3
  95. package/lib/draft-sleep.ts +0 -1
  96. package/lib/execution.ts +2 -0
  97. package/lib/extension-runtime.ts +42 -4
  98. package/lib/inspector.ts +57 -11
  99. package/lib/paths.ts +0 -7
  100. package/lib/prompts.ts +4 -4
  101. package/lib/recipes-context.ts +51 -6
  102. package/lib/recipes-discovery.ts +164 -24
  103. package/lib/recipes-references.ts +359 -146
  104. package/lib/registry.ts +185 -94
  105. package/lib/runtime.ts +109 -17
  106. package/lib/tools-inspect.ts +77 -10
  107. package/lib/tools-local.ts +9 -1
  108. package/lib/tools-response.ts +2 -0
  109. package/lib/tools-spawn.ts +38 -74
  110. package/lib/tools.ts +4 -1
  111. package/package.json +2 -4
  112. package/scripts/build-dist.mjs +13 -4
  113. package/skills/actors/SKILL.md +8 -8
  114. package/skills/actors/recipes/recipe-validate.json +11 -0
  115. package/{dist/recipes/utility-coordinator-lock-snapshot.json → skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  116. package/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  117. package/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  118. package/skills/actors/recipes/run-summary.json +9 -0
  119. package/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  120. package/skills/actors/scripts/run-utils.mjs +164 -0
  121. package/{dist → skills/actors}/scripts/validate-recipe.mjs +134 -17
  122. package/skills/artifacts/SKILL.md +16 -0
  123. package/{dist/recipes/pipeline-artifact-bundle.json → skills/artifacts/recipes/bundle.json} +4 -4
  124. package/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  125. package/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  126. package/{dist/recipes/pipeline-artifact-report.json → skills/artifacts/recipes/report.json} +2 -2
  127. package/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  128. package/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  129. package/skills/media/SKILL.md +16 -0
  130. package/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  131. package/{dist/recipes/music-player.json → skills/media/recipes/player.json} +1 -3
  132. package/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  133. package/skills/media/scripts/media-utils.mjs +47 -0
  134. package/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  135. package/skills/project-work/SKILL.md +16 -0
  136. package/skills/project-work/recipes/changelog-section.json +11 -0
  137. package/{dist/recipes/pipeline-docs-maintenance.json → skills/project-work/recipes/docs-maintenance.json} +4 -4
  138. package/skills/project-work/recipes/package-summary.json +9 -0
  139. package/{dist/recipes/pipeline-release-readiness.json → skills/project-work/recipes/release-readiness.json} +6 -6
  140. package/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  141. package/{dist/recipes/pipeline-repo-health.json → skills/project-work/recipes/repo-health.json} +6 -6
  142. package/{dist/recipes/pipeline-async-run-ops.json → skills/project-work/recipes/run-ops.json} +3 -3
  143. package/skills/project-work/recipes/skill-summary.json +11 -0
  144. package/skills/project-work/scripts/project-utils.mjs +89 -0
  145. package/skills/recipe-memory/SKILL.md +16 -0
  146. package/skills/swarm/SKILL.md +4 -4
  147. package/{dist/recipes/pipeline-architect-coordinator.json → skills/swarm/recipes/architect.json} +5 -5
  148. package/{dist/recipes/pipeline-checkpoint-continuation.json → skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  149. package/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  150. package/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  151. package/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  152. package/{dist/recipes/pipeline-research-synthesis.json → skills/swarm/recipes/research-synthesis.json} +6 -6
  153. package/{dist/recipes/pipeline-review-readiness.json → skills/swarm/recipes/review-readiness.json} +1 -1
  154. package/{dist/recipes/subagents-prompts.json → skills/swarm/recipes/subagent-prompts.json} +1 -1
  155. package/{dist → skills/swarm}/recipes/subagent-quorum.json +1 -1
  156. package/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  157. package/dist/recipes/utility-changelog-section.json +0 -13
  158. package/dist/recipes/utility-package-summary.json +0 -11
  159. package/dist/recipes/utility-run-summary.json +0 -11
  160. package/dist/recipes/utility-skill-summary.json +0 -13
  161. package/dist/recipes/utility-validate-recipe.json +0 -13
  162. package/dist/scripts/executable-block-style.d.mts +0 -1
  163. package/dist/scripts/executable-block-style.mjs +0 -73
  164. package/dist/scripts/recipe-utils.mjs +0 -404
  165. package/dist/scripts/release-gates.mjs +0 -281
  166. package/recipes/utility-changelog-section.json +0 -13
  167. package/recipes/utility-package-summary.json +0 -11
  168. package/recipes/utility-run-summary.json +0 -11
  169. package/recipes/utility-skill-summary.json +0 -13
  170. package/recipes/utility-validate-recipe.json +0 -13
  171. package/scripts/executable-block-style.d.mts +0 -1
  172. package/scripts/executable-block-style.mjs +0 -73
  173. package/scripts/recipe-utils.mjs +0 -404
  174. package/scripts/release-gates.mjs +0 -281
  175. /package/dist/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  176. /package/dist/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  177. /package/dist/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  178. /package/dist/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  179. /package/dist/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  180. /package/dist/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  181. /package/dist/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  182. /package/dist/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  183. /package/dist/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  184. /package/dist/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  185. /package/dist/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  186. /package/dist/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  187. /package/dist/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  188. /package/dist/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  189. /package/dist/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  190. /package/dist/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  191. /package/dist/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  192. /package/dist/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  193. /package/dist/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  194. /package/dist/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  195. /package/dist/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  196. /package/dist/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  197. /package/dist/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  198. /package/dist/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  199. /package/dist/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  200. /package/dist/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  201. /package/dist/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
  202. /package/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  203. /package/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  204. /package/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  205. /package/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  206. /package/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  207. /package/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  208. /package/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  209. /package/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  210. /package/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  211. /package/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  212. /package/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  213. /package/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  214. /package/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  215. /package/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  216. /package/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  217. /package/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  218. /package/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  219. /package/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  220. /package/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  221. /package/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  222. /package/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  223. /package/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  224. /package/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  225. /package/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  226. /package/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  227. /package/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  228. /package/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
@@ -1,281 +0,0 @@
1
- #!/usr/bin/env node
2
- /** Reproducible exact-tree, Domain DAG, secret-hygiene, and ABCd release gates. */
3
-
4
- import { mkdtempSync, rmSync } from "node:fs";
5
- import { tmpdir } from "node:os";
6
- import { dirname, extname, join, normalize, relative, resolve } from "node:path";
7
- import { spawnSync } from "node:child_process";
8
- import { fileURLToPath } from "node:url";
9
-
10
- import { executableBlockBlankLines } from "./executable-block-style.mjs";
11
-
12
- const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
13
- const temp = mkdtempSync(join(tmpdir(), "pi-actors-release-index-"));
14
- const indexPath = join(temp, "index");
15
- const gitEnv = { ...process.env, GIT_INDEX_FILE: indexPath };
16
- const failures = [];
17
-
18
- function run(command, args, options = {}) {
19
- const result = spawnSync(command, args, {
20
- cwd: root,
21
- encoding: "utf8",
22
- maxBuffer: 32 * 1024 * 1024,
23
- ...options,
24
- });
25
- if (result.status !== 0) {
26
- throw new Error(
27
- `${command} ${args.join(" ")} failed (${result.status}): ${(result.stderr || result.stdout || "no output").trim()}`,
28
- );
29
- }
30
- return result.stdout;
31
- }
32
-
33
- function check(condition, message) {
34
- if (!condition) failures.push(message);
35
- }
36
-
37
- function stagedText(path) {
38
- const result = spawnSync("git", ["show", `:${path}`], {
39
- cwd: root,
40
- env: gitEnv,
41
- encoding: "buffer",
42
- maxBuffer: 16 * 1024 * 1024,
43
- });
44
- if (result.status !== 0) {
45
- failures.push(`could not read staged file: ${path}`);
46
- return undefined;
47
- }
48
- const bytes = result.stdout;
49
- if (bytes.includes(0)) return undefined;
50
- return bytes.toString("utf8");
51
- }
52
-
53
- function sourceImports(source) {
54
- return [...source.matchAll(/^import(?:\s+type)?\s+(?:[^"']+?\s+from\s+)?["']([^"']+)["'];?$/gmu)]
55
- .map((match) => match[1]);
56
- }
57
-
58
- function resolveLocalImport(from, specifier, sourceSet) {
59
- if (!specifier.startsWith(".")) return undefined;
60
- const base = normalize(join(dirname(from), specifier)).replaceAll("\\", "/");
61
- const candidates = extname(base)
62
- ? [base.replace(/\.js$/u, ".ts")]
63
- : [`${base}.ts`, `${base}/index.ts`];
64
- return candidates.find((candidate) => sourceSet.has(candidate));
65
- }
66
-
67
- try {
68
- run("git", ["read-tree", "HEAD"], { env: gitEnv });
69
- run("git", ["add", "-A"], { env: gitEnv });
70
- run("git", ["diff", "--cached", "--check"], { env: gitEnv });
71
- const files = run("git", ["ls-files", "-z"], { env: gitEnv })
72
- .split("\0")
73
- .filter(Boolean);
74
- const fileSet = new Set(files);
75
- console.log(`[release] exact temporary index: ${files.length} files`);
76
- const secretPatterns = [
77
- [/-----BEGIN(?: [A-Z0-9]+)? PRIVATE KEY-----[\s\S]{80,}?-----END(?: [A-Z0-9]+)? PRIVATE KEY-----/u, "private-key block"],
78
- [/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/u, "AWS access key"],
79
- [/\bgithub_pat_[A-Za-z0-9_]{20,}\b|\bgh[pousr]_[A-Za-z0-9]{20,}\b/u, "GitHub token"],
80
- [/\bglpat-[A-Za-z0-9_-]{20,}\b|\bnpm_[A-Za-z0-9]{20,}\b|\bxox[baprs]-[A-Za-z0-9-]{10,}\b/u, "service token"],
81
- ];
82
- const publicPath = /^(?:README\.md|AGENTS\.md|BACKLOG\.md|CHANGELOG\.md|docs\/|skills\/|recipes\/)/u;
83
- for (const path of files) {
84
- const text = stagedText(path);
85
- if (text === undefined) continue;
86
- if (!path.startsWith("tests/") && !path.startsWith("fixtures/")) {
87
- for (const [pattern, label] of secretPatterns) {
88
- check(!pattern.test(text), `${label} detected in ${path}`);
89
- }
90
- }
91
- if (publicPath.test(path)) {
92
- check(!/(?:^|[\s"'`])\/home\/[A-Za-z0-9._-]+\//u.test(text), `machine-local path in ${path}`);
93
- }
94
- }
95
- console.log("[release] bounded secret and public-path hygiene checked");
96
- const executableSources = files.filter((path) =>
97
- /\.(?:[cm]?js|ts)$/u.test(path) && !path.startsWith("dist/"),
98
- );
99
- for (const path of executableSources) {
100
- const blankLines = executableBlockBlankLines(stagedText(path) ?? "");
101
- check(
102
- blankLines.length === 0,
103
- `blank lines inside executable blocks: ${path}:${blankLines.join(",")}`,
104
- );
105
- }
106
- console.log("[release] executable blocks contain no blank lines");
107
- const removedPaths = [
108
- "lib/messages.ts",
109
- "lib/rooms.ts",
110
- "lib/mailbox-loop.ts",
111
- "lib/runs-mailbox.ts",
112
- "lib/runs-messages.ts",
113
- "lib/runs-outbox.ts",
114
- "lib/tools-mailbox.ts",
115
- "scripts/actor-worker.mjs",
116
- "scripts/coordinator.mjs",
117
- "recipes/actor-worker.json",
118
- "recipes/pipeline-room-swarm.json",
119
- "recipes/subagent-message.json",
120
- "recipes/utility-actor-message.json",
121
- "docs/actor-messages.md",
122
- "docs/run-inspector.md",
123
- "lib/run-inspector.ts",
124
- "lib/run-inspector-overlay.ts",
125
- ];
126
- for (const path of removedPaths) check(!fileSet.has(path), `removed surface returned: ${path}`);
127
- const currentSurface = /^(?:lib\/|scripts\/|recipes\/|fixtures\/|skills\/|docs\/|README\.md|AGENTS\.md)/u;
128
- const forbiddenPatterns = [
129
- [/room:</u, "room address"],
130
- [/branch:</u, "branch address"],
131
- [/communication\.json/u, "communication snapshot"],
132
- [/\bActor(?:Address|Message)\b/u, "legacy actor type"],
133
- [/\b(?:actor_address|default_room)\b/u, "legacy spawn placeholder"],
134
- [/inbox\.jsonl/u, "legacy inbox state"],
135
- ];
136
- for (const path of files.filter((candidate) => currentSurface.test(candidate))) {
137
- if (path === "BACKLOG.md" || path === "CHANGELOG.md" || path === "scripts/release-gates.mjs") continue;
138
- const text = stagedText(path) ?? "";
139
- for (const [pattern, label] of forbiddenPatterns) {
140
- check(!pattern.test(text), `${label} in current surface: ${path}`);
141
- }
142
- }
143
- const legacyFallbacks = new Map([
144
- ["lib/observability.ts", "outbox.jsonl"],
145
- ["lib/runs-status.ts", "events.jsonl"],
146
- ["lib/runs-start.ts", "events.jsonl"],
147
- ]);
148
- for (const path of files.filter((candidate) => currentSurface.test(candidate))) {
149
- if (path === "BACKLOG.md" || path === "CHANGELOG.md" || path === "scripts/release-gates.mjs") continue;
150
- const text = stagedText(path) ?? "";
151
- for (const term of ["outbox.jsonl", "events.jsonl"]) {
152
- if (!text.includes(term)) continue;
153
- check(legacyFallbacks.get(path) === term, `legacy state reference outside read-only fallback: ${path} (${term})`);
154
- }
155
- }
156
- console.log("[release] removed-surface and legacy-fallback allowlists checked");
157
- const directTraceWrite = /(?:appendFileSync|writeFileSync|writeText(?:Atomic)?)\s*\(\s*[A-Za-z0-9_.]*?(?:trace|event)(?:Path|File)/iu;
158
- for (const path of files.filter((candidate) =>
159
- (candidate.startsWith("lib/") && candidate.endsWith(".ts")) ||
160
- (candidate.startsWith("scripts/") && candidate.endsWith(".mjs"))
161
- )) {
162
- if (path === "lib/runs-trace.ts") continue;
163
- check(!directTraceWrite.test(stagedText(path) ?? ""), `direct Trace writer outside canonical authority: ${path}`);
164
- }
165
- const canonicalTrace = stagedText("lib/runs-trace.ts") ?? "";
166
- check(/withFileMutationLock\(path/u.test(canonicalTrace), "canonical Trace append lacks mutation lock");
167
- for (const path of [
168
- "scripts/async-runner.mjs",
169
- "scripts/locker.mjs",
170
- "scripts/music-player.mjs",
171
- ]) {
172
- const text = stagedText(path) ?? "";
173
- check(
174
- text.includes('importRuntimeModule("runs-trace")') && text.includes("appendRunTraceEvent"),
175
- `first-party Trace writer bypasses canonical runtime module: ${path}`,
176
- );
177
- if (path !== "scripts/async-runner.mjs") check(
178
- text.includes('importRuntimeModule("runs-controls")') &&
179
- !/function (?:read|write|claimControls|finalizeControls)\b/u.test(text),
180
- `first-party Control writer bypasses canonical runtime module: ${path}`,
181
- );
182
- }
183
- console.log("[release] canonical Trace and Control writer residue checked");
184
- // owner | class | lock | record bound | byte bound | recovery
185
- const appendOnlyOwners = new Set([
186
- "lib/runs-trace.ts", // canonical Run evidence | token lock | 2048 | 4 MiB | compact valid suffix
187
- "lib/runs-retention.ts", // shared kernel evidence | token lock | 256 | 1 MiB | skip malformed
188
- "scripts/locker.mjs", // first-party actor state | token lock | 512 | 1 MiB | skip malformed
189
- "lib/command-templates.ts", // complete execution capture | command owner | n/a | artifact policy | preserve
190
- "scripts/async-runner.mjs", // captures/prompts | Run owner | n/a | artifact policy | preserve
191
- "scripts/recipe-utils.mjs", // user-declared artifact | caller owner | n/a | caller policy | preserve
192
- "scripts/release-gates.mjs", // build/test-only source inventory | n/a | n/a | n/a | self-match
193
- ]);
194
- const appendOnlyPattern = /\bappendFileSync\b|\b(?:writeFileSync|writeTextAtomic)\s*\([^)]*\{\s*flag:\s*["']a["']/su;
195
- for (const path of files.filter((candidate) => /^(?:lib\/.*\.ts|scripts\/.*\.mjs)$/u.test(candidate)))
196
- if (appendOnlyPattern.test(stagedText(path) ?? ""))
197
- check(appendOnlyOwners.has(path), `unregistered shipped append-only writer: ${path}`);
198
- for (const path of appendOnlyOwners) check(fileSet.has(path), `stale append-only owner inventory: ${path}`);
199
- console.log(`[release] append-only owner inventory checked: ${appendOnlyOwners.size} source owners`);
200
- check(
201
- (stagedText("scripts/validate-recipe.mjs") ?? "").includes(
202
- "qaReport.diagnostics.length === 0 && qaReport.warnings.length === 0",
203
- ),
204
- "Recipe QA warnings are not release-blocking",
205
- );
206
- console.log("[release] zero-warning Recipe QA gate checked");
207
- const maximumShippedLines = 32_000;
208
- const shippedPath = /^(?:lib\/|scripts\/|recipes\/|docs\/|skills\/)/u;
209
- const shippedLines = files
210
- .filter((path) => shippedPath.test(path))
211
- .reduce((total, path) => total + (((stagedText(path) ?? "").match(/\n/gu) ?? []).length + 1), 0);
212
- check(shippedLines <= maximumShippedLines, `shipped lines ${shippedLines} exceed release maximum ${maximumShippedLines}`);
213
- console.log(`[release] shipped lines ${shippedLines} <= release maximum ${maximumShippedLines}`);
214
- const sources = files.filter((path) => path === "index.ts" || (path.startsWith("lib/") && path.endsWith(".ts")));
215
- const sourceSet = new Set(sources);
216
- const graph = new Map();
217
- for (const path of sources) {
218
- const text = stagedText(path) ?? "";
219
- const headerEnd = text.indexOf("*/");
220
- const header = headerEnd >= 0 ? text.slice(0, headerEnd + 2) : "";
221
- check(
222
- header.startsWith("/**") && (header.includes("Zones:") || header.includes("Owns:")),
223
- `missing domain header: ${path}`,
224
- );
225
- const edges = sourceImports(text)
226
- .map((specifier) => resolveLocalImport(path, specifier, sourceSet))
227
- .filter(Boolean);
228
- graph.set(path, edges);
229
- if (path.startsWith("lib/")) {
230
- check(!edges.includes("index.ts"), `domain imports entrypoint: ${path}`);
231
- }
232
- }
233
- const visiting = new Set();
234
- const visited = new Set();
235
- function visit(path, stack = []) {
236
- if (visiting.has(path)) {
237
- failures.push(`Domain DAG cycle: ${[...stack, path].join(" -> ")}`);
238
- return;
239
- }
240
- if (visited.has(path)) return;
241
- visiting.add(path);
242
- for (const next of graph.get(path) ?? []) visit(next, [...stack, path]);
243
- visiting.delete(path);
244
- visited.add(path);
245
- }
246
- for (const path of sources) visit(path);
247
- console.log(`[release] strict Domain DAG: ${sources.length} sources, acyclic`);
248
- for (const path of ["README.md", "AGENTS.md", "BACKLOG.md", "CHANGELOG.md", "docs/README.md"]) {
249
- check(fileSet.has(path), `missing ABCd root/context file: ${path}`);
250
- }
251
- const readStaged = (path) => stagedText(path) ?? "";
252
- const readme = readStaged("README.md");
253
- for (const path of ["AGENTS.md", "BACKLOG.md", "CHANGELOG.md", "docs/README.md"]) {
254
- check(readme.includes(path), `README.md does not route to ${path}`);
255
- }
256
- for (const path of files.filter((candidate) => candidate.endsWith(".md"))) {
257
- const text = readStaged(path);
258
- for (const match of text.matchAll(/\[[^\]]*\]\(([^)]+)\)/gu)) {
259
- const target = match[1].split("#", 1)[0];
260
- if (!target || /^(?:https?:|mailto:)/u.test(target)) continue;
261
- const resolved = normalize(join(dirname(path), decodeURIComponent(target))).replaceAll("\\", "/");
262
- check(fileSet.has(resolved), `broken Markdown link: ${path} -> ${target}`);
263
- }
264
- }
265
- const docsIndex = readStaged("docs/README.md");
266
- for (const path of files.filter((candidate) => candidate.startsWith("docs/") && candidate.endsWith(".md") && candidate !== "docs/README.md")) {
267
- check(docsIndex.includes(relative("docs", path).replaceAll("\\", "/")), `docs/README.md omits ${path}`);
268
- }
269
- console.log("[release] ABCd context roots, routing, and Markdown links checked");
270
- if (failures.length > 0) {
271
- for (const failure of failures) console.error(`[FAIL] ${failure}`);
272
- process.exitCode = 1;
273
- } else {
274
- console.log("[release] all supplemental release gates passed");
275
- }
276
- } catch (error) {
277
- console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`);
278
- process.exitCode = 1;
279
- } finally {
280
- rmSync(temp, { recursive: true, force: true });
281
- }