@akagilnc/pi-workflow-roles 0.1.3545 → 0.1.3552
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/grok/production-host.js +36 -430
- package/dist/public-cli/main.js +60 -46
- package/dist/public-cli/registry.js +2 -1
- package/package.json +1 -1
- package/src/doctor-evidence.ts +1 -8
- package/src/grok/production-host.ts +13 -216
- package/src/grok/role-turn-host.ts +4 -358
- package/src/host-transition-prior-native.ts +23 -32
- package/src/public-cli/cli.ts +33 -4
- package/src/public-cli/countersign-run.ts +1 -0
- package/src/public-cli/inspector-run.ts +1 -0
- package/src/public-cli/notary-run.ts +1 -0
- package/src/public-cli/option-definitions.ts +11 -0
- package/src/public-cli/post-admission.ts +5 -1
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/seat-ticket-binding.ts +6 -2
- package/src/grok/bash-seatbelt.ts +0 -69
|
@@ -149,22 +149,26 @@ export async function resolveSeatTicketBinding(
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
|
-
*
|
|
152
|
+
* Sole same-ticket → resume decision (#637 / #724).
|
|
153
153
|
* Looks up the latest retained run for seat+ticket; when found, runs resume with
|
|
154
154
|
* this summons' materials. Lookup/resume failures propagate (失败诚实) — never
|
|
155
|
-
* wash into a fresh mint. Returns undefined
|
|
155
|
+
* wash into a fresh mint. Returns undefined when the caller declared an explicit
|
|
156
|
+
* fresh summons (`ak-role new`) or when no prior run exists; both mint new.
|
|
157
|
+
* freshSummons is required so no seat can drift back into its own skip branch.
|
|
156
158
|
*/
|
|
157
159
|
export async function tryResumeSameTicketSeatRun<T>(input: {
|
|
158
160
|
readonly home: string;
|
|
159
161
|
readonly projectRoot: string;
|
|
160
162
|
readonly role: RoleRunRecord["role"];
|
|
161
163
|
readonly ticketNumber: number;
|
|
164
|
+
readonly freshSummons: true | undefined;
|
|
162
165
|
readonly summons?: SameTicketSummonsMaterials;
|
|
163
166
|
readonly resume: (
|
|
164
167
|
runId: string,
|
|
165
168
|
summons: SameTicketSummonsMaterials | undefined,
|
|
166
169
|
) => Promise<T>;
|
|
167
170
|
}): Promise<T | undefined> {
|
|
171
|
+
if (input.freshSummons === true) return undefined;
|
|
168
172
|
const previousRunId = await findLatestRunIdForSeatTicket({
|
|
169
173
|
home: input.home,
|
|
170
174
|
bookKey: resolveBookKeyFromGit(input.projectRoot),
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
FIXER_BASH_FORBIDDEN_LITERALS,
|
|
6
|
-
fixerBashSeatbeltDenyReason,
|
|
7
|
-
} from "../fixer-bash-seatbelt.ts";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Render the Grok PreToolUse hook script.
|
|
11
|
-
* Literals and deny reason come from the single ADR 0008 authority; this file is
|
|
12
|
-
* transport-only (stdin event → stdout decision JSON for the Grok hook runner).
|
|
13
|
-
*/
|
|
14
|
-
export function renderGrokBashSeatbeltHookScript(): string {
|
|
15
|
-
// Reason templates are baked from the authority so the standalone hook process
|
|
16
|
-
// cannot drift from fixerBashSeatbeltDenyReason without editing this render call.
|
|
17
|
-
const reasons = Object.fromEntries(
|
|
18
|
-
FIXER_BASH_FORBIDDEN_LITERALS.map((literal) => [literal, fixerBashSeatbeltDenyReason(literal)]),
|
|
19
|
-
);
|
|
20
|
-
return `#!/usr/bin/env node
|
|
21
|
-
const LITERALS = ${JSON.stringify([...FIXER_BASH_FORBIDDEN_LITERALS])};
|
|
22
|
-
const REASONS = ${JSON.stringify(reasons)};
|
|
23
|
-
let raw = "";
|
|
24
|
-
process.stdin.setEncoding("utf8");
|
|
25
|
-
process.stdin.on("data", (chunk) => { raw += chunk; });
|
|
26
|
-
process.stdin.on("end", () => {
|
|
27
|
-
let event = {};
|
|
28
|
-
try { event = JSON.parse(raw); } catch { /* fail-open on malformed host payload */ }
|
|
29
|
-
const input = event && typeof event === "object" ? event.toolInput : undefined;
|
|
30
|
-
const command = input && typeof input === "object" && typeof input.command === "string"
|
|
31
|
-
? input.command : undefined;
|
|
32
|
-
const matched = typeof command === "string"
|
|
33
|
-
? LITERALS.find((literal) => command.includes(literal))
|
|
34
|
-
: undefined;
|
|
35
|
-
const decision = matched === undefined
|
|
36
|
-
? { decision: "allow" }
|
|
37
|
-
: { decision: "deny", reason: REASONS[matched] };
|
|
38
|
-
process.stdout.write(JSON.stringify(decision));
|
|
39
|
-
});
|
|
40
|
-
`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Install the AK bash seatbelt into a controlled Grok home (GROK_HOME root).
|
|
45
|
-
* Never writes the operator's private ~/.grok — callers must pass the isolated home.
|
|
46
|
-
*/
|
|
47
|
-
export async function installGrokPreToolUseDeny(controlledHome: string): Promise<void> {
|
|
48
|
-
const hooksDir = join(controlledHome, "hooks");
|
|
49
|
-
await mkdir(hooksDir, { recursive: true });
|
|
50
|
-
const scriptName = "ak-bash-seatbelt.mjs";
|
|
51
|
-
const scriptPath = join(hooksDir, scriptName);
|
|
52
|
-
await writeFile(scriptPath, renderGrokBashSeatbeltHookScript(), { mode: 0o755 });
|
|
53
|
-
await writeFile(join(hooksDir, "ak-bash-seatbelt.json"), `${JSON.stringify({
|
|
54
|
-
hooks: {
|
|
55
|
-
PreToolUse: [
|
|
56
|
-
{
|
|
57
|
-
matcher: "Bash|run_terminal_command",
|
|
58
|
-
hooks: [
|
|
59
|
-
{
|
|
60
|
-
type: "command",
|
|
61
|
-
command: process.execPath + " " + JSON.stringify(scriptPath),
|
|
62
|
-
timeout: 5,
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
}, null, 2)}\n`);
|
|
69
|
-
}
|