@akagilnc/pi-workflow-roles 0.1.5714 → 0.1.5753
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 +517 -516
- package/dist/analyst-gate-cycles-read.js +7 -6
- package/dist/archivist-record-pointer.js +9 -45
- package/dist/auditor-soul.js +7 -5
- package/dist/external-host-turn-loop.js +2 -16
- package/dist/gatekeeper-role.js +14 -1
- package/dist/headless-host/production-host.js +517 -516
- package/dist/judge-role.js +1 -1
- package/dist/migrate-book-topology.js +61 -51
- package/dist/navigator-public-session.js +17 -8
- package/dist/notary-contracts.js +2 -2
- package/dist/notary-source-run.js +2 -2
- package/dist/packaged-role-registry.js +0 -10
- package/dist/public-cli/cli.js +13 -6
- package/dist/public-cli/instruction-seat-run.js +157 -138
- package/dist/public-cli/invocation.js +35 -0
- package/dist/public-cli/main.js +497 -505
- package/dist/public-cli/post-admission.js +11 -12
- package/dist/public-cli/run-lifecycle.js +56 -34
- package/dist/public-cli/seat-ticket-binding.js +8 -7
- package/dist/public-cli/settlement.js +4 -126
- package/dist/public-cli/terminal.js +3 -3
- package/dist/public-role-summons.js +14 -6
- package/dist/review-submission.js +47 -14
- package/dist/role-run-relocation.js +4 -3
- package/dist/role-submission-declarations.js +5 -5
- package/dist/run-dossier.js +6 -21
- package/dist/run-terminal-artifacts.js +11 -0
- package/dist/secretariat-contracts.js +0 -4
- package/dist/submission-gate.js +58 -42
- package/dist/submission-ledger.js +3 -2
- package/package.json +1 -1
- package/souls/notary.md +6 -5
- package/src/analyst-gate-cycles-read.ts +7 -6
- package/src/analyst-ledger.ts +2 -2
- package/src/archivist-record-pointer.ts +10 -64
- package/src/auditor-soul.ts +7 -5
- package/src/countersign-role.ts +5 -5
- package/src/external-host-turn-loop.ts +2 -23
- package/src/gatekeeper-role.ts +24 -3
- package/src/judge-role.ts +1 -1
- package/src/navigator-public-session.ts +22 -10
- package/src/notary-contracts.ts +3 -2
- package/src/notary-source-run.ts +2 -7
- package/src/packaged-role-registry.ts +0 -13
- package/src/public-cli/cli.ts +18 -4
- package/src/public-cli/instruction-seat-run.ts +213 -155
- package/src/public-cli/invocation.ts +39 -0
- package/src/public-cli/post-admission.ts +11 -9
- package/src/public-cli/run-lifecycle.ts +80 -33
- package/src/public-cli/seat-ticket-binding.ts +9 -7
- package/src/public-cli/settlement.ts +3 -167
- package/src/public-cli/terminal.ts +3 -3
- package/src/public-role-summons.ts +40 -12
- package/src/review-submission.ts +72 -21
- package/src/role-run-relocation.ts +4 -3
- package/src/role-runtime.ts +3 -3
- package/src/role-submission-declarations.ts +5 -5
- package/src/run-dossier.ts +7 -19
- package/src/run-terminal-artifacts.ts +13 -0
- package/src/secretariat-contracts.ts +0 -19
- package/src/submission-gate.ts +75 -62
- package/src/submission-ledger.ts +3 -6
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Execute lives in filed-submission.ts.
|
|
6
6
|
*/
|
|
7
7
|
import { packagedRoleOutputTool } from "./packaged-role-registry.js";
|
|
8
|
-
import { reviewSubmissionSchema } from "./review-submission.js";
|
|
8
|
+
import { courtReviewSubmissionSchema, reviewSubmissionSchema } from "./review-submission.js";
|
|
9
9
|
import { collectorOutputArgsSchema } from "./collector-tool-schemas.js";
|
|
10
10
|
import { diaristOutputSchema } from "./diarist-contracts.js";
|
|
11
11
|
import { doctorSubmissionSchema, DOCTOR_OUTPUT_TOOL_DESCRIPTION } from "./doctor-contracts.js";
|
|
@@ -61,15 +61,15 @@ const SUBMISSION_FACE = {
|
|
|
61
61
|
},
|
|
62
62
|
notary: {
|
|
63
63
|
label: "符宝郎输出",
|
|
64
|
-
description: "提交引文保真与票面对齐的 converged/continue/escalate
|
|
64
|
+
description: "提交引文保真与票面对齐的 converged/continue/escalate 决议(含逐条核旨 clauses)。",
|
|
65
65
|
promptSnippet: "提交符宝郎决议",
|
|
66
|
-
parameters:
|
|
66
|
+
parameters: courtReviewSubmissionSchema,
|
|
67
67
|
},
|
|
68
68
|
countersign: {
|
|
69
69
|
label: "给事中输出",
|
|
70
|
-
description: "
|
|
70
|
+
description: "给事中决议(含逐条核旨 clauses)。",
|
|
71
71
|
promptSnippet: "给事中决议",
|
|
72
|
-
parameters:
|
|
72
|
+
parameters: courtReviewSubmissionSchema,
|
|
73
73
|
},
|
|
74
74
|
secretariat: {
|
|
75
75
|
label: "中书省输出",
|
package/dist/run-dossier.js
CHANGED
|
@@ -119,14 +119,14 @@ function lastPagePayload(rows, kind, runDirectory) {
|
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
121
|
* Latest officer-pointer payload per officer from already-decoded history rows.
|
|
122
|
-
* Sole reducer for the "last booking wins per officer" rule
|
|
122
|
+
* Sole reducer for the "last booking wins per officer" rule on archived rows
|
|
123
|
+
* (#753 / #1161; historical decode only — #1195 does not project into current.json).
|
|
123
124
|
* A booked officer-pointer row with a non-object payload or non-string officer is
|
|
124
125
|
* damaged topology — never silently omitted into lawful zero rounds (#1161 O1).
|
|
125
126
|
* Absence of any officer-pointer row remains lawful empty.
|
|
126
127
|
* Invalid input is a TypeError (same class as other dossier illegal payloads).
|
|
127
128
|
* Control readers (`readBookedOfficerPointers`) let this throw into the existing
|
|
128
|
-
* auditor-roles unreadable seam
|
|
129
|
-
* `history.jsonl` unreadable so other reachable facts stay in current.json.
|
|
129
|
+
* auditor-roles unreadable seam.
|
|
130
130
|
*/
|
|
131
131
|
export function latestOfficerPointersFromRecords(records) {
|
|
132
132
|
const latest = {};
|
|
@@ -163,21 +163,9 @@ function render(runDirectory, history, state, log, unreadable) {
|
|
|
163
163
|
latest = { toolCallId: payload.toolCallId, role: payload.role, accepted: payload.accepted, at: row.timestamp };
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
// Catch only the reducer's known TypeError; unknown throws stay unknown
|
|
170
|
-
// (never wash into malformed by free-text message).
|
|
171
|
-
let officers = {};
|
|
172
|
-
try {
|
|
173
|
-
officers = latestOfficerPointersFromRecords(history);
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
if (!(error instanceof TypeError))
|
|
177
|
-
throw error;
|
|
178
|
-
if (unreadable[RUN_HISTORY_FILE] === undefined)
|
|
179
|
-
unreadable[RUN_HISTORY_FILE] = "malformed";
|
|
180
|
-
}
|
|
166
|
+
// #1195: parent current.json no longer projects officers from officer-pointer
|
|
167
|
+
// history. Archive rows stay in history.jsonl; analysts decode via
|
|
168
|
+
// readOfficerPointers / latestOfficerPointersFromRecords — not this render.
|
|
181
169
|
const sessions = {};
|
|
182
170
|
for (const row of state) {
|
|
183
171
|
const payload = isRecord(row.payload) ? row.payload : undefined;
|
|
@@ -198,7 +186,6 @@ function render(runDirectory, history, state, log, unreadable) {
|
|
|
198
186
|
original = join(runDirectory, "session", basename(original));
|
|
199
187
|
whole.host = { sessions, ...(original === undefined ? {} : { original }) };
|
|
200
188
|
whole.submission = latest === undefined ? {} : { latest };
|
|
201
|
-
whole.officers = officers;
|
|
202
189
|
if (Object.keys(unreadable).length > 0)
|
|
203
190
|
whole.unreadable = unreadable;
|
|
204
191
|
return whole;
|
|
@@ -248,8 +235,6 @@ export function renderCurrentSync(runDirectory) {
|
|
|
248
235
|
else if (file.diagnostics !== undefined && file.diagnostics.length > 0)
|
|
249
236
|
unreadable[name] = "malformed";
|
|
250
237
|
}
|
|
251
|
-
// Render may add officer-pointer TypeError damage onto the same unreadable map;
|
|
252
|
-
// declare after render so that cause enters the existing diagnostics/unreadable seam.
|
|
253
238
|
const whole = render(runDirectory, history.rows, state.rows, log.rows, unreadable);
|
|
254
239
|
for (const [name, code] of Object.entries(unreadable)) {
|
|
255
240
|
const key = `${runDirectory}\0${name}`;
|
|
@@ -95,3 +95,14 @@ function withSubmittedPayloads(runDirectory, body) {
|
|
|
95
95
|
export function runIdFromRunDirectory(runDirectory) {
|
|
96
96
|
return parseRunLeaf(basename(runDirectory))?.runId;
|
|
97
97
|
}
|
|
98
|
+
/** Run-directory face → seat role (last `@` split). */
|
|
99
|
+
export function roleFromRunDirectory(runDirectory) {
|
|
100
|
+
return parseRunLeaf(basename(runDirectory))?.role;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* #1195 ticket-court blind review: notary source is a countersign run.
|
|
104
|
+
* Identity still binds; countersign body is not preloaded into dialogue.
|
|
105
|
+
*/
|
|
106
|
+
export function isTicketCourtCountersignSource(runDirectory) {
|
|
107
|
+
return roleFromRunDirectory(runDirectory) === "countersign";
|
|
108
|
+
}
|
|
@@ -20,11 +20,7 @@ const secretariatVerdictSchema = withTerminatingOutputDeclarations(
|
|
|
20
20
|
)
|
|
21
21
|
);
|
|
22
22
|
secretariatVerdictSchema.required = [];
|
|
23
|
-
const SECRETARIAT_GATE_OFFICER_ENTRY_TYPE = "ak-secretariat-gate-officer";
|
|
24
|
-
const SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY = "countersignTerminal";
|
|
25
23
|
export {
|
|
26
|
-
SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY,
|
|
27
|
-
SECRETARIAT_GATE_OFFICER_ENTRY_TYPE,
|
|
28
24
|
SECRETARIAT_OUTPUT_TOOL_NAME,
|
|
29
25
|
secretariatVerdictSchema
|
|
30
26
|
};
|
package/dist/submission-gate.js
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { persistAdmittedAuditedSubmissionToolCallId } from "./public-cli/invocation.js";
|
|
2
|
+
import { readRunParentPath, readRoleRunIdentity } from "./public-cli/run-lifecycle.js";
|
|
2
3
|
import { GatekeeperDecisionError, officerConclusionReask, projectGatekeeperRun, } from "./gatekeeper-role.js";
|
|
3
4
|
import { receivedDiscriminator } from "./submission-errors.js";
|
|
4
5
|
import { deliveryLimitFromConfig } from "./receipt-delivery-policy.js";
|
|
6
|
+
/**
|
|
7
|
+
* Directory of the seat this gate actually summoned — not a nested escalate
|
|
8
|
+
* terminal that public-role-summons may surface on runDirectory (#1195).
|
|
9
|
+
* Walk sourceRunPath upward until role matches the summoned officer.
|
|
10
|
+
*/
|
|
11
|
+
async function directoryForSummonedOfficer(officer, summoned) {
|
|
12
|
+
if (summoned.admitted?.role === officer) {
|
|
13
|
+
return summoned.admitted.runDirectory;
|
|
14
|
+
}
|
|
15
|
+
let dir = typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== ""
|
|
16
|
+
? summoned.runDirectory
|
|
17
|
+
: summoned.admitted?.runDirectory;
|
|
18
|
+
for (let hop = 0; hop < 8 && dir !== undefined; hop += 1) {
|
|
19
|
+
const identity = await readRoleRunIdentity(dir);
|
|
20
|
+
if (identity?.role === officer)
|
|
21
|
+
return dir;
|
|
22
|
+
const parent = await readRunParentPath(dir);
|
|
23
|
+
if (parent === undefined || parent === dir)
|
|
24
|
+
break;
|
|
25
|
+
dir = parent;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
5
29
|
/** Received discriminator of the latest payload, retained verbatim for re-ask. */
|
|
6
30
|
export function latestQueueStatus(terminal) {
|
|
7
31
|
const outcome = terminal?.roleOutcome;
|
|
@@ -26,7 +50,6 @@ export function latestQueuePayload(terminal) {
|
|
|
26
50
|
const payloads = outcome.payloads ?? [];
|
|
27
51
|
return payloads.length === 0 ? undefined : payloads[payloads.length - 1];
|
|
28
52
|
}
|
|
29
|
-
import { sessionFileFromPublicSummon } from "./session-assistant-usage.js";
|
|
30
53
|
import { isRecord } from "./unknown-value.js";
|
|
31
54
|
/**
|
|
32
55
|
* Shared-envelope default officer summon (ADR 0018).
|
|
@@ -52,41 +75,12 @@ export function createDefaultGateOfficerSummon(options) {
|
|
|
52
75
|
};
|
|
53
76
|
}
|
|
54
77
|
/**
|
|
55
|
-
*
|
|
56
|
-
* Offline mocks without a real session leave no nested volume (lawful zero).
|
|
57
|
-
*/
|
|
58
|
-
function bookDirectOfficerPointer(context, officer, result, summoned, toolCallId) {
|
|
59
|
-
if (result.status !== "converged"
|
|
60
|
-
&& result.status !== "continue"
|
|
61
|
-
&& result.status !== "escalate"
|
|
62
|
-
&& result.status !== "needs_reask"
|
|
63
|
-
&& result.status !== "transport_failure") {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const parentFile = context.sessionManager?.getSessionFile?.();
|
|
67
|
-
if (typeof parentFile !== "string" || parentFile.trim() === "")
|
|
68
|
-
return;
|
|
69
|
-
const sessionFile = sessionFileFromPublicSummon(summoned);
|
|
70
|
-
if (sessionFile === undefined) {
|
|
71
|
-
// No independent 正本 to point at — do not synthesize a parallel session.
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
bookDirectOfficerRunPointer({
|
|
75
|
-
parentSessionFile: parentFile,
|
|
76
|
-
officer,
|
|
77
|
-
sessionFile,
|
|
78
|
-
...(typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== ""
|
|
79
|
-
? { runDirectory: summoned.runDirectory }
|
|
80
|
-
: {}),
|
|
81
|
-
...(toolCallId.trim() === "" ? {} : { submissionToolCallId: toolCallId }),
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Shared envelope: project gate, book officer pointer, map onto host actions.
|
|
78
|
+
* Shared envelope: project gate, map onto host actions.
|
|
86
79
|
* A real converged / continue / escalate returns immediately. An unreadable
|
|
87
80
|
* conclusion reasks that officer against the configured ceiling; exhaustion
|
|
88
81
|
* returns the receipt actually received.
|
|
89
|
-
*
|
|
82
|
+
* Nested incomplete (directionUnsettled) surfaces immediately — resume the
|
|
83
|
+
* actual audit seat, never convert into a reask of the outer officer (ADR 0055).
|
|
90
84
|
*/
|
|
91
85
|
export async function requireSubmissionGate(options) {
|
|
92
86
|
let reask;
|
|
@@ -106,13 +100,18 @@ export async function requireSubmissionGate(options) {
|
|
|
106
100
|
...(reask === undefined ? {} : { reask }),
|
|
107
101
|
});
|
|
108
102
|
const gatekeeper = projected.result;
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
103
|
+
// #1195 option 1: record parent seal on the summoned seat's admitted-request
|
|
104
|
+
// (not a nested lower terminal that may ride summoned.runDirectory).
|
|
105
|
+
if (projected.summoned !== undefined
|
|
106
|
+
&& options.toolCallId.trim() !== ""
|
|
107
|
+
&& (gatekeeper.status === "converged"
|
|
108
|
+
|| gatekeeper.status === "continue"
|
|
109
|
+
|| gatekeeper.status === "escalate"
|
|
110
|
+
|| gatekeeper.status === "needs_reask"
|
|
111
|
+
|| gatekeeper.status === "transport_failure")) {
|
|
112
|
+
const officerRunDirectory = await directoryForSummonedOfficer(projected.officer, projected.summoned);
|
|
113
|
+
if (officerRunDirectory !== undefined) {
|
|
114
|
+
persistAdmittedAuditedSubmissionToolCallId(officerRunDirectory, options.toolCallId);
|
|
116
115
|
}
|
|
117
116
|
}
|
|
118
117
|
if (gatekeeper.status === "converged") {
|
|
@@ -123,6 +122,15 @@ export async function requireSubmissionGate(options) {
|
|
|
123
122
|
...(typeof gatekeeper.runId === "string" && gatekeeper.runId.trim() !== ""
|
|
124
123
|
? { runId: gatekeeper.runId }
|
|
125
124
|
: {}),
|
|
125
|
+
...(typeof projected.summoned?.runDirectory === "string"
|
|
126
|
+
&& projected.summoned.runDirectory.trim() !== ""
|
|
127
|
+
? { runDirectory: projected.summoned.runDirectory }
|
|
128
|
+
: {}),
|
|
129
|
+
// Keep the officer terminal for escalate / unsettled surfaces; parent
|
|
130
|
+
// finals do not project other-seat tables (#1195).
|
|
131
|
+
...(projected.summoned?.terminal === undefined
|
|
132
|
+
? {}
|
|
133
|
+
: { terminal: projected.summoned.terminal }),
|
|
126
134
|
};
|
|
127
135
|
}
|
|
128
136
|
if (gatekeeper.status === "continue") {
|
|
@@ -136,7 +144,11 @@ export async function requireSubmissionGate(options) {
|
|
|
136
144
|
};
|
|
137
145
|
}
|
|
138
146
|
if (gatekeeper.status === "needs_reask") {
|
|
139
|
-
|
|
147
|
+
// Nested incomplete already exhausted the inner seat's own reask. Surface it;
|
|
148
|
+
// do not convert into a reask of this outer officer (ADR 0055 / #1195).
|
|
149
|
+
const nestedIncomplete = projected.summoned?.terminal?.roleOutcome.kind === "accepted"
|
|
150
|
+
&& projected.summoned.terminal.roleOutcome.decisiveFacts?.directionUnsettled === true;
|
|
151
|
+
if (nestedIncomplete || reasksSpent >= reaskLimit) {
|
|
140
152
|
return {
|
|
141
153
|
status: "needs_reask",
|
|
142
154
|
officer: projected.officer,
|
|
@@ -176,6 +188,10 @@ export async function requireSubmissionGate(options) {
|
|
|
176
188
|
&& projected.summoned.runDirectory.trim() !== ""
|
|
177
189
|
? { runDirectory: projected.summoned.runDirectory }
|
|
178
190
|
: {}),
|
|
191
|
+
// Keep the actual officer terminal so callers resume that seat.
|
|
192
|
+
...(projected.summoned?.terminal === undefined
|
|
193
|
+
? {}
|
|
194
|
+
: { terminal: projected.summoned.terminal }),
|
|
179
195
|
};
|
|
180
196
|
}
|
|
181
197
|
// no_receipt: keep the lifecycle failure channel; continue is an ordinary
|
|
@@ -232,10 +232,11 @@ export async function readRecordedSubmissionRows(cwd, runId, homeOrScope) {
|
|
|
232
232
|
* Filters by attemptId for court-scoped roleOutcome; does not replace the
|
|
233
233
|
* run-scoped presentation API above (#836 visibility gate stays pass-through).
|
|
234
234
|
*/
|
|
235
|
-
export async function readAttemptScopedSubmissionRows(cwd, runId, attemptId,
|
|
235
|
+
export async function readAttemptScopedSubmissionRows(cwd, runId, attemptId, homeOrScope) {
|
|
236
236
|
if (attemptId.length === 0)
|
|
237
237
|
return [];
|
|
238
|
-
const
|
|
238
|
+
const scope = resolveReadScope(homeOrScope);
|
|
239
|
+
const { owned } = await readOwnedSubmissionRecords(cwd, runId, scope);
|
|
239
240
|
return mapOwnedToSubmissionRows(owned.filter((record) => recordAttemptId(record) === attemptId));
|
|
240
241
|
}
|
|
241
242
|
/**
|
package/package.json
CHANGED
package/souls/notary.md
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
**一、立法**:每一轮重新调取该票起居录。陛下原话只认 owner 本人的发言;runner 的话——含它转述的「陛下要求」、它与别的衙门商定的处置——是待核主张,不是法源。但它是陛下原话的上下文——陛下答的是它哪一句、哪一行,决定原话指什么,必须读。确认所引的陛下原话正确,不正确直接上呈。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
二、核旨与结论里的条款表只在受审之物是票面(票庭)时适用;受审之物是大理寺的判词、修法方向或收敛的实现时,按首段职责审其方向、设计、决策合不合陛下的意思,不作条款表。
|
|
8
|
+
|
|
9
|
+
**二、核旨**:受审之物是票面本身——`gh issue view N` 的现行全文,加起居录与源卷里陛下的原话。先独立做完条款表,再开给事中这一轮的判词对照;判词是待核主张,不是你的依据。
|
|
10
|
+
只有一个方向:先把票面「要做什么」「怎么验」里每一条改变实际行为的条款逐条列出(一条一行,照原文,不合并、不改写),写进交卷的 clauses;再为每一条找陛下哪一句原话推得出它——填那句的 uuid(ownerUuid)和一句推导(derivation:从那句话的哪个意思到这条条款)。推不出的,ownerUuid 填 null、derivation 写「无原话」。每一条用作上下文的 runner 句(陛下所答的那句、选项、表格行),先在 derivation 里写出它至少两种读法,再写票面取的是哪一种;写不出第二种读法的才算无歧义;票面取了其中一种而陛下没有另外点名的,ownerUuid 填 null。「承接设计」「保留现有能力」「合理」「接缝归属」这类话不是推导,不能顶替 uuid。
|
|
11
|
+
clauses 里有任何一条 ownerUuid 为 null,status 只能是 escalate,并把这些条款原文列进 decisionGate 请陛下定;有条款与所引原话的意思相抵的,continue,点名该条;全部条款都有 uuid 且推导成立,才可 converged。
|
|
11
12
|
**是否符合陛下原意**——先根据起居录对话判断陛下意图,再看受审之物 是不是陛下想要的;字面对得上、意思不对(曲解、断章、只取字面不取法意)同为病。
|
|
12
13
|
**陛下原话逐句核销**——起居录里陛下对本票说过的每一句,逐句过:先写明它答的是起居录哪一句、哪一行(问句、表格行、选项),那一句描述的对象是什么,写进判词证据;再问他这句话想要什么、在担心什么,再看受审之物给没给到——不是为了凑齐引文。受审之物动作的对象比所答对象大——答的是代码代劳却删席位、删衙门、删能力、改流程——而原话没有点名该对象的,封驳。衙门与替它干活的代码是两个对象:说某机制多余、可以删,不是说撤该衙门;席位、衙门、能力的存废只认点名它本身的原话。质问句——陛下在问这张票、这条约束凭什么存在——是对受审之物的未决挑战,不是授权:没被事实或适用的法答掉的,或被摘来当「支持」的,封驳。runner 在录里已自认不成立的理由仍撑着受审之物的,同。
|
|
13
14
|
**找不到陛下原话**——受审之物里方向、设计、决策一级的条款,从陛下的意思推不出、又指不出哪条过了审的法源的,即加戏。不得以「授权实质在录」放行。
|
|
@@ -31,4 +32,4 @@
|
|
|
31
32
|
|
|
32
33
|
## 结论
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
结论三态,裁的是票面每一条条款有没有陛下原话撑着:'converged'(署)——clauses 每条都有 ownerUuid 且推导成立;'continue'(封驳)——有条款与所引原话相抵,退签发方改;'escalate'(上呈)——有条款 ownerUuid 为 null(无原话),陛下定。
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Sole reader for gate-cycle facts of
|
|
2
|
+
* Sole reader for gate-cycle facts of archived officer-pointer history rows
|
|
3
|
+
* (decoded via readOfficerPointers; parent current.json no longer projects officers — #1195).
|
|
3
4
|
*
|
|
4
5
|
* Consumer: Analyst sole ledger scan (classifyScopedRun). Metric families must
|
|
5
6
|
* not open a second disk scan — they consume retained facts.
|
|
@@ -8,7 +9,7 @@
|
|
|
8
9
|
* the current gatekeeper/inspector/notary English face. Projection always uses
|
|
9
10
|
* the current English officer identity (inspector | notary).
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
+
* No archived pointers → empty rounds (lawful zero). A pointer whose
|
|
12
13
|
* officer session fails canonical read/parse must fail loudly (never silently under-count).
|
|
13
14
|
* An accepted gate terminating receipt (isError:false pair on dispatch/officer
|
|
14
15
|
* tool) whose required typed facts are unusable — status, dispatch officer, or
|
|
@@ -414,10 +415,10 @@ function pairGateRounds(
|
|
|
414
415
|
}
|
|
415
416
|
|
|
416
417
|
/**
|
|
417
|
-
* Read and pair gate-cycle rounds from
|
|
418
|
-
* run
|
|
419
|
-
*
|
|
420
|
-
*
|
|
418
|
+
* Read and pair gate-cycle rounds from archived officer-pointer history on one
|
|
419
|
+
* parent run; each pointer names the independent officer session 正本.
|
|
420
|
+
* No pointers → [] (lawful zero). A damaged pointer or officer session propagates
|
|
421
|
+
* — damaged topology must not wash to zero rounds.
|
|
421
422
|
*
|
|
422
423
|
* Pass `parentSessionFile` to keep only rounds whose attempt binding names that parent.
|
|
423
424
|
*/
|
package/src/analyst-ledger.ts
CHANGED
|
@@ -336,8 +336,8 @@ export type AnalystReadableRunFacts = {
|
|
|
336
336
|
*/
|
|
337
337
|
readonly models: readonly string[];
|
|
338
338
|
/**
|
|
339
|
-
* Paired gate-cycle rounds
|
|
340
|
-
* No
|
|
339
|
+
* Paired gate-cycle rounds from archived officer-pointer history (#446 / #1195).
|
|
340
|
+
* No pointers → empty (lawful zero rounds).
|
|
341
341
|
* A damaged officer pointer or session → leg unreadable (`auditor-roles` source).
|
|
342
342
|
*/
|
|
343
343
|
readonly gateCycles: readonly AnalystGateCycleRound[];
|
|
@@ -2,14 +2,18 @@ import { basename, join } from "node:path";
|
|
|
2
2
|
import { isRecord } from "./unknown-value.ts";
|
|
3
3
|
import { latestOfficerPointersFromRecords, RUN_HISTORY_FILE } from "./run-dossier.ts";
|
|
4
4
|
import { OFFICER_POINTER_RECORD_KIND } from "./run-dossier-files.ts";
|
|
5
|
-
import { readSitianRecords
|
|
5
|
+
import { readSitianRecords } from "./sitian-facade.ts";
|
|
6
6
|
|
|
7
7
|
import { homeFromRunDirectory } from "./activation-ledger-topology.ts";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveLiveRunDirectoryPath, readRoleRunIdentity } from "./public-cli/run-lifecycle.ts";
|
|
9
9
|
import { rewriteRunDirectoryPathValue } from "./role-run-relocation.ts";
|
|
10
10
|
import { parseRunLeaf, runDirectoryOfSessionFile } from "./role-run-placement.ts";
|
|
11
11
|
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Historical parent-side pointer shape (ADR 0079 / #675).
|
|
14
|
+
* Production no longer writes these (#1195); retained only so analysts can read
|
|
15
|
+
* already-archived officer volumes. New runs leave officers empty (lawful zero).
|
|
16
|
+
*/
|
|
13
17
|
export const DIRECT_OFFICER_RUN_POINTER_KIND = "direct-officer-run-pointer" as const;
|
|
14
18
|
|
|
15
19
|
export type DirectOfficerRunPointer = {
|
|
@@ -20,48 +24,12 @@ export type DirectOfficerRunPointer = {
|
|
|
20
24
|
readonly sessionFile: string;
|
|
21
25
|
/** Officer run directory when known. */
|
|
22
26
|
readonly runDirectory?: string;
|
|
23
|
-
/**
|
|
24
|
-
* Parent submission tool call this officer run was summoned for.
|
|
25
|
-
* Absent on pointers booked before that binding existed.
|
|
26
|
-
*/
|
|
27
|
-
readonly submissionToolCallId?: string;
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
/** History record kind of a booked officer pointer (appender routes it to history.jsonl). */
|
|
31
30
|
export { OFFICER_POINTER_RECORD_KIND };
|
|
32
31
|
|
|
33
|
-
/**
|
|
34
|
-
* Book a typed pointer as one history record of the parent run; the settlement
|
|
35
|
-
* seam projects the latest per officer into current.json `officers`.
|
|
36
|
-
* Never fabricates user/assistant/toolResult rows (#675).
|
|
37
|
-
*
|
|
38
|
-
* Latest record wins per officer under one parent (#753 gate-round accounting):
|
|
39
|
-
* a same-parent re-summons supersedes the earlier pointer instead of adding a
|
|
40
|
-
* second one that re-scans the full officer session and multiplies gate-cycle counts.
|
|
41
|
-
*/
|
|
42
|
-
export function bookDirectOfficerRunPointer(options: {
|
|
43
|
-
readonly parentSessionFile: string;
|
|
44
|
-
readonly officer: "inspector" | "notary" | "auditor" | "countersign";
|
|
45
|
-
readonly sessionFile: string;
|
|
46
|
-
readonly runDirectory?: string;
|
|
47
|
-
readonly submissionToolCallId?: string;
|
|
48
|
-
}): DirectOfficerRunPointer {
|
|
49
|
-
const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
|
|
50
|
-
const pointer: DirectOfficerRunPointer = {
|
|
51
|
-
version: 1,
|
|
52
|
-
kind: DIRECT_OFFICER_RUN_POINTER_KIND,
|
|
53
|
-
officer: options.officer,
|
|
54
|
-
sessionFile: options.sessionFile,
|
|
55
|
-
...(options.runDirectory !== undefined && options.runDirectory.trim() !== ""
|
|
56
|
-
? { runDirectory: options.runDirectory }
|
|
57
|
-
: {}),
|
|
58
|
-
...(submissionToolCallId === "" ? {} : { submissionToolCallId }),
|
|
59
|
-
};
|
|
60
|
-
reportRunRecord(runDirectoryOfSessionFile(options.parentSessionFile), OFFICER_POINTER_RECORD_KIND, pointer, "submission-gate");
|
|
61
|
-
return pointer;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Shared strict pointer IO; internal audit wraps unreadability as a re-summons. */
|
|
32
|
+
/** Decode one archived pointer; relocates session/run paths when the leaf moved. */
|
|
65
33
|
export async function resolveOfficerPointer(
|
|
66
34
|
raw: unknown,
|
|
67
35
|
parentRunDirectory: string,
|
|
@@ -69,7 +37,6 @@ export async function resolveOfficerPointer(
|
|
|
69
37
|
sessionFile: string;
|
|
70
38
|
officer?: DirectOfficerRunPointer["officer"];
|
|
71
39
|
runDirectory?: string;
|
|
72
|
-
submissionToolCallId?: string;
|
|
73
40
|
}> {
|
|
74
41
|
const where = `${parentRunDirectory} officers`;
|
|
75
42
|
if (!isRecord(raw) || raw.kind !== DIRECT_OFFICER_RUN_POINTER_KIND || raw.version !== 1) {
|
|
@@ -87,21 +54,18 @@ export async function resolveOfficerPointer(
|
|
|
87
54
|
const leaf = parseRunLeaf(basename(recordedRunDirectory));
|
|
88
55
|
const parentIdentity = await readRoleRunIdentity(parentRunDirectory);
|
|
89
56
|
if (leaf !== undefined && parentIdentity !== undefined) {
|
|
90
|
-
const currentRunDirectory = await
|
|
91
|
-
homeFromRunDirectory(parentRunDirectory),
|
|
57
|
+
const currentRunDirectory = await resolveLiveRunDirectoryPath(
|
|
58
|
+
recordedRunDirectory, homeFromRunDirectory(parentRunDirectory), parentIdentity.bookKey,
|
|
92
59
|
);
|
|
93
60
|
if (currentRunDirectory !== undefined) {
|
|
94
61
|
sessionFile = rewriteRunDirectoryPathValue(sessionFile, recordedRunDirectory, currentRunDirectory) as string;
|
|
95
62
|
if (runDirectory !== undefined) runDirectory = currentRunDirectory;
|
|
96
63
|
}
|
|
97
64
|
}
|
|
98
|
-
const submissionToolCallId = typeof raw.submissionToolCallId === "string"
|
|
99
|
-
&& raw.submissionToolCallId.trim() !== "" ? raw.submissionToolCallId : undefined;
|
|
100
65
|
return {
|
|
101
66
|
sessionFile,
|
|
102
67
|
...(officer === undefined ? {} : { officer }),
|
|
103
68
|
...(runDirectory === undefined ? {} : { runDirectory }),
|
|
104
|
-
...(submissionToolCallId === undefined ? {} : { submissionToolCallId }),
|
|
105
69
|
};
|
|
106
70
|
}
|
|
107
71
|
|
|
@@ -127,21 +91,3 @@ export async function readOfficerPointers(parentRunDirectory: string): Promise<r
|
|
|
127
91
|
Object.keys(officers).sort().map((name) => resolveOfficerPointer(officers[name], parentRunDirectory)),
|
|
128
92
|
);
|
|
129
93
|
}
|
|
130
|
-
|
|
131
|
-
/** Missing or unreadable is not a pass: the internal audit caller re-runs the gate. */
|
|
132
|
-
export async function readDirectOfficerRunPointer(
|
|
133
|
-
parentSessionFile: string,
|
|
134
|
-
officer: DirectOfficerRunPointer["officer"],
|
|
135
|
-
): Promise<DirectOfficerRunPointer | undefined> {
|
|
136
|
-
try {
|
|
137
|
-
const parentRunDirectory = runDirectoryOfSessionFile(parentSessionFile);
|
|
138
|
-
const pointer = await resolveOfficerPointer(
|
|
139
|
-
(await readBookedOfficerPointers(parentRunDirectory))[officer],
|
|
140
|
-
parentRunDirectory,
|
|
141
|
-
);
|
|
142
|
-
if (pointer.officer !== officer) return undefined;
|
|
143
|
-
return { ...pointer, officer, version: 1, kind: DIRECT_OFFICER_RUN_POINTER_KIND };
|
|
144
|
-
} catch {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
147
|
-
}
|
package/src/auditor-soul.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { readPageSync } from "./run-dossier.ts";
|
|
3
|
+
import { admittedSourceRunPath, type AdmittedRoleInvocation } from "./public-cli/invocation.ts";
|
|
3
4
|
import { basename, join } from "node:path";
|
|
4
5
|
|
|
5
6
|
import { parseRunLeaf } from "./role-run-placement.ts";
|
|
@@ -119,16 +120,17 @@ function subjectFromSourceDirectory(sourceRunDirectory: string): AuditorSoulRole
|
|
|
119
120
|
* Resume binding already on the admitted page.
|
|
120
121
|
* Explicit subject wins; otherwise the source-run role is the audited object.
|
|
121
122
|
*/
|
|
122
|
-
export async function readAuditorResumeBinding(
|
|
123
|
+
export async function readAuditorResumeBinding(admitted: AdmittedRoleInvocation): Promise<
|
|
123
124
|
| { readonly subject: AuditorSoulRole; readonly sourceRunDirectory: string }
|
|
124
125
|
| undefined
|
|
125
126
|
> {
|
|
126
|
-
const record = readPageSync(runDirectory, "admitted");
|
|
127
|
+
const record = readPageSync(admitted.runDirectory, "admitted");
|
|
127
128
|
if (record === undefined) return undefined;
|
|
128
|
-
|
|
129
|
+
const sourceRunPath = admittedSourceRunPath(admitted);
|
|
130
|
+
if (sourceRunPath === undefined) return undefined;
|
|
129
131
|
const subject = isAuditorSoulRole(record.auditorSubject)
|
|
130
132
|
? record.auditorSubject
|
|
131
|
-
: subjectFromSourceDirectory(
|
|
133
|
+
: subjectFromSourceDirectory(sourceRunPath);
|
|
132
134
|
if (subject === undefined) return undefined;
|
|
133
|
-
return { subject, sourceRunDirectory:
|
|
135
|
+
return { subject, sourceRunDirectory: sourceRunPath };
|
|
134
136
|
}
|
package/src/countersign-role.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { courtReviewSubmissionSchema } from "./review-submission.ts";
|
|
2
2
|
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
3
3
|
import {
|
|
4
4
|
COUNTERSIGN_OUTPUT_TOOL_NAME,
|
|
@@ -12,11 +12,11 @@ export type { CountersignVerdict };
|
|
|
12
12
|
// #836 r16 class 1: fix/note/decisionGate are LLM/human-read narrative content —
|
|
13
13
|
// no code branches on their length or nested presence. `status` alone is the
|
|
14
14
|
// machine discriminator the queue reads.
|
|
15
|
-
// #1055: the three-state field is an enum+required host generation constraint
|
|
16
|
-
// on
|
|
17
|
-
//
|
|
15
|
+
// #1055: the three-state field is an enum+required host generation constraint.
|
|
16
|
+
// #1195: clauses is generation-required on this seat; package execute still does
|
|
17
|
+
// not reject a missing table (ADR 0055).
|
|
18
18
|
/** 给事中票庭审读五问的交卷形状(ADR 0074);形状指引,非 schema 闸。 */
|
|
19
|
-
export const countersignVerdictSchema =
|
|
19
|
+
export const countersignVerdictSchema = courtReviewSubmissionSchema;
|
|
20
20
|
export type CountersignVerdictParameters = import("./review-submission.ts").ReviewSubmission;
|
|
21
21
|
|
|
22
22
|
export type CountersignRuntimeDependencies = {
|
|
@@ -14,36 +14,15 @@ import type {
|
|
|
14
14
|
RoleTurnResult,
|
|
15
15
|
} from "./host-contracts.ts";
|
|
16
16
|
import type { PreparedRoleTurn } from "./prepared-role-turn.ts";
|
|
17
|
-
import { tryBookKeyFromAkRolesPath } from "./activation-ledger-topology.ts";
|
|
18
17
|
import { projectThrownFailureLeaf, retainPackageFault } from "./public-cli/settlement.ts";
|
|
19
|
-
import { describeErrorIdentity,
|
|
18
|
+
import { describeErrorIdentity, resolveLiveRunDirectoryPath } from "./public-cli/run-lifecycle.ts";
|
|
19
|
+
export { resolveLiveRunDirectoryPath } from "./public-cli/run-lifecycle.ts";
|
|
20
20
|
import { deliveryLimitFromConfig } from "./receipt-delivery-policy.ts";
|
|
21
21
|
import { parseRunLeaf } from "./role-run-placement.ts";
|
|
22
22
|
import { projectTurnRequestLiveRunDirectory } from "./role-run-relocation.ts";
|
|
23
23
|
import { reportRunRecord } from "./sitian-facade.ts";
|
|
24
24
|
import { isOneShotWorkerReminderCode } from "./submission-errors.ts";
|
|
25
25
|
|
|
26
|
-
/**
|
|
27
|
-
* #1171: mid-turn report-ticket may have moved the leg. Prefer the recorded
|
|
28
|
-
* path when it still exists; otherwise re-locate by run id inside the book.
|
|
29
|
-
* Undefined means vanished and unlocatable — callers must not revive the dead leaf.
|
|
30
|
-
*/
|
|
31
|
-
export async function resolveLiveRunDirectoryPath(
|
|
32
|
-
recordedPath: string,
|
|
33
|
-
home: string,
|
|
34
|
-
): Promise<string | undefined> {
|
|
35
|
-
if (existsSync(recordedPath)) return recordedPath;
|
|
36
|
-
const parsed = parseRunLeaf(basename(recordedPath));
|
|
37
|
-
const bookKey = tryBookKeyFromAkRolesPath(recordedPath);
|
|
38
|
-
if (parsed === undefined || bookKey === undefined) return undefined;
|
|
39
|
-
return await findRunDirectoryById(
|
|
40
|
-
home,
|
|
41
|
-
parsed.runId,
|
|
42
|
-
bookKey,
|
|
43
|
-
parsed.role,
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
26
|
/**
|
|
48
27
|
* Prefer the request path when it still exists; otherwise re-locate by run id
|
|
49
28
|
* (resolveLiveRunDirectoryPath). Mutates the live request so later turn-record /
|
package/src/gatekeeper-role.ts
CHANGED
|
@@ -20,7 +20,11 @@ export const NOTARY_OUTPUT_TOOL = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
|
20
20
|
/** Gate review officers — 台院 / 符宝郎 / 审刑院 / 给事中 (#753 / #756 / #969). */
|
|
21
21
|
export type GateOfficer = "inspector" | "notary" | "auditor" | "countersign";
|
|
22
22
|
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Officer routing only. Ordinary audit dialogue is the parent submission body
|
|
25
|
+
* (or ticket-court blind materials for notary); code does not open a second
|
|
26
|
+
* run-dossier content channel here.
|
|
27
|
+
*/
|
|
24
28
|
export type GatekeeperSubject =
|
|
25
29
|
| { readonly kind: "worker_completion" }
|
|
26
30
|
| { readonly kind: "judge_draft" }
|
|
@@ -34,7 +38,8 @@ export type GatekeeperSubject =
|
|
|
34
38
|
* `receipt` unchanged — no findings rewrite, no unreadable/unusable label,
|
|
35
39
|
* no next-step selection for the parent.
|
|
36
40
|
* `runId` is the nested officer run id when known (summoned.runDirectory /
|
|
37
|
-
* terminal.runId)
|
|
41
|
+
* terminal.runId) so callers resume that seat; parent public finals do not
|
|
42
|
+
* project other-seat tables (#1195).
|
|
38
43
|
*/
|
|
39
44
|
export type GatekeeperResult =
|
|
40
45
|
| {
|
|
@@ -227,7 +232,7 @@ function projectOfficerPayloads(
|
|
|
227
232
|
return projectOfficerDecision(officer, payloads[payloads.length - 1], fallbackStatus);
|
|
228
233
|
}
|
|
229
234
|
|
|
230
|
-
/** Nested officer runId from summoned.runDirectory, else terminal.runId (
|
|
235
|
+
/** Nested officer runId from summoned.runDirectory, else terminal.runId (resume identity). */
|
|
231
236
|
export function officerRunIdFromSummoned(summoned: PublicSummonResult): string | undefined {
|
|
232
237
|
if (typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== "") {
|
|
233
238
|
const fromDir = runIdFromRunDirectory(summoned.runDirectory);
|
|
@@ -314,6 +319,22 @@ function projectOfficerTerminal(
|
|
|
314
319
|
);
|
|
315
320
|
}
|
|
316
321
|
if (outcome.kind === "accepted") {
|
|
322
|
+
// Nested / prior incomplete (directionUnsettled) is not a gate pass (ADR 0055).
|
|
323
|
+
// Receipt stays this-court or retained; runId comes from the summoned volume
|
|
324
|
+
// (public-role-summons already prefers nested terminal.runId when roles differ).
|
|
325
|
+
// No parent-side officerPayloads / officerRunId copies (#1195).
|
|
326
|
+
if (outcome.decisiveFacts?.directionUnsettled === true) {
|
|
327
|
+
const receipt = thisCourt.length > 0 ? thisCourt[thisCourt.length - 1] : retainedReceipt(outcome);
|
|
328
|
+
return withOfficerRunId(
|
|
329
|
+
{
|
|
330
|
+
status: "needs_reask",
|
|
331
|
+
officer,
|
|
332
|
+
receipt,
|
|
333
|
+
receivedStatus: receivedDiscriminator(receipt, "status"),
|
|
334
|
+
},
|
|
335
|
+
summoned,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
317
338
|
// outcome.status is the fixture/compat leaf: production settlement leaves
|
|
318
339
|
// it undefined once payloads are recorded. It may interpret a receipt
|
|
319
340
|
// lacking its own status, never substitute for a missing receipt.
|