@akagilnc/pi-workflow-roles 0.1.3669 → 0.1.3673
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 +19 -25
- package/dist/public-cli/main.js +20 -28
- package/dist/public-cli/run-lifecycle.js +4 -0
- package/dist/public-cli/seat-ticket-binding.js +37 -45
- package/package.json +1 -1
- package/src/public-cli/diarist-run.ts +2 -2
- package/src/public-cli/run-lifecycle.ts +3 -0
- package/src/public-cli/seat-ticket-binding.ts +40 -47
|
@@ -4658,6 +4658,7 @@ async function collectBookRunTicketNumbers(input) {
|
|
|
4658
4658
|
}
|
|
4659
4659
|
const known = /* @__PURE__ */ new Set();
|
|
4660
4660
|
for (const entry of entries) {
|
|
4661
|
+
if (!entry.includes("@")) continue;
|
|
4661
4662
|
const ticketNumber = await readRunTicketNumber(join11(runsDir, entry));
|
|
4662
4663
|
if (ticketNumber !== void 0) known.add(ticketNumber);
|
|
4663
4664
|
}
|
|
@@ -9634,36 +9635,29 @@ var init_ticket_provenance = __esm({
|
|
|
9634
9635
|
// src/public-cli/seat-ticket-binding.ts
|
|
9635
9636
|
import { existsSync as existsSync6 } from "node:fs";
|
|
9636
9637
|
function instructionTicketTokens(instruction) {
|
|
9637
|
-
const tokens =
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
const parsed = Number(
|
|
9641
|
-
if (!Number.isSafeInteger(parsed)
|
|
9642
|
-
|
|
9638
|
+
const tokens = [];
|
|
9639
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9640
|
+
for (const match of instruction.matchAll(/#([1-9]\d*)/g)) {
|
|
9641
|
+
const parsed = Number(match[1]);
|
|
9642
|
+
if (!Number.isSafeInteger(parsed)) continue;
|
|
9643
|
+
if (seen.has(parsed)) continue;
|
|
9644
|
+
seen.add(parsed);
|
|
9645
|
+
tokens.push(parsed);
|
|
9643
9646
|
}
|
|
9644
|
-
return
|
|
9647
|
+
return tokens;
|
|
9645
9648
|
}
|
|
9646
9649
|
async function resolveKnownTicketNumber(input) {
|
|
9647
9650
|
const tokens = instructionTicketTokens(input.instruction);
|
|
9648
9651
|
if (tokens.length === 0) return void 0;
|
|
9649
|
-
const
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
known.push(token);
|
|
9659
|
-
continue;
|
|
9660
|
-
}
|
|
9661
|
-
if (runTickets === void 0) {
|
|
9662
|
-
runTickets = await readBookRunTickets(input);
|
|
9663
|
-
}
|
|
9664
|
-
if (runTickets.has(token)) known.push(token);
|
|
9665
|
-
}
|
|
9666
|
-
return known.length === 1 ? known[0] : void 0;
|
|
9652
|
+
const target = tokens[0];
|
|
9653
|
+
const volume = resolveTicketProvenanceVolume(
|
|
9654
|
+
target,
|
|
9655
|
+
input.projectRoot,
|
|
9656
|
+
input.home
|
|
9657
|
+
);
|
|
9658
|
+
if (existsSync6(volume.volumeDir)) return target;
|
|
9659
|
+
const runTickets = await readBookRunTickets(input);
|
|
9660
|
+
return runTickets.has(target) ? target : void 0;
|
|
9667
9661
|
}
|
|
9668
9662
|
async function readBookRunTickets(input) {
|
|
9669
9663
|
let bookKey;
|
package/dist/public-cli/main.js
CHANGED
|
@@ -17831,6 +17831,7 @@ async function collectBookRunTicketNumbers(input) {
|
|
|
17831
17831
|
}
|
|
17832
17832
|
const known = /* @__PURE__ */ new Set();
|
|
17833
17833
|
for (const entry of entries) {
|
|
17834
|
+
if (!entry.includes("@")) continue;
|
|
17834
17835
|
const ticketNumber = await readRunTicketNumber(join11(runsDir, entry));
|
|
17835
17836
|
if (ticketNumber !== void 0) known.add(ticketNumber);
|
|
17836
17837
|
}
|
|
@@ -22240,42 +22241,33 @@ var init_ticket_provenance = __esm({
|
|
|
22240
22241
|
// src/public-cli/seat-ticket-binding.ts
|
|
22241
22242
|
import { existsSync as existsSync7 } from "node:fs";
|
|
22242
22243
|
function instructionTicketTokens(instruction) {
|
|
22243
|
-
const tokens =
|
|
22244
|
-
|
|
22245
|
-
|
|
22246
|
-
const parsed = Number(
|
|
22247
|
-
if (!Number.isSafeInteger(parsed)
|
|
22248
|
-
|
|
22244
|
+
const tokens = [];
|
|
22245
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22246
|
+
for (const match of instruction.matchAll(/#([1-9]\d*)/g)) {
|
|
22247
|
+
const parsed = Number(match[1]);
|
|
22248
|
+
if (!Number.isSafeInteger(parsed)) continue;
|
|
22249
|
+
if (seen.has(parsed)) continue;
|
|
22250
|
+
seen.add(parsed);
|
|
22251
|
+
tokens.push(parsed);
|
|
22249
22252
|
}
|
|
22250
|
-
return
|
|
22253
|
+
return tokens;
|
|
22251
22254
|
}
|
|
22252
22255
|
async function resolveKnownTicketNumber(input) {
|
|
22253
22256
|
const tokens = instructionTicketTokens(input.instruction);
|
|
22254
22257
|
if (tokens.length === 0) return void 0;
|
|
22255
|
-
const
|
|
22256
|
-
|
|
22257
|
-
|
|
22258
|
-
|
|
22259
|
-
|
|
22260
|
-
|
|
22261
|
-
|
|
22262
|
-
|
|
22263
|
-
|
|
22264
|
-
known.push(token);
|
|
22265
|
-
continue;
|
|
22266
|
-
}
|
|
22267
|
-
if (runTickets === void 0) {
|
|
22268
|
-
runTickets = await readBookRunTickets(input);
|
|
22269
|
-
}
|
|
22270
|
-
if (runTickets.has(token)) known.push(token);
|
|
22271
|
-
}
|
|
22272
|
-
return known.length === 1 ? known[0] : void 0;
|
|
22258
|
+
const target = tokens[0];
|
|
22259
|
+
const volume = resolveTicketProvenanceVolume(
|
|
22260
|
+
target,
|
|
22261
|
+
input.projectRoot,
|
|
22262
|
+
input.home
|
|
22263
|
+
);
|
|
22264
|
+
if (existsSync7(volume.volumeDir)) return target;
|
|
22265
|
+
const runTickets = await readBookRunTickets(input);
|
|
22266
|
+
return runTickets.has(target) ? target : void 0;
|
|
22273
22267
|
}
|
|
22274
22268
|
async function resolveDiaristSummonsTicketNumber(input) {
|
|
22275
|
-
const known = await resolveKnownTicketNumber(input);
|
|
22276
|
-
if (known !== void 0) return known;
|
|
22277
22269
|
const tokens = instructionTicketTokens(input.instruction);
|
|
22278
|
-
return tokens
|
|
22270
|
+
return tokens[0];
|
|
22279
22271
|
}
|
|
22280
22272
|
async function readBookRunTickets(input) {
|
|
22281
22273
|
let bookKey;
|
|
@@ -845,6 +845,10 @@ export async function collectBookRunTicketNumbers(input) {
|
|
|
845
845
|
}
|
|
846
846
|
const known = new Set();
|
|
847
847
|
for (const entry of entries) {
|
|
848
|
+
// runs/ also holds non-run files (institutional-resolution.json, Finder
|
|
849
|
+
// .DS_Store); only `<runId>@<role>` directories are runs (#769).
|
|
850
|
+
if (!entry.includes("@"))
|
|
851
|
+
continue;
|
|
848
852
|
const ticketNumber = await readRunTicketNumber(join(runsDir, entry));
|
|
849
853
|
if (ticketNumber !== undefined)
|
|
850
854
|
known.add(ticketNumber);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared ticket identity seam for public court seats (#635 / #637 / #709 / #747).
|
|
3
|
-
*
|
|
4
|
-
* (retained run pages + 起居录
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* No CLI --ticket and no attachment
|
|
9
|
-
* #747: officer same-parent resume also lives here
|
|
2
|
+
* Shared ticket identity seam for public court seats (#635 / #637 / #709 / #747 / #771).
|
|
3
|
+
* Court target = first `#N` in the summons instruction. Other seats reuse that
|
|
4
|
+
* number only when this book already records it (retained run pages + 起居录
|
|
5
|
+
* volumes); 起居郎 takes it as the caller-supplied identity on a first summons
|
|
6
|
+
* (ADR 0081 `initial-court-ticket-supplied`). No seat-side model call, no second
|
|
7
|
+
* ticket-number source of truth, no minting from human titles. No `#N` leaves
|
|
8
|
+
* the run unbound (真无票), which is lawful. No CLI --ticket and no attachment
|
|
9
|
+
* frontmatter binding. #747: officer same-parent resume also lives here.
|
|
10
10
|
*/
|
|
11
11
|
import { existsSync } from "node:fs";
|
|
12
12
|
import { ActivationGitRepositoryRequiredError, resolveBookKeyFromGit, } from "../activation-ledger-git.js";
|
|
@@ -14,61 +14,53 @@ import { resolveTicketProvenanceVolume } from "../ticket-provenance.js";
|
|
|
14
14
|
import { bindAdmittedTicketNumber, } from "./invocation.js";
|
|
15
15
|
import { collectBookRunTicketNumbers, findLatestRunIdForSeatTicket, } from "./run-lifecycle.js";
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Hash-marked ticket references in an instruction, in order of first appearance.
|
|
18
|
+
* `#582` is one token; a leading-zero run is not a ticket literal; bare digit
|
|
19
|
+
* runs (`r1`, `D2`, sha islands, counts) are not ticket references. Callers name
|
|
20
|
+
* the court target as the first `#N` (ADR 0081 `initial-court-ticket-supplied`).
|
|
20
21
|
*/
|
|
21
22
|
export function instructionTicketTokens(instruction) {
|
|
22
|
-
const tokens =
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const tokens = [];
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
for (const match of instruction.matchAll(/#([1-9]\d*)/g)) {
|
|
26
|
+
const parsed = Number(match[1]);
|
|
27
|
+
if (!Number.isSafeInteger(parsed))
|
|
25
28
|
continue;
|
|
26
|
-
|
|
27
|
-
if (!Number.isSafeInteger(parsed) || parsed < 1)
|
|
29
|
+
if (seen.has(parsed))
|
|
28
30
|
continue;
|
|
29
|
-
|
|
31
|
+
seen.add(parsed);
|
|
32
|
+
tokens.push(parsed);
|
|
30
33
|
}
|
|
31
|
-
return
|
|
34
|
+
return tokens;
|
|
32
35
|
}
|
|
33
36
|
/**
|
|
34
|
-
* Ticket identity this summons reuses, or undefined when
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
37
|
+
* Ticket identity this summons reuses, or undefined when the court target is not
|
|
38
|
+
* already on this book. The first `#N` is the court target; later `#N` are
|
|
39
|
+
* neighbors/PRs and never steal the bind. Known identities come only from
|
|
40
|
+
* records this book already holds: 起居录 volume partitions and ticket numbers
|
|
41
|
+
* on retained run pages. Nothing matched leaves the run unbound — never guess.
|
|
38
42
|
*/
|
|
39
43
|
export async function resolveKnownTicketNumber(input) {
|
|
40
44
|
const tokens = instructionTicketTokens(input.instruction);
|
|
41
45
|
if (tokens.length === 0)
|
|
42
46
|
return undefined;
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (runTickets === undefined) {
|
|
52
|
-
runTickets = await readBookRunTickets(input);
|
|
53
|
-
}
|
|
54
|
-
if (runTickets.has(token))
|
|
55
|
-
known.push(token);
|
|
56
|
-
}
|
|
57
|
-
return known.length === 1 ? known[0] : undefined;
|
|
47
|
+
const target = tokens[0];
|
|
48
|
+
const volume = resolveTicketProvenanceVolume(target, input.projectRoot, input.home);
|
|
49
|
+
if (existsSync(volume.volumeDir))
|
|
50
|
+
return target;
|
|
51
|
+
const runTickets = await readBookRunTickets(input);
|
|
52
|
+
return runTickets.has(target) ? target : undefined;
|
|
58
53
|
}
|
|
59
54
|
/**
|
|
60
|
-
* Diarist
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
55
|
+
* Diarist summons identity (ADR 0081 `initial-court-ticket-supplied`).
|
|
56
|
+
* The first `#N` in the caller's dispatch is the supplied court target — the
|
|
57
|
+
* working 起居郎 round establishes the volume on a first summons; later `#N`
|
|
58
|
+
* (neighbors, PR numbers) do not unbind it. No `#N` stays unbound (真无票).
|
|
64
59
|
* Not a second ticket-number source of truth and not an extra recognizer call.
|
|
65
60
|
*/
|
|
66
61
|
export async function resolveDiaristSummonsTicketNumber(input) {
|
|
67
|
-
const known = await resolveKnownTicketNumber(input);
|
|
68
|
-
if (known !== undefined)
|
|
69
|
-
return known;
|
|
70
62
|
const tokens = instructionTicketTokens(input.instruction);
|
|
71
|
-
return tokens
|
|
63
|
+
return tokens[0];
|
|
72
64
|
}
|
|
73
65
|
/**
|
|
74
66
|
* Ticket numbers on this book's retained runs.
|
package/package.json
CHANGED
|
@@ -169,8 +169,8 @@ export async function runPublicDiarist(
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
// #637: same ticket → resume this seat's prior run with this summons' materials.
|
|
172
|
-
// #709 / ADR 0081:
|
|
173
|
-
//
|
|
172
|
+
// #709 / #771 / ADR 0081: first `#N` in the dispatch is the court target
|
|
173
|
+
// (neighbors/PRs/rN later in the prose do not unbind) — no seat recognizer call.
|
|
174
174
|
const projectRoot = parsed.project ?? env.cwd;
|
|
175
175
|
const reusedTicketNumber = await resolveDiaristSummonsTicketNumber({
|
|
176
176
|
instruction: parsed.instruction,
|
|
@@ -1161,6 +1161,9 @@ export async function collectBookRunTicketNumbers(input: {
|
|
|
1161
1161
|
}
|
|
1162
1162
|
const known = new Set<number>();
|
|
1163
1163
|
for (const entry of entries) {
|
|
1164
|
+
// runs/ also holds non-run files (institutional-resolution.json, Finder
|
|
1165
|
+
// .DS_Store); only `<runId>@<role>` directories are runs (#769).
|
|
1166
|
+
if (!entry.includes("@")) continue;
|
|
1164
1167
|
const ticketNumber = await readRunTicketNumber(join(runsDir, entry));
|
|
1165
1168
|
if (ticketNumber !== undefined) known.add(ticketNumber);
|
|
1166
1169
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared ticket identity seam for public court seats (#635 / #637 / #709 / #747).
|
|
3
|
-
*
|
|
4
|
-
* (retained run pages + 起居录
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* No CLI --ticket and no attachment
|
|
9
|
-
* #747: officer same-parent resume also lives here
|
|
2
|
+
* Shared ticket identity seam for public court seats (#635 / #637 / #709 / #747 / #771).
|
|
3
|
+
* Court target = first `#N` in the summons instruction. Other seats reuse that
|
|
4
|
+
* number only when this book already records it (retained run pages + 起居录
|
|
5
|
+
* volumes); 起居郎 takes it as the caller-supplied identity on a first summons
|
|
6
|
+
* (ADR 0081 `initial-court-ticket-supplied`). No seat-side model call, no second
|
|
7
|
+
* ticket-number source of truth, no minting from human titles. No `#N` leaves
|
|
8
|
+
* the run unbound (真无票), which is lawful. No CLI --ticket and no attachment
|
|
9
|
+
* frontmatter binding. #747: officer same-parent resume also lives here.
|
|
10
10
|
*/
|
|
11
11
|
import { existsSync } from "node:fs";
|
|
12
12
|
|
|
@@ -31,28 +31,32 @@ export type SeatTicketBindingEnv = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
34
|
+
* Hash-marked ticket references in an instruction, in order of first appearance.
|
|
35
|
+
* `#582` is one token; a leading-zero run is not a ticket literal; bare digit
|
|
36
|
+
* runs (`r1`, `D2`, sha islands, counts) are not ticket references. Callers name
|
|
37
|
+
* the court target as the first `#N` (ADR 0081 `initial-court-ticket-supplied`).
|
|
37
38
|
*/
|
|
38
39
|
export function instructionTicketTokens(
|
|
39
40
|
instruction: string,
|
|
40
41
|
): readonly number[] {
|
|
41
|
-
const tokens =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const parsed = Number(
|
|
45
|
-
if (!Number.isSafeInteger(parsed)
|
|
46
|
-
|
|
42
|
+
const tokens: number[] = [];
|
|
43
|
+
const seen = new Set<number>();
|
|
44
|
+
for (const match of instruction.matchAll(/#([1-9]\d*)/g)) {
|
|
45
|
+
const parsed = Number(match[1]);
|
|
46
|
+
if (!Number.isSafeInteger(parsed)) continue;
|
|
47
|
+
if (seen.has(parsed)) continue;
|
|
48
|
+
seen.add(parsed);
|
|
49
|
+
tokens.push(parsed);
|
|
47
50
|
}
|
|
48
|
-
return
|
|
51
|
+
return tokens;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
/**
|
|
52
|
-
* Ticket identity this summons reuses, or undefined when
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
55
|
+
* Ticket identity this summons reuses, or undefined when the court target is not
|
|
56
|
+
* already on this book. The first `#N` is the court target; later `#N` are
|
|
57
|
+
* neighbors/PRs and never steal the bind. Known identities come only from
|
|
58
|
+
* records this book already holds: 起居录 volume partitions and ticket numbers
|
|
59
|
+
* on retained run pages. Nothing matched leaves the run unbound — never guess.
|
|
56
60
|
*/
|
|
57
61
|
export async function resolveKnownTicketNumber(input: {
|
|
58
62
|
readonly instruction: string;
|
|
@@ -62,31 +66,22 @@ export async function resolveKnownTicketNumber(input: {
|
|
|
62
66
|
}): Promise<number | undefined> {
|
|
63
67
|
const tokens = instructionTicketTokens(input.instruction);
|
|
64
68
|
if (tokens.length === 0) return undefined;
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
known.push(token);
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (runTickets === undefined) {
|
|
78
|
-
runTickets = await readBookRunTickets(input);
|
|
79
|
-
}
|
|
80
|
-
if (runTickets.has(token)) known.push(token);
|
|
81
|
-
}
|
|
82
|
-
return known.length === 1 ? known[0] : undefined;
|
|
69
|
+
const target = tokens[0]!;
|
|
70
|
+
const volume = resolveTicketProvenanceVolume(
|
|
71
|
+
target,
|
|
72
|
+
input.projectRoot,
|
|
73
|
+
input.home,
|
|
74
|
+
);
|
|
75
|
+
if (existsSync(volume.volumeDir)) return target;
|
|
76
|
+
const runTickets = await readBookRunTickets(input);
|
|
77
|
+
return runTickets.has(target) ? target : undefined;
|
|
83
78
|
}
|
|
84
79
|
|
|
85
80
|
/**
|
|
86
|
-
* Diarist
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
81
|
+
* Diarist summons identity (ADR 0081 `initial-court-ticket-supplied`).
|
|
82
|
+
* The first `#N` in the caller's dispatch is the supplied court target — the
|
|
83
|
+
* working 起居郎 round establishes the volume on a first summons; later `#N`
|
|
84
|
+
* (neighbors, PR numbers) do not unbind it. No `#N` stays unbound (真无票).
|
|
90
85
|
* Not a second ticket-number source of truth and not an extra recognizer call.
|
|
91
86
|
*/
|
|
92
87
|
export async function resolveDiaristSummonsTicketNumber(input: {
|
|
@@ -95,10 +90,8 @@ export async function resolveDiaristSummonsTicketNumber(input: {
|
|
|
95
90
|
readonly home: string;
|
|
96
91
|
readonly bookKey?: string;
|
|
97
92
|
}): Promise<number | undefined> {
|
|
98
|
-
const known = await resolveKnownTicketNumber(input);
|
|
99
|
-
if (known !== undefined) return known;
|
|
100
93
|
const tokens = instructionTicketTokens(input.instruction);
|
|
101
|
-
return tokens
|
|
94
|
+
return tokens[0];
|
|
102
95
|
}
|
|
103
96
|
|
|
104
97
|
/**
|