@akagilnc/pi-workflow-roles 0.1.3671 → 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.
|
@@ -9635,36 +9635,29 @@ var init_ticket_provenance = __esm({
|
|
|
9635
9635
|
// src/public-cli/seat-ticket-binding.ts
|
|
9636
9636
|
import { existsSync as existsSync6 } from "node:fs";
|
|
9637
9637
|
function instructionTicketTokens(instruction) {
|
|
9638
|
-
const tokens =
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
const parsed = Number(
|
|
9642
|
-
if (!Number.isSafeInteger(parsed)
|
|
9643
|
-
|
|
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);
|
|
9644
9646
|
}
|
|
9645
|
-
return
|
|
9647
|
+
return tokens;
|
|
9646
9648
|
}
|
|
9647
9649
|
async function resolveKnownTicketNumber(input) {
|
|
9648
9650
|
const tokens = instructionTicketTokens(input.instruction);
|
|
9649
9651
|
if (tokens.length === 0) return void 0;
|
|
9650
|
-
const
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
known.push(token);
|
|
9660
|
-
continue;
|
|
9661
|
-
}
|
|
9662
|
-
if (runTickets === void 0) {
|
|
9663
|
-
runTickets = await readBookRunTickets(input);
|
|
9664
|
-
}
|
|
9665
|
-
if (runTickets.has(token)) known.push(token);
|
|
9666
|
-
}
|
|
9667
|
-
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;
|
|
9668
9661
|
}
|
|
9669
9662
|
async function readBookRunTickets(input) {
|
|
9670
9663
|
let bookKey;
|
package/dist/public-cli/main.js
CHANGED
|
@@ -22241,42 +22241,33 @@ var init_ticket_provenance = __esm({
|
|
|
22241
22241
|
// src/public-cli/seat-ticket-binding.ts
|
|
22242
22242
|
import { existsSync as existsSync7 } from "node:fs";
|
|
22243
22243
|
function instructionTicketTokens(instruction) {
|
|
22244
|
-
const tokens =
|
|
22245
|
-
|
|
22246
|
-
|
|
22247
|
-
const parsed = Number(
|
|
22248
|
-
if (!Number.isSafeInteger(parsed)
|
|
22249
|
-
|
|
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);
|
|
22250
22252
|
}
|
|
22251
|
-
return
|
|
22253
|
+
return tokens;
|
|
22252
22254
|
}
|
|
22253
22255
|
async function resolveKnownTicketNumber(input) {
|
|
22254
22256
|
const tokens = instructionTicketTokens(input.instruction);
|
|
22255
22257
|
if (tokens.length === 0) return void 0;
|
|
22256
|
-
const
|
|
22257
|
-
|
|
22258
|
-
|
|
22259
|
-
|
|
22260
|
-
|
|
22261
|
-
|
|
22262
|
-
|
|
22263
|
-
|
|
22264
|
-
|
|
22265
|
-
known.push(token);
|
|
22266
|
-
continue;
|
|
22267
|
-
}
|
|
22268
|
-
if (runTickets === void 0) {
|
|
22269
|
-
runTickets = await readBookRunTickets(input);
|
|
22270
|
-
}
|
|
22271
|
-
if (runTickets.has(token)) known.push(token);
|
|
22272
|
-
}
|
|
22273
|
-
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;
|
|
22274
22267
|
}
|
|
22275
22268
|
async function resolveDiaristSummonsTicketNumber(input) {
|
|
22276
|
-
const known = await resolveKnownTicketNumber(input);
|
|
22277
|
-
if (known !== void 0) return known;
|
|
22278
22269
|
const tokens = instructionTicketTokens(input.instruction);
|
|
22279
|
-
return tokens
|
|
22270
|
+
return tokens[0];
|
|
22280
22271
|
}
|
|
22281
22272
|
async function readBookRunTickets(input) {
|
|
22282
22273
|
let bookKey;
|
|
@@ -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,
|
|
@@ -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
|
/**
|