@akagilnc/pi-workflow-roles 0.1.4444 → 0.1.4503
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 -0
- package/README.zh-CN.md +2 -0
- package/dist/acp-host/description.js +2 -3
- package/dist/acp-host/production-host.js +512 -288
- package/dist/auditor-soul.js +8 -1
- package/dist/headless-host/description.js +3 -3
- package/dist/headless-host/production-host.js +519 -257
- package/dist/host-descriptions.js +3 -18
- package/dist/method-host-plugin/.claude-plugin/plugin.json +5 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +48 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +21 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +170 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +118 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +128 -0
- package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +41 -0
- package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +134 -0
- package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +31 -0
- package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +14 -0
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +26 -0
- package/dist/method-host-plugin/skills/tdd/SKILL.md +38 -0
- package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +3 -0
- package/dist/method-host-plugin/skills/tdd/mocking.md +59 -0
- package/dist/method-host-plugin/skills/tdd/provenance.json +36 -0
- package/dist/method-host-plugin/skills/tdd/tests.md +77 -0
- package/dist/public-cli/countersign-run.js +214 -155
- package/dist/public-cli/diarist-run.js +4 -1
- package/dist/public-cli/invocation.js +129 -21
- package/dist/public-cli/main.js +386 -202
- package/dist/session-opening-materials.js +17 -5
- package/extensions/role-runtime.ts +16 -6
- package/package.json +1 -1
- package/resources/method-host-plugin/.claude-plugin/plugin.json +5 -0
- package/scripts/build-package.mjs +6 -1
- package/src/acp-host/description.ts +2 -4
- package/src/acp-host/production-host.ts +0 -1
- package/src/auditor-soul.ts +10 -1
- package/src/headless-host/description.ts +4 -3
- package/src/headless-host/role-turn-host.ts +27 -4
- package/src/host-descriptions.ts +3 -23
- package/src/host-native-method.ts +67 -0
- package/src/public-cli/countersign-run.ts +326 -218
- package/src/public-cli/diarist-run.ts +4 -0
- package/src/public-cli/invocation.ts +205 -23
- package/src/role-envelope.ts +17 -47
- package/src/role-runtime-dependencies.ts +17 -2
- package/src/role-runtime.ts +12 -7
- package/src/session-opening-materials.ts +27 -11
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
|
-
import { lstat, readFile, realpath, rename, writeFile, } from "node:fs/promises";
|
|
7
|
+
import { lstat, mkdtemp, readFile, realpath, rename, rm, writeFile, } from "node:fs/promises";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
8
9
|
import { basename, dirname, isAbsolute, join, resolve, sep } from "node:path";
|
|
9
10
|
import { activationBookDirectory, ensureRealDirectoryTree, homeFromRunDirectory, pathContainedIn, resolveActivationLedgerHome, } from "../activation-ledger-topology.js";
|
|
10
11
|
import { resolveBookKeyFromGit } from "../activation-ledger-git.js";
|
|
@@ -36,7 +37,8 @@ export function issueAdmissionPlacement(authority, request) {
|
|
|
36
37
|
runId: request.runId,
|
|
37
38
|
role: request.role,
|
|
38
39
|
});
|
|
39
|
-
|
|
40
|
+
if (request.materialize !== false)
|
|
41
|
+
ensureRoleRunPlacement(ledgerHome, placement);
|
|
40
42
|
return {
|
|
41
43
|
principal: authority.seal(placement),
|
|
42
44
|
...placement,
|
|
@@ -172,6 +174,27 @@ export async function bindAdmittedTicketNumber(admitted, ticketNumber) {
|
|
|
172
174
|
await bindTicketNumberOnRunDirectory(admitted.runDirectory, ticketNumber);
|
|
173
175
|
admitted.ticketNumber = ticketNumber;
|
|
174
176
|
}
|
|
177
|
+
/** Persist each direct caller observed while a retained run is resumed. */
|
|
178
|
+
export async function recordAdmittedCorrelation(admitted, correlationId) {
|
|
179
|
+
const current = JSON.parse(await readFile(admitted.admittedRequestPath, "utf8"));
|
|
180
|
+
const prior = [
|
|
181
|
+
...(Array.isArray(current.correlationIds)
|
|
182
|
+
? current.correlationIds.filter((value) => typeof value === "string" && value.trim() !== "")
|
|
183
|
+
: []),
|
|
184
|
+
...(typeof current.correlationId === "string" && current.correlationId.trim() !== ""
|
|
185
|
+
? [current.correlationId]
|
|
186
|
+
: []),
|
|
187
|
+
];
|
|
188
|
+
const correlationIds = [...new Set([...prior, correlationId])];
|
|
189
|
+
await writeFile(admitted.admittedRequestPath, `${JSON.stringify({ ...current, correlationId, correlationIds }, null, 2)}\n`, "utf8");
|
|
190
|
+
await mergeInvocationIdentityPage(admitted.runDirectory, {
|
|
191
|
+
correlationId,
|
|
192
|
+
correlationIds,
|
|
193
|
+
});
|
|
194
|
+
const mutable = admitted;
|
|
195
|
+
mutable.correlationId = correlationId;
|
|
196
|
+
mutable.correlationIds = correlationIds;
|
|
197
|
+
}
|
|
175
198
|
/**
|
|
176
199
|
* #871: persist the typed co-review set as a countersign run fact (admitted-request +
|
|
177
200
|
* invocation.json). Whole-set replace — never union with a prior set. Main ticket
|
|
@@ -584,7 +607,7 @@ export function parseFixerArgv(args) {
|
|
|
584
607
|
...(project === undefined ? {} : { project }),
|
|
585
608
|
};
|
|
586
609
|
}
|
|
587
|
-
async function
|
|
610
|
+
async function readRegularFileAttachment(sourcePath) {
|
|
588
611
|
const absolute = isAbsolute(sourcePath) ? sourcePath : resolve(sourcePath);
|
|
589
612
|
let st;
|
|
590
613
|
try {
|
|
@@ -596,18 +619,66 @@ async function freezeRegularFileAttachment(sourcePath, destinationDir, index) {
|
|
|
596
619
|
if (!st.isFile() || st.isSymbolicLink()) {
|
|
597
620
|
throw new CliUsageError(`attachment must be a regular file (not a directory or symlink): ${sourcePath}`);
|
|
598
621
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
622
|
+
try {
|
|
623
|
+
return { absolute, bytes: await readFile(absolute) };
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
throw new CliUsageError(`attachment is not a readable regular file: ${sourcePath}`, { cause: error });
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Snapshot deferred inputs sequentially before identity side effects. The staging
|
|
631
|
+
* files keep aggregate attachment bytes off heap until their final run is known.
|
|
632
|
+
*/
|
|
633
|
+
async function removePreparedAttachmentDirectory(stagingDirectory) {
|
|
634
|
+
await rm(stagingDirectory, { recursive: true, force: true });
|
|
635
|
+
}
|
|
636
|
+
/** Own the complete deferred-snapshot lifetime without masking either failure. */
|
|
637
|
+
export async function withPreparedAttachments(attachmentPaths, use) {
|
|
638
|
+
if (attachmentPaths.length === 0)
|
|
639
|
+
return await use([]);
|
|
640
|
+
const stagingDirectory = await mkdtemp(join(tmpdir(), "ak-role-attachments-"));
|
|
641
|
+
const prepared = [];
|
|
642
|
+
let result;
|
|
643
|
+
try {
|
|
644
|
+
for (let index = 0; index < attachmentPaths.length; index += 1) {
|
|
645
|
+
const { absolute, bytes } = await readRegularFileAttachment(attachmentPaths[index]);
|
|
646
|
+
const snapshotPath = join(stagingDirectory, String(index).padStart(6, "0"));
|
|
647
|
+
await writeFile(snapshotPath, bytes);
|
|
648
|
+
prepared.push({ absolute, snapshotPath });
|
|
649
|
+
}
|
|
650
|
+
result = await use(prepared);
|
|
651
|
+
}
|
|
652
|
+
catch (primary) {
|
|
653
|
+
try {
|
|
654
|
+
await removePreparedAttachmentDirectory(stagingDirectory);
|
|
655
|
+
}
|
|
656
|
+
catch (cleanup) {
|
|
657
|
+
throw new AggregateError([primary, cleanup], "attachment snapshot operation failed and cleanup also failed", { cause: primary });
|
|
658
|
+
}
|
|
659
|
+
throw primary;
|
|
660
|
+
}
|
|
661
|
+
await removePreparedAttachmentDirectory(stagingDirectory);
|
|
662
|
+
return result;
|
|
663
|
+
}
|
|
664
|
+
async function freezeAttachmentBytes(provenancePath, bytes, destinationDir, index) {
|
|
665
|
+
const frozenPath = join(destinationDir, `${String(index).padStart(2, "0")}-${basename(provenancePath)}`);
|
|
602
666
|
await writeFile(frozenPath, bytes);
|
|
603
667
|
return {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
668
|
+
provenancePath,
|
|
669
|
+
frozenPath,
|
|
670
|
+
byteLength: bytes.byteLength,
|
|
671
|
+
sha256: sha256Hex(bytes),
|
|
672
|
+
mediaKind: "regular-file",
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
async function freezePreparedAttachment(prepared, destinationDir, index) {
|
|
676
|
+
return freezeAttachmentBytes(prepared.absolute, await readFile(prepared.snapshotPath), destinationDir, index);
|
|
677
|
+
}
|
|
678
|
+
async function freezeRegularFileAttachment(sourcePath, destinationDir, index) {
|
|
679
|
+
const { absolute, bytes } = await readRegularFileAttachment(sourcePath);
|
|
680
|
+
return {
|
|
681
|
+
attachment: await freezeAttachmentBytes(absolute, bytes, destinationDir, index),
|
|
611
682
|
body: bytes,
|
|
612
683
|
};
|
|
613
684
|
}
|
|
@@ -633,6 +704,21 @@ export async function freezeAttachmentsIntoRun(attachmentPaths, runDirectory, su
|
|
|
633
704
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
634
705
|
return freezeAttachments(attachmentPaths, attachmentsDirectory);
|
|
635
706
|
}
|
|
707
|
+
/** Freeze prepared bytes and metadata through one path for birth or retained runs. */
|
|
708
|
+
export async function freezePreparedAttachmentsIntoRun(prepared, runDirectory, summonsKey) {
|
|
709
|
+
if (prepared.length === 0)
|
|
710
|
+
return [];
|
|
711
|
+
const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(runDirectory));
|
|
712
|
+
const attachmentsDirectory = summonsKey === undefined
|
|
713
|
+
? join(runDirectory, "attachments")
|
|
714
|
+
: join(runDirectory, "attachments", summonsKey);
|
|
715
|
+
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
716
|
+
const attachments = [];
|
|
717
|
+
for (let index = 0; index < prepared.length; index += 1) {
|
|
718
|
+
attachments.push(await freezePreparedAttachment(prepared[index], attachmentsDirectory, index));
|
|
719
|
+
}
|
|
720
|
+
return attachments;
|
|
721
|
+
}
|
|
636
722
|
function ticketAdmissionFields(ticketNumber) {
|
|
637
723
|
if (ticketNumber === undefined)
|
|
638
724
|
return {};
|
|
@@ -776,8 +862,8 @@ export function buildInspectorTransportPrompt(admitted, engineMaterial) {
|
|
|
776
862
|
return buildInstructionTransportPrompt(admitted, engineMaterial);
|
|
777
863
|
}
|
|
778
864
|
/**
|
|
779
|
-
*
|
|
780
|
-
*
|
|
865
|
+
* Admit a Countersign run immediately, or reserve its coordinates for deferred
|
|
866
|
+
* materialization after identity lookup (#572 / ADR 0074 / #863).
|
|
781
867
|
*/
|
|
782
868
|
export async function admitCountersignInvocation(options) {
|
|
783
869
|
// Same shared freeze/coordinate body as judge but role: "countersign" so
|
|
@@ -793,8 +879,11 @@ export async function admitCountersignInvocation(options) {
|
|
|
793
879
|
role: "countersign",
|
|
794
880
|
subject: { unbound: true },
|
|
795
881
|
home: options.home,
|
|
882
|
+
materialize: options.deferPersistence !== true,
|
|
796
883
|
});
|
|
797
|
-
const attachments =
|
|
884
|
+
const attachments = options.deferPersistence === true
|
|
885
|
+
? []
|
|
886
|
+
: await freezeAttachments(options.attachmentPaths, attachmentsDirectory);
|
|
798
887
|
// Ticket binding is LLM-only post-admission (#635); admission stays unbound.
|
|
799
888
|
const instruction = options.instruction;
|
|
800
889
|
const instructionEmpty = instruction.trim() === "";
|
|
@@ -817,11 +906,13 @@ export async function admitCountersignInvocation(options) {
|
|
|
817
906
|
})),
|
|
818
907
|
};
|
|
819
908
|
const admittedRequestPath = join(runDirectory, "admitted-request.json");
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
909
|
+
if (options.deferPersistence !== true) {
|
|
910
|
+
await writeAdmittedRequestPersistence(admittedRequestPath, admitted, {
|
|
911
|
+
sessionDirectory,
|
|
912
|
+
sessionFile,
|
|
913
|
+
});
|
|
914
|
+
await writeRoleInvocationLedger({ ...admitted, sessionDirectory, sessionFile }, admitted.role, options.model);
|
|
915
|
+
}
|
|
825
916
|
return {
|
|
826
917
|
role: "countersign",
|
|
827
918
|
runId,
|
|
@@ -836,6 +927,23 @@ export async function admitCountersignInvocation(options) {
|
|
|
836
927
|
...(options.correlationId === undefined ? {} : { correlationId: options.correlationId }),
|
|
837
928
|
};
|
|
838
929
|
}
|
|
930
|
+
/** Persist a deferred Countersign admission after same-ticket lookup found no retained run. */
|
|
931
|
+
export async function materializeCountersignInvocation(admitted, options) {
|
|
932
|
+
const placement = issueAdmissionPlacement(options.principalAuthority, {
|
|
933
|
+
cwd: admitted.projectRoot,
|
|
934
|
+
runId: admitted.runId,
|
|
935
|
+
role: "countersign",
|
|
936
|
+
subject: { unbound: true },
|
|
937
|
+
home: options.home,
|
|
938
|
+
});
|
|
939
|
+
const attachments = await freezePreparedAttachmentsIntoRun(options.preparedAttachments, admitted.runDirectory);
|
|
940
|
+
admitted.attachments = attachments;
|
|
941
|
+
await writeAdmittedRequestPersistence(admitted.admittedRequestPath, admitted, {
|
|
942
|
+
sessionDirectory: placement.sessionDirectory,
|
|
943
|
+
sessionFile: placement.sessionFile,
|
|
944
|
+
});
|
|
945
|
+
await writeRoleInvocationLedger({ ...admitted, sessionDirectory: placement.sessionDirectory, sessionFile: placement.sessionFile }, admitted.role, options.model);
|
|
946
|
+
}
|
|
839
947
|
/** Build the Pi prompt transport for an admitted Countersign request. */
|
|
840
948
|
export function buildCountersignTransportPrompt(admitted, engineMaterial) {
|
|
841
949
|
return buildInstructionTransportPrompt(admitted, engineMaterial);
|