@akagilnc/pi-workflow-roles 0.1.1751

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 (192) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +104 -0
  3. package/README.zh-CN.md +133 -0
  4. package/THIRD_PARTY_NOTICES.md +60 -0
  5. package/dist/activation-ledger-git.js +68 -0
  6. package/dist/activation-ledger-session.js +120 -0
  7. package/dist/activation-ledger-topology.js +239 -0
  8. package/dist/activation-reconciliation.js +61 -0
  9. package/dist/audit-escalation.js +108 -0
  10. package/dist/auditor-dossier-tool.js +35 -0
  11. package/dist/canonical-json.js +78 -0
  12. package/dist/compliance-transport.js +77 -0
  13. package/dist/doctor-contracts.js +172 -0
  14. package/dist/dossier-resolution.js +103 -0
  15. package/dist/evidence-child-executor.js +661 -0
  16. package/dist/exact-utf8.js +12 -0
  17. package/dist/git-object-id.js +7 -0
  18. package/dist/in-process-session.js +50 -0
  19. package/dist/merger-contracts.js +76 -0
  20. package/dist/navigator-attendance.js +995 -0
  21. package/dist/navigator-invocation-identity.js +220 -0
  22. package/dist/open-tool-schema.js +39 -0
  23. package/dist/package-contracts/collector-output.js +50 -0
  24. package/dist/package-contracts/fixer-output.js +72 -0
  25. package/dist/package-contracts/fixer-packet.js +77 -0
  26. package/dist/package-contracts/judge-output.js +17 -0
  27. package/dist/package-contracts/reviewer-output.js +82 -0
  28. package/dist/package-contracts/terminating-tools.js +173 -0
  29. package/dist/package-contracts/worker-output.js +13 -0
  30. package/dist/package-owned-tool-idle.js +104 -0
  31. package/dist/packaged-role-registry.js +34 -0
  32. package/dist/public-cli/main.js +23867 -0
  33. package/dist/public-command-renderer.js +20 -0
  34. package/dist/reviewer-agent.js +93 -0
  35. package/dist/reviewer-child-executor.js +23 -0
  36. package/dist/reviewer-construction.js +95 -0
  37. package/dist/reviewer-dispatch.js +77 -0
  38. package/dist/reviewer-execution-ledger.js +160 -0
  39. package/dist/reviewer-failure-diagnostic.js +17 -0
  40. package/dist/reviewer-git-snapshot.js +38 -0
  41. package/dist/reviewer-pinned-git.js +146 -0
  42. package/dist/reviewer-preflight-error.js +15 -0
  43. package/dist/reviewer-prompt-identity.js +10 -0
  44. package/dist/reviewer-scope-prompt.js +21 -0
  45. package/dist/reviewer-workspace.js +151 -0
  46. package/dist/sha256.js +5 -0
  47. package/dist/sitian-record-entry.js +33 -0
  48. package/dist/stderr-jsonl.js +26 -0
  49. package/dist/stream-idle-guard.js +75 -0
  50. package/dist/tool-execution-observation.js +141 -0
  51. package/dist/uuidv7.js +21 -0
  52. package/dist/work-subject-identity.js +53 -0
  53. package/extensions/role-runtime.ts +303 -0
  54. package/package.json +69 -0
  55. package/packets/fixer-prerequisites.json +6 -0
  56. package/packets/fixer-repair.md +5 -0
  57. package/packets/judge-apply.md +77 -0
  58. package/packets/judge-authority.md +64 -0
  59. package/packets/judge-plan.md +55 -0
  60. package/packets/judge-review.md +49 -0
  61. package/packets/judge-submission.md +34 -0
  62. package/resources/methods/code-review/SKILL.md +92 -0
  63. package/resources/methods/code-review/agents/openai.yaml +3 -0
  64. package/resources/methods/code-review/provenance.json +26 -0
  65. package/resources/methods/diagnosing-bugs/SKILL.md +134 -0
  66. package/resources/methods/diagnosing-bugs/agents/openai.yaml +3 -0
  67. package/resources/methods/diagnosing-bugs/provenance.json +31 -0
  68. package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  69. package/resources/methods/resolving-merge-conflicts/SKILL.md +14 -0
  70. package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +3 -0
  71. package/resources/methods/resolving-merge-conflicts/provenance.json +26 -0
  72. package/resources/methods/tdd/SKILL.md +38 -0
  73. package/resources/methods/tdd/agents/openai.yaml +3 -0
  74. package/resources/methods/tdd/mocking.md +59 -0
  75. package/resources/methods/tdd/provenance.json +36 -0
  76. package/resources/methods/tdd/tests.md +77 -0
  77. package/resources/navigator-route-playbook.md +32 -0
  78. package/schemas/tool-execution-observation.schema.json +107 -0
  79. package/scripts/build-package.mjs +65 -0
  80. package/scripts/generate-tool-execution-observation-schema.ts +7 -0
  81. package/souls/coder.md +10 -0
  82. package/souls/collector.md +11 -0
  83. package/souls/doctor-auditor.md +23 -0
  84. package/souls/doctor.md +8 -0
  85. package/souls/fixer-auditor.md +33 -0
  86. package/souls/fixer.md +13 -0
  87. package/souls/judge-auditor.md +33 -0
  88. package/souls/judge.md +74 -0
  89. package/souls/merger.md +5 -0
  90. package/souls/navigator.md +5 -0
  91. package/souls/reviewer-auditor.md +25 -0
  92. package/souls/reviewer.md +11 -0
  93. package/src/activation-ledger-git.ts +96 -0
  94. package/src/activation-ledger-session.ts +188 -0
  95. package/src/activation-ledger-topology.ts +301 -0
  96. package/src/activation-ledger.ts +240 -0
  97. package/src/activation-reconciliation.ts +163 -0
  98. package/src/activation-trace.ts +38 -0
  99. package/src/audit-escalation.ts +177 -0
  100. package/src/auditor-dossier-tool.ts +48 -0
  101. package/src/auditor-soul.ts +28 -0
  102. package/src/canonical-json.ts +74 -0
  103. package/src/canonical-skill-binding.ts +107 -0
  104. package/src/collector-config.ts +89 -0
  105. package/src/collector-evidence.ts +461 -0
  106. package/src/collector-github.ts +656 -0
  107. package/src/collector-identity.ts +161 -0
  108. package/src/collector-ledger.ts +827 -0
  109. package/src/collector-receipt.ts +87 -0
  110. package/src/collector-role.ts +592 -0
  111. package/src/collector-tool-schemas.ts +19 -0
  112. package/src/compliance-transport.ts +130 -0
  113. package/src/doctor-auditor.ts +53 -0
  114. package/src/doctor-contracts.ts +166 -0
  115. package/src/doctor-evidence.ts +47 -0
  116. package/src/doctor-role.ts +18 -0
  117. package/src/dossier-resolution.ts +137 -0
  118. package/src/evidence-child-executor.ts +775 -0
  119. package/src/exact-utf8.ts +9 -0
  120. package/src/factory-board.ts +1822 -0
  121. package/src/git-object-id.ts +11 -0
  122. package/src/human-format.ts +65 -0
  123. package/src/in-process-session.ts +78 -0
  124. package/src/judge-auditor.ts +55 -0
  125. package/src/judge-recording-anti-forge.ts +53 -0
  126. package/src/judge-role.ts +160 -0
  127. package/src/merger-contracts.ts +71 -0
  128. package/src/merger-git-state.ts +76 -0
  129. package/src/merger-role.ts +60 -0
  130. package/src/navigator-attendance.ts +1254 -0
  131. package/src/navigator-invocation-identity.ts +446 -0
  132. package/src/open-tool-schema.ts +46 -0
  133. package/src/package-contracts/collector-output.ts +109 -0
  134. package/src/package-contracts/fixer-output.ts +81 -0
  135. package/src/package-contracts/fixer-packet.ts +93 -0
  136. package/src/package-contracts/judge-output.ts +39 -0
  137. package/src/package-contracts/reviewer-output.ts +115 -0
  138. package/src/package-contracts/terminating-tools.ts +259 -0
  139. package/src/package-contracts/worker-output.ts +36 -0
  140. package/src/package-owned-tool-idle.ts +134 -0
  141. package/src/package-resources/method-skill-binding.ts +87 -0
  142. package/src/package-resources/method-skill.ts +358 -0
  143. package/src/packaged-role-registry.ts +36 -0
  144. package/src/public-cli/cli-errors.ts +11 -0
  145. package/src/public-cli/cli-io.ts +4 -0
  146. package/src/public-cli/cli.ts +912 -0
  147. package/src/public-cli/coder-run.ts +575 -0
  148. package/src/public-cli/collector-run.ts +375 -0
  149. package/src/public-cli/command-renderer.ts +8 -0
  150. package/src/public-cli/config.ts +346 -0
  151. package/src/public-cli/doctor-run.ts +355 -0
  152. package/src/public-cli/explicit-internal.ts +274 -0
  153. package/src/public-cli/fixer-run.ts +587 -0
  154. package/src/public-cli/host-pi-runtime.ts +112 -0
  155. package/src/public-cli/invocation.ts +1958 -0
  156. package/src/public-cli/judge-run.ts +507 -0
  157. package/src/public-cli/main.ts +15 -0
  158. package/src/public-cli/merger-run.ts +681 -0
  159. package/src/public-cli/public-run-credentials.ts +71 -0
  160. package/src/public-cli/registry.ts +153 -0
  161. package/src/public-cli/reviewer-run.ts +561 -0
  162. package/src/public-cli/run-lifecycle.ts +884 -0
  163. package/src/public-cli/settlement.ts +3765 -0
  164. package/src/public-cli/terminal.ts +325 -0
  165. package/src/public-command-renderer.ts +43 -0
  166. package/src/reviewer-agent.ts +94 -0
  167. package/src/reviewer-auditor.ts +53 -0
  168. package/src/reviewer-child-executor.ts +31 -0
  169. package/src/reviewer-construction.ts +137 -0
  170. package/src/reviewer-dispatch.ts +94 -0
  171. package/src/reviewer-execution-ledger.ts +206 -0
  172. package/src/reviewer-failure-diagnostic.ts +18 -0
  173. package/src/reviewer-git-snapshot.ts +53 -0
  174. package/src/reviewer-pinned-git.ts +144 -0
  175. package/src/reviewer-preflight-error.ts +14 -0
  176. package/src/reviewer-prompt-identity.ts +17 -0
  177. package/src/reviewer-role.ts +193 -0
  178. package/src/reviewer-scope-prompt.ts +24 -0
  179. package/src/reviewer-settlement.ts +63 -0
  180. package/src/reviewer-workspace.ts +111 -0
  181. package/src/role-runtime.ts +884 -0
  182. package/src/sha256.ts +6 -0
  183. package/src/sitian-record-entry.ts +57 -0
  184. package/src/stderr-jsonl.ts +28 -0
  185. package/src/stream-idle-guard.ts +98 -0
  186. package/src/ticket-snapshot.ts +662 -0
  187. package/src/ticket-trajectory.ts +1000 -0
  188. package/src/tool-execution-observation.ts +168 -0
  189. package/src/uuidv7.ts +1 -0
  190. package/src/work-subject-identity.ts +94 -0
  191. package/src/worker-role.ts +434 -0
  192. package/src/worker-submission-gates.ts +225 -0
