@akagilnc/pi-workflow-roles 0.1.3549 → 0.1.3554
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/CLAUDE.md +1 -1
- package/README.zh-CN.md +2 -2
- package/dist/grok/production-host.js +10 -0
- package/dist/public-cli/main.js +36 -5
- package/dist/public-cli/registry.js +2 -1
- package/package.json +1 -1
- package/src/public-cli/cli.ts +33 -4
- package/src/public-cli/countersign-run.ts +1 -0
- package/src/public-cli/inspector-run.ts +1 -0
- package/src/public-cli/notary-run.ts +1 -0
- package/src/public-cli/option-definitions.ts +11 -0
- package/src/public-cli/post-admission.ts +5 -0
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/seat-ticket-binding.ts +6 -2
package/CLAUDE.md
CHANGED
|
@@ -82,7 +82,7 @@ A probe is temporary evidence. After its evidence purpose is disposed, either de
|
|
|
82
82
|
|
|
83
83
|
**票面先过给事中再开工;决策问题上呈陛下。**(ADR 0074:票庭审读由大理寺移交门下省给事中。)
|
|
84
84
|
|
|
85
|
-
**设计修订后重新过庭。**
|
|
85
|
+
**设计修订后重新过庭。** 施工中实质设计变更须由陛下拍定;拍定后将修订后的票重新送给事中,由起居郎补录修订依据(ADR 0075;起居郎与票庭的先后归调用者,`no-call-rule`),给事中通过后再按新设计继续施工。既定设计内的实现取舍不属设计修订。
|
|
86
86
|
|
|
87
87
|
丞相编排建议:御史台 findings 宜经大理寺裁决后再派修理腿(劾→判→修)。
|
|
88
88
|
|
package/README.zh-CN.md
CHANGED
|
@@ -135,7 +135,7 @@ ak-role resume <runId> "<裁定>"
|
|
|
135
135
|
| **大理寺** | judge | **审理定谳。** 承接各方意见与材料,依照既定规则逐项判断,辨明是非曲直。可以准行、退回或请示更高决定,但自身不参与建设与修改。 |
|
|
136
136
|
| **审刑院** | judge-auditor/doctor-auditor(无 CLI,共享内部接缝;御史台侧闸已退役) | **复核成案。** 不重新争论事情本身,而是检查整个办理过程是否合乎规矩。关注是否有人越过职责、是否遗漏必要步骤、是否以错误方式得出正确结果。直属陛下,不入门下省编制。 |
|
|
137
137
|
| **门下省** | gatekeeper(交卷闸不再自动出席;可 `ak-role gatekeeper` 独立直调) | **审署诏敕与质量保证的省。** 交卷闸按受审物直接传召察院/符宝郎,本省不介入选席;调用者仍可独立传召本省作 dispatch/pass;给事中票庭由调用者开工前传召;左拾遗由调用者合并前传召;省内政,不是外层编排器。规范见 [ADR 0067](docs/adr/0067-menxia-province-founding-jishizhong-fubaolang.md)、[ADR 0072](docs/adr/0072-menxia-pre-pr-submission-hooks.md)、[ADR 0074](docs/adr/0074-gate-province-reorg-jishizhong-chaiyuan-split.md)、[ADR 0079](docs/adr/0079-direct-officer-summons-ticket-memory-pointer-input.md)。 |
|
|
138
|
-
| **给事中** | countersign(无交卷闸派发;开工前由调用者传召) | **票庭审读五问。**
|
|
138
|
+
| **给事中** | countersign(无交卷闸派发;开工前由调用者传召) | **票庭审读五问。** 制度符合/授权真实(以起居录为据)/文书符意/退回重议/发布资格;读码取证是本职,实现细节不上票面。起居录由起居郎(独立角色)修,先后归调用者;交卷闸出席符宝郎。署=放行开工,封驳=退票重议,上呈=陛下裁决。规范见 [ADR 0074](docs/adr/0074-gate-province-reorg-jishizhong-chaiyuan-split.md)、[ADR 0075](docs/adr/0075-ticket-provenance-diarist-pipeline.md)。 |
|
|
139
139
|
| **左拾遗** | gleaner-left(无交卷闸派发;合并前由调用者传召) | **合并前无锚定风闻。** 对全幅合并候选作冷眼评审;只上弹章、不封驳不裁决。规范见 [ADR 0067](docs/adr/0067-menxia-province-founding-jishizhong-fubaolang.md) 修正案。 |
|
|
140
140
|
| **察院** | inspector | **事后察举:复杂度与测试质量两轴。** 受审物是将作监/修内司完成侧交卷;封驳=当场打回重写,不是本局失败。可被门下省派发,也可 `ak-role inspector` 单独调。原给事中,ADR 0074 分立。 |
|
|
141
141
|
| **符宝郎** | notary | **首责唯一:核实实际授权出处**(防乱编乱扩)。行事两步:读该票起居录→以录核旨;引语真伪与票面对齐为手段。受审物是大理寺拟判与给事中署章;可被门下省派发,也可 `ak-role notary` 单独调。规范见 [ADR 0075](docs/adr/0075-ticket-provenance-diarist-pipeline.md)。 |
|
|
@@ -150,7 +150,7 @@ ak-role resume <runId> "<裁定>"
|
|
|
150
150
|
| doctor | **太医署** | 单案诊断工厂机制,开 `keep|thin|delete` 方 | 已建 |
|
|
151
151
|
| analyst | **太史** | 司天台分析席:只读司天记录、出高阶指标;确定性机制,非 LLM,可单独调用 | 已建([ADR 0068](docs/adr/0068-taishi-analysis-seat-reads-records-writes-sibling-home.md);机器面键 `analyst`,[#445](https://github.com/Akagilnc/ak-pi-workflow-roles/issues/445) 拼音清零) |
|
|
152
152
|
| — | **司天台** | 记候簿——只打点、只指针,不分析不执法;二期含每票起居录 kind `ticket-provenance` | **一期不是角色**([ADR 0047](docs/adr/0047-sitian-phase-one-mechanism-not-role.md):零 LLM 双面对账);分析席已由太史承担;起居录见 [ADR 0075](docs/adr/0075-ticket-provenance-diarist-pipeline.md);机器面键 `archivist`([#445](https://github.com/Akagilnc/ak-pi-workflow-roles/issues/445)) |
|
|
153
|
-
|
|
|
153
|
+
| `diarist` | **起居郎** | 为本票搜集、整理决策依据并修订起居录:LLM 语义收集+机械保全带 | **LLM 角色**(soul、席位表一行、公开入口 `ak-role diarist`、交卷工具;建制施工见 #708 r2;[ADR 0075](docs/adr/0075-ticket-provenance-diarist-pipeline.md) `diarist-is-role`;谁调用、何时调用归调用者,`no-call-rule`) |
|
|
154
154
|
| marshal | **尚书省** | 审→判→修 质量收敛环的省部级驱动角色:调用方递票号与 baseline,尚书省驱动御史台/大理寺/修内司滚到收敛(converged 唯庭可判)或 escalate 上呈,交回 typed 报告;不弹、不判、不修,只让链条转到收敛 | 已定名(#145);席位待落地(#146) |
|
|
155
155
|
| — | **兰台** | 读档议制——耗时/缺口/冗余三条,上奏不执法 | 未建 |
|
|
156
156
|
| — | **考功司** | 考具体效率——角色与档位的升档率、一次通过率、每票成本 | 留档,需要时另立票 |
|
|
@@ -6952,6 +6952,16 @@ var SUPPORT_COMMAND_HELP = {
|
|
|
6952
6952
|
"ak-role --host grok-build resume 01abc\u2026",
|
|
6953
6953
|
"ak-role --engine agy resume 01abc\u2026"
|
|
6954
6954
|
]
|
|
6955
|
+
},
|
|
6956
|
+
new: {
|
|
6957
|
+
command: "new",
|
|
6958
|
+
summary: "Explicit fresh summons: same role options as a direct call, but always mint a new run (skip same-ticket auto-resume). Caller chooses new vs resume; no overflow judgment.",
|
|
6959
|
+
usage: ["ak-role new <role> [options] \u2026"],
|
|
6960
|
+
examples: [
|
|
6961
|
+
'ak-role new countersign --attach ./ticket.md "\u88C1\uFF1A\u672C\u7968 #708 \u662F\u5426\u8DB3\u4EE5\u5F00\u5DE5\u3002"',
|
|
6962
|
+
"ak-role new notary --source-run 01abc\u2026@countersign",
|
|
6963
|
+
"ak-role --host grok-build new inspector --attach ./change.patch"
|
|
6964
|
+
]
|
|
6955
6965
|
}
|
|
6956
6966
|
};
|
|
6957
6967
|
var PUBLIC_COMMAND_HELP = {
|
package/dist/public-cli/main.js
CHANGED
|
@@ -15270,7 +15270,8 @@ var init_registry2 = __esm({
|
|
|
15270
15270
|
"roles",
|
|
15271
15271
|
"config",
|
|
15272
15272
|
"help",
|
|
15273
|
-
"resume"
|
|
15273
|
+
"resume",
|
|
15274
|
+
"new"
|
|
15274
15275
|
];
|
|
15275
15276
|
STARTUP_CANDIDATES = {
|
|
15276
15277
|
judge: [
|
|
@@ -19356,6 +19357,16 @@ var init_option_definitions = __esm({
|
|
|
19356
19357
|
"ak-role --host grok-build resume 01abc\u2026",
|
|
19357
19358
|
"ak-role --engine agy resume 01abc\u2026"
|
|
19358
19359
|
]
|
|
19360
|
+
},
|
|
19361
|
+
new: {
|
|
19362
|
+
command: "new",
|
|
19363
|
+
summary: "Explicit fresh summons: same role options as a direct call, but always mint a new run (skip same-ticket auto-resume). Caller chooses new vs resume; no overflow judgment.",
|
|
19364
|
+
usage: ["ak-role new <role> [options] \u2026"],
|
|
19365
|
+
examples: [
|
|
19366
|
+
'ak-role new countersign --attach ./ticket.md "\u88C1\uFF1A\u672C\u7968 #708 \u662F\u5426\u8DB3\u4EE5\u5F00\u5DE5\u3002"',
|
|
19367
|
+
"ak-role new notary --source-run 01abc\u2026@countersign",
|
|
19368
|
+
"ak-role --host grok-build new inspector --attach ./change.patch"
|
|
19369
|
+
]
|
|
19359
19370
|
}
|
|
19360
19371
|
};
|
|
19361
19372
|
PUBLIC_COMMAND_HELP = {
|
|
@@ -23705,6 +23716,7 @@ async function resolveSeatTicketBinding(admitted, env = {}) {
|
|
|
23705
23716
|
return resolution;
|
|
23706
23717
|
}
|
|
23707
23718
|
async function tryResumeSameTicketSeatRun(input) {
|
|
23719
|
+
if (input.freshSummons === true) return void 0;
|
|
23708
23720
|
const previousRunId = await findLatestRunIdForSeatTicket({
|
|
23709
23721
|
home: input.home,
|
|
23710
23722
|
bookKey: resolveBookKeyFromGit(input.projectRoot),
|
|
@@ -29353,6 +29365,7 @@ async function runPublicCountersign(argv, env, io, parseCountersignArgv2) {
|
|
|
29353
29365
|
projectRoot,
|
|
29354
29366
|
role: "countersign",
|
|
29355
29367
|
ticketNumber: probedTicketNumber,
|
|
29368
|
+
freshSummons: env.freshSummons,
|
|
29356
29369
|
summons,
|
|
29357
29370
|
resume: (runId, materials) => runPublicCountersignResume(
|
|
29358
29371
|
{ runId, ...materials === void 0 ? {} : { summons: materials } },
|
|
@@ -29978,6 +29991,7 @@ async function runPublicNotary(argv, env, io, parseNotaryArgv2) {
|
|
|
29978
29991
|
projectRoot,
|
|
29979
29992
|
role: "notary",
|
|
29980
29993
|
ticketNumber,
|
|
29994
|
+
freshSummons: env.freshSummons,
|
|
29981
29995
|
summons,
|
|
29982
29996
|
resume: (runId, materials) => runPublicNotaryResume(
|
|
29983
29997
|
{ runId, ...materials === void 0 ? {} : { summons: materials } },
|
|
@@ -30133,6 +30147,7 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
|
|
|
30133
30147
|
projectRoot,
|
|
30134
30148
|
role: "inspector",
|
|
30135
30149
|
ticketNumber: probedTicketNumber,
|
|
30150
|
+
freshSummons: env.freshSummons,
|
|
30136
30151
|
summons,
|
|
30137
30152
|
resume: (runId, materials) => runPublicInspectorResume(
|
|
30138
30153
|
{ runId, ...materials === void 0 ? {} : { summons: materials } },
|
|
@@ -33060,7 +33075,8 @@ function createRoleEnvironment(env, options) {
|
|
|
33060
33075
|
...projectSeatHost(options.seat),
|
|
33061
33076
|
...timeoutMs === void 0 ? {} : { timeoutMs },
|
|
33062
33077
|
...env.createRunId === void 0 ? {} : { createRunId: env.createRunId },
|
|
33063
|
-
...options.config?.autoResumeLimit === void 0 ? {} : { autoResumeLimit: options.config.autoResumeLimit }
|
|
33078
|
+
...options.config?.autoResumeLimit === void 0 ? {} : { autoResumeLimit: options.config.autoResumeLimit },
|
|
33079
|
+
...env.freshSummons === true ? { freshSummons: true } : {}
|
|
33064
33080
|
};
|
|
33065
33081
|
}
|
|
33066
33082
|
function cliResultFromRoleRun(result2) {
|
|
@@ -33547,8 +33563,8 @@ async function runAkRole(argv, env) {
|
|
|
33547
33563
|
packageRoot: await realpath6(env.packageRoot),
|
|
33548
33564
|
principalAuthority: env.principalAuthority ?? piDurablePrincipalAuthority
|
|
33549
33565
|
};
|
|
33550
|
-
|
|
33551
|
-
const acceptsSeatAxes = parsed.command !== void 0 && (isPublicCallableRole(parsed.command) || parsed.command === "resume");
|
|
33566
|
+
let parsed = parseArgv(argv);
|
|
33567
|
+
const acceptsSeatAxes = parsed.command !== void 0 && (isPublicCallableRole(parsed.command) || parsed.command === "resume" || parsed.command === "new");
|
|
33552
33568
|
if (parsed.host !== void 0 && !parsed.help && parsed.command !== void 0 && parsed.command !== "help" && !acceptsSeatAxes) {
|
|
33553
33569
|
throw new CliUsageError(`host axis is role commands only; refused command ${parsed.command}`);
|
|
33554
33570
|
}
|
|
@@ -33593,6 +33609,21 @@ async function runAkRole(argv, env) {
|
|
|
33593
33609
|
exitCode: await runConfigCommand(parsed.args, home, env.packageRoot, io)
|
|
33594
33610
|
};
|
|
33595
33611
|
}
|
|
33612
|
+
if (parsed.command === "new") {
|
|
33613
|
+
const role = parsed.args[0];
|
|
33614
|
+
if (role === void 0) {
|
|
33615
|
+
throw new CliUsageError("usage: ak-role new <role> \u2026");
|
|
33616
|
+
}
|
|
33617
|
+
if (!isPublicCallableRole(role)) {
|
|
33618
|
+
throw new CliUsageError(`usage: ak-role new <role> \u2026; unknown role: ${role}`);
|
|
33619
|
+
}
|
|
33620
|
+
parsed = {
|
|
33621
|
+
...parsed,
|
|
33622
|
+
command: role,
|
|
33623
|
+
args: parsed.args.slice(1)
|
|
33624
|
+
};
|
|
33625
|
+
env = { ...env, freshSummons: true };
|
|
33626
|
+
}
|
|
33596
33627
|
if (parsed.command === "resume") {
|
|
33597
33628
|
const agentDir = resolveAgentDir(env, home);
|
|
33598
33629
|
const cwd = env.cwd ?? process.cwd();
|
|
@@ -33622,7 +33653,7 @@ async function runAkRole(argv, env) {
|
|
|
33622
33653
|
);
|
|
33623
33654
|
return cliResultFromRoleRun(result2);
|
|
33624
33655
|
}
|
|
33625
|
-
if (isPublicCliSupportCommand(parsed.command)) {
|
|
33656
|
+
if (parsed.command !== void 0 && isPublicCliSupportCommand(parsed.command)) {
|
|
33626
33657
|
throw new CliUsageError(`unhandled support command: ${parsed.command}`);
|
|
33627
33658
|
}
|
|
33628
33659
|
if (parsed.command === "judge") {
|
package/package.json
CHANGED
package/src/public-cli/cli.ts
CHANGED
|
@@ -294,6 +294,11 @@ export type CliEnv = {
|
|
|
294
294
|
/** Override Notary role-run timeout (tests). */
|
|
295
295
|
notaryTimeoutMs?: number;
|
|
296
296
|
createRunId?: () => string;
|
|
297
|
+
/**
|
|
298
|
+
* #724: set by the `new` support verb before role dispatch; seat runners
|
|
299
|
+
* skip same-ticket auto-resume. Not a public flag — the verb is the choice.
|
|
300
|
+
*/
|
|
301
|
+
freshSummons?: true;
|
|
297
302
|
};
|
|
298
303
|
|
|
299
304
|
/** Compose the Pi turn host for one role dispatch (sole public-cli → pi contact). */
|
|
@@ -437,6 +442,7 @@ function createRoleEnvironment(
|
|
|
437
442
|
...(options.config?.autoResumeLimit === undefined
|
|
438
443
|
? {}
|
|
439
444
|
: { autoResumeLimit: options.config.autoResumeLimit }),
|
|
445
|
+
...(env.freshSummons === true ? { freshSummons: true as const } : {}),
|
|
440
446
|
};
|
|
441
447
|
}
|
|
442
448
|
|
|
@@ -1084,12 +1090,14 @@ export async function runAkRole(
|
|
|
1084
1090
|
packageRoot: await realpath(env.packageRoot),
|
|
1085
1091
|
principalAuthority: env.principalAuthority ?? piDurablePrincipalAuthority,
|
|
1086
1092
|
};
|
|
1087
|
-
|
|
1088
|
-
// Host/engine axes: callable roles + resume (#617 DK-3
|
|
1093
|
+
let parsed = parseArgv(argv);
|
|
1094
|
+
// Host/engine axes: callable roles + resume + new (#617 DK-3; #724 new shares seat axes).
|
|
1089
1095
|
// Support commands (roles/config/…) still refuse both flags.
|
|
1090
1096
|
const acceptsSeatAxes =
|
|
1091
1097
|
parsed.command !== undefined &&
|
|
1092
|
-
(isPublicCallableRole(parsed.command) ||
|
|
1098
|
+
(isPublicCallableRole(parsed.command) ||
|
|
1099
|
+
parsed.command === "resume" ||
|
|
1100
|
+
parsed.command === "new");
|
|
1093
1101
|
if (
|
|
1094
1102
|
parsed.host !== undefined &&
|
|
1095
1103
|
!parsed.help &&
|
|
@@ -1160,6 +1168,24 @@ export async function runAkRole(
|
|
|
1160
1168
|
};
|
|
1161
1169
|
}
|
|
1162
1170
|
|
|
1171
|
+
// #724 explicit fresh summons: `ak-role new <role> …` — same role argv, always mint.
|
|
1172
|
+
// Rewrites onto the role command with freshSummons; auto-resume and resume stay intact.
|
|
1173
|
+
if (parsed.command === "new") {
|
|
1174
|
+
const role = parsed.args[0];
|
|
1175
|
+
if (role === undefined) {
|
|
1176
|
+
throw new CliUsageError("usage: ak-role new <role> …");
|
|
1177
|
+
}
|
|
1178
|
+
if (!isPublicCallableRole(role)) {
|
|
1179
|
+
throw new CliUsageError(`usage: ak-role new <role> …; unknown role: ${role}`);
|
|
1180
|
+
}
|
|
1181
|
+
parsed = {
|
|
1182
|
+
...parsed,
|
|
1183
|
+
command: role,
|
|
1184
|
+
args: parsed.args.slice(1),
|
|
1185
|
+
};
|
|
1186
|
+
env = { ...env, freshSummons: true };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1163
1189
|
// Resume reopens an exact Role run (#416): caller decides; session principal
|
|
1164
1190
|
// must still exist. Seat and dispatch follow the durable admitted role.
|
|
1165
1191
|
// #471: unique parser owns {runId, message?}; five role paths only consume it.
|
|
@@ -1202,7 +1228,10 @@ export async function runAkRole(
|
|
|
1202
1228
|
return cliResultFromRoleRun(result);
|
|
1203
1229
|
}
|
|
1204
1230
|
|
|
1205
|
-
if (
|
|
1231
|
+
if (
|
|
1232
|
+
parsed.command !== undefined &&
|
|
1233
|
+
isPublicCliSupportCommand(parsed.command)
|
|
1234
|
+
) {
|
|
1206
1235
|
throw new CliUsageError(`unhandled support command: ${parsed.command}`);
|
|
1207
1236
|
}
|
|
1208
1237
|
|
|
@@ -1271,6 +1271,17 @@ const SUPPORT_COMMAND_HELP = {
|
|
|
1271
1271
|
"ak-role --engine agy resume 01abc…",
|
|
1272
1272
|
],
|
|
1273
1273
|
},
|
|
1274
|
+
new: {
|
|
1275
|
+
command: "new",
|
|
1276
|
+
summary:
|
|
1277
|
+
"Explicit fresh summons: same role options as a direct call, but always mint a new run (skip same-ticket auto-resume). Caller chooses new vs resume; no overflow judgment.",
|
|
1278
|
+
usage: ["ak-role new <role> [options] …"],
|
|
1279
|
+
examples: [
|
|
1280
|
+
'ak-role new countersign --attach ./ticket.md "裁:本票 #708 是否足以开工。"',
|
|
1281
|
+
"ak-role new notary --source-run 01abc…@countersign",
|
|
1282
|
+
"ak-role --host grok-build new inspector --attach ./change.patch",
|
|
1283
|
+
],
|
|
1284
|
+
},
|
|
1274
1285
|
} as const satisfies Record<string, PublicCommandHelpFacts>;
|
|
1275
1286
|
|
|
1276
1287
|
/**
|
|
@@ -110,6 +110,11 @@ export type PostAdmissionEnv = {
|
|
|
110
110
|
sessionAppender: SessionCustomEntryAppender;
|
|
111
111
|
autoResumeLimit?: number;
|
|
112
112
|
createRunId?: () => string;
|
|
113
|
+
/**
|
|
114
|
+
* #724 explicit fresh summons (`ak-role new <role>`): skip same-ticket auto-resume
|
|
115
|
+
* and mint a new run. Absent on ordinary role commands and on `ak-role resume`.
|
|
116
|
+
*/
|
|
117
|
+
freshSummons?: true;
|
|
113
118
|
};
|
|
114
119
|
|
|
115
120
|
/**
|
|
@@ -149,22 +149,26 @@ export async function resolveSeatTicketBinding(
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
|
-
*
|
|
152
|
+
* Sole same-ticket → resume decision (#637 / #724).
|
|
153
153
|
* Looks up the latest retained run for seat+ticket; when found, runs resume with
|
|
154
154
|
* this summons' materials. Lookup/resume failures propagate (失败诚实) — never
|
|
155
|
-
* wash into a fresh mint. Returns undefined
|
|
155
|
+
* wash into a fresh mint. Returns undefined when the caller declared an explicit
|
|
156
|
+
* fresh summons (`ak-role new`) or when no prior run exists; both mint new.
|
|
157
|
+
* freshSummons is required so no seat can drift back into its own skip branch.
|
|
156
158
|
*/
|
|
157
159
|
export async function tryResumeSameTicketSeatRun<T>(input: {
|
|
158
160
|
readonly home: string;
|
|
159
161
|
readonly projectRoot: string;
|
|
160
162
|
readonly role: RoleRunRecord["role"];
|
|
161
163
|
readonly ticketNumber: number;
|
|
164
|
+
readonly freshSummons: true | undefined;
|
|
162
165
|
readonly summons?: SameTicketSummonsMaterials;
|
|
163
166
|
readonly resume: (
|
|
164
167
|
runId: string,
|
|
165
168
|
summons: SameTicketSummonsMaterials | undefined,
|
|
166
169
|
) => Promise<T>;
|
|
167
170
|
}): Promise<T | undefined> {
|
|
171
|
+
if (input.freshSummons === true) return undefined;
|
|
168
172
|
const previousRunId = await findLatestRunIdForSeatTicket({
|
|
169
173
|
home: input.home,
|
|
170
174
|
bookKey: resolveBookKeyFromGit(input.projectRoot),
|