@akagilnc/pi-workflow-roles 0.1.5864 → 0.1.5877
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/dist/acp-host/production-host.js +79 -11
- package/dist/audited-run-identity.js +4 -3
- package/dist/auditor-soul.js +3 -1
- package/dist/diarist-contracts.js +4 -3
- package/dist/headless-host/production-host.js +79 -11
- package/dist/migrate-book-topology.js +16 -5
- package/dist/notary-role.js +10 -2
- package/dist/packaged-role-registry.js +3 -1
- package/dist/public-cli/cli.js +7 -0
- package/dist/public-cli/dialogue-command.js +37 -0
- package/dist/public-cli/main.js +209 -6
- package/dist/public-cli/option-definitions.js +8 -0
- package/dist/public-cli/registry.js +2 -1
- package/dist/role-runtime.js +5 -2
- package/dist/role-submission-declarations.js +1 -1
- package/dist/ticket-provenance.js +1 -1
- package/package.json +1 -1
- package/resources/collector-bot-handbook.md +1 -1
- package/resources/diarist-collect.md +4 -3
- package/src/audited-run-identity.ts +5 -4
- package/src/auditor-soul.ts +3 -1
- package/src/diarist-contracts.ts +7 -4
- package/src/notary-role.ts +14 -2
- package/src/packaged-role-registry.ts +3 -1
- package/src/public-cli/cli.ts +7 -0
- package/src/public-cli/dialogue-command.ts +53 -0
- package/src/public-cli/option-definitions.ts +9 -0
- package/src/public-cli/registry.ts +1 -0
- package/src/role-runtime.ts +5 -1
- package/src/role-submission-declarations.ts +1 -1
- package/src/ticket-provenance.ts +1 -1
package/dist/notary-role.js
CHANGED
|
@@ -49,11 +49,14 @@ export function projectNotaryBoundFromFlags(getFlag) {
|
|
|
49
49
|
...(ticketNumber === undefined ? {} : { ticketNumber }),
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
/** Assemble systemPrompt body from base + soul
|
|
52
|
+
/** Assemble systemPrompt body from base + soul + the audited seat's Soul (NO embedded bound JSON).
|
|
53
53
|
* Audited-run identity travels separately as `readingMaterial`; adapters fold
|
|
54
54
|
* it into the provider-visible prompt at the send boundary. */
|
|
55
55
|
export function assembleNotaryAgentStartPrompt(input) {
|
|
56
|
-
|
|
56
|
+
const audited = input.audited === undefined
|
|
57
|
+
? ""
|
|
58
|
+
: `\n\n<audited_seat_soul seat="${input.audited.seat}">\n${input.audited.soul}\n</audited_seat_soul>`;
|
|
59
|
+
return `${input.baseSystemPrompt}\n\n<notary_soul>\n${input.soul}\n</notary_soul>${audited}`;
|
|
57
60
|
}
|
|
58
61
|
export function createNotaryRoleRuntime(pi, dependencies, host) {
|
|
59
62
|
let activation;
|
|
@@ -74,9 +77,11 @@ export function createNotaryRoleRuntime(pi, dependencies, host) {
|
|
|
74
77
|
if (soul.length === 0)
|
|
75
78
|
throw new Error("Notary soul is empty");
|
|
76
79
|
const sourceRun = await dependencies.loadSourceRunLocator(path);
|
|
80
|
+
const auditedSoul = (await dependencies.loadAuditedSoul(sourceRun.role))?.trim();
|
|
77
81
|
activation = {
|
|
78
82
|
soul,
|
|
79
83
|
sourceRun,
|
|
84
|
+
...(auditedSoul === undefined || auditedSoul === "" ? {} : { auditedSoul }),
|
|
80
85
|
...(admitted?.ticketNumber === undefined
|
|
81
86
|
? {}
|
|
82
87
|
: { ticketNumber: admitted.ticketNumber }),
|
|
@@ -96,6 +101,9 @@ export function createNotaryRoleRuntime(pi, dependencies, host) {
|
|
|
96
101
|
systemPrompt: assembleNotaryAgentStartPrompt({
|
|
97
102
|
baseSystemPrompt: event.systemPrompt,
|
|
98
103
|
soul: activation.soul,
|
|
104
|
+
...(activation.auditedSoul === undefined
|
|
105
|
+
? {}
|
|
106
|
+
: { audited: { seat: activation.sourceRun.role, soul: activation.auditedSoul } }),
|
|
99
107
|
}),
|
|
100
108
|
readingMaterial: projectNotaryAuditedRunIdentity({
|
|
101
109
|
sourceRun: activation.sourceRun,
|
|
@@ -26,6 +26,7 @@ const NOTARY_SESSION_MATERIALS = [
|
|
|
26
26
|
"souls/notary.md",
|
|
27
27
|
"souls/audit-law.md",
|
|
28
28
|
"souls/ticket-law.md",
|
|
29
|
+
"souls/quality-law.md",
|
|
29
30
|
"souls/gate-output-guide.md",
|
|
30
31
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
31
32
|
];
|
|
@@ -41,6 +42,7 @@ const AUDITOR_PUBLIC_SESSION_MATERIALS = [
|
|
|
41
42
|
"CLAUDE.md",
|
|
42
43
|
"souls/judge-auditor.md",
|
|
43
44
|
"souls/doctor-auditor.md",
|
|
45
|
+
"souls/judge.md",
|
|
44
46
|
"souls/audit-law.md",
|
|
45
47
|
"souls/quality-law.md",
|
|
46
48
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
@@ -292,7 +294,7 @@ const PUBLIC_ROLE_RECORDS = [
|
|
|
292
294
|
activationStage: "load-and-install",
|
|
293
295
|
receiptStatusKey: "status",
|
|
294
296
|
// #924: 公用《票面法》三席同装
|
|
295
|
-
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
|
|
297
|
+
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "souls/audit-law.md", "souls/quality-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
|
|
296
298
|
},
|
|
297
299
|
{
|
|
298
300
|
role: "secretariat",
|
package/dist/public-cli/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import { formatHostSelectionFailure, HostSelectionError, } from "./role-turn-hos
|
|
|
19
19
|
import { admittedSourceRunPath, parseAnalystArgv, parsePublicSeatArgv, } from "./invocation.js";
|
|
20
20
|
import { createTypedOptionConsumer, optionsForOwner, projectCommandHelp, projectOwnerOptions, PUBLIC_NAVIGATOR_HELP_NOTE, PUBLIC_ROLE_OPTION_OWNERS, renderHumanOwnerOptionLines, } from "./option-definitions.js";
|
|
21
21
|
import { TurnDispatchedFailure } from "./auto-resume.js";
|
|
22
|
+
import { readSessionDialogue, renderSessionDialogue } from "./dialogue-command.js";
|
|
22
23
|
import { continueParentAfterChild, presentAuditedOriginalOfUnsettledOfficer, runPublicInstructionSeat, runPublicInstructionSeatResume, } from "./instruction-seat-run.js";
|
|
23
24
|
import { latestPayloadEscalated } from "./countersign-run.js";
|
|
24
25
|
import { runPublicAnalyst } from "./analyst-run.js";
|
|
@@ -780,6 +781,12 @@ export async function runAkRole(argv, env) {
|
|
|
780
781
|
// Profile home only after home-free paths return. Failures keep real identity
|
|
781
782
|
// and settle through the outer catch — no $HOME fallback (#604).
|
|
782
783
|
const home = resolveHome(env);
|
|
784
|
+
if (parsed.command === "dialogue") {
|
|
785
|
+
if (parsed.args.length !== 1)
|
|
786
|
+
throw new CliUsageError("usage: ak-role dialogue <session.jsonl>");
|
|
787
|
+
io.stdout(renderSessionDialogue(await readSessionDialogue(parsed.args[0], home)));
|
|
788
|
+
return { exitCode: 0 };
|
|
789
|
+
}
|
|
783
790
|
if (parsed.command === "roles") {
|
|
784
791
|
if (parsed.args.length > 0) {
|
|
785
792
|
throw new CliUsageError("roles takes no arguments");
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ak-role dialogue <session>`: the speaker lines a diary range would project,
|
|
3
|
+
* one JSON object per line, so the diarist searches the dialogue instead of
|
|
4
|
+
* re-deriving the session format (owner 2026-10-21). Same read and adapter as
|
|
5
|
+
* the ticket-provenance projection — no second speaker rule.
|
|
6
|
+
*/
|
|
7
|
+
import { readLedgerSessionJsonlLines } from "../ledger-session-read.js";
|
|
8
|
+
import { adaptSessionDialogue } from "../session-dialogue.js";
|
|
9
|
+
import { assertDialogueSessionSourcePath } from "../ticket-provenance.js";
|
|
10
|
+
export async function readSessionDialogue(path, home) {
|
|
11
|
+
assertDialogueSessionSourcePath(path, home);
|
|
12
|
+
const sessionLines = await readLedgerSessionJsonlLines(path);
|
|
13
|
+
const dialogue = adaptSessionDialogue(sessionLines.map((entry) => entry.row));
|
|
14
|
+
const seenIds = new Set();
|
|
15
|
+
const out = [];
|
|
16
|
+
sessionLines.forEach((entry, index) => {
|
|
17
|
+
if (entry.row === undefined) {
|
|
18
|
+
out.push({ line: entry.line, raw: entry.raw });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const event of dialogue[index] ?? []) {
|
|
22
|
+
const firstId = event.id !== undefined && !seenIds.has(event.id);
|
|
23
|
+
if (event.id !== undefined)
|
|
24
|
+
seenIds.add(event.id);
|
|
25
|
+
out.push({
|
|
26
|
+
line: entry.line,
|
|
27
|
+
...(firstId ? { id: event.id } : {}),
|
|
28
|
+
speaker: event.speaker,
|
|
29
|
+
text: event.text,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
export function renderSessionDialogue(lines) {
|
|
36
|
+
return lines.map((line) => `${JSON.stringify(line)}\n`).join("");
|
|
37
|
+
}
|
package/dist/public-cli/main.js
CHANGED
|
@@ -9612,7 +9612,7 @@ var init_ticket_provenance_contracts = __esm({
|
|
|
9612
9612
|
});
|
|
9613
9613
|
|
|
9614
9614
|
// src/diarist-contracts.ts
|
|
9615
|
-
var DIARIST_OUTPUT_TOOL_NAME, DIARIST_SESSIONS_DESCRIPTION, diaristOutputSchema;
|
|
9615
|
+
var DIARIST_OUTPUT_TOOL_NAME, DIARIST_BOUND_ENDPOINTS, DIARIST_SESSIONS_DESCRIPTION, diaristOutputSchema;
|
|
9616
9616
|
var init_diarist_contracts = __esm({
|
|
9617
9617
|
"src/diarist-contracts.ts"() {
|
|
9618
9618
|
"use strict";
|
|
@@ -9623,7 +9623,8 @@ var init_diarist_contracts = __esm({
|
|
|
9623
9623
|
init_run_ticket_number();
|
|
9624
9624
|
init_unknown_value();
|
|
9625
9625
|
DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
|
|
9626
|
-
|
|
9626
|
+
DIARIST_BOUND_ENDPOINTS = "\u8D77\u70B9\u4E0E\u7EC8\u70B9\u5404\u5199 id \u6216 line\uFF0C\u4E8C\u9009\u4E00\uFF1Aid\uFF1D\u4F1A\u8BDD\u5377\u91CC\u90A3\u4E00\u884C JSON \u7684 uuid \u5B57\u6BB5\u503C\uFF08\u6CA1\u6709 uuid \u53D6 id\uFF1B\u9876\u5C42\u90FD\u6CA1\u6709\u518D\u53D6 message \u6216 payload \u91CC\u7684 uuid / id\uFF09\uFF0C\u540C\u4E00 id \u51FA\u73B0\u591A\u6B21\u65F6\u53D6\u7B2C\u4E00\u6B21\u51FA\u73B0\u7684\u90A3\u4E00\u884C\uFF1Bline\uFF1D\u90A3\u4E00\u884C\u5728\u6587\u4EF6\u91CC\u4ECE 1 \u6570\u8D77\u7684\u884C\u53F7\u3002\u4E24\u7AEF\u90FD\u542B\u5728\u533A\u95F4\u5185\u3002";
|
|
9627
|
+
DIARIST_SESSIONS_DESCRIPTION = `\u5BF9\u8BDD\u8FB9\u754C\u3002\u6BCF\u5377\u542B path\uFF08\u4F1A\u8BDD\u5377\u7EDD\u5BF9\u6216\u53EF\u8BFB\u8DEF\u5F84\uFF09\u4E0E ranges\uFF08\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF09\u3002\u6BCF\u6BB5\u533A\u95F4\u542B from / to\uFF1B${DIARIST_BOUND_ENDPOINTS}\u533A\u95F4\u91CC\u53EA\u6709\u8BF4\u8BDD\u4EBA\u7684\u539F\u6587\u8FDB\u5F55\uFF1A\u7528\u6237\u4E0E\u52A9\u624B\u6D88\u606F\u91CC\u7684\u6587\u672C\u3001\u771F\u4EBA\u7ECF\u961F\u5217\u7684\u63D2\u8BDD\uFF1B\u601D\u8003\u3001\u5DE5\u5177\u8C03\u7528\u3001\u5DE5\u5177\u7ED3\u679C\u548C\u673A\u5668\u901A\u77E5\u4E0D\u8FDB\u5F55\uFF0C\u533A\u95F4\u53EF\u4EE5\u76F4\u63A5\u8DE8\u8FC7\u5B83\u4EEC\uFF0C\u4E0D\u5FC5\u62C6\u6BB5\u3002\u6BCF\u6B21\u4EA4\u5377\u7684\u8FB9\u754C\u7167\u6295\u5F71\u8FFD\u52A0\u8FDB\u672C\u7968\u8D77\u5C45\u5F55\uFF0C\u4E0D\u53BB\u91CD\uFF0C\u4E5F\u4E0D\u6539\u5DF2\u6709\u7684\u5F55\u3002\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002`;
|
|
9627
9628
|
diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
9628
9629
|
openToolObject(
|
|
9629
9630
|
typebox_exports.Object({
|
|
@@ -9636,7 +9637,7 @@ var init_diarist_contracts = __esm({
|
|
|
9636
9637
|
})
|
|
9637
9638
|
),
|
|
9638
9639
|
reason: typebox_exports.Unknown({
|
|
9639
|
-
description: "status \u4E3A escalate \u65F6\uFF1A\
|
|
9640
|
+
description: "status \u4E3A escalate \u65F6\uFF1A\u4E0A\u5448\u7684\u539F\u56E0"
|
|
9640
9641
|
}),
|
|
9641
9642
|
sessions: typebox_exports.Optional(typebox_exports.Unknown({ description: DIARIST_SESSIONS_DESCRIPTION })),
|
|
9642
9643
|
ticketSessions: typebox_exports.Unknown({
|
|
@@ -9888,6 +9889,7 @@ var init_packaged_role_registry = __esm({
|
|
|
9888
9889
|
"souls/notary.md",
|
|
9889
9890
|
"souls/audit-law.md",
|
|
9890
9891
|
"souls/ticket-law.md",
|
|
9892
|
+
"souls/quality-law.md",
|
|
9891
9893
|
"souls/gate-output-guide.md",
|
|
9892
9894
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
9893
9895
|
];
|
|
@@ -9903,6 +9905,7 @@ var init_packaged_role_registry = __esm({
|
|
|
9903
9905
|
"CLAUDE.md",
|
|
9904
9906
|
"souls/judge-auditor.md",
|
|
9905
9907
|
"souls/doctor-auditor.md",
|
|
9908
|
+
"souls/judge.md",
|
|
9906
9909
|
"souls/audit-law.md",
|
|
9907
9910
|
"souls/quality-law.md",
|
|
9908
9911
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
@@ -10154,7 +10157,7 @@ var init_packaged_role_registry = __esm({
|
|
|
10154
10157
|
activationStage: "load-and-install",
|
|
10155
10158
|
receiptStatusKey: "status",
|
|
10156
10159
|
// #924: 公用《票面法》三席同装
|
|
10157
|
-
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
|
|
10160
|
+
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "souls/audit-law.md", "souls/quality-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
|
|
10158
10161
|
},
|
|
10159
10162
|
{
|
|
10160
10163
|
role: "secretariat",
|
|
@@ -10378,7 +10381,8 @@ var init_registry = __esm({
|
|
|
10378
10381
|
"help",
|
|
10379
10382
|
"resume",
|
|
10380
10383
|
"new",
|
|
10381
|
-
"setup"
|
|
10384
|
+
"setup",
|
|
10385
|
+
"dialogue"
|
|
10382
10386
|
];
|
|
10383
10387
|
PUBLIC_DETERMINISTIC_COMMANDS = ["analyst"];
|
|
10384
10388
|
}
|
|
@@ -11584,7 +11588,7 @@ var init_role_submission_declarations = __esm({
|
|
|
11584
11588
|
},
|
|
11585
11589
|
diarist: {
|
|
11586
11590
|
label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
|
|
11587
|
-
description: "\u8D77\u5C45\u90CE\u4EA4\u5355\u7968 sessions \u6216\u591A\u7968\u9010\u7968 ticketSessions \u8FB9\u754C\
|
|
11591
|
+
description: "\u8D77\u5C45\u90CE\u4EA4\u5355\u7968 sessions \u6216\u591A\u7968\u9010\u7968 ticketSessions \u8FB9\u754C\uFF0C\u6216 escalate\u3002",
|
|
11588
11592
|
promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C",
|
|
11589
11593
|
parameters: diaristOutputSchema
|
|
11590
11594
|
}
|
|
@@ -13458,16 +13462,151 @@ var init_merger_git_state = __esm({
|
|
|
13458
13462
|
});
|
|
13459
13463
|
|
|
13460
13464
|
// src/session-dialogue.ts
|
|
13465
|
+
function nativeEventId(row) {
|
|
13466
|
+
for (const key of ["uuid", "id"]) {
|
|
13467
|
+
const value = row[key];
|
|
13468
|
+
if (typeof value === "string" && value !== "") return value;
|
|
13469
|
+
}
|
|
13470
|
+
for (const nestKey of ["message", "payload"]) {
|
|
13471
|
+
const nested = row[nestKey];
|
|
13472
|
+
if (!isRecord(nested)) continue;
|
|
13473
|
+
for (const key of ["uuid", "id"]) {
|
|
13474
|
+
const value = nested[key];
|
|
13475
|
+
if (typeof value === "string" && value !== "") return value;
|
|
13476
|
+
}
|
|
13477
|
+
}
|
|
13478
|
+
return void 0;
|
|
13479
|
+
}
|
|
13480
|
+
function textParts(content) {
|
|
13481
|
+
if (typeof content === "string") return content === "" ? [] : [content];
|
|
13482
|
+
if (!Array.isArray(content)) return [];
|
|
13483
|
+
const out = [];
|
|
13484
|
+
for (const part of content) {
|
|
13485
|
+
if (!isRecord(part) || !SPEAKER_TEXT_PART_TYPES.has(String(part.type))) continue;
|
|
13486
|
+
const text = part.text;
|
|
13487
|
+
if (typeof text === "string" && text !== "") out.push(text);
|
|
13488
|
+
}
|
|
13489
|
+
return out;
|
|
13490
|
+
}
|
|
13491
|
+
function responseItemMessage(row) {
|
|
13492
|
+
if (row.type !== "response_item" || !isRecord(row.payload)) return void 0;
|
|
13493
|
+
if (row.payload.type !== "message") return void 0;
|
|
13494
|
+
return row.payload;
|
|
13495
|
+
}
|
|
13496
|
+
function messageBody(row) {
|
|
13497
|
+
if (isRecord(row.message)) return row.message;
|
|
13498
|
+
return responseItemMessage(row);
|
|
13499
|
+
}
|
|
13500
|
+
function speakerOf(message) {
|
|
13501
|
+
if (message.role === "assistant") return "runner";
|
|
13502
|
+
if (message.role === "user") return "owner";
|
|
13503
|
+
return void 0;
|
|
13504
|
+
}
|
|
13505
|
+
function codexContentItemKinds(message) {
|
|
13506
|
+
const pass = message.internal_chat_message_metadata_passthrough;
|
|
13507
|
+
if (!isRecord(pass) || !Array.isArray(pass.content_item_kinds)) return void 0;
|
|
13508
|
+
const kinds = [];
|
|
13509
|
+
for (const kind of pass.content_item_kinds) {
|
|
13510
|
+
if (typeof kind === "string" && kind !== "") kinds.push(kind);
|
|
13511
|
+
}
|
|
13512
|
+
return kinds;
|
|
13513
|
+
}
|
|
13514
|
+
function isCodexOwnerResponseItemUser(message) {
|
|
13515
|
+
if (message.role !== "user") return false;
|
|
13516
|
+
const kinds = codexContentItemKinds(message);
|
|
13517
|
+
if (kinds === void 0) return false;
|
|
13518
|
+
return kinds.some((kind) => kind.startsWith("user."));
|
|
13519
|
+
}
|
|
13520
|
+
function fromQueueEvent(row) {
|
|
13521
|
+
if (row.type !== "queue-operation" || row.operation !== "enqueue") return [];
|
|
13522
|
+
const content = row.content;
|
|
13523
|
+
if (typeof content !== "string" || content === "") return [];
|
|
13524
|
+
const id = nativeEventId(row);
|
|
13525
|
+
return [{ speaker: "owner", text: content, ...id === void 0 ? {} : { id } }];
|
|
13526
|
+
}
|
|
13527
|
+
function hasFixedOpenTagPrefix(content, tag) {
|
|
13528
|
+
if (!content.startsWith(tag)) return false;
|
|
13529
|
+
const next = content.charAt(tag.length);
|
|
13530
|
+
return next === "" || next === ">" || next === " " || next === " " || next === "\n" || next === "\r";
|
|
13531
|
+
}
|
|
13532
|
+
function isFixedNonOwnerEnqueueShape(content) {
|
|
13533
|
+
return hasFixedOpenTagPrefix(content, TASK_NOTIFICATION_OPEN_TAG);
|
|
13534
|
+
}
|
|
13535
|
+
function materializationOriginKind(row) {
|
|
13536
|
+
if (!isRecord(row.origin)) return void 0;
|
|
13537
|
+
const kind = row.origin.kind;
|
|
13538
|
+
return typeof kind === "string" && kind !== "" ? kind : void 0;
|
|
13539
|
+
}
|
|
13540
|
+
function isNonOwnerOriginKind(kind) {
|
|
13541
|
+
if (kind === void 0) return false;
|
|
13542
|
+
return kind !== "human";
|
|
13543
|
+
}
|
|
13544
|
+
function fromMessageEvent(row) {
|
|
13545
|
+
const message = messageBody(row);
|
|
13546
|
+
if (message === void 0) return [];
|
|
13547
|
+
if (message.role === "toolResult") return [];
|
|
13548
|
+
const speaker = speakerOf(message);
|
|
13549
|
+
if (speaker === void 0) return [];
|
|
13550
|
+
if (row.type === "response_item" && speaker === "owner") {
|
|
13551
|
+
if (!isCodexOwnerResponseItemUser(message)) return [];
|
|
13552
|
+
}
|
|
13553
|
+
const parts = textParts(message.content);
|
|
13554
|
+
if (parts.length === 0) return [];
|
|
13555
|
+
const text = parts.join("");
|
|
13556
|
+
if (text === "") return [];
|
|
13557
|
+
const id = nativeEventId(row);
|
|
13558
|
+
return [{ speaker, text, ...id === void 0 ? {} : { id } }];
|
|
13559
|
+
}
|
|
13560
|
+
function adaptSessionDialogue(rows) {
|
|
13561
|
+
return rows.map((row) => {
|
|
13562
|
+
if (row === void 0) return [];
|
|
13563
|
+
const originKind = materializationOriginKind(row);
|
|
13564
|
+
if (isNonOwnerOriginKind(originKind)) return [];
|
|
13565
|
+
if (row.type === "queue-operation" && row.operation === "enqueue" && typeof row.content === "string" && isFixedNonOwnerEnqueueShape(row.content)) {
|
|
13566
|
+
return [];
|
|
13567
|
+
}
|
|
13568
|
+
const queued = fromQueueEvent(row);
|
|
13569
|
+
if (queued.length > 0) return queued;
|
|
13570
|
+
return fromMessageEvent(row);
|
|
13571
|
+
});
|
|
13572
|
+
}
|
|
13573
|
+
var SPEAKER_TEXT_PART_TYPES, TASK_NOTIFICATION_OPEN_TAG;
|
|
13461
13574
|
var init_session_dialogue = __esm({
|
|
13462
13575
|
"src/session-dialogue.ts"() {
|
|
13463
13576
|
"use strict";
|
|
13464
13577
|
init_unknown_value();
|
|
13578
|
+
SPEAKER_TEXT_PART_TYPES = /* @__PURE__ */ new Set(["text", "input_text", "output_text"]);
|
|
13579
|
+
TASK_NOTIFICATION_OPEN_TAG = "<task-notification";
|
|
13465
13580
|
}
|
|
13466
13581
|
});
|
|
13467
13582
|
|
|
13468
13583
|
// src/ticket-provenance.ts
|
|
13469
13584
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
13470
13585
|
import { join as join12, resolve as resolve6 } from "node:path";
|
|
13586
|
+
function dialogueSessionSourceRoots(home) {
|
|
13587
|
+
const machineHome = typeof home === "string" && home.trim() !== "" ? home : packageMachineHome();
|
|
13588
|
+
return [
|
|
13589
|
+
join12(machineHome, ".claude", "projects"),
|
|
13590
|
+
join12(machineHome, ".codex", "sessions"),
|
|
13591
|
+
join12(machineHome, ".pi", "agent", "sessions")
|
|
13592
|
+
];
|
|
13593
|
+
}
|
|
13594
|
+
function isLedgerRoleSessionFile(absolute, home) {
|
|
13595
|
+
const machineHome = typeof home === "string" && home.trim() !== "" ? home : packageMachineHome();
|
|
13596
|
+
const ledgerHome = resolveActivationLedgerHome(machineHome);
|
|
13597
|
+
if (!physicallyContainedIn(ledgerHome, absolute)) return false;
|
|
13598
|
+
return sessionFileOf(runDirectoryOfSessionFile(absolute)) === absolute;
|
|
13599
|
+
}
|
|
13600
|
+
function assertDialogueSessionSourcePath(path, home) {
|
|
13601
|
+
const absolute = resolve6(path);
|
|
13602
|
+
for (const root of dialogueSessionSourceRoots(home)) {
|
|
13603
|
+
if (physicallyContainedIn(root, absolute)) return;
|
|
13604
|
+
}
|
|
13605
|
+
if (isLedgerRoleSessionFile(absolute, home)) return;
|
|
13606
|
+
throw new TicketProvenanceInputError(
|
|
13607
|
+
`session unreadable: ${path} (outside authorized source roots)`
|
|
13608
|
+
);
|
|
13609
|
+
}
|
|
13471
13610
|
function ticketProvenanceSubject(ticketNumber) {
|
|
13472
13611
|
if (!isSafePositiveTicketNumber(ticketNumber)) {
|
|
13473
13612
|
throw new Error(
|
|
@@ -13504,6 +13643,7 @@ async function rehomeUnboundTicketProvenance(runDirectory, ticketNumber, cwd, ho
|
|
|
13504
13643
|
}).join("");
|
|
13505
13644
|
if (block !== "") appendSitianRecordBlock(ticketInput, block);
|
|
13506
13645
|
}
|
|
13646
|
+
var TicketProvenanceInputError;
|
|
13507
13647
|
var init_ticket_provenance = __esm({
|
|
13508
13648
|
"src/ticket-provenance.ts"() {
|
|
13509
13649
|
"use strict";
|
|
@@ -13517,6 +13657,16 @@ var init_ticket_provenance = __esm({
|
|
|
13517
13657
|
init_sitian_reader();
|
|
13518
13658
|
init_ticket_provenance_contracts();
|
|
13519
13659
|
init_unknown_value();
|
|
13660
|
+
TicketProvenanceInputError = class extends Error {
|
|
13661
|
+
code = "ticket-provenance-input";
|
|
13662
|
+
constructor(message, options) {
|
|
13663
|
+
super(
|
|
13664
|
+
message,
|
|
13665
|
+
options?.cause === void 0 ? void 0 : { cause: options.cause }
|
|
13666
|
+
);
|
|
13667
|
+
this.name = "TicketProvenanceInputError";
|
|
13668
|
+
}
|
|
13669
|
+
};
|
|
13520
13670
|
}
|
|
13521
13671
|
});
|
|
13522
13672
|
|
|
@@ -14727,6 +14877,14 @@ var init_option_definitions = __esm({
|
|
|
14727
14877
|
"ak-role new notary --source-run 01abc\u2026@countersign",
|
|
14728
14878
|
"ak-role --host grok-build new inspector --attach ./change.patch"
|
|
14729
14879
|
]
|
|
14880
|
+
},
|
|
14881
|
+
dialogue: {
|
|
14882
|
+
command: "dialogue",
|
|
14883
|
+
summary: "Print what a diary range projects from a session volume, one JSON object per line: speaker lines {line, id, speaker: owner|runner, text} and unparsable lines {line, raw}. line and id are what a range endpoint names; a repeated id is shown on its first line only, where it resolves. Same authorized session roots as the projection.",
|
|
14884
|
+
usage: ["ak-role dialogue <session.jsonl>"],
|
|
14885
|
+
examples: [
|
|
14886
|
+
"ak-role dialogue ~/.claude/projects/-Users-me-repo/0b1c\u2026.jsonl > /tmp/dialogue.jsonl"
|
|
14887
|
+
]
|
|
14730
14888
|
}
|
|
14731
14889
|
};
|
|
14732
14890
|
PUBLIC_COMMAND_HELP = {
|
|
@@ -19021,6 +19179,7 @@ var init_auditor_soul = __esm({
|
|
|
19021
19179
|
judge: [
|
|
19022
19180
|
"CLAUDE.md",
|
|
19023
19181
|
"souls/judge-auditor.md",
|
|
19182
|
+
"souls/judge.md",
|
|
19024
19183
|
"souls/audit-law.md",
|
|
19025
19184
|
"souls/quality-law.md",
|
|
19026
19185
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
|
|
@@ -23896,6 +24055,44 @@ var init_post_admission = __esm({
|
|
|
23896
24055
|
}
|
|
23897
24056
|
});
|
|
23898
24057
|
|
|
24058
|
+
// src/public-cli/dialogue-command.ts
|
|
24059
|
+
async function readSessionDialogue(path, home) {
|
|
24060
|
+
assertDialogueSessionSourcePath(path, home);
|
|
24061
|
+
const sessionLines = await readLedgerSessionJsonlLines(path);
|
|
24062
|
+
const dialogue = adaptSessionDialogue(sessionLines.map((entry) => entry.row));
|
|
24063
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
24064
|
+
const out = [];
|
|
24065
|
+
sessionLines.forEach((entry, index) => {
|
|
24066
|
+
if (entry.row === void 0) {
|
|
24067
|
+
out.push({ line: entry.line, raw: entry.raw });
|
|
24068
|
+
return;
|
|
24069
|
+
}
|
|
24070
|
+
for (const event of dialogue[index] ?? []) {
|
|
24071
|
+
const firstId = event.id !== void 0 && !seenIds.has(event.id);
|
|
24072
|
+
if (event.id !== void 0) seenIds.add(event.id);
|
|
24073
|
+
out.push({
|
|
24074
|
+
line: entry.line,
|
|
24075
|
+
...firstId ? { id: event.id } : {},
|
|
24076
|
+
speaker: event.speaker,
|
|
24077
|
+
text: event.text
|
|
24078
|
+
});
|
|
24079
|
+
}
|
|
24080
|
+
});
|
|
24081
|
+
return out;
|
|
24082
|
+
}
|
|
24083
|
+
function renderSessionDialogue(lines) {
|
|
24084
|
+
return lines.map((line2) => `${JSON.stringify(line2)}
|
|
24085
|
+
`).join("");
|
|
24086
|
+
}
|
|
24087
|
+
var init_dialogue_command = __esm({
|
|
24088
|
+
"src/public-cli/dialogue-command.ts"() {
|
|
24089
|
+
"use strict";
|
|
24090
|
+
init_ledger_session_read();
|
|
24091
|
+
init_session_dialogue();
|
|
24092
|
+
init_ticket_provenance();
|
|
24093
|
+
}
|
|
24094
|
+
});
|
|
24095
|
+
|
|
23899
24096
|
// node_modules/.pnpm/typebox@1.3.8/node_modules/typebox/build/schema/types/_refine.mjs
|
|
23900
24097
|
function IsRefine2(value) {
|
|
23901
24098
|
return guard_exports.HasPropertyKey(value, "~refine") && guard_exports.IsArray(value["~refine"]) && guard_exports.Every(value["~refine"], 0, (value2) => guard_exports.IsObject(value2) && guard_exports.HasPropertyKey(value2, "check") && guard_exports.HasPropertyKey(value2, "error") && guard_exports.IsFunction(value2.check) && guard_exports.IsFunction(value2.error));
|
|
@@ -32942,6 +33139,11 @@ async function runAkRole(argv2, env) {
|
|
|
32942
33139
|
return { exitCode: 0 };
|
|
32943
33140
|
}
|
|
32944
33141
|
const home = resolveHome(env);
|
|
33142
|
+
if (parsed.command === "dialogue") {
|
|
33143
|
+
if (parsed.args.length !== 1) throw new CliUsageError("usage: ak-role dialogue <session.jsonl>");
|
|
33144
|
+
io.stdout(renderSessionDialogue(await readSessionDialogue(parsed.args[0], home)));
|
|
33145
|
+
return { exitCode: 0 };
|
|
33146
|
+
}
|
|
32945
33147
|
if (parsed.command === "roles") {
|
|
32946
33148
|
if (parsed.args.length > 0) {
|
|
32947
33149
|
throw new CliUsageError("roles takes no arguments");
|
|
@@ -33132,6 +33334,7 @@ var init_cli = __esm({
|
|
|
33132
33334
|
init_invocation();
|
|
33133
33335
|
init_option_definitions();
|
|
33134
33336
|
init_auto_resume();
|
|
33337
|
+
init_dialogue_command();
|
|
33135
33338
|
init_instruction_seat_run();
|
|
33136
33339
|
init_countersign_run();
|
|
33137
33340
|
init_analyst_run();
|
|
@@ -1141,6 +1141,14 @@ const SUPPORT_COMMAND_HELP = {
|
|
|
1141
1141
|
"ak-role --host grok-build new inspector --attach ./change.patch",
|
|
1142
1142
|
],
|
|
1143
1143
|
},
|
|
1144
|
+
dialogue: {
|
|
1145
|
+
command: "dialogue",
|
|
1146
|
+
summary: "Print what a diary range projects from a session volume, one JSON object per line: speaker lines {line, id, speaker: owner|runner, text} and unparsable lines {line, raw}. line and id are what a range endpoint names; a repeated id is shown on its first line only, where it resolves. Same authorized session roots as the projection.",
|
|
1147
|
+
usage: ["ak-role dialogue <session.jsonl>"],
|
|
1148
|
+
examples: [
|
|
1149
|
+
"ak-role dialogue ~/.claude/projects/-Users-me-repo/0b1c….jsonl > /tmp/dialogue.jsonl",
|
|
1150
|
+
],
|
|
1151
|
+
},
|
|
1144
1152
|
};
|
|
1145
1153
|
/**
|
|
1146
1154
|
* Sole public help-copy owner keyed by command/topic id.
|
package/dist/role-runtime.js
CHANGED
|
@@ -30,7 +30,7 @@ import { INSPECTOR_SOURCE_RUN_FLAG } from "./inspector-contracts.js";
|
|
|
30
30
|
import { DIARIST_TOOL_SPEC, } from "./diarist-role.js";
|
|
31
31
|
import { SECRETARIAT_OUTPUT_TOOL_SPEC, } from "./secretariat-role.js";
|
|
32
32
|
import { SECRETARIAT_OUTPUT_TOOL_NAME } from "./secretariat-contracts.js";
|
|
33
|
-
import { projectDiaristSessions, projectDiaristTicketSessions, } from "./diarist-contracts.js";
|
|
33
|
+
import { DIARIST_BOUND_ENDPOINTS, projectDiaristSessions, projectDiaristTicketSessions, } from "./diarist-contracts.js";
|
|
34
34
|
import { commitDiaristProjection } from "./diarist.js";
|
|
35
35
|
import { TicketProvenanceInputError } from "./ticket-provenance.js";
|
|
36
36
|
import { GATEKEEPER_TOOL_SPEC, } from "./gatekeeper-role.js";
|
|
@@ -480,7 +480,7 @@ function readDiaristRunCoordinates(ctx) {
|
|
|
480
480
|
};
|
|
481
481
|
}
|
|
482
482
|
/** Plain-language re-ask when diarist bounds cannot be used (#901 / reask-not-explode). */
|
|
483
|
-
const DIARIST_BOUNDS_REASK =
|
|
483
|
+
const DIARIST_BOUNDS_REASK = `边界无法使用。多票请逐票重交 ticketSessions,单票重交 sessions;每卷 path + ranges。${DIARIST_BOUND_ENDPOINTS}`;
|
|
484
484
|
/**
|
|
485
485
|
* #708 / #779 / #901: 起居郎 public seat on the shared filed-officer envelope.
|
|
486
486
|
* LLM judges ticket + dialogue bounds; mechanical layer reprojects the unique
|
|
@@ -1038,6 +1038,9 @@ deliveryRequestLimit) {
|
|
|
1038
1038
|
throw new Error("Notary runtime dependencies are not configured");
|
|
1039
1039
|
return dependencies.loadNotarySourceRun(path);
|
|
1040
1040
|
},
|
|
1041
|
+
async loadAuditedSoul(role) {
|
|
1042
|
+
return packagedRoleMetadata(role) === undefined ? undefined : requireRoleSoul(role);
|
|
1043
|
+
},
|
|
1041
1044
|
}, hostActions);
|
|
1042
1045
|
const countersign = createCountersignRoleRuntime(roleHost, {
|
|
1043
1046
|
loadSoul: () => requireRoleSoul("countersign"),
|
|
@@ -109,7 +109,7 @@ const SUBMISSION_FACE = {
|
|
|
109
109
|
},
|
|
110
110
|
diarist: {
|
|
111
111
|
label: "起居郎输出",
|
|
112
|
-
description: "起居郎交单票 sessions 或多票逐票 ticketSessions
|
|
112
|
+
description: "起居郎交单票 sessions 或多票逐票 ticketSessions 边界,或 escalate。",
|
|
113
113
|
promptSnippet: "起居郎交边界",
|
|
114
114
|
parameters: diaristOutputSchema,
|
|
115
115
|
},
|
|
@@ -54,7 +54,7 @@ function isLedgerRoleSessionFile(absolute, home) {
|
|
|
54
54
|
return sessionFileOf(runDirectoryOfSessionFile(absolute)) === absolute;
|
|
55
55
|
}
|
|
56
56
|
/** Real I/O seam gate: only host session stores or sitian role-run session.jsonl. */
|
|
57
|
-
function assertDialogueSessionSourcePath(path, home) {
|
|
57
|
+
export function assertDialogueSessionSourcePath(path, home) {
|
|
58
58
|
const absolute = resolve(path);
|
|
59
59
|
for (const root of dialogueSessionSourceRoots(home)) {
|
|
60
60
|
if (physicallyContainedIn(root, absolute))
|
package/package.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
## 工序
|
|
33
33
|
|
|
34
|
-
从任务材料与 `--pr` / `--request-manifest` 材料判定目标后,用宿主 CLI 读取有评审的 PR,按各 reviewer 已记录的完成形态收集 findings,整理并交卷。未绑定 PR 时用 `gh`
|
|
34
|
+
从任务材料与 `--pr` / `--request-manifest` 材料判定目标后,用宿主 CLI 读取有评审的 PR,按各 reviewer 已记录的完成形态收集 findings,整理并交卷。未绑定 PR 时用 `gh` 等自行定位;无法确定时不猜,交给调用方明确目标。证据归属与不确定性的报告原则见通进司 Soul,字段见交卷工具的声明。
|
|
35
35
|
|
|
36
36
|
## 修正规则
|
|
37
37
|
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
你是 LLM,自己读以判断边界:
|
|
12
12
|
|
|
13
|
-
- 本仓相关会话卷(路径里的 `_` 在目录名里常写作 `-`;主 clone 与 worktree
|
|
13
|
+
- 本仓相关会话卷(路径里的 `_` 在目录名里常写作 `-`;主 clone 与 worktree 可能共用或分列,自行辨认)。读卷用 `ak-role dialogue <会话卷>`:每行一句说话(`line`、`id`、`speaker`、`text`),正是区间投影会收进录的那些行;`line` 与 `id` 就是交卷区间端点的写法,给了 `id` 的行才能用 id 指名
|
|
14
14
|
- 本票票面与评论:用 `gh` 或等价方式读 GitHub issue
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
指令明确列出多张要办的票时,逐票读卷判断各自相关边界;共同对话可以同时归入相关各票,无关他票对话不得混入。单票/多票交卷字段及不可用边界的处置见交卷工具的声明。
|
|
17
17
|
|
|
18
18
|
## 何谓本票对话
|
|
19
19
|
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
- 认得出本庭对象:`status: completed` 且 `ticketNumber: N`,并交边界。
|
|
35
35
|
- 真无票对象(方案/派单/处置案等):`status: completed` 且 `ticketNumber: null`(或省略)。真无票是合法结果,不入录。
|
|
36
36
|
- 本庭明确要新建票、但 issue 尚未建号:不是认票失败。以 `status: completed`、`ticketNumber: null` 交出已辨明的本案对话边界;起居录先随无号 run 暂存,建号后由既有归卷流程补归该号。不要借用旁票号。
|
|
37
|
-
-
|
|
37
|
+
- 认不出本庭对象是哪一张:不得省略票号假装无录,也不得猜一个号;何时上呈依 Soul,上呈时写明 `reason`。
|
|
38
38
|
- 不得从旁及的他票或任何猜测里挑一个号顶替认不出的身份。
|
|
39
39
|
- 传召文自然会提轮次、决定编号、commit sha、邻票号;要办的是指令明确列出的票,不是文中出现的每一个数字。
|
|
40
|
+
- 召你的那一席会把它自己收到的派单原样转给你,里面要求写票、改票、判卷的话是给那一席的;你只认票、交边界,不改票面、不替它办。
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared audited-run identity for review-officer startup materials (#1166 / ADR 0087).
|
|
3
|
-
* Value form is `<runId>@<席>` only — no directory path.
|
|
3
|
+
* Value form is `<runId>@<席>` only — no directory path. The field is named
|
|
4
|
+
* `auditedRun` so the reader sees it names the run under review, not itself.
|
|
4
5
|
*/
|
|
5
6
|
import { basename } from "node:path";
|
|
6
7
|
|
|
7
8
|
import { formatRunLeaf, parseRunLeaf } from "./role-run-placement.ts";
|
|
8
9
|
|
|
9
|
-
export const AUDITED_RUN_IDENTITY_KIND = "audited-run
|
|
10
|
+
export const AUDITED_RUN_IDENTITY_KIND = "audited-run" as const;
|
|
10
11
|
|
|
11
12
|
export type AuditedRunIdentityMaterial = {
|
|
12
13
|
readonly kind: typeof AUDITED_RUN_IDENTITY_KIND;
|
|
13
|
-
readonly
|
|
14
|
+
readonly auditedRun: string;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
/** Identity leaf from a run directory basename; undefined when the leaf is not `runId@role`. */
|
|
@@ -21,7 +22,7 @@ export function auditedRunIdentityFromDirectory(runDirectory: string): string |
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export function auditedRunIdentityMaterial(identity: string): AuditedRunIdentityMaterial {
|
|
24
|
-
return { kind: AUDITED_RUN_IDENTITY_KIND, identity };
|
|
25
|
+
return { kind: AUDITED_RUN_IDENTITY_KIND, auditedRun: identity };
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
/** Identity from locator fields already in hand (notary source-run). */
|
package/src/auditor-soul.ts
CHANGED
|
@@ -43,7 +43,8 @@ function auditorSoulRelativePath(role: AuditorSoulRole): string {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* #470 auditor session materials. Judge carries
|
|
46
|
+
* #470 auditor session materials. Judge carries the audited judge Soul + audit-law +
|
|
47
|
+
* quality-law (verdicts cite judge.md; audit-law makes the auditor check the cited line); doctor does
|
|
47
48
|
* not (御批四: 参审席 = 大理寺主会话 + 其审计席; 太医线不动).
|
|
48
49
|
* Reviewer auditor roster removed with #495 S6 gate retirement.
|
|
49
50
|
* #675 owner: no generic auditor.md — subject selects this table.
|
|
@@ -52,6 +53,7 @@ export const AUDITOR_SESSION_MATERIALS = {
|
|
|
52
53
|
judge: [
|
|
53
54
|
"CLAUDE.md",
|
|
54
55
|
"souls/judge-auditor.md",
|
|
56
|
+
"souls/judge.md",
|
|
55
57
|
"souls/audit-law.md",
|
|
56
58
|
"souls/quality-law.md",
|
|
57
59
|
"docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md",
|