@@ -0,0 +1,225 @@
1
+ /** #242 worker gates ①②④. ① durability: ADR 0065/#216 createRecordSession only — no appendCustomEntry bypass / parallel ledger. */
2
+ import { execFileSync } from "node:child_process";
3
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import { SessionManager } from "@earendil-works/pi-coding-agent";
6
+
7
+ import {
8
+ createRecordSession,
9
+ type RecordSessionParent,
10
+ } from "./sitian-record-entry.ts";
11
+
12
+ export const WORKER_COMMIT_SUBJECT_PREFIX = "ak-roles:";
13
+ /** Sitian kind for gate ① durable baseline / bounce records (single path segment, not a destination). */
14
+ export const WORKER_SUBMISSION_GATE_RECORD_KIND = "worker-submission-gate";
15
+ export const WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
16
+ export const WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE = "commit-reminder-bounce";
17
+
18
+ const DONE = new Set(["completed", "partially_completed"]);
19
+ /** Marker: own-package hooks are reloadable across HOOK body changes; foreign hooks refuse. */
20
+ const HOOK_MARKER = "ak-roles: worker-submission-gates reference-transaction";
21
+
22
+ export class WorkerCommitReminderError extends Error {
23
+ readonly code = "worker_commit_reminder" as const;
24
+ constructor() { super("未观察到 commit"); this.name = "WorkerCommitReminderError"; }
25
+ }
26
+
27
+ export type WorkerSubmissionGateParent = RecordSessionParent;
28
+
29
+ function git(cwd: string, args: string[]): string {
30
+ return execFileSync("git", args, {
31
+ cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"],
32
+ env: { ...process.env, GIT_DIR: undefined, GIT_WORK_TREE: undefined, GIT_COMMON_DIR: undefined },
33
+ }).trim();
34
+ }
35
+
36
+ function gitFile(file: string, args: string[]): string {
37
+ return execFileSync("git", ["config", "--file", file, ...args], {
38
+ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"],
39
+ env: { ...process.env, GIT_DIR: undefined, GIT_WORK_TREE: undefined, GIT_COMMON_DIR: undefined },
40
+ }).trim();
41
+ }
42
+
43
+ // ② each newly-created commit (incl. empty subject); ④ ban non-fast-forward.
44
+ // Scoped by install: worktree-local core.hooksPath → only the armed tree.
45
+ const HOOK = `#!/bin/sh
46
+ # ${HOOK_MARKER}
47
+ [ "$1" = prepared ] || exit 0
48
+ prefix=${WORKER_COMMIT_SUBJECT_PREFIX}
49
+ while read -r old new ref; do
50
+ case $ref in refs/heads/*|HEAD) ;; *) continue ;; esac
51
+ [ -n "$new" ] && [ -n "$(printf %s "$new" | tr -d 0)" ] || continue
52
+ if [ -n "$old" ] && [ -n "$(printf %s "$old" | tr -d 0)" ]; then
53
+ git merge-base --is-ancestor "$old" "$new" 2>/dev/null || { echo "ak-roles: rejected non-fast-forward update of $ref (no amend/rebase/reset)" >&2; exit 1; }
54
+ fi
55
+ for commit in $(git rev-list "$new" --not --all 2>/dev/null); do
56
+ subj=$(git log -1 --format=%s "$commit")
57
+ case $subj in "$prefix"*) ;; *) echo "ak-roles: commit subject must start with $prefix (got: $subj)" >&2; exit 1 ;; esac
58
+ done
59
+ done
60
+ `;
61
+
62
+ /**
63
+ * Bind ②④ to this worktree only — private hooksPath + worktree config.
64
+ * Never leave shared common config in a state that bricks sibling/main trees
65
+ * (git requires core.bare/core.worktree moved out of common when worktreeConfig is on).
66
+ */
67
+ export function installWorkerGitHooks(cwd: string): void {
68
+ // Fail closed before any shared-config write: bare host / non-work-tree is not armable.
69
+ let inside: string;
70
+ try {
71
+ inside = git(cwd, ["rev-parse", "--is-inside-work-tree"]);
72
+ } catch (error) {
73
+ throw new Error(
74
+ `ak-roles: refusing worker hooks install outside a git work tree: ${
75
+ error instanceof Error ? error.message : String(error)
76
+ }`,
77
+ );
78
+ }
79
+ if (inside !== "true") {
80
+ throw new Error("ak-roles: refusing worker hooks install outside a git work tree");
81
+ }
82
+
83
+ const commonDir = git(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
84
+ const commonConfig = resolve(commonDir, "config");
85
+ const mainWorktreeConfig = resolve(commonDir, "config.worktree");
86
+
87
+ // Snapshot worktree-only keys still sitting in common config (git docs: must move on enable).
88
+ let bareInCommon = false;
89
+ let worktreeInCommon: string | undefined;
90
+ try { bareInCommon = gitFile(commonConfig, ["--get", "core.bare"]) === "true"; } catch { /* unset */ }
91
+ try { worktreeInCommon = gitFile(commonConfig, ["--get", "core.worktree"]); } catch { /* unset */ }
92
+
93
+ git(cwd, ["config", "extensions.worktreeConfig", "true"]);
94
+
95
+ // Migrate immediately so sibling trees never observe bare-in-common under worktreeConfig.
96
+ if (bareInCommon) {
97
+ try { gitFile(commonConfig, ["--unset", "core.bare"]); } catch { /* raced */ }
98
+ gitFile(mainWorktreeConfig, ["core.bare", "true"]);
99
+ }
100
+ if (worktreeInCommon !== undefined) {
101
+ try { gitFile(commonConfig, ["--unset", "core.worktree"]); } catch { /* raced */ }
102
+ gitFile(mainWorktreeConfig, ["core.worktree", worktreeInCommon]);
103
+ }
104
+
105
+ const gitDir = git(cwd, ["rev-parse", "--path-format=absolute", "--git-dir"]);
106
+ const dir = resolve(gitDir, "ak-roles-hooks");
107
+ const path = resolve(dir, "reference-transaction");
108
+ if (existsSync(path)) {
109
+ const existing = readFileSync(path, "utf8");
110
+ // Own-package marker → reload OK (HOOK body may change across versions).
111
+ // Foreign same-name hook → fail closed, never overwrite.
112
+ if (!existing.includes(HOOK_MARKER)) {
113
+ throw new Error("ak-roles: refusing to overwrite existing reference-transaction hook");
114
+ }
115
+ }
116
+ mkdirSync(dir, { recursive: true });
117
+ writeFileSync(path, HOOK, "utf8");
118
+ chmodSync(path, 0o755);
119
+ git(cwd, ["config", "--worktree", "core.hooksPath", dir]);
120
+ }
121
+
122
+ function isRecord(value: unknown): value is Record<string, unknown> {
123
+ return typeof value === "object" && value !== null && !Array.isArray(value);
124
+ }
125
+
126
+ /**
127
+ * Pi defers session-file create until the first assistant message. Gate records are
128
+ * custom-entry only (no LLM turn), so materialize the header first — same shape as
129
+ * activation-ledger-session materializeDeferredSessionFile — then custom entries append.
130
+ */
131
+ function materializeSessionHeader(session: SessionManager): void {
132
+ if (!session.isPersisted()) return;
133
+ const file = session.getSessionFile();
134
+ if (file === undefined || existsSync(file)) return;
135
+ const header = session.getHeader();
136
+ if (header === null || header.type !== "session") return;
137
+ writeFileSync(file, `${JSON.stringify(header)}\n`, { flag: "wx" });
138
+ // Rebind so subsequent appendCustomEntry uses O_APPEND (flushed=true).
139
+ session.setSessionFile(file);
140
+ }
141
+
142
+ /** Open gate ① record via sitian entry; resume continues the nest the entry resolved (no self-computed destination). */
143
+ function openGateRecord(cwd: string, parent?: WorkerSubmissionGateParent): SessionManager {
144
+ const discovered = createRecordSession({
145
+ cwd,
146
+ kind: WORKER_SUBMISSION_GATE_RECORD_KIND,
147
+ ...(parent === undefined ? {} : { parent }),
148
+ });
149
+ // No durable parent principal → in-memory only (same-process bounce still works).
150
+ if (!discovered.isPersisted()) return discovered;
151
+ // Destination came from createRecordSession; continueRecent only picks the latest file in that nest.
152
+ const session = SessionManager.continueRecent(cwd, discovered.getSessionDir());
153
+ materializeSessionHeader(session);
154
+ return session;
155
+ }
156
+
157
+ function readGateState(session: SessionManager): {
158
+ baseline: string | null | undefined;
159
+ reminded: boolean;
160
+ } {
161
+ let baseline: string | null | undefined;
162
+ let reminded = false;
163
+ for (const entry of session.getEntries()) {
164
+ if (entry.type !== "custom") continue;
165
+ if (entry.customType === WORKER_COMMIT_BASELINE_ENTRY_TYPE) {
166
+ const data = entry.data;
167
+ if (isRecord(data) && (data.head === null || typeof data.head === "string")) {
168
+ baseline = data.head as string | null;
169
+ }
170
+ } else if (entry.customType === WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE) {
171
+ reminded = true;
172
+ }
173
+ }
174
+ return { baseline, reminded };
175
+ }
176
+
177
+ export function createWorkerSubmissionGate(): {
178
+ arm(cwd: string, parent?: WorkerSubmissionGateParent): void;
179
+ assertAcceptable(status: string): void;
180
+ } {
181
+ let baseline: string | null | undefined;
182
+ let root: string | undefined;
183
+ let reminded = false;
184
+ let record: SessionManager | undefined;
185
+ // null = unborn HEAD only; any other git failure throws (no swallow).
186
+ const head = (cwd: string): string | null => {
187
+ try { return git(cwd, ["rev-parse", "HEAD"]); }
188
+ catch {
189
+ git(cwd, ["rev-parse", "--git-dir"]); // surface real git/repo failures
190
+ return null;
191
+ }
192
+ };
193
+ return {
194
+ arm(cwd, parent) {
195
+ root = cwd;
196
+ record = openGateRecord(cwd, parent);
197
+ const prior = readGateState(record);
198
+ if (prior.baseline !== undefined) {
199
+ // Cross-resume: keep first-arm baseline and any prior bounce (no second false bounce).
200
+ baseline = prior.baseline;
201
+ reminded = prior.reminded;
202
+ return;
203
+ }
204
+ baseline = head(cwd);
205
+ reminded = false;
206
+ // First arm writes baseline through the sitian-created session (auditor pattern).
207
+ record.appendCustomEntry(WORKER_COMMIT_BASELINE_ENTRY_TYPE, {
208
+ version: 1,
209
+ head: baseline,
210
+ });
211
+ },
212
+ assertAcceptable(status) {
213
+ if (baseline === undefined || root === undefined || !DONE.has(status)) return;
214
+ const now = head(root);
215
+ if ((now !== null && (baseline === null || now !== baseline)) || reminded) {
216
+ reminded = true;
217
+ return;
218
+ }
219
+ reminded = true;
220
+ // Durable bounce once per run — resume must not re-fire the same reminder.
221
+ record?.appendCustomEntry(WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
222
+ throw new WorkerCommitReminderError();
223
+ },
224
+ };
225
+ }