@akagilnc/pi-workflow-roles 0.1.5037 → 0.1.5066
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 +2 -2
- package/README.zh-CN.md +2 -2
- package/THIRD_PARTY_NOTICES.md +11 -23
- package/dist/acp-host/production-host.js +410 -878
- package/dist/headless-host/description.js +0 -2
- package/dist/headless-host/production-host.js +413 -914
- package/dist/host-descriptions.js +2 -3
- package/dist/migrate-book-topology.js +4 -10
- package/dist/packaged-role-registry.js +17 -16
- package/dist/pi/role-turn-host.js +3 -27
- package/dist/public-cli/cli.js +6 -0
- package/dist/public-cli/instruction-seat-run.js +12 -40
- package/dist/public-cli/machine-method-skills.js +150 -0
- package/dist/public-cli/main.js +378 -579
- package/dist/public-cli/post-admission.js +2 -0
- package/dist/public-cli/registry.js +2 -1
- package/dist/public-cli/settlement.js +12 -99
- package/dist/public-cli/turn-request.js +16 -8
- package/package.json +3 -1
- package/resources/836-deleted-machine-instruction-inventory.md +1 -1
- package/scripts/build-package.mjs +1 -6
- package/src/headless-host/description.ts +0 -3
- package/src/headless-host/role-turn-host.ts +2 -23
- package/src/host-contracts.ts +2 -23
- package/src/host-descriptions.ts +2 -3
- package/src/packaged-role-registry.ts +14 -14
- package/src/pi/adapter.ts +0 -27
- package/src/pi/role-turn-host.ts +3 -31
- package/src/public-cli/cli.ts +6 -0
- package/src/public-cli/instruction-seat-run.ts +9 -42
- package/src/public-cli/machine-method-skills.ts +153 -0
- package/src/public-cli/post-admission.ts +2 -0
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/settlement.ts +6 -138
- package/src/public-cli/turn-request.ts +24 -16
- package/src/reviewer-role.ts +1 -12
- package/src/role-envelope.ts +0 -13
- package/src/role-runtime-dependencies.ts +0 -13
- package/src/role-runtime.ts +4 -56
- package/src/worker-role.ts +1 -81
- package/dist/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +0 -48
- package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +0 -21
- package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +0 -170
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +0 -41
- package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +0 -134
- package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +0 -31
- package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +0 -14
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +0 -26
- package/dist/method-host-plugin/skills/tdd/SKILL.md +0 -38
- package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/tdd/mocking.md +0 -59
- package/dist/method-host-plugin/skills/tdd/provenance.json +0 -36
- package/dist/method-host-plugin/skills/tdd/tests.md +0 -77
- package/dist/package-resources/method-skill.js +0 -259
- package/resources/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/resources/methods/ak-cross-m-review/CONTEXT.md +0 -48
- package/resources/methods/ak-cross-m-review/LICENSE +0 -21
- package/resources/methods/ak-cross-m-review/SKILL.md +0 -170
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/resources/methods/ak-cross-m-review/provenance.json +0 -41
- package/resources/methods/diagnosing-bugs/SKILL.md +0 -134
- package/resources/methods/diagnosing-bugs/agents/openai.yaml +0 -3
- package/resources/methods/diagnosing-bugs/provenance.json +0 -31
- package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/resources/methods/resolving-merge-conflicts/SKILL.md +0 -14
- package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/resources/methods/resolving-merge-conflicts/provenance.json +0 -26
- package/resources/methods/tdd/SKILL.md +0 -38
- package/resources/methods/tdd/agents/openai.yaml +0 -3
- package/resources/methods/tdd/mocking.md +0 -59
- package/resources/methods/tdd/provenance.json +0 -36
- package/resources/methods/tdd/tests.md +0 -77
- package/src/canonical-skill-binding.ts +0 -118
- package/src/host-native-method.ts +0 -185
- package/src/package-resources/method-skill-binding.ts +0 -60
- package/src/package-resources/method-skill.ts +0 -363
package/src/public-cli/cli.ts
CHANGED
|
@@ -48,6 +48,7 @@ import { packagedModelParent } from "../packaged-role-registry.ts";
|
|
|
48
48
|
import { seatModelOnly } from "./registry.ts";
|
|
49
49
|
import { CliUsageError } from "./cli-errors.ts";
|
|
50
50
|
import type { CliIo } from "./cli-io.ts";
|
|
51
|
+
import { runMachineSkillSetup } from "./machine-method-skills.ts";
|
|
51
52
|
import type { PostAdmissionEnv } from "./post-admission.ts";
|
|
52
53
|
import type { RoleTurnHost } from "../host-contracts.ts";
|
|
53
54
|
import { appendPiSessionCustomEntry } from "../pi/role-turn-host.ts";
|
|
@@ -1179,6 +1180,11 @@ export async function runAkRole(
|
|
|
1179
1180
|
};
|
|
1180
1181
|
}
|
|
1181
1182
|
|
|
1183
|
+
if (parsed.command === "setup") {
|
|
1184
|
+
if (parsed.args.length !== 0) throw new CliUsageError("setup takes no arguments");
|
|
1185
|
+
return { exitCode: await runMachineSkillSetup(home, io.stdout) };
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1182
1188
|
// #724 explicit fresh summons: `ak-role new <role> …` — same role argv, always mint.
|
|
1183
1189
|
// Rewrites onto the role command with freshSummons; auto-resume and resume stay intact.
|
|
1184
1190
|
if (parsed.command === "new") {
|
|
@@ -10,15 +10,10 @@ import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contrac
|
|
|
10
10
|
import { isSafePositiveTicketNumber, readBoardTicketNumber } from "../run-ticket-number.ts";
|
|
11
11
|
import { NotarySourceRunError, resolveNotarySourceRunLocator } from "../notary-source-run.ts";
|
|
12
12
|
import { engineSessionMaterialFromOptions, pickEngineAxis } from "../package-resources/engine-material.ts";
|
|
13
|
-
import {
|
|
14
|
-
loadPackagedMethodSkillMaterial,
|
|
15
|
-
type PackagedMethodSkillMaterial,
|
|
16
|
-
} from "../package-resources/method-skill.ts";
|
|
17
13
|
import type { PackagedRole } from "../packaged-role-registry.ts";
|
|
18
14
|
import {
|
|
19
15
|
packagedAdmitsCountersign,
|
|
20
16
|
packagedBindsBoardTicket,
|
|
21
|
-
packagedMethodLoadFailureCause,
|
|
22
17
|
packagedRebindSourceOnResume,
|
|
23
18
|
packagedRoleMetadata,
|
|
24
19
|
} from "../packaged-role-registry.ts";
|
|
@@ -42,7 +37,6 @@ import {
|
|
|
42
37
|
import {
|
|
43
38
|
presentControlledFailure,
|
|
44
39
|
prepareSummonsResumeMaterials,
|
|
45
|
-
resolveResumeMethodMaterialAdapters,
|
|
46
40
|
roleTurnOptions,
|
|
47
41
|
runPostAdmissionOneShot,
|
|
48
42
|
runPostAdmissionResumable,
|
|
@@ -67,6 +61,7 @@ import {
|
|
|
67
61
|
trySettlePublicSeat,
|
|
68
62
|
} from "./settlement.ts";
|
|
69
63
|
import type { CliIo } from "./cli-io.ts";
|
|
64
|
+
import { warnMissingMethodSkills } from "./machine-method-skills.ts";
|
|
70
65
|
import {
|
|
71
66
|
formatTerminalResult,
|
|
72
67
|
isLawfulTypedTerminalOutcome,
|
|
@@ -74,8 +69,8 @@ import {
|
|
|
74
69
|
} from "./terminal.ts";
|
|
75
70
|
import {
|
|
76
71
|
admittedSeatTurnDetails,
|
|
77
|
-
packagedSettleSkill,
|
|
78
72
|
projectRoleTurnRequest,
|
|
73
|
+
requiredMethodSkills,
|
|
79
74
|
type RoleTurnRequestProjectionOptions,
|
|
80
75
|
} from "./turn-request.ts";
|
|
81
76
|
import {
|
|
@@ -110,7 +105,7 @@ export function buildInstructionSeatTurnRequest(
|
|
|
110
105
|
): RoleTurnRequest {
|
|
111
106
|
return projectRoleTurnRequest(
|
|
112
107
|
admitted,
|
|
113
|
-
admittedSeatTurnDetails(admitted, options.
|
|
108
|
+
admittedSeatTurnDetails(admitted, options.home, options.host),
|
|
114
109
|
options,
|
|
115
110
|
);
|
|
116
111
|
}
|
|
@@ -160,13 +155,12 @@ async function bindAndRelocateDiarist(
|
|
|
160
155
|
function seatAdapters(
|
|
161
156
|
admitted: AdmittedRoleInvocation,
|
|
162
157
|
env: InstructionSeatRunEnv,
|
|
163
|
-
material?: PackagedMethodSkillMaterial,
|
|
164
158
|
): PostAdmissionAdapters<AdmittedRoleInvocation> {
|
|
165
159
|
const record = roleRecord(admitted.role);
|
|
166
160
|
const present = "presentSettled" in record ? record.presentSettled : "default";
|
|
167
161
|
return {
|
|
168
162
|
trySettle: (seat, authority, scope) =>
|
|
169
|
-
trySettlePublicSeat(seat, authority, scope
|
|
163
|
+
trySettlePublicSeat(seat, authority, scope),
|
|
170
164
|
...(present === "always" ? { shouldPresentSettled: () => true } : {}),
|
|
171
165
|
...(present === "typed"
|
|
172
166
|
? { shouldPresentSettled: (terminal: TerminalResult) => isLawfulTypedTerminalOutcome(terminal.roleOutcome) }
|
|
@@ -233,23 +227,8 @@ async function dispatchAdmitted(
|
|
|
233
227
|
io: CliIo,
|
|
234
228
|
): Promise<SeatRunResult> {
|
|
235
229
|
const record = roleRecord(admitted.role);
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
if (skill !== undefined) {
|
|
239
|
-
try {
|
|
240
|
-
material = await loadPackagedMethodSkillMaterial(env.packageRoot, skill);
|
|
241
|
-
} catch (error) {
|
|
242
|
-
const knownCause = packagedMethodLoadFailureCause(admitted.role);
|
|
243
|
-
return await presentControlledFailure(admitted, {
|
|
244
|
-
timedOut: false,
|
|
245
|
-
code: null,
|
|
246
|
-
stderr: "",
|
|
247
|
-
thrown: error,
|
|
248
|
-
...(knownCause === undefined ? {} : { knownCause }),
|
|
249
|
-
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
const adapters = seatAdapters(admitted, env, material);
|
|
230
|
+
await warnMissingMethodSkills(env.home, env.host, admitted.role, requiredMethodSkills(admitted), io.stdout);
|
|
231
|
+
const adapters = seatAdapters(admitted, env);
|
|
253
232
|
const execute = async (activeEnv: InstructionSeatRunEnv): Promise<SeatRunResult> => {
|
|
254
233
|
const auto = "inCallAutoResume" in record && record.inCallAutoResume === true;
|
|
255
234
|
if (auto) {
|
|
@@ -818,21 +797,9 @@ export async function runPublicInstructionSeatResume(
|
|
|
818
797
|
adapters: {
|
|
819
798
|
trySettle: async () => undefined,
|
|
820
799
|
},
|
|
821
|
-
afterAdmittedLoad: (admitted) => {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
return Promise.resolve({ kind: "continue" as const, adapters: seatAdapters(admitted, env) });
|
|
825
|
-
}
|
|
826
|
-
const knownCause = packagedMethodLoadFailureCause(admitted.role);
|
|
827
|
-
return resolveResumeMethodMaterialAdapters({
|
|
828
|
-
admitted,
|
|
829
|
-
authority: env.principalAuthority,
|
|
830
|
-
io,
|
|
831
|
-
loadMaterial: () => loadPackagedMethodSkillMaterial(env.packageRoot, skill),
|
|
832
|
-
adaptersWith: (material) => seatAdapters(admitted, env, material),
|
|
833
|
-
emptyAdapters: seatAdapters(admitted, env),
|
|
834
|
-
...(knownCause === undefined ? {} : { knownCause }),
|
|
835
|
-
});
|
|
800
|
+
afterAdmittedLoad: async (admitted) => {
|
|
801
|
+
await warnMissingMethodSkills(env.home, env.host, admitted.role, requiredMethodSkills(admitted), io.stdout);
|
|
802
|
+
return { kind: "continue" as const, adapters: seatAdapters(admitted, env) };
|
|
836
803
|
},
|
|
837
804
|
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
838
805
|
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { accessSync, constants, statSync } from "node:fs";
|
|
2
|
+
import { lstat, mkdir, symlink } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { HEADLESS_HOST_DESCRIPTIONS, HOST_DESCRIPTIONS } from "../host-descriptions.ts";
|
|
6
|
+
import { packagedMethodSkillNames } from "../packaged-role-registry.ts";
|
|
7
|
+
|
|
8
|
+
/** Install source only. Which names are required comes from the role registry. */
|
|
9
|
+
const SKILL_SOURCE: Readonly<Record<string, string>> = {
|
|
10
|
+
tdd: "mattpocock/skills",
|
|
11
|
+
"diagnosing-bugs": "mattpocock/skills",
|
|
12
|
+
"resolving-merge-conflicts": "mattpocock/skills",
|
|
13
|
+
"ak-cross-m-review": "Akagilnc/ak-cross-m-review",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function skillRoot(home: string): string {
|
|
17
|
+
return join(home, ".agents/skills");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function installedMethodSkillPath(home: string, name: string): string | undefined {
|
|
21
|
+
return installedSkillPath(skillRoot(home), name);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function installedSkillPath(root: string, name: string): string | undefined {
|
|
25
|
+
const path = join(root, name, "SKILL.md");
|
|
26
|
+
try {
|
|
27
|
+
if (!statSync(path).isFile()) return undefined;
|
|
28
|
+
accessSync(path, constants.R_OK);
|
|
29
|
+
return path;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
32
|
+
if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM" || code === "ELOOP") return undefined;
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function linkedSkillRoot(home: string, host: string | undefined): string | undefined {
|
|
38
|
+
if (host === "claude" || host === "claude-code") {
|
|
39
|
+
return join(process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, ".claude"), "skills");
|
|
40
|
+
}
|
|
41
|
+
if (host === "hermes") return join(home, ".hermes/skills");
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function occupied(path: string): Promise<boolean> {
|
|
46
|
+
try {
|
|
47
|
+
await lstat(path);
|
|
48
|
+
return true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function warnOccupied(path: string, stdout: (text: string) => void): void {
|
|
56
|
+
stdout(`Warning: ${path} is already occupied; left untouched.\n`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function warnMissingMethodSkills(
|
|
60
|
+
home: string,
|
|
61
|
+
host: string | undefined,
|
|
62
|
+
role: string,
|
|
63
|
+
skills: readonly string[],
|
|
64
|
+
stdout: (text: string) => void,
|
|
65
|
+
): Promise<void> {
|
|
66
|
+
const missing: string[] = [];
|
|
67
|
+
const linkedRoot = linkedSkillRoot(home, host);
|
|
68
|
+
for (const skill of skills) {
|
|
69
|
+
if (installedMethodSkillPath(home, skill) === undefined ||
|
|
70
|
+
(linkedRoot !== undefined && installedSkillPath(linkedRoot, skill) === undefined)) missing.push(skill);
|
|
71
|
+
}
|
|
72
|
+
for (const skill of missing) {
|
|
73
|
+
stdout(`Warning: required machine Skill "${skill}" is missing for ${role}; its method guidance may be unavailable and reduce work quality. Run \`ak-role setup\` to install required Skills.\n`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function runSkillsCli(args: readonly string[], home: string): boolean {
|
|
78
|
+
const result = spawnSync("npx", ["--yes", "skills", ...args], {
|
|
79
|
+
stdio: "inherit",
|
|
80
|
+
env: { ...process.env, HOME: home },
|
|
81
|
+
});
|
|
82
|
+
if (result.error !== undefined) throw result.error;
|
|
83
|
+
return result.status === 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function addSkills(source: string, skills: readonly string[], home: string): boolean {
|
|
87
|
+
if (skills.length === 0) return true;
|
|
88
|
+
return runSkillsCli([
|
|
89
|
+
"add", source,
|
|
90
|
+
...skills.flatMap((skill) => ["--skill", skill]),
|
|
91
|
+
"--agent", "codex", "--global", "--yes",
|
|
92
|
+
], home);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function updateRequiredSkills(home: string): boolean {
|
|
96
|
+
const names = packagedMethodSkillNames();
|
|
97
|
+
if (names.length === 0) return true;
|
|
98
|
+
return runSkillsCli(["update", "-g", "-y", ...names], home);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Explicit user-run setup; delegates acquisition/install to the ecosystem Skills CLI. */
|
|
102
|
+
export async function runMachineSkillSetup(home: string, stdout: (text: string) => void): Promise<number> {
|
|
103
|
+
const canonical = skillRoot(home);
|
|
104
|
+
const missingBySource = new Map<string, string[]>();
|
|
105
|
+
let unsourced = false;
|
|
106
|
+
for (const name of packagedMethodSkillNames()) {
|
|
107
|
+
const path = join(canonical, name);
|
|
108
|
+
if (await occupied(path)) {
|
|
109
|
+
warnOccupied(path, stdout);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const source = SKILL_SOURCE[name];
|
|
113
|
+
if (source === undefined) {
|
|
114
|
+
unsourced = true;
|
|
115
|
+
stdout(`Warning: required machine Skill "${name}" has no install source; setup did not install it.\n`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const missing = missingBySource.get(source) ?? [];
|
|
119
|
+
missing.push(name);
|
|
120
|
+
missingBySource.set(source, missing);
|
|
121
|
+
}
|
|
122
|
+
for (const [source, missing] of missingBySource) {
|
|
123
|
+
if (!addSkills(source, missing, home)) return 1;
|
|
124
|
+
}
|
|
125
|
+
if (unsourced) return 1;
|
|
126
|
+
|
|
127
|
+
for (const host of ["claude-code", "hermes"] as const) {
|
|
128
|
+
const root = linkedSkillRoot(home, host)!;
|
|
129
|
+
const binaryFromHome = host === "claude-code"
|
|
130
|
+
? HEADLESS_HOST_DESCRIPTIONS.claude!.binaryFromHome
|
|
131
|
+
: HOST_DESCRIPTIONS.hermes!.binaryFromHome;
|
|
132
|
+
try {
|
|
133
|
+
accessSync(join(home, ...binaryFromHome), constants.X_OK);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (["ENOENT", "ENOTDIR", "EACCES"].includes((error as NodeJS.ErrnoException).code ?? "")) continue;
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
for (const name of packagedMethodSkillNames()) {
|
|
139
|
+
const target = join(canonical, name);
|
|
140
|
+
if (installedMethodSkillPath(home, name) === undefined) continue;
|
|
141
|
+
const link = join(root, name);
|
|
142
|
+
if (await occupied(link)) {
|
|
143
|
+
warnOccupied(link, stdout);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
await mkdir(root, { recursive: true });
|
|
147
|
+
await symlink(target, link, "dir");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!updateRequiredSkills(home)) return 1;
|
|
151
|
+
stdout("Machine method Skills setup finished. Existing same-name Skills were left untouched.\n");
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
@@ -1367,6 +1367,7 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
1367
1367
|
return {
|
|
1368
1368
|
packageRoot: env.packageRoot,
|
|
1369
1369
|
home: env.home,
|
|
1370
|
+
...(env.host === undefined ? {} : { host: env.host }),
|
|
1370
1371
|
agentDir: env.agentDir,
|
|
1371
1372
|
...(env.model === undefined ? {} : { model: env.model }),
|
|
1372
1373
|
...pickEngineAxis(env),
|
|
@@ -1393,6 +1394,7 @@ export function roleTurnOptions(
|
|
|
1393
1394
|
return {
|
|
1394
1395
|
packageRoot: env.packageRoot,
|
|
1395
1396
|
home: env.home,
|
|
1397
|
+
...(env.host === undefined ? {} : { host: env.host }),
|
|
1396
1398
|
agentDir: env.agentDir,
|
|
1397
1399
|
...(env.model === undefined ? {} : { model: env.model }),
|
|
1398
1400
|
...pickEngineAxis(env),
|
|
@@ -92,14 +92,6 @@ import {
|
|
|
92
92
|
SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY,
|
|
93
93
|
SECRETARIAT_GATE_OFFICER_ENTRY_TYPE,
|
|
94
94
|
} from "../secretariat-contracts.ts";
|
|
95
|
-
import {
|
|
96
|
-
observePackagedMethodSkillInvocation,
|
|
97
|
-
resolvePackagedMethodSkillPath,
|
|
98
|
-
type ObservedPackagedMethodSkillInvocation,
|
|
99
|
-
type PackagedMethodSkillMaterial,
|
|
100
|
-
type PackagedMethodSkillName,
|
|
101
|
-
type PackagedMethodSkillProvenance,
|
|
102
|
-
} from "../package-resources/method-skill.ts";
|
|
103
95
|
import {
|
|
104
96
|
classifyPackagedRoleTerminalResult,
|
|
105
97
|
findLatestDurablePackagedRoleTerminal,
|
|
@@ -2482,21 +2474,14 @@ async function publishAcceptedTerminalArtifacts(
|
|
|
2482
2474
|
];
|
|
2483
2475
|
}
|
|
2484
2476
|
|
|
2485
|
-
type MethodPublicationOptions = {
|
|
2486
|
-
readonly methodProvenance?: PackagedMethodSkillProvenance;
|
|
2487
|
-
readonly methodSkillPath?: string;
|
|
2488
|
-
readonly methodSkillConfiguredPath?: string;
|
|
2489
|
-
};
|
|
2490
|
-
|
|
2491
2477
|
/** Publish one accepted seat's report/evidence face from the shared leaf table. */
|
|
2492
2478
|
export async function publishSeatAcceptedArtifacts(
|
|
2493
2479
|
admitted: AdmittedRoleInvocation,
|
|
2494
2480
|
roleOutcome: TerminalRoleOutcome,
|
|
2495
2481
|
coordinates: DurablePrincipalCoordinates,
|
|
2496
2482
|
entries: readonly SessionEntry[] = [],
|
|
2497
|
-
options: MethodPublicationOptions = {},
|
|
2498
2483
|
): Promise<TerminalArtifactRef[]> {
|
|
2499
|
-
return publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries
|
|
2484
|
+
return publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries);
|
|
2500
2485
|
}
|
|
2501
2486
|
|
|
2502
2487
|
/**
|
|
@@ -2623,13 +2608,12 @@ async function settleSealedAcceptedOrToolResidual(
|
|
|
2623
2608
|
/**
|
|
2624
2609
|
* One settlement for every registered seat. The registry `settlement` leaf
|
|
2625
2610
|
* picks sealed ledger, sealed-or-residual, or the accepted-tool scan.
|
|
2626
|
-
* Seat evidence
|
|
2611
|
+
* Seat evidence stays on the artifact face.
|
|
2627
2612
|
*/
|
|
2628
2613
|
async function settleSeat(
|
|
2629
2614
|
admitted: AdmittedRoleInvocation,
|
|
2630
2615
|
authority: DurablePrincipalAuthority,
|
|
2631
2616
|
scope: SettlementCourtScope | undefined,
|
|
2632
|
-
options: MethodPublicationOptions,
|
|
2633
2617
|
): Promise<TerminalResult | undefined> {
|
|
2634
2618
|
const record = packagedRoleMetadata(admitted.role);
|
|
2635
2619
|
if (record === undefined) {
|
|
@@ -2642,7 +2626,7 @@ async function settleSeat(
|
|
|
2642
2626
|
roleOutcome: Extract<TerminalRoleOutcome, { kind: "accepted" | "audit_escalation" }>,
|
|
2643
2627
|
coordinates: DurablePrincipalCoordinates,
|
|
2644
2628
|
entries: readonly SessionEntry[],
|
|
2645
|
-
) => publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries
|
|
2629
|
+
) => publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries);
|
|
2646
2630
|
if (record.settlement === "residual") {
|
|
2647
2631
|
return settleSealedAcceptedOrToolResidual(
|
|
2648
2632
|
admitted,
|
|
@@ -2669,10 +2653,9 @@ async function settleSeat(
|
|
|
2669
2653
|
export async function trySettleSeatTerminalResult(
|
|
2670
2654
|
admitted: AdmittedRoleInvocation,
|
|
2671
2655
|
authority: DurablePrincipalAuthority,
|
|
2672
|
-
options: MethodPublicationOptions = {},
|
|
2673
2656
|
scope?: SettlementCourtScope,
|
|
2674
2657
|
): Promise<TerminalResult | undefined> {
|
|
2675
|
-
return settleSeat(admitted, authority, scope
|
|
2658
|
+
return settleSeat(admitted, authority, scope);
|
|
2676
2659
|
}
|
|
2677
2660
|
|
|
2678
2661
|
/**
|
|
@@ -2682,10 +2665,9 @@ export async function trySettleSeatTerminalResult(
|
|
|
2682
2665
|
export async function settleSeatTerminalResult(
|
|
2683
2666
|
admitted: AdmittedRoleInvocation,
|
|
2684
2667
|
authority: DurablePrincipalAuthority,
|
|
2685
|
-
options: MethodPublicationOptions = {},
|
|
2686
2668
|
scope?: SettlementCourtScope,
|
|
2687
2669
|
): Promise<TerminalResult> {
|
|
2688
|
-
const settled = await settleSeat(admitted, authority, scope
|
|
2670
|
+
const settled = await settleSeat(admitted, authority, scope);
|
|
2689
2671
|
if (settled === undefined) {
|
|
2690
2672
|
const label = admitted.role.charAt(0).toUpperCase() + admitted.role.slice(1);
|
|
2691
2673
|
throw new Error(
|
|
@@ -2695,71 +2677,6 @@ export async function settleSeatTerminalResult(
|
|
|
2695
2677
|
return settled;
|
|
2696
2678
|
}
|
|
2697
2679
|
|
|
2698
|
-
function sessionMessageText(message: SessionMessage | undefined): string {
|
|
2699
|
-
if (message === undefined) return "";
|
|
2700
|
-
if (typeof message.content === "string") return message.content;
|
|
2701
|
-
if (!Array.isArray(message.content)) return "";
|
|
2702
|
-
const parts: string[] = [];
|
|
2703
|
-
for (const part of message.content) {
|
|
2704
|
-
if (
|
|
2705
|
-
typeof part === "object" &&
|
|
2706
|
-
part !== null &&
|
|
2707
|
-
!Array.isArray(part) &&
|
|
2708
|
-
(part as { type?: unknown }).type === "text" &&
|
|
2709
|
-
typeof (part as { text?: unknown }).text === "string"
|
|
2710
|
-
) {
|
|
2711
|
-
parts.push((part as { text: string }).text);
|
|
2712
|
-
}
|
|
2713
|
-
}
|
|
2714
|
-
return parts.join("\n");
|
|
2715
|
-
}
|
|
2716
|
-
|
|
2717
|
-
/**
|
|
2718
|
-
* Locations a loaded packaged method may be observed at.
|
|
2719
|
-
* The name is the loaded material; the configured path is the package copy.
|
|
2720
|
-
*/
|
|
2721
|
-
export function observedMethodSkillOptions(
|
|
2722
|
-
packageRoot: string,
|
|
2723
|
-
material: PackagedMethodSkillMaterial,
|
|
2724
|
-
): {
|
|
2725
|
-
readonly methodProvenance: PackagedMethodSkillProvenance;
|
|
2726
|
-
readonly methodSkillPath: string;
|
|
2727
|
-
readonly methodSkillConfiguredPath: string;
|
|
2728
|
-
} {
|
|
2729
|
-
return {
|
|
2730
|
-
methodProvenance: material.provenance,
|
|
2731
|
-
methodSkillPath: material.skillPath,
|
|
2732
|
-
methodSkillConfiguredPath: resolvePackagedMethodSkillPath(packageRoot, material.name),
|
|
2733
|
-
};
|
|
2734
|
-
}
|
|
2735
|
-
|
|
2736
|
-
/**
|
|
2737
|
-
* Observe packaged method Skill expansions from the session.
|
|
2738
|
-
* The skill name is the caller's packaged method; home locations never count.
|
|
2739
|
-
*/
|
|
2740
|
-
function extractObservedMethodInvocations(
|
|
2741
|
-
entries: readonly SessionEntry[],
|
|
2742
|
-
options: {
|
|
2743
|
-
readonly name: PackagedMethodSkillName;
|
|
2744
|
-
readonly allowedLocations: readonly string[];
|
|
2745
|
-
},
|
|
2746
|
-
): readonly ObservedPackagedMethodSkillInvocation[] {
|
|
2747
|
-
const observed: ObservedPackagedMethodSkillInvocation[] = [];
|
|
2748
|
-
for (const entry of entries) {
|
|
2749
|
-
if (entry?.type !== "message") continue;
|
|
2750
|
-
const message = entry.message;
|
|
2751
|
-
if (message?.role !== "user") continue;
|
|
2752
|
-
const text = sessionMessageText(message);
|
|
2753
|
-
if (text.length === 0) continue;
|
|
2754
|
-
const hit = observePackagedMethodSkillInvocation(text, {
|
|
2755
|
-
name: options.name,
|
|
2756
|
-
allowedLocations: options.allowedLocations,
|
|
2757
|
-
});
|
|
2758
|
-
if (hit !== undefined) observed.push(hit);
|
|
2759
|
-
}
|
|
2760
|
-
return Object.freeze(observed);
|
|
2761
|
-
}
|
|
2762
|
-
|
|
2763
2680
|
/**
|
|
2764
2681
|
* #836: cost and the auditor's no-receipt facts ride beside the role's
|
|
2765
2682
|
* testimony on the current attempt's candidate entry. Absence is omitted,
|
|
@@ -2834,49 +2751,11 @@ function doctorReportFacts(
|
|
|
2834
2751
|
};
|
|
2835
2752
|
}
|
|
2836
2753
|
|
|
2837
|
-
function observedMethodTail(
|
|
2838
|
-
face: PackagedArtifactFace,
|
|
2839
|
-
entries: readonly SessionEntry[],
|
|
2840
|
-
options: {
|
|
2841
|
-
readonly methodProvenance?: PackagedMethodSkillProvenance;
|
|
2842
|
-
readonly methodSkillPath?: string;
|
|
2843
|
-
readonly methodSkillConfiguredPath?: string;
|
|
2844
|
-
},
|
|
2845
|
-
): Record<string, unknown> {
|
|
2846
|
-
if (face.method === undefined) return {};
|
|
2847
|
-
if (face.method === "optional") {
|
|
2848
|
-
return options.methodProvenance === undefined
|
|
2849
|
-
? {}
|
|
2850
|
-
: { methodProvenance: options.methodProvenance };
|
|
2851
|
-
}
|
|
2852
|
-
if (
|
|
2853
|
-
options.methodProvenance === undefined
|
|
2854
|
-
|| options.methodSkillPath === undefined
|
|
2855
|
-
|| options.methodSkillConfiguredPath === undefined
|
|
2856
|
-
) {
|
|
2857
|
-
throw new Error("observed method publication is missing packaged method coordinates");
|
|
2858
|
-
}
|
|
2859
|
-
const methodInvocations = extractObservedMethodInvocations(entries, {
|
|
2860
|
-
name: options.methodProvenance.name,
|
|
2861
|
-
allowedLocations: [options.methodSkillPath, options.methodSkillConfiguredPath],
|
|
2862
|
-
});
|
|
2863
|
-
return {
|
|
2864
|
-
methodProvenance: options.methodProvenance,
|
|
2865
|
-
methodInvocationObserved: methodInvocations.length > 0,
|
|
2866
|
-
methodInvocations,
|
|
2867
|
-
};
|
|
2868
|
-
}
|
|
2869
|
-
|
|
2870
2754
|
async function publishDeclaredSeatArtifacts(
|
|
2871
2755
|
admitted: AdmittedRoleInvocation,
|
|
2872
2756
|
roleOutcome: TerminalRoleOutcome,
|
|
2873
2757
|
coordinates: DurablePrincipalCoordinates,
|
|
2874
2758
|
entries: readonly SessionEntry[],
|
|
2875
|
-
options: {
|
|
2876
|
-
readonly methodProvenance?: PackagedMethodSkillProvenance;
|
|
2877
|
-
readonly methodSkillPath?: string;
|
|
2878
|
-
readonly methodSkillConfiguredPath?: string;
|
|
2879
|
-
} = {},
|
|
2880
2759
|
): Promise<TerminalArtifactRef[]> {
|
|
2881
2760
|
const face = seatArtifactFace(admitted.role);
|
|
2882
2761
|
const phase = face.reportPhase === true
|
|
@@ -2898,7 +2777,6 @@ async function publishDeclaredSeatArtifacts(
|
|
|
2898
2777
|
sessionFile: coordinates.sessionFile,
|
|
2899
2778
|
admittedRequestPath: admitted.admittedRequestPath,
|
|
2900
2779
|
attachments: acceptedArtifactAttachmentRefs(admitted.attachments),
|
|
2901
|
-
...observedMethodTail(face, entries, options),
|
|
2902
2780
|
},
|
|
2903
2781
|
});
|
|
2904
2782
|
}
|
|
@@ -3040,18 +2918,8 @@ export async function trySettlePublicSeat(
|
|
|
3040
2918
|
admitted: AdmittedRoleInvocation,
|
|
3041
2919
|
authority: DurablePrincipalAuthority,
|
|
3042
2920
|
scope: { readonly courtAttemptId?: string } | undefined,
|
|
3043
|
-
material: PackagedMethodSkillMaterial | undefined,
|
|
3044
|
-
packageRoot: string,
|
|
3045
2921
|
): Promise<TerminalResult | undefined> {
|
|
3046
|
-
|
|
3047
|
-
if (face.method === "observed" && material === undefined) return undefined;
|
|
3048
|
-
const options: MethodPublicationOptions =
|
|
3049
|
-
face.method === "observed" && material !== undefined
|
|
3050
|
-
? observedMethodSkillOptions(packageRoot, material)
|
|
3051
|
-
: face.method === "optional" && material !== undefined
|
|
3052
|
-
? { methodProvenance: material.provenance }
|
|
3053
|
-
: {};
|
|
3054
|
-
return settleSeat(admitted, authority, scope, options);
|
|
2922
|
+
return settleSeat(admitted, authority, scope);
|
|
3055
2923
|
}
|
|
3056
2924
|
|
|
3057
2925
|
/**
|
|
@@ -10,16 +10,13 @@ import type {
|
|
|
10
10
|
RoleTurnRequest,
|
|
11
11
|
} from "../host-contracts.ts";
|
|
12
12
|
import { pickEngineAxis } from "../package-resources/engine-material.ts";
|
|
13
|
-
import {
|
|
14
|
-
resolvePackagedMethodSkillPath,
|
|
15
|
-
type PackagedMethodSkillName,
|
|
16
|
-
} from "../package-resources/method-skill.ts";
|
|
17
13
|
import {
|
|
18
14
|
packagedRoleActivationFlags,
|
|
19
15
|
packagedRoleMetadata,
|
|
20
16
|
} from "../packaged-role-registry.ts";
|
|
21
17
|
import type { SeatModelConfig } from "./config.ts";
|
|
22
18
|
import type { AdmittedRoleInvocation } from "./invocation.ts";
|
|
19
|
+
import { installedMethodSkillPath } from "./machine-method-skills.ts";
|
|
23
20
|
import { parentRunPathFromGatePointerInstruction } from "./run-lifecycle.ts";
|
|
24
21
|
import type { PublicThinkingLevel } from "./registry.ts";
|
|
25
22
|
|
|
@@ -33,6 +30,7 @@ export type ResumeModelConfig = {
|
|
|
33
30
|
export type RoleTurnRequestProjectionOptions = {
|
|
34
31
|
packageRoot: string;
|
|
35
32
|
home: string;
|
|
33
|
+
host?: string;
|
|
36
34
|
agentDir: string;
|
|
37
35
|
model?: SeatModelConfig;
|
|
38
36
|
engine?: string;
|
|
@@ -103,7 +101,7 @@ export function projectRoleTurnRequest(
|
|
|
103
101
|
*/
|
|
104
102
|
export function packagedSettleSkill(
|
|
105
103
|
admitted: AdmittedRoleInvocation,
|
|
106
|
-
):
|
|
104
|
+
): string | undefined {
|
|
107
105
|
const record = packagedRoleMetadata(admitted.role);
|
|
108
106
|
if (record === undefined) return undefined;
|
|
109
107
|
if ("applyMethod" in record && record.applyMethod !== undefined) {
|
|
@@ -148,33 +146,43 @@ function activationForAdmitted(admitted: AdmittedRoleInvocation): RoleTurnActiva
|
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
/** Skill bindings declared on the composition-root record for this admitted run. */
|
|
151
|
-
function
|
|
152
|
-
admitted: AdmittedRoleInvocation,
|
|
153
|
-
packageRoot: string,
|
|
154
|
-
): readonly MethodBinding[] {
|
|
149
|
+
export function requiredMethodSkills(admitted: AdmittedRoleInvocation): readonly string[] {
|
|
155
150
|
const record = packagedRoleMetadata(admitted.role);
|
|
156
|
-
const names:
|
|
151
|
+
const names: string[] = [];
|
|
157
152
|
if (record !== undefined && "methodSkills" in record && record.methodSkills !== undefined) {
|
|
158
153
|
names.push(...record.methodSkills);
|
|
159
154
|
}
|
|
160
155
|
const apply = packagedSettleSkill(admitted);
|
|
161
156
|
if (apply !== undefined && !names.includes(apply)) names.push(apply);
|
|
162
|
-
return names
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
return names;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function methodBindings(
|
|
161
|
+
admitted: AdmittedRoleInvocation,
|
|
162
|
+
home: string,
|
|
163
|
+
host: string | undefined,
|
|
164
|
+
): readonly MethodBinding[] {
|
|
165
|
+
if (host !== undefined && host !== "pi") return [];
|
|
166
|
+
return requiredMethodSkills(admitted).flatMap((name) => {
|
|
167
|
+
const path = installedMethodSkillPath(home, name);
|
|
168
|
+
return path === undefined ? [] : [{
|
|
169
|
+
kind: "skill" as const,
|
|
170
|
+
path,
|
|
171
|
+
}];
|
|
172
|
+
});
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
/** Registry activation and method bindings for one admitted public seat. */
|
|
169
176
|
export function admittedSeatTurnDetails(
|
|
170
177
|
admitted: AdmittedRoleInvocation,
|
|
171
|
-
|
|
178
|
+
home: string,
|
|
179
|
+
host: string | undefined,
|
|
172
180
|
): {
|
|
173
181
|
readonly activation: RoleTurnActivation;
|
|
174
182
|
readonly methods: readonly MethodBinding[];
|
|
175
183
|
} {
|
|
176
184
|
return {
|
|
177
185
|
activation: activationForAdmitted(admitted),
|
|
178
|
-
methods: methodBindings(admitted,
|
|
186
|
+
methods: methodBindings(admitted, home, host),
|
|
179
187
|
};
|
|
180
188
|
}
|