@akagilnc/pi-workflow-roles 0.1.5005 → 0.1.5013
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 +33 -6
- package/dist/headless-host/description.js +12 -3
- package/dist/headless-host/production-host.js +41 -9
- package/package.json +1 -1
- package/souls/audit-law.md +3 -1
- package/src/headless-host/description.ts +13 -3
- package/src/package-contracts/worker-output.ts +1 -1
- package/src/role-runtime.ts +10 -0
- package/src/worker-role.ts +32 -15
|
@@ -26438,7 +26438,7 @@ function fixerBashSeatbeltDenyReason(matched) {
|
|
|
26438
26438
|
}
|
|
26439
26439
|
|
|
26440
26440
|
// src/worker-role.ts
|
|
26441
|
-
var CODER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u56DE\u6267\u542B TDD\u3001\u540C\u6A21\u5F0F\u3001\u5F15\u5165\u56DE\u5F52\u3001\u884C\u4E3A\u4E8B\u5B9E\u56DB\u9879\u8BC1\u636E\uFF1Bunfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
|
|
26441
|
+
var CODER_STATUS_DESCRIPTION = "planned | completed | refused | partially_completed | unfinished \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u56DE\u6267\u542B TDD\u3001\u540C\u6A21\u5F0F\u3001\u5F15\u5165\u56DE\u5F52\u3001\u884C\u4E3A\u4E8B\u5B9E\u56DB\u9879\u8BC1\u636E\uFF1Bunfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
|
|
26442
26442
|
var coderOutputVariants = Type22.Union([
|
|
26443
26443
|
Type22.Object({
|
|
26444
26444
|
status: Type22.Unknown({ description: CODER_STATUS_DESCRIPTION }),
|
|
@@ -26488,8 +26488,26 @@ var FIXER_PHASES = ["plan", "apply"];
|
|
|
26488
26488
|
function isWorkerPhase(value) {
|
|
26489
26489
|
return typeof value === "string" && FIXER_PHASES.includes(value);
|
|
26490
26490
|
}
|
|
26491
|
+
function isRecord19(value) {
|
|
26492
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26493
|
+
}
|
|
26494
|
+
var WORKER_ROUTING_STATUSES = /* @__PURE__ */ new Set([
|
|
26495
|
+
"planned",
|
|
26496
|
+
"completed",
|
|
26497
|
+
"refused",
|
|
26498
|
+
"partially_completed",
|
|
26499
|
+
"unfinished"
|
|
26500
|
+
]);
|
|
26501
|
+
var WORKER_STATUS_REASK = "status \u4E0D\u662F planned\u3001completed\u3001refused\u3001partially_completed\u3001unfinished \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
|
|
26491
26502
|
function workerStatusOf(output) {
|
|
26492
|
-
return typeof output.status === "string" ? output.status :
|
|
26503
|
+
return isRecord19(output) && typeof output.status === "string" ? output.status : void 0;
|
|
26504
|
+
}
|
|
26505
|
+
function requireReadableWorkerStatus(output) {
|
|
26506
|
+
const status = workerStatusOf(output);
|
|
26507
|
+
if (status === void 0 || !WORKER_ROUTING_STATUSES.has(status)) {
|
|
26508
|
+
throw new ParentQueueReaskError(WORKER_STATUS_REASK);
|
|
26509
|
+
}
|
|
26510
|
+
return status;
|
|
26493
26511
|
}
|
|
26494
26512
|
function deepFreeze2(value) {
|
|
26495
26513
|
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
@@ -26572,9 +26590,10 @@ function createFixerRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26572
26590
|
throw new Error("\u4FEE\u5185\u53F8\u4FEE\u7406\u5305\u4E0E\u9636\u6BB5\u672A\u88C5\u8F7D");
|
|
26573
26591
|
}
|
|
26574
26592
|
const output = deepFreeze2(validateFixerOutput(parameters, phase));
|
|
26593
|
+
const status = requireReadableWorkerStatus(output);
|
|
26575
26594
|
assertAcceptableThroughHost(
|
|
26576
26595
|
submissionGate,
|
|
26577
|
-
|
|
26596
|
+
status,
|
|
26578
26597
|
output,
|
|
26579
26598
|
hostActions,
|
|
26580
26599
|
ctx,
|
|
@@ -26582,7 +26601,7 @@ function createFixerRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26582
26601
|
);
|
|
26583
26602
|
let pass;
|
|
26584
26603
|
try {
|
|
26585
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
26604
|
+
pass = WORKER_DONE_STATUSES.has(status) ? await pi.requireSubmissionGate({
|
|
26586
26605
|
context: ctx,
|
|
26587
26606
|
subject: { kind: "worker_completion" },
|
|
26588
26607
|
..._signal === void 0 ? {} : { signal: _signal },
|
|
@@ -26723,9 +26742,10 @@ function createCoderRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26723
26742
|
throw new Error("\u5C06\u4F5C\u76D1\u4EFB\u52A1\u4E0E\u9636\u6BB5\u672A\u88C5\u8F7D");
|
|
26724
26743
|
}
|
|
26725
26744
|
const output = validateWorkerOutput(parameters, phase, "Coder");
|
|
26745
|
+
const status = requireReadableWorkerStatus(output);
|
|
26726
26746
|
assertAcceptableThroughHost(
|
|
26727
26747
|
submissionGate,
|
|
26728
|
-
|
|
26748
|
+
status,
|
|
26729
26749
|
output,
|
|
26730
26750
|
hostActions,
|
|
26731
26751
|
ctx2,
|
|
@@ -26733,7 +26753,7 @@ function createCoderRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26733
26753
|
);
|
|
26734
26754
|
let pass;
|
|
26735
26755
|
try {
|
|
26736
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
26756
|
+
pass = WORKER_DONE_STATUSES.has(status) ? await pi.requireSubmissionGate({
|
|
26737
26757
|
context: ctx2,
|
|
26738
26758
|
subject: { kind: "worker_completion" },
|
|
26739
26759
|
..._signal === void 0 ? {} : { signal: _signal },
|
|
@@ -27314,6 +27334,8 @@ function readDiaristRunCoordinates(ctx) {
|
|
|
27314
27334
|
};
|
|
27315
27335
|
}
|
|
27316
27336
|
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u8BF7\u91CD\u4EA4 sessions\uFF1A\u6BCF\u5377 path + ranges\uFF0C\u6BCF\u7AEF\u4EE5\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00\u6307\u540D\u3002";
|
|
27337
|
+
var DIARIST_ROUTING_STATUSES = /* @__PURE__ */ new Set(["completed", "escalate"]);
|
|
27338
|
+
var DIARIST_STATUS_REASK = "status \u4E0D\u662F completed\u3001escalate \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
|
|
27317
27339
|
function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
27318
27340
|
return createFiledOfficerRuntime(
|
|
27319
27341
|
roleHost,
|
|
@@ -27323,6 +27345,11 @@ function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
|
27323
27345
|
soulTag: "diarist",
|
|
27324
27346
|
beforeAccept: async ({ parameters, ctx }) => {
|
|
27325
27347
|
const submitted = parameters !== null && typeof parameters === "object" && !Array.isArray(parameters) ? parameters : void 0;
|
|
27348
|
+
const status = submitted?.status;
|
|
27349
|
+
if (typeof status !== "string" || !DIARIST_ROUTING_STATUSES.has(status)) {
|
|
27350
|
+
throw new ParentQueueReaskError(DIARIST_STATUS_REASK);
|
|
27351
|
+
}
|
|
27352
|
+
if (status === "escalate") return parameters;
|
|
27326
27353
|
const assertion = readDiaristTicketAssertion(submitted);
|
|
27327
27354
|
const coords = readDiaristRunCoordinates(ctx);
|
|
27328
27355
|
const ticketNumber = assertion.kind === "ticket" ? assertion.ticketNumber : void 0;
|
|
@@ -168,13 +168,22 @@ function nonNullLeaves(schema) {
|
|
|
168
168
|
* Required → closed non-null leaf(s). Optional → closed leaf(s) + null.
|
|
169
169
|
*/
|
|
170
170
|
function closePropertySchema(schema, optional) {
|
|
171
|
+
const description = isPlainObject(schema) && typeof schema.description === "string"
|
|
172
|
+
? { description: schema.description }
|
|
173
|
+
: {};
|
|
171
174
|
const leaves = nonNullLeaves(schema).map(closeSchemaNode);
|
|
172
175
|
if (leaves.length === 0)
|
|
173
|
-
return { type: "null" };
|
|
176
|
+
return { type: "null", ...description };
|
|
174
177
|
if (!optional) {
|
|
175
|
-
|
|
178
|
+
const closed = leaves.length === 1 ? leaves[0] : { anyOf: leaves };
|
|
179
|
+
// Codex strict does not allow sibling keys on $ref; put property guidance
|
|
180
|
+
// on an enclosing schema instead of losing it or weakening the free-JSON ref.
|
|
181
|
+
if (isPlainObject(closed) && typeof closed.$ref === "string") {
|
|
182
|
+
return { anyOf: [closed], ...description };
|
|
183
|
+
}
|
|
184
|
+
return isPlainObject(closed) ? { ...closed, ...description } : closed;
|
|
176
185
|
}
|
|
177
|
-
return { anyOf: [...leaves, { type: "null" }] };
|
|
186
|
+
return { anyOf: [...leaves, { type: "null" }], ...description };
|
|
178
187
|
}
|
|
179
188
|
/**
|
|
180
189
|
* Strict generators require every schema node to declare `type` (or a $ref).
|
|
@@ -26387,7 +26387,7 @@ function fixerBashSeatbeltDenyReason(matched) {
|
|
|
26387
26387
|
}
|
|
26388
26388
|
|
|
26389
26389
|
// src/worker-role.ts
|
|
26390
|
-
var CODER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u56DE\u6267\u542B TDD\u3001\u540C\u6A21\u5F0F\u3001\u5F15\u5165\u56DE\u5F52\u3001\u884C\u4E3A\u4E8B\u5B9E\u56DB\u9879\u8BC1\u636E\uFF1Bunfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
|
|
26390
|
+
var CODER_STATUS_DESCRIPTION = "planned | completed | refused | partially_completed | unfinished \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u56DE\u6267\u542B TDD\u3001\u540C\u6A21\u5F0F\u3001\u5F15\u5165\u56DE\u5F52\u3001\u884C\u4E3A\u4E8B\u5B9E\u56DB\u9879\u8BC1\u636E\uFF1Bunfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
|
|
26391
26391
|
var coderOutputVariants = Type22.Union([
|
|
26392
26392
|
Type22.Object({
|
|
26393
26393
|
status: Type22.Unknown({ description: CODER_STATUS_DESCRIPTION }),
|
|
@@ -26437,8 +26437,26 @@ var FIXER_PHASES = ["plan", "apply"];
|
|
|
26437
26437
|
function isWorkerPhase(value) {
|
|
26438
26438
|
return typeof value === "string" && FIXER_PHASES.includes(value);
|
|
26439
26439
|
}
|
|
26440
|
+
function isRecord19(value) {
|
|
26441
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26442
|
+
}
|
|
26443
|
+
var WORKER_ROUTING_STATUSES = /* @__PURE__ */ new Set([
|
|
26444
|
+
"planned",
|
|
26445
|
+
"completed",
|
|
26446
|
+
"refused",
|
|
26447
|
+
"partially_completed",
|
|
26448
|
+
"unfinished"
|
|
26449
|
+
]);
|
|
26450
|
+
var WORKER_STATUS_REASK = "status \u4E0D\u662F planned\u3001completed\u3001refused\u3001partially_completed\u3001unfinished \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
|
|
26440
26451
|
function workerStatusOf(output) {
|
|
26441
|
-
return typeof output.status === "string" ? output.status :
|
|
26452
|
+
return isRecord19(output) && typeof output.status === "string" ? output.status : void 0;
|
|
26453
|
+
}
|
|
26454
|
+
function requireReadableWorkerStatus(output) {
|
|
26455
|
+
const status = workerStatusOf(output);
|
|
26456
|
+
if (status === void 0 || !WORKER_ROUTING_STATUSES.has(status)) {
|
|
26457
|
+
throw new ParentQueueReaskError(WORKER_STATUS_REASK);
|
|
26458
|
+
}
|
|
26459
|
+
return status;
|
|
26442
26460
|
}
|
|
26443
26461
|
function deepFreeze2(value) {
|
|
26444
26462
|
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
@@ -26521,9 +26539,10 @@ function createFixerRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26521
26539
|
throw new Error("\u4FEE\u5185\u53F8\u4FEE\u7406\u5305\u4E0E\u9636\u6BB5\u672A\u88C5\u8F7D");
|
|
26522
26540
|
}
|
|
26523
26541
|
const output = deepFreeze2(validateFixerOutput(parameters, phase));
|
|
26542
|
+
const status = requireReadableWorkerStatus(output);
|
|
26524
26543
|
assertAcceptableThroughHost(
|
|
26525
26544
|
submissionGate,
|
|
26526
|
-
|
|
26545
|
+
status,
|
|
26527
26546
|
output,
|
|
26528
26547
|
hostActions,
|
|
26529
26548
|
ctx,
|
|
@@ -26531,7 +26550,7 @@ function createFixerRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26531
26550
|
);
|
|
26532
26551
|
let pass;
|
|
26533
26552
|
try {
|
|
26534
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
26553
|
+
pass = WORKER_DONE_STATUSES.has(status) ? await pi.requireSubmissionGate({
|
|
26535
26554
|
context: ctx,
|
|
26536
26555
|
subject: { kind: "worker_completion" },
|
|
26537
26556
|
..._signal === void 0 ? {} : { signal: _signal },
|
|
@@ -26672,9 +26691,10 @@ function createCoderRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26672
26691
|
throw new Error("\u5C06\u4F5C\u76D1\u4EFB\u52A1\u4E0E\u9636\u6BB5\u672A\u88C5\u8F7D");
|
|
26673
26692
|
}
|
|
26674
26693
|
const output = validateWorkerOutput(parameters, phase, "Coder");
|
|
26694
|
+
const status = requireReadableWorkerStatus(output);
|
|
26675
26695
|
assertAcceptableThroughHost(
|
|
26676
26696
|
submissionGate,
|
|
26677
|
-
|
|
26697
|
+
status,
|
|
26678
26698
|
output,
|
|
26679
26699
|
hostActions,
|
|
26680
26700
|
ctx2,
|
|
@@ -26682,7 +26702,7 @@ function createCoderRoleRuntime(pi, dependencies, hostActions) {
|
|
|
26682
26702
|
);
|
|
26683
26703
|
let pass;
|
|
26684
26704
|
try {
|
|
26685
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
26705
|
+
pass = WORKER_DONE_STATUSES.has(status) ? await pi.requireSubmissionGate({
|
|
26686
26706
|
context: ctx2,
|
|
26687
26707
|
subject: { kind: "worker_completion" },
|
|
26688
26708
|
..._signal === void 0 ? {} : { signal: _signal },
|
|
@@ -27239,6 +27259,8 @@ function readDiaristRunCoordinates(ctx) {
|
|
|
27239
27259
|
};
|
|
27240
27260
|
}
|
|
27241
27261
|
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u8BF7\u91CD\u4EA4 sessions\uFF1A\u6BCF\u5377 path + ranges\uFF0C\u6BCF\u7AEF\u4EE5\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00\u6307\u540D\u3002";
|
|
27262
|
+
var DIARIST_ROUTING_STATUSES = /* @__PURE__ */ new Set(["completed", "escalate"]);
|
|
27263
|
+
var DIARIST_STATUS_REASK = "status \u4E0D\u662F completed\u3001escalate \u4E4B\u4E00\u3002\u8BF7\u91CD\u65B0\u4EA4\u5377\uFF0Cstatus \u5199\u660E\u5176\u4E00\u3002";
|
|
27242
27264
|
function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
27243
27265
|
return createFiledOfficerRuntime(
|
|
27244
27266
|
roleHost,
|
|
@@ -27248,6 +27270,11 @@ function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
|
27248
27270
|
soulTag: "diarist",
|
|
27249
27271
|
beforeAccept: async ({ parameters, ctx }) => {
|
|
27250
27272
|
const submitted = parameters !== null && typeof parameters === "object" && !Array.isArray(parameters) ? parameters : void 0;
|
|
27273
|
+
const status = submitted?.status;
|
|
27274
|
+
if (typeof status !== "string" || !DIARIST_ROUTING_STATUSES.has(status)) {
|
|
27275
|
+
throw new ParentQueueReaskError(DIARIST_STATUS_REASK);
|
|
27276
|
+
}
|
|
27277
|
+
if (status === "escalate") return parameters;
|
|
27251
27278
|
const assertion = readDiaristTicketAssertion(submitted);
|
|
27252
27279
|
const coords = readDiaristRunCoordinates(ctx);
|
|
27253
27280
|
const ticketNumber = assertion.kind === "ticket" ? assertion.ticketNumber : void 0;
|
|
@@ -29327,12 +29354,17 @@ function nonNullLeaves(schema) {
|
|
|
29327
29354
|
return flattenUnionLeaves(schema).map(stripNullFromLeafType).filter((leaf) => !isPureNullTypeSchema(leaf));
|
|
29328
29355
|
}
|
|
29329
29356
|
function closePropertySchema(schema, optional) {
|
|
29357
|
+
const description = isPlainObject2(schema) && typeof schema.description === "string" ? { description: schema.description } : {};
|
|
29330
29358
|
const leaves = nonNullLeaves(schema).map(closeSchemaNode);
|
|
29331
|
-
if (leaves.length === 0) return { type: "null" };
|
|
29359
|
+
if (leaves.length === 0) return { type: "null", ...description };
|
|
29332
29360
|
if (!optional) {
|
|
29333
|
-
|
|
29361
|
+
const closed = leaves.length === 1 ? leaves[0] : { anyOf: leaves };
|
|
29362
|
+
if (isPlainObject2(closed) && typeof closed.$ref === "string") {
|
|
29363
|
+
return { anyOf: [closed], ...description };
|
|
29364
|
+
}
|
|
29365
|
+
return isPlainObject2(closed) ? { ...closed, ...description } : closed;
|
|
29334
29366
|
}
|
|
29335
|
-
return { anyOf: [...leaves, { type: "null" }] };
|
|
29367
|
+
return { anyOf: [...leaves, { type: "null" }], ...description };
|
|
29336
29368
|
}
|
|
29337
29369
|
function ensureTypedLeaf(schema) {
|
|
29338
29370
|
if (schema.type !== void 0) return schema;
|
package/package.json
CHANGED
package/souls/audit-law.md
CHANGED
|
@@ -19,7 +19,9 @@ finding 提**类别**;实例只作证据。一次找齐全,不逐轮抽样
|
|
|
19
19
|
|
|
20
20
|
判断不收敛(同类问题反复、修理只增不减)可上呈;你的打回与上一轮相同、对方重交只换措辞,须上呈,不得再打回。修理 diff 自身按同尺复核。
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
衙门不是需求来源。弹章、施工方的注释与测试、你造的探针,都只是线索。判一条 finding 成立、开一条约束,判词须写明两样:要它的那一句法(先看那句讲的是不是这一条),和它在哪条真实 run 上发生过(指针)。缺一样,按过度防御或加戏驳回;判词缺这两样,审刑院打回,符宝郎驳。对方按你处方加的东西,下轮同审。
|
|
23
|
+
|
|
24
|
+
判例:#1025 御史台据一句注释造场景,大理寺引「上呈暂停」判成立,审刑院、符宝郎皆署;那句法没要过「谁有资格唤醒」,场景也从未发生。
|
|
23
25
|
|
|
24
26
|
## 取证边界(owner 2026-09-05)
|
|
25
27
|
|
|
@@ -250,12 +250,22 @@ function nonNullLeaves(schema: unknown): unknown[] {
|
|
|
250
250
|
* Required → closed non-null leaf(s). Optional → closed leaf(s) + null.
|
|
251
251
|
*/
|
|
252
252
|
function closePropertySchema(schema: unknown, optional: boolean): unknown {
|
|
253
|
+
const description =
|
|
254
|
+
isPlainObject(schema) && typeof schema.description === "string"
|
|
255
|
+
? { description: schema.description }
|
|
256
|
+
: {};
|
|
253
257
|
const leaves = nonNullLeaves(schema).map(closeSchemaNode);
|
|
254
|
-
if (leaves.length === 0) return { type: "null" };
|
|
258
|
+
if (leaves.length === 0) return { type: "null", ...description };
|
|
255
259
|
if (!optional) {
|
|
256
|
-
|
|
260
|
+
const closed = leaves.length === 1 ? leaves[0] : { anyOf: leaves };
|
|
261
|
+
// Codex strict does not allow sibling keys on $ref; put property guidance
|
|
262
|
+
// on an enclosing schema instead of losing it or weakening the free-JSON ref.
|
|
263
|
+
if (isPlainObject(closed) && typeof closed.$ref === "string") {
|
|
264
|
+
return { anyOf: [closed], ...description };
|
|
265
|
+
}
|
|
266
|
+
return isPlainObject(closed) ? { ...closed, ...description } : closed;
|
|
257
267
|
}
|
|
258
|
-
return { anyOf: [...leaves, { type: "null" }] };
|
|
268
|
+
return { anyOf: [...leaves, { type: "null" }], ...description };
|
|
259
269
|
}
|
|
260
270
|
|
|
261
271
|
/**
|
|
@@ -19,7 +19,7 @@ export const CODER_OUTPUT_TOOL_NAME = "ak_coder_output";
|
|
|
19
19
|
export type WorkerRoleLabel = "Coder" | "Fixer";
|
|
20
20
|
export type CoderOutput =
|
|
21
21
|
| { status: "planned"; report: string }
|
|
22
|
-
| { status: "completed" | "refused"; report: string }
|
|
22
|
+
| { status: "completed" | "refused" | "partially_completed"; report: string }
|
|
23
23
|
| { status: "unfinished"; report: string; remainingScope: string; reason?: string };
|
|
24
24
|
export type WorkerOutput = CoderOutput | FixerOutput;
|
|
25
25
|
|
package/src/role-runtime.ts
CHANGED
|
@@ -883,6 +883,9 @@ function readDiaristRunCoordinates(ctx: HostContext): {
|
|
|
883
883
|
/** Plain-language re-ask when diarist bounds cannot be used (#901 / reask-not-explode). */
|
|
884
884
|
const DIARIST_BOUNDS_REASK =
|
|
885
885
|
"边界无法使用。请重交 sessions:每卷 path + ranges,每端以原生 id 或本轮行号二选一指名。" as const;
|
|
886
|
+
const DIARIST_ROUTING_STATUSES = new Set(["completed", "escalate"]);
|
|
887
|
+
const DIARIST_STATUS_REASK =
|
|
888
|
+
"status 不是 completed、escalate 之一。请重新交卷,status 写明其一。" as const;
|
|
886
889
|
|
|
887
890
|
/**
|
|
888
891
|
* #708 / #779 / #901: 起居郎 public seat on the shared filed-officer envelope.
|
|
@@ -905,6 +908,13 @@ export function createDiaristRoleRuntime(
|
|
|
905
908
|
parameters !== null && typeof parameters === "object" && !Array.isArray(parameters)
|
|
906
909
|
? (parameters as Record<string, unknown>)
|
|
907
910
|
: undefined;
|
|
911
|
+
// This status selects package-owned continuation vs escalation. Check it
|
|
912
|
+
// before interpreting any other submitted field; caller-owned data stays open.
|
|
913
|
+
const status = submitted?.status;
|
|
914
|
+
if (typeof status !== "string" || !DIARIST_ROUTING_STATUSES.has(status)) {
|
|
915
|
+
throw new ParentQueueReaskError(DIARIST_STATUS_REASK);
|
|
916
|
+
}
|
|
917
|
+
if (status === "escalate") return parameters;
|
|
908
918
|
const assertion = readDiaristTicketAssertion(submitted);
|
|
909
919
|
const coords = readDiaristRunCoordinates(ctx);
|
|
910
920
|
// #836 7.3: pre-bound ticket is material for the LLM, not an override.
|
package/src/worker-role.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
} from "./canonical-skill-binding.ts";
|
|
11
11
|
import { readableGateItem } from "./readable-gate-item.ts";
|
|
12
12
|
import { projectGatekeeperEscalation } from "./audit-escalation.ts";
|
|
13
|
-
import { GatekeeperDecisionError } from "./submission-errors.ts";
|
|
13
|
+
import { GatekeeperDecisionError, ParentQueueReaskError } from "./submission-errors.ts";
|
|
14
14
|
import {
|
|
15
15
|
CODER_OUTPUT_TOOL_NAME,
|
|
16
16
|
FIXER_OUTPUT_TOOL_NAME,
|
|
@@ -53,7 +53,7 @@ export type { WorkerOutput };
|
|
|
53
53
|
// (src/countersign-role.ts) — one shared description across every variant
|
|
54
54
|
// so openToolObjectFromUnion's identical-declaration collapse drops none of it.
|
|
55
55
|
const CODER_STATUS_DESCRIPTION =
|
|
56
|
-
"planned | completed | refused | unfinished — 形状指引,非 schema 闸;completed 回执含 TDD、同模式、引入回归、行为事实四项证据;unfinished 缺前置或违宪约束致本局未完成时可用,缺待决 owner 决定或答复属缺前置。" as const;
|
|
56
|
+
"planned | completed | refused | partially_completed | unfinished — 形状指引,非 schema 闸;completed 回执含 TDD、同模式、引入回归、行为事实四项证据;unfinished 缺前置或违宪约束致本局未完成时可用,缺待决 owner 决定或答复属缺前置。" as const;
|
|
57
57
|
const coderOutputVariants = Type.Union([
|
|
58
58
|
Type.Object({
|
|
59
59
|
status: Type.Unknown({ description: CODER_STATUS_DESCRIPTION }),
|
|
@@ -154,15 +154,30 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
154
154
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
/** Routing words shared by Coder and Fixer; provider schemas remain open. */
|
|
158
|
+
const WORKER_ROUTING_STATUSES = new Set([
|
|
159
|
+
"planned",
|
|
160
|
+
"completed",
|
|
161
|
+
"refused",
|
|
162
|
+
"partially_completed",
|
|
163
|
+
"unfinished",
|
|
164
|
+
]);
|
|
165
|
+
const WORKER_STATUS_REASK =
|
|
166
|
+
"status 不是 planned、completed、refused、partially_completed、unfinished 之一。请重新交卷,status 写明其一。" as const;
|
|
167
|
+
|
|
168
|
+
/** Read only the field that selects the worker's next package-owned path. */
|
|
169
|
+
function workerStatusOf(output: WorkerOutput): string | undefined {
|
|
170
|
+
return isRecord(output) && typeof output.status === "string"
|
|
171
|
+
? output.status
|
|
172
|
+
: undefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function requireReadableWorkerStatus(output: WorkerOutput): string {
|
|
176
|
+
const status = workerStatusOf(output);
|
|
177
|
+
if (status === undefined || !WORKER_ROUTING_STATUSES.has(status)) {
|
|
178
|
+
throw new ParentQueueReaskError(WORKER_STATUS_REASK);
|
|
179
|
+
}
|
|
180
|
+
return status;
|
|
166
181
|
}
|
|
167
182
|
|
|
168
183
|
function deepFreeze<T>(value: T): T {
|
|
@@ -276,9 +291,10 @@ export function createFixerRoleRuntime(
|
|
|
276
291
|
throw new Error("修内司修理包与阶段未装载");
|
|
277
292
|
}
|
|
278
293
|
const output = deepFreeze(validateFixerOutput(parameters, phase));
|
|
294
|
+
const status = requireReadableWorkerStatus(output);
|
|
279
295
|
assertAcceptableThroughHost(
|
|
280
296
|
submissionGate,
|
|
281
|
-
|
|
297
|
+
status,
|
|
282
298
|
output,
|
|
283
299
|
hostActions,
|
|
284
300
|
ctx,
|
|
@@ -286,7 +302,7 @@ export function createFixerRoleRuntime(
|
|
|
286
302
|
);
|
|
287
303
|
let pass;
|
|
288
304
|
try {
|
|
289
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
305
|
+
pass = WORKER_DONE_STATUSES.has(status)
|
|
290
306
|
? await pi.requireSubmissionGate!({
|
|
291
307
|
context: ctx,
|
|
292
308
|
subject: { kind: "worker_completion" },
|
|
@@ -429,11 +445,12 @@ export function createCoderRoleRuntime(
|
|
|
429
445
|
throw new Error("将作监任务与阶段未装载");
|
|
430
446
|
}
|
|
431
447
|
const output = validateWorkerOutput(parameters, phase, "Coder");
|
|
448
|
+
const status = requireReadableWorkerStatus(output);
|
|
432
449
|
// #836: skill-expansion evidence rejection deleted (陛下「2.4/5 删」).
|
|
433
450
|
// Skill still ships with the package (ADR 0052); code no longer refuses on it.
|
|
434
451
|
assertAcceptableThroughHost(
|
|
435
452
|
submissionGate,
|
|
436
|
-
|
|
453
|
+
status,
|
|
437
454
|
output,
|
|
438
455
|
hostActions,
|
|
439
456
|
ctx,
|
|
@@ -441,7 +458,7 @@ export function createCoderRoleRuntime(
|
|
|
441
458
|
);
|
|
442
459
|
let pass;
|
|
443
460
|
try {
|
|
444
|
-
pass = WORKER_DONE_STATUSES.has(
|
|
461
|
+
pass = WORKER_DONE_STATUSES.has(status)
|
|
445
462
|
? await pi.requireSubmissionGate!({
|
|
446
463
|
context: ctx,
|
|
447
464
|
subject: { kind: "worker_completion" },
|