halfcycle 0.4.13 → 0.4.14
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-plugin/plugin.json +1 -1
- package/bin/bin.bundle.mjs +4105 -369
- package/bin/pre-tool-use-filter.sh +93 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +0 -0
- package/dist/build-record/pair-io.d.ts +49 -0
- package/dist/build-record/pair-io.d.ts.map +1 -0
- package/dist/build-record/render-change.d.ts +25 -0
- package/dist/build-record/render-change.d.ts.map +1 -0
- package/dist/build-record/render-v2.d.ts +10 -5
- package/dist/build-record/render-v2.d.ts.map +1 -1
- package/dist/build-record/write-change.d.ts +63 -0
- package/dist/build-record/write-change.d.ts.map +1 -0
- package/dist/build-record/write.d.ts +5 -15
- package/dist/build-record/write.d.ts.map +1 -1
- package/dist/change.d.ts +136 -0
- package/dist/change.d.ts.map +1 -0
- package/dist/check-tasks.d.ts +71 -0
- package/dist/check-tasks.d.ts.map +1 -0
- package/dist/claude-plan.d.ts +114 -0
- package/dist/claude-plan.d.ts.map +1 -0
- package/dist/cli-contract.d.ts +12 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +5192 -2132
- package/dist/cli.js.map +3 -3
- package/dist/close-phase.d.ts +53 -1
- package/dist/close-phase.d.ts.map +1 -1
- package/dist/index.js +1529 -911
- package/dist/index.js.map +3 -3
- package/dist/install-manifest.d.ts +11 -1
- package/dist/install-manifest.d.ts.map +1 -1
- package/dist/install.d.ts +58 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/merge-settings.d.ts +21 -2
- package/dist/merge-settings.d.ts.map +1 -1
- package/dist/open-phase.d.ts +1 -1
- package/dist/open-phase.d.ts.map +1 -1
- package/dist/pace.d.ts +138 -0
- package/dist/pace.d.ts.map +1 -0
- package/dist/phase-work.d.ts +37 -0
- package/dist/phase-work.d.ts.map +1 -0
- package/dist/plan.d.ts +5 -2
- package/dist/plan.d.ts.map +1 -1
- package/dist/prove.d.ts +77 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/review.d.ts +19 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/system-report.d.ts +1 -1
- package/dist/system-report.d.ts.map +1 -1
- package/dist/uninstall.d.ts.map +1 -1
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3
3
|
import { createHash as createHash2 } from "node:crypto";
|
|
4
4
|
import { existsSync as existsSync3, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5
|
-
import {
|
|
5
|
+
import { homedir as homedir2 } from "node:os";
|
|
6
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join5, posix, relative, resolve } from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
|
|
8
9
|
// ../core/dist/guard-record.js
|
|
@@ -267,13 +268,69 @@ var REMOTE_FORMS = [
|
|
|
267
268
|
var SIGN_IN_COMMAND = '"npx halfcycle"';
|
|
268
269
|
var HOOK_REMEDY = `Run ${SIGN_IN_COMMAND} in the project folder to sign in.`;
|
|
269
270
|
|
|
270
|
-
// ../
|
|
271
|
+
// ../core/dist/task-plan.js
|
|
271
272
|
import { z as z2 } from "zod";
|
|
272
|
-
var
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
var TASK_PLAN_TASKS_MAX = 500;
|
|
274
|
+
var TASK_PLAN_ID_MAX = 64;
|
|
275
|
+
var TASK_PLAN_KINDS = ["build", "review", "spec", "walk", "check"];
|
|
276
|
+
var CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/;
|
|
277
|
+
var planText = z2.string().refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" });
|
|
278
|
+
var taskIdSchema = z2.string().min(1).max(TASK_PLAN_ID_MAX).refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" });
|
|
279
|
+
var taskPlanTaskSchema = z2.object({
|
|
280
|
+
id: taskIdSchema,
|
|
281
|
+
kind: z2.enum(TASK_PLAN_KINDS),
|
|
282
|
+
dependsOn: z2.array(taskIdSchema).max(TASK_PLAN_TASKS_MAX),
|
|
283
|
+
reviews: taskIdSchema.optional(),
|
|
284
|
+
heldBy: z2.literal("person").optional(),
|
|
285
|
+
touches: z2.object({
|
|
286
|
+
files: z2.array(planText).optional(),
|
|
287
|
+
interfaces: z2.array(planText).optional()
|
|
288
|
+
}).strict().optional(),
|
|
289
|
+
wholeProject: z2.literal(true).optional(),
|
|
290
|
+
ships: z2.enum(["deploy", "release"]).optional()
|
|
291
|
+
}).strict().superRefine((task, ctx) => {
|
|
292
|
+
if (task.reviews !== void 0 && task.kind !== "review") {
|
|
293
|
+
ctx.addIssue({
|
|
294
|
+
code: "custom",
|
|
295
|
+
path: ["reviews"],
|
|
296
|
+
message: "only a review task names the task it reviews"
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (task.wholeProject !== void 0 && task.kind !== "check") {
|
|
300
|
+
ctx.addIssue({
|
|
301
|
+
code: "custom",
|
|
302
|
+
path: ["wholeProject"],
|
|
303
|
+
message: "only a check task is a whole-project check"
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if ((task.kind === "review" || task.kind === "check" || task.kind === "walk") && ((task.touches?.files?.length ?? 0) > 0 || (task.touches?.interfaces?.length ?? 0) > 0)) {
|
|
307
|
+
ctx.addIssue({
|
|
308
|
+
code: "custom",
|
|
309
|
+
path: ["touches"],
|
|
310
|
+
message: "a review, check or walk task touches nothing"
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
var taskPlanSchema = z2.object({
|
|
315
|
+
phase: z2.string().min(1).refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" }),
|
|
316
|
+
tasks: z2.array(taskPlanTaskSchema).max(TASK_PLAN_TASKS_MAX)
|
|
317
|
+
}).strict();
|
|
318
|
+
var taskListRowSchema = z2.object({
|
|
319
|
+
id: planText,
|
|
320
|
+
dependsOn: z2.array(planText)
|
|
321
|
+
}).loose();
|
|
322
|
+
var taskListFileSchema = z2.union([
|
|
323
|
+
z2.object({ phase: planText, tasks: z2.array(taskListRowSchema) }).loose(),
|
|
324
|
+
z2.array(z2.unknown())
|
|
325
|
+
]);
|
|
326
|
+
|
|
327
|
+
// ../events/dist/result.js
|
|
328
|
+
import { z as z3 } from "zod";
|
|
329
|
+
var firedGuardSchema = z3.object({
|
|
330
|
+
guardId: z3.string(),
|
|
331
|
+
patternRef: z3.string(),
|
|
275
332
|
severity: severitySchema,
|
|
276
|
-
explanation:
|
|
333
|
+
explanation: z3.string(),
|
|
277
334
|
/**
|
|
278
335
|
* The repo-relative path of the file this firing was decided on. The matcher
|
|
279
336
|
* has the file live at the moment it decides to fire; this is the field that
|
|
@@ -297,62 +354,62 @@ var firedGuardSchema = z2.object({
|
|
|
297
354
|
* safe-parse it and decide what to do with a refusal, rather than assume the
|
|
298
355
|
* two shapes agree.
|
|
299
356
|
*/
|
|
300
|
-
path:
|
|
357
|
+
path: z3.string().optional()
|
|
301
358
|
}).strict();
|
|
302
|
-
var notRunCheckSchema =
|
|
359
|
+
var notRunCheckSchema = z3.object({
|
|
303
360
|
/** Which check did not run, by the same reference a fired check carries. */
|
|
304
|
-
patternRef:
|
|
361
|
+
patternRef: z3.string(),
|
|
305
362
|
/**
|
|
306
363
|
* Why it could not run, in plain words — what this client did not send, or
|
|
307
364
|
* that the check's kind is not implemented yet. Never the check's own rule.
|
|
308
365
|
*/
|
|
309
|
-
reason:
|
|
366
|
+
reason: z3.string()
|
|
310
367
|
}).strict();
|
|
311
|
-
var resultEnvelopeSchema =
|
|
312
|
-
guardsFired:
|
|
368
|
+
var resultEnvelopeSchema = z3.object({
|
|
369
|
+
guardsFired: z3.array(firedGuardSchema),
|
|
313
370
|
severity: severitySchema.nullable(),
|
|
314
|
-
blocking:
|
|
315
|
-
explanation:
|
|
371
|
+
blocking: z3.boolean(),
|
|
372
|
+
explanation: z3.string(),
|
|
316
373
|
/**
|
|
317
374
|
* The checks that could not run on this edit, each named with the reason.
|
|
318
375
|
* Absent when every check ran — so an evaluation where nothing was skipped
|
|
319
376
|
* looks exactly as it always has, and an absent list is never an empty one.
|
|
320
377
|
*/
|
|
321
|
-
notRun:
|
|
378
|
+
notRun: z3.array(notRunCheckSchema).optional()
|
|
322
379
|
}).strict();
|
|
323
|
-
var wireErrorSchema =
|
|
324
|
-
statusCode:
|
|
325
|
-
error:
|
|
326
|
-
message:
|
|
380
|
+
var wireErrorSchema = z3.object({
|
|
381
|
+
statusCode: z3.number(),
|
|
382
|
+
error: z3.string(),
|
|
383
|
+
message: z3.string()
|
|
327
384
|
}).strict();
|
|
328
385
|
|
|
329
386
|
// ../events/dist/build-record.js
|
|
330
|
-
import { z as
|
|
387
|
+
import { z as z6 } from "zod";
|
|
331
388
|
|
|
332
389
|
// ../events/dist/state.js
|
|
333
|
-
import { z as
|
|
390
|
+
import { z as z5 } from "zod";
|
|
334
391
|
|
|
335
392
|
// ../events/dist/human-agent.js
|
|
336
|
-
import { z as
|
|
393
|
+
import { z as z4 } from "zod";
|
|
337
394
|
var HUMAN_AGENT = "Human";
|
|
338
395
|
var AGENT_NAME_MAX = 32;
|
|
339
|
-
var agentNameSchema =
|
|
396
|
+
var agentNameSchema = z4.string().min(1).max(AGENT_NAME_MAX);
|
|
340
397
|
|
|
341
398
|
// ../events/dist/state.js
|
|
342
|
-
var utcIso8601 =
|
|
399
|
+
var utcIso8601 = z5.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/, "must be a UTC ISO-8601 timestamp ending in Z");
|
|
343
400
|
var STATE_RECORD_FORMAT = "halfcycle-state-record/v1";
|
|
344
|
-
var stepIdSchema =
|
|
345
|
-
var methodVersionSchema =
|
|
401
|
+
var stepIdSchema = z5.string().regex(/^(l[0-5](-l[0-5])?|xl)\.[a-z0-9-]+$/);
|
|
402
|
+
var methodVersionSchema = z5.string().regex(RELEASE_VERSION_PATTERN);
|
|
346
403
|
var anchorPathRegex = /^(?!\/)(?!.*#)(?!method\/)(?!(.*\/)?docs\/method\/).+$/;
|
|
347
|
-
var recordKindSchema =
|
|
348
|
-
var methodLayerSchema =
|
|
404
|
+
var recordKindSchema = z5.enum(["artefact", "step-run", "gate", "intervention"]);
|
|
405
|
+
var methodLayerSchema = z5.enum(["l0", "l1", "l2", "l3", "l3-l4", "l4", "l5", "xl"]);
|
|
349
406
|
var PHASE_SCOPED_LAYERS = ["l4", "l5"];
|
|
350
407
|
function isPhaseScopedLayer(layer) {
|
|
351
408
|
return PHASE_SCOPED_LAYERS.includes(layer);
|
|
352
409
|
}
|
|
353
|
-
var evidenceKindSchema =
|
|
354
|
-
var declarableEvidenceKindSchema =
|
|
355
|
-
var dispositionSchema =
|
|
410
|
+
var evidenceKindSchema = z5.enum(["anchor", "diff", "repro", "question-answer", "no-op"]);
|
|
411
|
+
var declarableEvidenceKindSchema = z5.enum(["anchor", "diff", "repro", "question-answer"]);
|
|
412
|
+
var dispositionSchema = z5.enum([
|
|
356
413
|
"prevented",
|
|
357
414
|
"corrected-in-spec",
|
|
358
415
|
"corrected-in-scope",
|
|
@@ -362,20 +419,20 @@ var dispositionSchema = z4.enum([
|
|
|
362
419
|
"surfaced",
|
|
363
420
|
"filed-forward"
|
|
364
421
|
]);
|
|
365
|
-
var mechanismSchema =
|
|
366
|
-
var artefactStateSchema =
|
|
422
|
+
var mechanismSchema = z5.enum(["guard", "verdict", "served-step", "method-step"]);
|
|
423
|
+
var artefactStateSchema = z5.enum(["created", "updated"]);
|
|
367
424
|
var QUALIFIED_OUTCOMES = ["declined", "parked"];
|
|
368
|
-
var qualifiedOutcomeSchema =
|
|
425
|
+
var qualifiedOutcomeSchema = z5.enum(QUALIFIED_OUTCOMES);
|
|
369
426
|
function isQualifiedOutcome(outcome) {
|
|
370
427
|
return QUALIFIED_OUTCOMES.includes(outcome);
|
|
371
428
|
}
|
|
372
|
-
var runOutcomeSchema =
|
|
429
|
+
var runOutcomeSchema = z5.enum([
|
|
373
430
|
"completed",
|
|
374
431
|
"attempted-failed",
|
|
375
432
|
...QUALIFIED_OUTCOMES
|
|
376
433
|
]);
|
|
377
|
-
var gateKindSchema =
|
|
378
|
-
var gateVerdictSchema =
|
|
434
|
+
var gateKindSchema = z5.enum(["approval", "mechanical"]);
|
|
435
|
+
var gateVerdictSchema = z5.enum(["pass", "fail", ...QUALIFIED_OUTCOMES]);
|
|
379
436
|
function outcomeReasonIssue(outcome, reason) {
|
|
380
437
|
if (isQualifiedOutcome(outcome) && reason === void 0) {
|
|
381
438
|
return { message: `outcomeReason is required when the outcome is '${outcome}'` };
|
|
@@ -387,47 +444,47 @@ function outcomeReasonIssue(outcome, reason) {
|
|
|
387
444
|
}
|
|
388
445
|
return null;
|
|
389
446
|
}
|
|
390
|
-
var anchorEvidenceSchema =
|
|
391
|
-
kind:
|
|
392
|
-
path:
|
|
447
|
+
var anchorEvidenceSchema = z5.object({
|
|
448
|
+
kind: z5.literal("anchor"),
|
|
449
|
+
path: z5.string().regex(anchorPathRegex),
|
|
393
450
|
// Optional 1-based line number within the file at `path`. Present when the
|
|
394
451
|
// writer knows the exact line; omitted — never `0`, never `null` — when it
|
|
395
452
|
// does not, because a line number is not always obtainable. Absence is a
|
|
396
453
|
// valid, permanent state here, not a gap meant to be filled in later.
|
|
397
|
-
line:
|
|
454
|
+
line: z5.number().optional()
|
|
398
455
|
}).strict();
|
|
399
|
-
var diffEvidenceSchema =
|
|
400
|
-
kind:
|
|
401
|
-
ref:
|
|
456
|
+
var diffEvidenceSchema = z5.object({
|
|
457
|
+
kind: z5.literal("diff"),
|
|
458
|
+
ref: z5.string()
|
|
402
459
|
}).strict();
|
|
403
|
-
var reproEvidenceSchema =
|
|
404
|
-
kind:
|
|
405
|
-
steps:
|
|
460
|
+
var reproEvidenceSchema = z5.object({
|
|
461
|
+
kind: z5.literal("repro"),
|
|
462
|
+
steps: z5.string().max(2e3)
|
|
406
463
|
}).strict();
|
|
407
|
-
var questionAnswerEvidenceSchema =
|
|
408
|
-
kind:
|
|
409
|
-
question:
|
|
410
|
-
before:
|
|
411
|
-
after:
|
|
464
|
+
var questionAnswerEvidenceSchema = z5.object({
|
|
465
|
+
kind: z5.literal("question-answer"),
|
|
466
|
+
question: z5.string().max(2e3),
|
|
467
|
+
before: z5.string().max(2e3),
|
|
468
|
+
after: z5.string().max(2e3)
|
|
412
469
|
}).strict();
|
|
413
|
-
var noOpEvidenceSchema =
|
|
414
|
-
kind:
|
|
415
|
-
inspected:
|
|
416
|
-
unchangedBecause:
|
|
470
|
+
var noOpEvidenceSchema = z5.object({
|
|
471
|
+
kind: z5.literal("no-op"),
|
|
472
|
+
inspected: z5.string().max(2e3),
|
|
473
|
+
unchangedBecause: z5.string().max(2e3)
|
|
417
474
|
}).strict();
|
|
418
|
-
var evidenceSchema =
|
|
475
|
+
var evidenceSchema = z5.discriminatedUnion("kind", [
|
|
419
476
|
anchorEvidenceSchema,
|
|
420
477
|
diffEvidenceSchema,
|
|
421
478
|
reproEvidenceSchema,
|
|
422
479
|
questionAnswerEvidenceSchema,
|
|
423
480
|
noOpEvidenceSchema
|
|
424
481
|
]);
|
|
425
|
-
var stateRecordEnvelopeSchema =
|
|
426
|
-
format:
|
|
482
|
+
var stateRecordEnvelopeSchema = z5.object({
|
|
483
|
+
format: z5.literal(STATE_RECORD_FORMAT),
|
|
427
484
|
recordKind: recordKindSchema,
|
|
428
|
-
recordId:
|
|
485
|
+
recordId: z5.string().uuid(),
|
|
429
486
|
methodVersion: methodVersionSchema,
|
|
430
|
-
engagementId:
|
|
487
|
+
engagementId: z5.string(),
|
|
431
488
|
stepId: stepIdSchema,
|
|
432
489
|
// Immutable: names when the thing happened, never when a later disposition
|
|
433
490
|
// moved.
|
|
@@ -443,38 +500,38 @@ var stateRecordEnvelopeSchema = z4.object({
|
|
|
443
500
|
// for the whole project rather than per phase. Absence is meaningful on its
|
|
444
501
|
// own — it is never replaced with a placeholder value, and it is read as
|
|
445
502
|
// "satisfies any phase", not as "unknown".
|
|
446
|
-
phase:
|
|
503
|
+
phase: z5.string().optional()
|
|
447
504
|
});
|
|
448
|
-
var artefactRefSchema =
|
|
449
|
-
name:
|
|
450
|
-
parent:
|
|
505
|
+
var artefactRefSchema = z5.object({
|
|
506
|
+
name: z5.string(),
|
|
507
|
+
parent: z5.string()
|
|
451
508
|
}).strict();
|
|
452
|
-
var coverageSchema =
|
|
453
|
-
asked:
|
|
454
|
-
answered:
|
|
509
|
+
var coverageSchema = z5.object({
|
|
510
|
+
asked: z5.number().int().nonnegative(),
|
|
511
|
+
answered: z5.number().int().nonnegative()
|
|
455
512
|
}).strict().superRefine((coverage, ctx) => {
|
|
456
513
|
if (coverage.answered > coverage.asked) {
|
|
457
514
|
ctx.addIssue({
|
|
458
|
-
code:
|
|
515
|
+
code: z5.ZodIssueCode.custom,
|
|
459
516
|
path: ["answered"],
|
|
460
517
|
message: "answered cannot be more than asked"
|
|
461
518
|
});
|
|
462
519
|
}
|
|
463
520
|
});
|
|
464
|
-
var projectTierSchema =
|
|
521
|
+
var projectTierSchema = z5.number().int().min(0).max(3);
|
|
465
522
|
var artefactRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
466
|
-
recordKind:
|
|
523
|
+
recordKind: z5.literal("artefact"),
|
|
467
524
|
artefactRef: artefactRefSchema,
|
|
468
525
|
// Some layer wrote it, by construction — an empty array is not a legitimate
|
|
469
526
|
// state, so the schema says so.
|
|
470
|
-
writtenByLayers:
|
|
527
|
+
writtenByLayers: z5.array(methodLayerSchema).min(1),
|
|
471
528
|
state: artefactStateSchema
|
|
472
529
|
}).strict();
|
|
473
530
|
var stepRunRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
474
|
-
recordKind:
|
|
531
|
+
recordKind: z5.literal("step-run"),
|
|
475
532
|
runOutcome: runOutcomeSchema,
|
|
476
|
-
failureReason:
|
|
477
|
-
outcomeReason:
|
|
533
|
+
failureReason: z5.string().optional(),
|
|
534
|
+
outcomeReason: z5.string().max(2e3).optional(),
|
|
478
535
|
// Who did this step, as the session reported it. Absent when not reported.
|
|
479
536
|
agent: agentNameSchema.optional(),
|
|
480
537
|
// When the session began this step. Absent when not reported.
|
|
@@ -484,29 +541,29 @@ var stepRunRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
|
484
541
|
}).strict().superRefine((rec, ctx) => {
|
|
485
542
|
if (rec.runOutcome === "attempted-failed" && rec.failureReason === void 0) {
|
|
486
543
|
ctx.addIssue({
|
|
487
|
-
code:
|
|
544
|
+
code: z5.ZodIssueCode.custom,
|
|
488
545
|
path: ["failureReason"],
|
|
489
546
|
message: "failureReason is required when runOutcome is 'attempted-failed'"
|
|
490
547
|
});
|
|
491
548
|
}
|
|
492
549
|
if (rec.runOutcome !== "attempted-failed" && rec.failureReason !== void 0) {
|
|
493
550
|
ctx.addIssue({
|
|
494
|
-
code:
|
|
551
|
+
code: z5.ZodIssueCode.custom,
|
|
495
552
|
path: ["failureReason"],
|
|
496
553
|
message: "failureReason is only present when runOutcome is 'attempted-failed'"
|
|
497
554
|
});
|
|
498
555
|
}
|
|
499
556
|
const issue = outcomeReasonIssue(rec.runOutcome, rec.outcomeReason);
|
|
500
557
|
if (issue) {
|
|
501
|
-
ctx.addIssue({ code:
|
|
558
|
+
ctx.addIssue({ code: z5.ZodIssueCode.custom, path: ["outcomeReason"], ...issue });
|
|
502
559
|
}
|
|
503
560
|
});
|
|
504
561
|
var gateRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
505
|
-
recordKind:
|
|
562
|
+
recordKind: z5.literal("gate"),
|
|
506
563
|
gateKind: gateKindSchema,
|
|
507
564
|
verdict: gateVerdictSchema,
|
|
508
|
-
actor:
|
|
509
|
-
outcomeReason:
|
|
565
|
+
actor: z5.string(),
|
|
566
|
+
outcomeReason: z5.string().max(2e3).optional(),
|
|
510
567
|
coverage: coverageSchema.optional(),
|
|
511
568
|
// Who did the step this checkpoint is on, as reported. Absent when not reported.
|
|
512
569
|
agent: agentNameSchema.optional(),
|
|
@@ -516,21 +573,21 @@ var gateRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
|
516
573
|
}).strict().superRefine((rec, ctx) => {
|
|
517
574
|
const issue = outcomeReasonIssue(rec.verdict, rec.outcomeReason);
|
|
518
575
|
if (issue) {
|
|
519
|
-
ctx.addIssue({ code:
|
|
576
|
+
ctx.addIssue({ code: z5.ZodIssueCode.custom, path: ["outcomeReason"], ...issue });
|
|
520
577
|
}
|
|
521
578
|
});
|
|
522
579
|
var interventionRecordSchema = stateRecordEnvelopeSchema.extend({
|
|
523
|
-
recordKind:
|
|
580
|
+
recordKind: z5.literal("intervention"),
|
|
524
581
|
layer: methodLayerSchema,
|
|
525
582
|
mechanism: mechanismSchema,
|
|
526
583
|
severity: severitySchema,
|
|
527
584
|
disposition: dispositionSchema,
|
|
528
|
-
summary:
|
|
585
|
+
summary: z5.string().max(2e3),
|
|
529
586
|
coverage: coverageSchema.optional(),
|
|
530
587
|
// Who caught it, as the session reported. Absent when not reported.
|
|
531
588
|
agent: agentNameSchema.optional()
|
|
532
589
|
}).strict();
|
|
533
|
-
var stateRecordSchema =
|
|
590
|
+
var stateRecordSchema = z5.discriminatedUnion("recordKind", [
|
|
534
591
|
artefactRecordSchema,
|
|
535
592
|
stepRunRecordSchema,
|
|
536
593
|
gateRecordSchema,
|
|
@@ -539,9 +596,9 @@ var stateRecordSchema = z4.discriminatedUnion("recordKind", [
|
|
|
539
596
|
|
|
540
597
|
// ../events/dist/control-characters.js
|
|
541
598
|
var CONTROL_CHARACTER_CLASS = "\\p{Cc}";
|
|
542
|
-
var
|
|
599
|
+
var CONTROL_CHARACTER2 = new RegExp(CONTROL_CHARACTER_CLASS, "u");
|
|
543
600
|
function hasControlCharacter(text) {
|
|
544
|
-
return
|
|
601
|
+
return CONTROL_CHARACTER2.test(text);
|
|
545
602
|
}
|
|
546
603
|
|
|
547
604
|
// ../events/dist/phase-identity.js
|
|
@@ -632,16 +689,16 @@ var ACTOR_MAX = 200;
|
|
|
632
689
|
var FINDING_MAX = 500;
|
|
633
690
|
var FINDINGS_SHOWN_MAX = 50;
|
|
634
691
|
var PHASE_CLOSE_REASON_MAX = 1900;
|
|
635
|
-
var closeCommitSchema =
|
|
636
|
-
var walkVerdictSchema =
|
|
637
|
-
var acceptanceOutcomeSchema =
|
|
692
|
+
var closeCommitSchema = z6.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/, "must be a full commit hash: 40 or 64 lowercase hex characters");
|
|
693
|
+
var walkVerdictSchema = z6.enum(["clean", "defects"]);
|
|
694
|
+
var acceptanceOutcomeSchema = z6.object({
|
|
638
695
|
verdict: walkVerdictSchema,
|
|
639
|
-
findings:
|
|
640
|
-
findingsDetail:
|
|
696
|
+
findings: z6.number().int().nonnegative(),
|
|
697
|
+
findingsDetail: z6.array(z6.object({ summary: z6.string().refine((v) => !hasLoneSurrogate(v), { message: LONE_SURROGATE_MESSAGE }) }).strict())
|
|
641
698
|
}).strict();
|
|
642
|
-
var closeDecisionSchema =
|
|
699
|
+
var closeDecisionSchema = z6.enum(["done-when-met", "override"]);
|
|
643
700
|
function plainText(max) {
|
|
644
|
-
const base = max === void 0 ?
|
|
701
|
+
const base = max === void 0 ? z6.string() : z6.string().max(max);
|
|
645
702
|
return base.refine((v) => !hasControlCharacter(v), {
|
|
646
703
|
message: "must be one line with no control characters (no line breaks, tabs or NUL)"
|
|
647
704
|
}).refine((v) => !hasLoneSurrogate(v), { message: LONE_SURROGATE_MESSAGE });
|
|
@@ -653,81 +710,81 @@ function statementText(max) {
|
|
|
653
710
|
}
|
|
654
711
|
var closeActorSchema = plainText(ACTOR_MAX);
|
|
655
712
|
var PHASE_NAME_RULE = `must be a phase name: not empty, no slash or backslash, not starting with a dot, no control characters, at most ${PHASE_NAME_MAX_BYTES} bytes`;
|
|
656
|
-
var phaseNameSchema =
|
|
713
|
+
var phaseNameSchema = z6.string().refine((v) => isValidPhaseIdentity(v), {
|
|
657
714
|
message: PHASE_NAME_RULE
|
|
658
715
|
});
|
|
659
|
-
var phaseIdentitySchema =
|
|
660
|
-
var closeStatementsSchema =
|
|
716
|
+
var phaseIdentitySchema = z6.union([z6.string(), z6.number()], { error: "must be a phase name or a whole number" }).refine((v) => isValidPhaseIdentity(v), { message: PHASE_NAME_RULE });
|
|
717
|
+
var closeStatementsSchema = z6.object({
|
|
661
718
|
thesis: statementText(STATEMENT_MAX).nullable(),
|
|
662
719
|
outcome: statementText(STATEMENT_MAX).nullable(),
|
|
663
|
-
deviations:
|
|
720
|
+
deviations: z6.array(statementText(DEVIATION_MAX)).max(DEVIATIONS_MAX),
|
|
664
721
|
closeCommit: closeCommitSchema.nullable()
|
|
665
722
|
}).strict();
|
|
666
|
-
var closedBySchema =
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
723
|
+
var closedBySchema = z6.discriminatedUnion("kind", [
|
|
724
|
+
z6.object({ kind: z6.literal("account"), email: plainText().nullable() }).strict(),
|
|
725
|
+
z6.object({ kind: z6.literal("no-account") }).strict(),
|
|
726
|
+
z6.object({ kind: z6.literal("account-removed") }).strict(),
|
|
727
|
+
z6.object({ kind: z6.literal("not-recorded") }).strict()
|
|
671
728
|
]);
|
|
672
729
|
var STEP_NAME_MAX = 200;
|
|
673
730
|
var stepNameSchema = plainText(STEP_NAME_MAX).refine((v) => v.trim().length > 0, {
|
|
674
731
|
message: "must not be blank"
|
|
675
732
|
});
|
|
676
|
-
var unfinishedStepSchema =
|
|
733
|
+
var unfinishedStepSchema = z6.object({
|
|
677
734
|
stepId: plainText(),
|
|
678
|
-
state:
|
|
735
|
+
state: z6.enum(["parked", "failed"]),
|
|
679
736
|
name: stepNameSchema.optional()
|
|
680
737
|
}).strict();
|
|
681
|
-
var crossedSchema =
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
738
|
+
var crossedSchema = z6.discriminatedUnion("kind", [
|
|
739
|
+
z6.object({ kind: z6.literal("none") }).strict(),
|
|
740
|
+
z6.object({ kind: z6.literal("unfinished-steps"), steps: z6.array(unfinishedStepSchema).min(1) }).strict(),
|
|
741
|
+
z6.object({ kind: z6.literal("clean-over-findings"), findings: z6.number().int().min(1) }).strict(),
|
|
742
|
+
z6.object({ kind: z6.literal("not-recorded") }).strict()
|
|
686
743
|
]);
|
|
687
|
-
var seatCoverageSchema =
|
|
688
|
-
enrolled:
|
|
689
|
-
conformant:
|
|
744
|
+
var seatCoverageSchema = z6.object({
|
|
745
|
+
enrolled: z6.number().int().nonnegative(),
|
|
746
|
+
conformant: z6.number().int().nonnegative()
|
|
690
747
|
}).strict().refine((c) => c.conformant <= c.enrolled, {
|
|
691
748
|
message: "conformant cannot exceed enrolled",
|
|
692
749
|
path: ["conformant"]
|
|
693
750
|
});
|
|
694
|
-
var observedCloseSchema =
|
|
695
|
-
sequence:
|
|
751
|
+
var observedCloseSchema = z6.object({
|
|
752
|
+
sequence: z6.number().int().min(1),
|
|
696
753
|
closedAt: utcIso8601,
|
|
697
754
|
closedBy: closedBySchema,
|
|
698
755
|
crossed: crossedSchema,
|
|
699
756
|
seatCoverage: seatCoverageSchema.nullable()
|
|
700
757
|
}).strict();
|
|
701
|
-
var couldNotRunCheckSchema =
|
|
758
|
+
var couldNotRunCheckSchema = z6.object({
|
|
702
759
|
check: plainText(),
|
|
703
760
|
description: plainText().nullable(),
|
|
704
761
|
reason: plainText()
|
|
705
762
|
}).strict();
|
|
706
|
-
var firedCheckSchema =
|
|
763
|
+
var firedCheckSchema = z6.object({
|
|
707
764
|
check: plainText(),
|
|
708
765
|
description: plainText().nullable(),
|
|
709
766
|
severity: severitySchema,
|
|
710
767
|
explanation: plainText().nullable(),
|
|
711
|
-
occurrences:
|
|
768
|
+
occurrences: z6.number().int().min(1)
|
|
712
769
|
}).strict();
|
|
713
|
-
var phaseChecksSchema =
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
state:
|
|
717
|
-
runs:
|
|
718
|
-
couldNotRun:
|
|
770
|
+
var phaseChecksSchema = z6.discriminatedUnion("state", [
|
|
771
|
+
z6.object({ state: z6.literal("not-observed") }).strict(),
|
|
772
|
+
z6.object({
|
|
773
|
+
state: z6.literal("nothing-fired"),
|
|
774
|
+
runs: z6.number().int().min(1),
|
|
775
|
+
couldNotRun: z6.array(couldNotRunCheckSchema)
|
|
719
776
|
}).strict(),
|
|
720
|
-
|
|
721
|
-
state:
|
|
722
|
-
runs:
|
|
723
|
-
couldNotRun:
|
|
724
|
-
fired:
|
|
777
|
+
z6.object({
|
|
778
|
+
state: z6.literal("fired"),
|
|
779
|
+
runs: z6.number().int().min(1),
|
|
780
|
+
couldNotRun: z6.array(couldNotRunCheckSchema),
|
|
781
|
+
fired: z6.array(firedCheckSchema).min(1)
|
|
725
782
|
}).strict()
|
|
726
783
|
]);
|
|
727
|
-
var observedSchema =
|
|
784
|
+
var observedSchema = z6.object({
|
|
728
785
|
engagementId: plainText(),
|
|
729
786
|
methodVersion: methodVersionSchema,
|
|
730
|
-
closes:
|
|
787
|
+
closes: z6.array(observedCloseSchema).min(1),
|
|
731
788
|
checks: phaseChecksSchema
|
|
732
789
|
}).strict().superRefine((o, ctx) => {
|
|
733
790
|
o.closes.forEach((close, i) => {
|
|
@@ -740,18 +797,18 @@ var observedSchema = z5.object({
|
|
|
740
797
|
}
|
|
741
798
|
});
|
|
742
799
|
});
|
|
743
|
-
var attestedWalkSchema =
|
|
800
|
+
var attestedWalkSchema = z6.object({
|
|
744
801
|
verdict: walkVerdictSchema,
|
|
745
|
-
findings:
|
|
746
|
-
findingsNotShown:
|
|
802
|
+
findings: z6.array(plainText(FINDING_MAX)).max(FINDINGS_SHOWN_MAX),
|
|
803
|
+
findingsNotShown: z6.number().int().nonnegative()
|
|
747
804
|
}).strict();
|
|
748
|
-
var attestedStatementsSchema =
|
|
805
|
+
var attestedStatementsSchema = z6.object({
|
|
749
806
|
thesis: plainText(STATEMENT_MAX).nullable(),
|
|
750
807
|
outcome: plainText(STATEMENT_MAX).nullable(),
|
|
751
|
-
deviations:
|
|
808
|
+
deviations: z6.array(plainText(DEVIATION_MAX)).max(DEVIATIONS_MAX)
|
|
752
809
|
}).strict();
|
|
753
|
-
var attestedCloseSchema =
|
|
754
|
-
sequence:
|
|
810
|
+
var attestedCloseSchema = z6.object({
|
|
811
|
+
sequence: z6.number().int().min(1),
|
|
755
812
|
decision: closeDecisionSchema,
|
|
756
813
|
actor: plainText(ACTOR_MAX).nullable(),
|
|
757
814
|
reason: plainText(PHASE_CLOSE_REASON_MAX).nullable(),
|
|
@@ -759,8 +816,8 @@ var attestedCloseSchema = z5.object({
|
|
|
759
816
|
closeCommit: closeCommitSchema.nullable(),
|
|
760
817
|
statements: attestedStatementsSchema
|
|
761
818
|
}).strict();
|
|
762
|
-
var attestedSchema =
|
|
763
|
-
closes:
|
|
819
|
+
var attestedSchema = z6.object({
|
|
820
|
+
closes: z6.array(attestedCloseSchema)
|
|
764
821
|
}).strict();
|
|
765
822
|
function checkRecordHalves(record2, ctx) {
|
|
766
823
|
const observedBySequence = new Map(record2.observed.closes.map((c) => [c.sequence, c]));
|
|
@@ -791,18 +848,18 @@ function checkRecordHalves(record2, ctx) {
|
|
|
791
848
|
}
|
|
792
849
|
});
|
|
793
850
|
}
|
|
794
|
-
var buildRecordV2Schema =
|
|
795
|
-
format:
|
|
851
|
+
var buildRecordV2Schema = z6.object({
|
|
852
|
+
format: z6.literal(BUILD_RECORD_V2_FORMAT),
|
|
796
853
|
phase: phaseNameSchema,
|
|
797
854
|
observed: observedSchema,
|
|
798
855
|
attested: attestedSchema
|
|
799
856
|
}).strict().superRefine(checkRecordHalves);
|
|
800
857
|
|
|
801
858
|
// ../events/dist/build-snapshot.js
|
|
802
|
-
import { z as
|
|
859
|
+
import { z as z8 } from "zod";
|
|
803
860
|
|
|
804
861
|
// ../events/dist/system-description.js
|
|
805
|
-
import { z as
|
|
862
|
+
import { z as z7 } from "zod";
|
|
806
863
|
var SYSTEM_DESCRIPTION_FORMAT = 1;
|
|
807
864
|
var SYSTEM_PARTS_MAX = 60;
|
|
808
865
|
var SYSTEM_CONNECTIONS_MAX = 400;
|
|
@@ -814,11 +871,11 @@ var SYSTEM_PART_DESCRIPTION_MAX = 160;
|
|
|
814
871
|
var SYSTEM_CONNECTION_LABEL_MAX = 60;
|
|
815
872
|
var SYSTEM_PART_ID_PATTERN = /^[a-z][a-z0-9-]{0,39}$/;
|
|
816
873
|
var SYSTEM_LANES = ["clients", "edge", "services", "data", "external"];
|
|
817
|
-
var systemLaneSchema =
|
|
874
|
+
var systemLaneSchema = z7.enum(SYSTEM_LANES, {
|
|
818
875
|
error: `must be one of ${SYSTEM_LANES.join(", ")}`
|
|
819
876
|
});
|
|
820
877
|
var SYSTEM_CONNECTION_KINDS = ["call", "event", "write", "external"];
|
|
821
|
-
var systemConnectionKindSchema =
|
|
878
|
+
var systemConnectionKindSchema = z7.enum(SYSTEM_CONNECTION_KINDS, {
|
|
822
879
|
error: `must be one of ${SYSTEM_CONNECTION_KINDS.join(", ")}`
|
|
823
880
|
});
|
|
824
881
|
var LINE_SEPARATOR = /[\u2028\u2029]/;
|
|
@@ -827,7 +884,7 @@ function descriptionText(max) {
|
|
|
827
884
|
message: "must be one line: it holds a line or paragraph separator"
|
|
828
885
|
});
|
|
829
886
|
}
|
|
830
|
-
var systemPartIdSchema =
|
|
887
|
+
var systemPartIdSchema = z7.string().regex(SYSTEM_PART_ID_PATTERN, {
|
|
831
888
|
message: "must be a short id: a lowercase letter, then lowercase letters, digits or hyphens, 40 characters at most"
|
|
832
889
|
}).refine((v) => !looksLikeSecret(v), { message: "looks like a password or key; choose another id" });
|
|
833
890
|
function hasEmptySegment(pattern) {
|
|
@@ -843,50 +900,50 @@ var SEGMENT_CHARACTERS = /^[A-Za-z0-9._\-*]*$/;
|
|
|
843
900
|
function hasForeignCharacter(pattern) {
|
|
844
901
|
return pattern.split("/").some((segment) => !SEGMENT_CHARACTERS.test(segment));
|
|
845
902
|
}
|
|
846
|
-
var systemOwnedPatternSchema =
|
|
903
|
+
var systemOwnedPatternSchema = z7.string().max(SYSTEM_OWNED_PATTERN_MAX, { message: `must be at most ${SYSTEM_OWNED_PATTERN_MAX} characters` }).refine((v) => !hasEmptySegment(v), {
|
|
847
904
|
message: "must not start or end with a slash, or have two slashes together"
|
|
848
905
|
}).refine((v) => !hasDotSegment(v), { message: 'must not have a "." or ".." folder in it' }).refine((v) => !hasPartialDoubleStar(v), { message: '"**" must stand alone between slashes' }).refine((v) => !hasForeignCharacter(v), {
|
|
849
906
|
message: 'may use only letters, digits, ".", "_", "-" and "*" between slashes'
|
|
850
907
|
}).refine((v) => !looksLikeSecret(v), {
|
|
851
908
|
message: "this path looks like a credential; list a shorter folder above it"
|
|
852
909
|
});
|
|
853
|
-
var systemPartSchema =
|
|
910
|
+
var systemPartSchema = z7.object({
|
|
854
911
|
id: systemPartIdSchema,
|
|
855
912
|
name: descriptionText(SYSTEM_PART_NAME_MAX),
|
|
856
913
|
description: descriptionText(SYSTEM_PART_DESCRIPTION_MAX),
|
|
857
914
|
lane: systemLaneSchema,
|
|
858
|
-
slot:
|
|
859
|
-
outside:
|
|
860
|
-
owns:
|
|
915
|
+
slot: z7.number({ error: `must be a whole number from 0 to ${SYSTEM_SLOT_MAX}` }).int({ error: `must be a whole number from 0 to ${SYSTEM_SLOT_MAX}` }).min(0, { error: `must be a whole number from 0 to ${SYSTEM_SLOT_MAX}` }).max(SYSTEM_SLOT_MAX, { error: `must be a whole number from 0 to ${SYSTEM_SLOT_MAX}` }),
|
|
916
|
+
outside: z7.boolean(),
|
|
917
|
+
owns: z7.array(systemOwnedPatternSchema).max(SYSTEM_OWNS_MAX, { message: `can list at most ${SYSTEM_OWNS_MAX} paths` })
|
|
861
918
|
}).strict();
|
|
862
|
-
var systemConnectionSchema =
|
|
919
|
+
var systemConnectionSchema = z7.object({
|
|
863
920
|
from: systemPartIdSchema,
|
|
864
921
|
to: systemPartIdSchema,
|
|
865
922
|
kind: systemConnectionKindSchema,
|
|
866
923
|
label: descriptionText(SYSTEM_CONNECTION_LABEL_MAX)
|
|
867
924
|
}).strict();
|
|
868
|
-
var systemDescriptionSchema =
|
|
869
|
-
format:
|
|
870
|
-
parts:
|
|
871
|
-
connections:
|
|
925
|
+
var systemDescriptionSchema = z7.object({
|
|
926
|
+
format: z7.literal(SYSTEM_DESCRIPTION_FORMAT, { error: `must be ${SYSTEM_DESCRIPTION_FORMAT}` }),
|
|
927
|
+
parts: z7.array(systemPartSchema).min(1, { message: "must list at least one part" }).max(SYSTEM_PARTS_MAX, { message: `can hold at most ${SYSTEM_PARTS_MAX} parts (five lanes of twelve slots)` }),
|
|
928
|
+
connections: z7.array(systemConnectionSchema).max(SYSTEM_CONNECTIONS_MAX, { message: `can hold at most ${SYSTEM_CONNECTIONS_MAX} connections` })
|
|
872
929
|
}).strict();
|
|
873
|
-
var systemDescriptionProblemSchema =
|
|
874
|
-
path:
|
|
875
|
-
message:
|
|
930
|
+
var systemDescriptionProblemSchema = z7.object({
|
|
931
|
+
path: z7.string(),
|
|
932
|
+
message: z7.string()
|
|
876
933
|
}).strict();
|
|
877
|
-
var systemReportRecordedSchema =
|
|
878
|
-
outcome:
|
|
879
|
-
version:
|
|
934
|
+
var systemReportRecordedSchema = z7.object({
|
|
935
|
+
outcome: z7.literal("recorded"),
|
|
936
|
+
version: z7.number().int().min(1),
|
|
880
937
|
reportedAt: utcIso8601
|
|
881
938
|
}).strict();
|
|
882
|
-
var systemReportRefusedSchema =
|
|
883
|
-
outcome:
|
|
884
|
-
problems:
|
|
939
|
+
var systemReportRefusedSchema = z7.object({
|
|
940
|
+
outcome: z7.literal("refused"),
|
|
941
|
+
problems: z7.array(systemDescriptionProblemSchema).min(1)
|
|
885
942
|
}).strict();
|
|
886
|
-
var systemReportUnavailableSchema =
|
|
887
|
-
outcome:
|
|
943
|
+
var systemReportUnavailableSchema = z7.object({
|
|
944
|
+
outcome: z7.literal("unavailable")
|
|
888
945
|
}).strict();
|
|
889
|
-
var systemReportResultSchema =
|
|
946
|
+
var systemReportResultSchema = z7.discriminatedUnion("outcome", [
|
|
890
947
|
systemReportRecordedSchema,
|
|
891
948
|
systemReportRefusedSchema,
|
|
892
949
|
systemReportUnavailableSchema
|
|
@@ -894,20 +951,20 @@ var systemReportResultSchema = z6.discriminatedUnion("outcome", [
|
|
|
894
951
|
var SYSTEM_DRAW_SVG_MAX_BYTES = 2 * 1024 * 1024;
|
|
895
952
|
var SYSTEM_DRAW_MERMAID_MAX_BYTES = 256 * 1024;
|
|
896
953
|
var SYSTEM_DRAW_PNG_MAX_BYTES = 8 * 1024 * 1024;
|
|
897
|
-
var systemDrawArchitectureRequestSchema =
|
|
898
|
-
picture:
|
|
899
|
-
version:
|
|
954
|
+
var systemDrawArchitectureRequestSchema = z7.object({
|
|
955
|
+
picture: z7.literal("architecture"),
|
|
956
|
+
version: z7.number().int().min(1)
|
|
900
957
|
}).strict();
|
|
901
|
-
var systemDrawPhaseRequestSchema =
|
|
902
|
-
picture:
|
|
958
|
+
var systemDrawPhaseRequestSchema = z7.object({
|
|
959
|
+
picture: z7.literal("phase"),
|
|
903
960
|
phase: phaseIdentitySchema,
|
|
904
|
-
planVersion:
|
|
961
|
+
planVersion: z7.number().int().min(1)
|
|
905
962
|
}).strict();
|
|
906
|
-
var systemDrawClosedPhaseRequestSchema =
|
|
907
|
-
picture:
|
|
963
|
+
var systemDrawClosedPhaseRequestSchema = z7.object({
|
|
964
|
+
picture: z7.literal("closed-phase"),
|
|
908
965
|
phase: phaseIdentitySchema
|
|
909
966
|
}).strict();
|
|
910
|
-
var systemDrawRequestSchema =
|
|
967
|
+
var systemDrawRequestSchema = z7.discriminatedUnion("picture", [
|
|
911
968
|
systemDrawArchitectureRequestSchema,
|
|
912
969
|
systemDrawPhaseRequestSchema,
|
|
913
970
|
systemDrawClosedPhaseRequestSchema
|
|
@@ -938,23 +995,23 @@ function base64DecodedLength(text) {
|
|
|
938
995
|
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
939
996
|
return text.length / 4 * 3 - padding;
|
|
940
997
|
}
|
|
941
|
-
var systemPictureSchema =
|
|
942
|
-
svg:
|
|
943
|
-
png:
|
|
998
|
+
var systemPictureSchema = z7.object({
|
|
999
|
+
svg: z7.string().min(1).refine((v) => utf8ByteLength2(v) <= SYSTEM_DRAW_SVG_MAX_BYTES, { message: "the picture is larger than 2 MB" }),
|
|
1000
|
+
png: z7.string().min(1).refine((v) => v.length % 4 === 0 && BASE64.test(v), { message: "the image is not valid base64" }).refine((v) => base64DecodedLength(v) <= SYSTEM_DRAW_PNG_MAX_BYTES, { message: "the image is larger than 8 MB" })
|
|
944
1001
|
}).strict();
|
|
945
|
-
var systemDrawRefusedSchema =
|
|
946
|
-
outcome:
|
|
947
|
-
reason:
|
|
1002
|
+
var systemDrawRefusedSchema = z7.object({
|
|
1003
|
+
outcome: z7.literal("refused"),
|
|
1004
|
+
reason: z7.string().min(1)
|
|
948
1005
|
}).strict();
|
|
949
|
-
var systemDrawUnavailableSchema =
|
|
950
|
-
outcome:
|
|
1006
|
+
var systemDrawUnavailableSchema = z7.object({
|
|
1007
|
+
outcome: z7.literal("unavailable")
|
|
951
1008
|
}).strict();
|
|
952
|
-
var systemDrawNotClosedSchema =
|
|
953
|
-
outcome:
|
|
1009
|
+
var systemDrawNotClosedSchema = z7.object({
|
|
1010
|
+
outcome: z7.literal("not-closed")
|
|
954
1011
|
}).strict();
|
|
955
1012
|
|
|
956
1013
|
// ../events/dist/build-snapshot.js
|
|
957
|
-
var buildTaskStateSchema =
|
|
1014
|
+
var buildTaskStateSchema = z8.enum([
|
|
958
1015
|
"pending",
|
|
959
1016
|
"in-flight",
|
|
960
1017
|
"completed",
|
|
@@ -967,27 +1024,27 @@ var BUILD_TASK_WHY_OUTSIDE_PLAN_MAX = 160;
|
|
|
967
1024
|
var BUILD_TASK_BUDGET_MAX_MINUTES = 10080;
|
|
968
1025
|
var BUILD_TASK_NOTE_MAX = 240;
|
|
969
1026
|
var BUILD_TASK_CLEAR_COMMAND_MAX = 240;
|
|
970
|
-
var buildTaskKindSchema =
|
|
971
|
-
var buildTaskIdSchema =
|
|
972
|
-
var buildTaskSchema =
|
|
1027
|
+
var buildTaskKindSchema = z8.enum(["build", "review", "spec", "walk", "check"]);
|
|
1028
|
+
var buildTaskIdSchema = z8.string().min(1).max(64);
|
|
1029
|
+
var buildTaskSchema = z8.object({
|
|
973
1030
|
// The task's own id, as the coordinator's graph names it.
|
|
974
1031
|
id: buildTaskIdSchema,
|
|
975
1032
|
// What the task is, in the coordinator's words. A description of the work,
|
|
976
1033
|
// bounded and scanned — never an excerpt of anybody's code.
|
|
977
|
-
title:
|
|
1034
|
+
title: z8.string().min(1).max(BUILD_TASK_TITLE_MAX),
|
|
978
1035
|
// What the task is doing right now.
|
|
979
1036
|
state: buildTaskStateSchema,
|
|
980
1037
|
// Who holds it — a bare callsign, or the value naming a person when the work is
|
|
981
1038
|
// a person's. Absent when nothing has been dispatched to it yet.
|
|
982
1039
|
agent: agentNameSchema.optional(),
|
|
983
1040
|
// The kind of work the holder does. Present exactly when an agent holds it.
|
|
984
|
-
discipline:
|
|
1041
|
+
discipline: z8.string().min(1).max(64).optional(),
|
|
985
1042
|
// How much thinking the holder brings. Present exactly when an agent holds it,
|
|
986
1043
|
// and there is no field naming the supplier behind it.
|
|
987
|
-
tier:
|
|
1044
|
+
tier: z8.string().min(1).max(32).optional(),
|
|
988
1045
|
// The tasks this one cannot start before. Always present; empty means it waits
|
|
989
1046
|
// on nothing, which is different from not having been computed.
|
|
990
|
-
dependsOn:
|
|
1047
|
+
dependsOn: z8.array(buildTaskIdSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
991
1048
|
// The one task this task checks, when it is a check on other work. Absent on a
|
|
992
1049
|
// task that is doing the work rather than checking it.
|
|
993
1050
|
reviews: buildTaskIdSchema.optional(),
|
|
@@ -1001,13 +1058,13 @@ var buildTaskSchema = z7.object({
|
|
|
1001
1058
|
settledAt: utcIso8601.optional(),
|
|
1002
1059
|
// The parts of this project's system the task builds, by their ids. Absent when
|
|
1003
1060
|
// it builds none; never an empty list.
|
|
1004
|
-
builds:
|
|
1061
|
+
builds: z8.array(systemPartIdSchema).min(1).max(SYSTEM_PARTS_MAX).optional(),
|
|
1005
1062
|
// In one line, why the task built a part the phase's plan does not include, in
|
|
1006
1063
|
// the words of whoever holds it. Absent when it gave no reason.
|
|
1007
1064
|
whyOutsidePlan: descriptionText(BUILD_TASK_WHY_OUTSIDE_PLAN_MAX).optional(),
|
|
1008
1065
|
// How long the task is expected to take, in whole minutes, from one minute to one
|
|
1009
1066
|
// week. A plan, not a measurement; absent when no budget was set.
|
|
1010
|
-
budgetMinutes:
|
|
1067
|
+
budgetMinutes: z8.number().int().min(1).max(BUILD_TASK_BUDGET_MAX_MINUTES).optional(),
|
|
1011
1068
|
// What kind of work the task is: building, checking other work, writing what to
|
|
1012
1069
|
// build, a person trying the product, or a run of the project's own checks.
|
|
1013
1070
|
// Absent when the graph does not say.
|
|
@@ -1024,14 +1081,14 @@ var buildTaskSchema = z7.object({
|
|
|
1024
1081
|
}).strict().superRefine((task, ctx) => {
|
|
1025
1082
|
if (task.reviews !== void 0 && task.reviews === task.id) {
|
|
1026
1083
|
ctx.addIssue({
|
|
1027
|
-
code:
|
|
1084
|
+
code: z8.ZodIssueCode.custom,
|
|
1028
1085
|
path: ["reviews"],
|
|
1029
1086
|
message: `'${task.id}' reviews itself \u2014 a review names the OTHER task it checks.`
|
|
1030
1087
|
});
|
|
1031
1088
|
}
|
|
1032
1089
|
if (task.layer !== void 0 && !isPhaseScopedLayer(task.layer)) {
|
|
1033
1090
|
ctx.addIssue({
|
|
1034
|
-
code:
|
|
1091
|
+
code: z8.ZodIssueCode.custom,
|
|
1035
1092
|
path: ["layer"],
|
|
1036
1093
|
message: `'${task.layer}' is not a wave a phase runs \u2014 expected one of ${PHASE_SCOPED_LAYERS.join(", ")}.`
|
|
1037
1094
|
});
|
|
@@ -1040,29 +1097,29 @@ var buildTaskSchema = z7.object({
|
|
|
1040
1097
|
for (const field of ["discipline", "tier"]) {
|
|
1041
1098
|
if (profiled && task[field] === void 0) {
|
|
1042
1099
|
ctx.addIssue({
|
|
1043
|
-
code:
|
|
1100
|
+
code: z8.ZodIssueCode.custom,
|
|
1044
1101
|
path: [field],
|
|
1045
1102
|
message: `'${field}' is required on a task an agent holds.`
|
|
1046
1103
|
});
|
|
1047
1104
|
}
|
|
1048
1105
|
if (!profiled && task[field] !== void 0) {
|
|
1049
1106
|
ctx.addIssue({
|
|
1050
|
-
code:
|
|
1107
|
+
code: z8.ZodIssueCode.custom,
|
|
1051
1108
|
path: [field],
|
|
1052
1109
|
message: task.agent === void 0 ? `'${field}' must be absent on a task nobody holds.` : `'${field}' must be absent on work a person holds.`
|
|
1053
1110
|
});
|
|
1054
1111
|
}
|
|
1055
1112
|
}
|
|
1056
1113
|
});
|
|
1057
|
-
var buildPhaseSchema =
|
|
1114
|
+
var buildPhaseSchema = z8.string().min(1).max(128);
|
|
1058
1115
|
var BUILD_PHASE_TITLE_MAX = 160;
|
|
1059
|
-
var buildPhaseTitleSchema =
|
|
1060
|
-
var buildTaskListSchema =
|
|
1116
|
+
var buildPhaseTitleSchema = z8.string().min(1).max(BUILD_PHASE_TITLE_MAX);
|
|
1117
|
+
var buildTaskListSchema = z8.array(buildTaskSchema).max(BUILD_SNAPSHOT_TASK_LIMIT).superRefine((tasks, ctx) => {
|
|
1061
1118
|
const seen = /* @__PURE__ */ new Set();
|
|
1062
1119
|
for (const [index, task] of tasks.entries()) {
|
|
1063
1120
|
if (seen.has(task.id)) {
|
|
1064
1121
|
ctx.addIssue({
|
|
1065
|
-
code:
|
|
1122
|
+
code: z8.ZodIssueCode.custom,
|
|
1066
1123
|
path: [index, "id"],
|
|
1067
1124
|
message: `duplicate task id '${task.id}' \u2014 one graph names each task once.`
|
|
1068
1125
|
});
|
|
@@ -1070,13 +1127,13 @@ var buildTaskListSchema = z7.array(buildTaskSchema).max(BUILD_SNAPSHOT_TASK_LIMI
|
|
|
1070
1127
|
seen.add(task.id);
|
|
1071
1128
|
}
|
|
1072
1129
|
});
|
|
1073
|
-
var buildTaskMarkSchema =
|
|
1130
|
+
var buildTaskMarkSchema = z8.object({
|
|
1074
1131
|
// The task that was marked.
|
|
1075
1132
|
task: buildTaskIdSchema,
|
|
1076
1133
|
// When it was first marked.
|
|
1077
1134
|
at: utcIso8601
|
|
1078
1135
|
}).strict();
|
|
1079
|
-
var buildSnapshotSchema =
|
|
1136
|
+
var buildSnapshotSchema = z8.object({
|
|
1080
1137
|
// Which phase this graph belongs to.
|
|
1081
1138
|
phase: buildPhaseSchema,
|
|
1082
1139
|
// That phase's name in words, when the project gives it one.
|
|
@@ -1089,9 +1146,9 @@ var buildSnapshotSchema = z7.object({
|
|
|
1089
1146
|
builtWithoutApproval: utcIso8601.optional(),
|
|
1090
1147
|
// Each task that started on a part still waiting for approval, and when it was
|
|
1091
1148
|
// first seen doing so. Absent when there is none.
|
|
1092
|
-
tasksBuiltWithoutApproval:
|
|
1149
|
+
tasksBuiltWithoutApproval: z8.array(buildTaskMarkSchema).min(1).max(BUILD_SNAPSHOT_TASK_LIMIT).optional()
|
|
1093
1150
|
}).strict();
|
|
1094
|
-
var buildPhaseEntrySchema =
|
|
1151
|
+
var buildPhaseEntrySchema = z8.object({
|
|
1095
1152
|
// Which phase has a stored graph.
|
|
1096
1153
|
phase: buildPhaseSchema,
|
|
1097
1154
|
// That phase's name in words, when the project gave it one.
|
|
@@ -1099,9 +1156,9 @@ var buildPhaseEntrySchema = z7.object({
|
|
|
1099
1156
|
// When that phase's graph was last reported.
|
|
1100
1157
|
reportedAt: utcIso8601,
|
|
1101
1158
|
// Present when work on this phase was reported with no approval of its scope in force.
|
|
1102
|
-
builtWithoutApproval:
|
|
1159
|
+
builtWithoutApproval: z8.literal(true).optional()
|
|
1103
1160
|
}).strict();
|
|
1104
|
-
var buildSnapshotReportSchema =
|
|
1161
|
+
var buildSnapshotReportSchema = z8.object({
|
|
1105
1162
|
// Which phase this graph belongs to.
|
|
1106
1163
|
phase: buildPhaseSchema,
|
|
1107
1164
|
// That phase's name in words, when the project gives it one.
|
|
@@ -1110,9 +1167,9 @@ var buildSnapshotReportSchema = z7.object({
|
|
|
1110
1167
|
// one thing this route does not accept.
|
|
1111
1168
|
tasks: buildTaskListSchema
|
|
1112
1169
|
}).strict();
|
|
1113
|
-
var buildSnapshotReportResultSchema =
|
|
1170
|
+
var buildSnapshotReportResultSchema = z8.object({
|
|
1114
1171
|
// What happened. One outcome today; a refusal travels as the shared wire error.
|
|
1115
|
-
outcome:
|
|
1172
|
+
outcome: z8.literal("recorded"),
|
|
1116
1173
|
// Which phase the graph was recorded against.
|
|
1117
1174
|
phase: buildPhaseSchema,
|
|
1118
1175
|
// When it was recorded.
|
|
@@ -1120,27 +1177,55 @@ var buildSnapshotReportResultSchema = z7.object({
|
|
|
1120
1177
|
}).strict();
|
|
1121
1178
|
|
|
1122
1179
|
// ../events/dist/phase-plan.js
|
|
1123
|
-
import { z as
|
|
1180
|
+
import { z as z10 } from "zod";
|
|
1181
|
+
|
|
1182
|
+
// ../events/dist/change-path-order.js
|
|
1183
|
+
import { z as z9 } from "zod";
|
|
1184
|
+
var PATH_ORDER = Object.freeze(["small", "mini", "full"]);
|
|
1185
|
+
var changePathSchema = z9.enum(PATH_ORDER);
|
|
1186
|
+
var PHASE_PATHS = Object.freeze(["mini", "full"]);
|
|
1187
|
+
var phasePathSchema = z9.enum(PHASE_PATHS);
|
|
1188
|
+
var changeUpPathSchema = z9.enum(["mini", "full"]);
|
|
1189
|
+
var CHANGE_PATH_NEXT = Object.freeze({
|
|
1190
|
+
small: Object.freeze({ say: "make the small change", section: "small" }),
|
|
1191
|
+
mini: Object.freeze({ say: "scope the mini phase", section: "mini" }),
|
|
1192
|
+
full: Object.freeze({ say: "plan the next phase", section: "full" })
|
|
1193
|
+
});
|
|
1194
|
+
var changePathNextSchema = z9.object({
|
|
1195
|
+
say: z9.enum([CHANGE_PATH_NEXT.small.say, CHANGE_PATH_NEXT.mini.say, CHANGE_PATH_NEXT.full.say]),
|
|
1196
|
+
section: changePathSchema
|
|
1197
|
+
}).strict();
|
|
1198
|
+
var CHANGE_SENTENCE_MAX = 4e3;
|
|
1199
|
+
var planMovedUpSchema = z9.object({
|
|
1200
|
+
to: z9.literal("full"),
|
|
1201
|
+
sentence: z9.string().min(1).max(CHANGE_SENTENCE_MAX),
|
|
1202
|
+
next: changePathNextSchema
|
|
1203
|
+
}).strict().refine((m) => m.next.say === CHANGE_PATH_NEXT.full.say && m.next.section === CHANGE_PATH_NEXT.full.section, {
|
|
1204
|
+
message: "names the full path's next phrase and section",
|
|
1205
|
+
path: ["next"]
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
// ../events/dist/phase-plan.js
|
|
1124
1209
|
var PHASE_PLAN_FORMAT = 1;
|
|
1125
1210
|
var PHASE_PLAN_CHANGES_MAX = 60;
|
|
1126
1211
|
var PHASE_PLAN_SUMMARY_MAX = 160;
|
|
1127
1212
|
var SCOPE_NOTE_MAX = 500;
|
|
1128
1213
|
var PHASE_PLAN_PHASE_MAX = buildPhaseSchema.maxLength ?? 0;
|
|
1129
1214
|
var PHASE_PLAN_CHANGE_KINDS = ["add", "change", "remove"];
|
|
1130
|
-
var phasePlanChangeSchema =
|
|
1215
|
+
var phasePlanChangeSchema = z10.enum(PHASE_PLAN_CHANGE_KINDS, {
|
|
1131
1216
|
error: `must be one of ${PHASE_PLAN_CHANGE_KINDS.join(", ")}`
|
|
1132
1217
|
});
|
|
1133
1218
|
var phasePlanPhaseSchema = phaseIdentitySchema.refine((v) => !isValidPhaseIdentity(v) || buildPhaseSchema.safeParse(String(v)).success, { message: `must be at most ${PHASE_PLAN_PHASE_MAX} characters` });
|
|
1134
1219
|
var phasePlanSummarySchema = descriptionText(PHASE_PLAN_SUMMARY_MAX);
|
|
1135
|
-
var phasePlanEntrySchema =
|
|
1220
|
+
var phasePlanEntrySchema = z10.object({
|
|
1136
1221
|
part: systemPartIdSchema,
|
|
1137
1222
|
change: phasePlanChangeSchema,
|
|
1138
1223
|
summary: phasePlanSummarySchema
|
|
1139
1224
|
}).strict();
|
|
1140
|
-
var phasePlanSchema =
|
|
1141
|
-
format:
|
|
1225
|
+
var phasePlanSchema = z10.object({
|
|
1226
|
+
format: z10.literal(PHASE_PLAN_FORMAT, { error: `must be ${PHASE_PLAN_FORMAT}` }),
|
|
1142
1227
|
phase: phasePlanPhaseSchema,
|
|
1143
|
-
changes:
|
|
1228
|
+
changes: z10.array(phasePlanEntrySchema).min(1, { message: "must list at least one part" }).max(PHASE_PLAN_CHANGES_MAX, { message: `can list at most ${PHASE_PLAN_CHANGES_MAX} parts` })
|
|
1144
1229
|
}).strict();
|
|
1145
1230
|
var scopePhaseSchema = buildPhaseSchema.refine((v) => isValidPhaseIdentity(v), {
|
|
1146
1231
|
message: "must be a phase name"
|
|
@@ -1152,109 +1237,110 @@ var SCOPE_STATE_NAMES = [
|
|
|
1152
1237
|
"approved",
|
|
1153
1238
|
"partly-stale"
|
|
1154
1239
|
];
|
|
1155
|
-
var scopeStateNameSchema =
|
|
1240
|
+
var scopeStateNameSchema = z10.enum(SCOPE_STATE_NAMES);
|
|
1156
1241
|
var plannedScopeStateSchema = scopeStateNameSchema.exclude(["not-planned"]);
|
|
1157
1242
|
var SCOPE_PART_STATUSES = ["approved", "waiting"];
|
|
1158
|
-
var scopePartStatusSchema =
|
|
1243
|
+
var scopePartStatusSchema = z10.enum(SCOPE_PART_STATUSES);
|
|
1159
1244
|
var SCOPE_ACTS = ["approve", "send-back"];
|
|
1160
|
-
var scopeActSchema =
|
|
1245
|
+
var scopeActSchema = z10.enum(SCOPE_ACTS);
|
|
1161
1246
|
var SCOPE_GIVEN_IN = ["console", "chat"];
|
|
1162
|
-
var scopeGivenInSchema =
|
|
1247
|
+
var scopeGivenInSchema = z10.enum(SCOPE_GIVEN_IN);
|
|
1163
1248
|
var scopeNoteSchema = descriptionText(SCOPE_NOTE_MAX);
|
|
1164
|
-
var scopeNoteWireSchema =
|
|
1249
|
+
var scopeNoteWireSchema = z10.string().max(SCOPE_NOTE_MAX);
|
|
1165
1250
|
var SCOPE_PART_VERDICTS = ["ok", "change"];
|
|
1166
|
-
var scopePartVerdictSchema =
|
|
1167
|
-
var scopeDecisionPartSchema =
|
|
1251
|
+
var scopePartVerdictSchema = z10.enum(SCOPE_PART_VERDICTS);
|
|
1252
|
+
var scopeDecisionPartSchema = z10.object({
|
|
1168
1253
|
part: systemPartIdSchema,
|
|
1169
1254
|
verdict: scopePartVerdictSchema,
|
|
1170
1255
|
note: scopeNoteWireSchema.optional()
|
|
1171
1256
|
}).strict();
|
|
1172
|
-
var planVersionSchema =
|
|
1173
|
-
var carriedPhaseSchema =
|
|
1257
|
+
var planVersionSchema = z10.number().int().min(1);
|
|
1258
|
+
var carriedPhaseSchema = z10.object({
|
|
1174
1259
|
phase: scopePhaseSchema,
|
|
1175
|
-
number:
|
|
1260
|
+
number: z10.number().int().min(1)
|
|
1176
1261
|
}).strict();
|
|
1177
1262
|
var carriedFromEntrySchema = carriedPhaseSchema.extend({
|
|
1178
1263
|
part: systemPartIdSchema
|
|
1179
1264
|
}).strict();
|
|
1180
|
-
var phasePlanRequestSchema =
|
|
1181
|
-
descriptionVersion:
|
|
1182
|
-
plan:
|
|
1265
|
+
var phasePlanRequestSchema = z10.object({
|
|
1266
|
+
descriptionVersion: z10.number().int().min(1),
|
|
1267
|
+
plan: z10.unknown()
|
|
1183
1268
|
}).strict();
|
|
1184
|
-
var phasePlanRecordedSchema =
|
|
1185
|
-
outcome:
|
|
1269
|
+
var phasePlanRecordedSchema = z10.object({
|
|
1270
|
+
outcome: z10.literal("recorded"),
|
|
1186
1271
|
version: planVersionSchema,
|
|
1187
|
-
phaseNumber:
|
|
1272
|
+
phaseNumber: z10.number().int().min(1),
|
|
1188
1273
|
state: plannedScopeStateSchema,
|
|
1189
|
-
changedParts:
|
|
1190
|
-
typedApprovalOffered:
|
|
1274
|
+
changedParts: z10.array(systemPartIdSchema).max(PHASE_PLAN_CHANGES_MAX),
|
|
1275
|
+
typedApprovalOffered: z10.boolean(),
|
|
1191
1276
|
reportedAt: utcIso8601,
|
|
1192
|
-
carriedFrom:
|
|
1277
|
+
carriedFrom: z10.array(carriedFromEntrySchema).min(1).max(PHASE_PLAN_CHANGES_MAX).optional(),
|
|
1278
|
+
movedUp: planMovedUpSchema.optional()
|
|
1193
1279
|
}).strict();
|
|
1194
|
-
var phasePlanRefusedSchema =
|
|
1195
|
-
outcome:
|
|
1196
|
-
problems:
|
|
1280
|
+
var phasePlanRefusedSchema = z10.object({
|
|
1281
|
+
outcome: z10.literal("refused"),
|
|
1282
|
+
problems: z10.array(systemDescriptionProblemSchema).min(1)
|
|
1197
1283
|
}).strict();
|
|
1198
|
-
var phasePlanUnavailableSchema =
|
|
1199
|
-
outcome:
|
|
1284
|
+
var phasePlanUnavailableSchema = z10.object({
|
|
1285
|
+
outcome: z10.literal("unavailable")
|
|
1200
1286
|
}).strict();
|
|
1201
1287
|
var REMOVAL_OWED_ACTS = ["dropped", "removed"];
|
|
1202
|
-
var removalOwedPartSchema =
|
|
1288
|
+
var removalOwedPartSchema = z10.object({
|
|
1203
1289
|
part: systemPartIdSchema,
|
|
1204
1290
|
name: systemPartSchema.shape.name,
|
|
1205
1291
|
phase: scopePhaseSchema,
|
|
1206
|
-
number:
|
|
1207
|
-
act:
|
|
1292
|
+
number: z10.number().int().min(1),
|
|
1293
|
+
act: z10.enum(REMOVAL_OWED_ACTS)
|
|
1208
1294
|
}).strict();
|
|
1209
|
-
var phasePlanRemovalOwedSchema =
|
|
1210
|
-
outcome:
|
|
1211
|
-
parts:
|
|
1295
|
+
var phasePlanRemovalOwedSchema = z10.object({
|
|
1296
|
+
outcome: z10.literal("removal-owed"),
|
|
1297
|
+
parts: z10.array(removalOwedPartSchema).min(1).max(SYSTEM_PARTS_MAX)
|
|
1212
1298
|
}).strict();
|
|
1213
|
-
var phasePlanResultSchema =
|
|
1299
|
+
var phasePlanResultSchema = z10.discriminatedUnion("outcome", [
|
|
1214
1300
|
phasePlanRecordedSchema,
|
|
1215
1301
|
phasePlanRefusedSchema,
|
|
1216
1302
|
phasePlanUnavailableSchema,
|
|
1217
1303
|
phasePlanRemovalOwedSchema
|
|
1218
1304
|
]);
|
|
1219
|
-
var scopeApproveRequestSchema =
|
|
1220
|
-
act:
|
|
1305
|
+
var scopeApproveRequestSchema = z10.object({
|
|
1306
|
+
act: z10.literal("approve"),
|
|
1221
1307
|
planVersion: planVersionSchema,
|
|
1222
|
-
parts:
|
|
1308
|
+
parts: z10.array(scopeDecisionPartSchema).max(PHASE_PLAN_CHANGES_MAX)
|
|
1223
1309
|
}).strict();
|
|
1224
|
-
var scopeSendBackRequestSchema =
|
|
1225
|
-
act:
|
|
1310
|
+
var scopeSendBackRequestSchema = z10.object({
|
|
1311
|
+
act: z10.literal("send-back"),
|
|
1226
1312
|
planVersion: planVersionSchema,
|
|
1227
|
-
parts:
|
|
1313
|
+
parts: z10.array(scopeDecisionPartSchema).max(PHASE_PLAN_CHANGES_MAX),
|
|
1228
1314
|
note: scopeNoteWireSchema.optional()
|
|
1229
1315
|
}).strict();
|
|
1230
|
-
var scopeDecisionRequestSchema =
|
|
1316
|
+
var scopeDecisionRequestSchema = z10.discriminatedUnion("act", [
|
|
1231
1317
|
scopeApproveRequestSchema,
|
|
1232
1318
|
scopeSendBackRequestSchema
|
|
1233
1319
|
]);
|
|
1234
|
-
var scopeDecisionRecordedSchema =
|
|
1235
|
-
outcome:
|
|
1320
|
+
var scopeDecisionRecordedSchema = z10.object({
|
|
1321
|
+
outcome: z10.literal("recorded"),
|
|
1236
1322
|
act: scopeActSchema,
|
|
1237
1323
|
phase: scopePhaseSchema,
|
|
1238
1324
|
planVersion: planVersionSchema,
|
|
1239
1325
|
state: plannedScopeStateSchema,
|
|
1240
1326
|
decidedAt: utcIso8601
|
|
1241
1327
|
}).strict();
|
|
1242
|
-
var scopeDecisionAlreadyApprovedSchema =
|
|
1243
|
-
outcome:
|
|
1244
|
-
replanNeeded:
|
|
1245
|
-
reason:
|
|
1328
|
+
var scopeDecisionAlreadyApprovedSchema = z10.object({
|
|
1329
|
+
outcome: z10.literal("already-approved"),
|
|
1330
|
+
replanNeeded: z10.boolean(),
|
|
1331
|
+
reason: z10.string().min(1)
|
|
1246
1332
|
}).strict();
|
|
1247
|
-
var scopeDecisionRefusedSchema =
|
|
1248
|
-
outcome:
|
|
1249
|
-
problems:
|
|
1333
|
+
var scopeDecisionRefusedSchema = z10.object({
|
|
1334
|
+
outcome: z10.literal("refused"),
|
|
1335
|
+
problems: z10.array(systemDescriptionProblemSchema).min(1)
|
|
1250
1336
|
}).strict();
|
|
1251
|
-
var scopeDecisionUnavailableSchema =
|
|
1252
|
-
outcome:
|
|
1337
|
+
var scopeDecisionUnavailableSchema = z10.object({
|
|
1338
|
+
outcome: z10.literal("unavailable")
|
|
1253
1339
|
}).strict();
|
|
1254
1340
|
function reasonOutcome(outcome) {
|
|
1255
|
-
return
|
|
1341
|
+
return z10.object({ outcome: z10.literal(outcome), reason: z10.string().min(1) }).strict();
|
|
1256
1342
|
}
|
|
1257
|
-
var scopeDecisionResultSchema =
|
|
1343
|
+
var scopeDecisionResultSchema = z10.discriminatedUnion("outcome", [
|
|
1258
1344
|
scopeDecisionRecordedSchema,
|
|
1259
1345
|
scopeDecisionAlreadyApprovedSchema,
|
|
1260
1346
|
scopeDecisionRefusedSchema,
|
|
@@ -1264,357 +1350,88 @@ var scopeDecisionResultSchema = z8.discriminatedUnion("outcome", [
|
|
|
1264
1350
|
reasonOutcome("plan-changed"),
|
|
1265
1351
|
reasonOutcome("build-started")
|
|
1266
1352
|
]);
|
|
1267
|
-
var scopeReadPartSchema =
|
|
1353
|
+
var scopeReadPartSchema = z10.object({
|
|
1268
1354
|
part: systemPartIdSchema,
|
|
1269
1355
|
name: systemPartSchema.shape.name,
|
|
1270
1356
|
change: phasePlanChangeSchema,
|
|
1271
1357
|
summary: phasePlanSummarySchema,
|
|
1272
1358
|
status: scopePartStatusSchema,
|
|
1273
|
-
changed:
|
|
1359
|
+
changed: z10.boolean(),
|
|
1274
1360
|
carriedFrom: carriedPhaseSchema.optional()
|
|
1275
1361
|
}).strict();
|
|
1276
|
-
var scopeReadDecisionSchema =
|
|
1362
|
+
var scopeReadDecisionSchema = z10.object({
|
|
1277
1363
|
act: scopeActSchema,
|
|
1278
1364
|
planVersion: planVersionSchema,
|
|
1279
1365
|
givenIn: scopeGivenInSchema,
|
|
1280
1366
|
at: utcIso8601,
|
|
1281
|
-
parts:
|
|
1367
|
+
parts: z10.array(scopeDecisionPartSchema).max(PHASE_PLAN_CHANGES_MAX),
|
|
1282
1368
|
note: scopeNoteWireSchema.optional()
|
|
1283
1369
|
}).strict();
|
|
1284
|
-
var scopeReadNotPlannedSchema =
|
|
1370
|
+
var scopeReadNotPlannedSchema = z10.object({
|
|
1285
1371
|
phase: scopePhaseSchema,
|
|
1286
|
-
state:
|
|
1287
|
-
canDecide:
|
|
1372
|
+
state: z10.literal("not-planned"),
|
|
1373
|
+
canDecide: z10.boolean()
|
|
1288
1374
|
}).strict();
|
|
1289
|
-
var scopeReadPlannedSchema =
|
|
1375
|
+
var scopeReadPlannedSchema = z10.object({
|
|
1290
1376
|
phase: scopePhaseSchema,
|
|
1291
1377
|
state: plannedScopeStateSchema,
|
|
1292
|
-
phaseNumber:
|
|
1378
|
+
phaseNumber: z10.number().int().min(1),
|
|
1293
1379
|
planVersion: planVersionSchema,
|
|
1294
|
-
parts:
|
|
1295
|
-
decisions:
|
|
1296
|
-
canDecide:
|
|
1297
|
-
replanLine:
|
|
1380
|
+
parts: z10.array(scopeReadPartSchema).min(1).max(PHASE_PLAN_CHANGES_MAX),
|
|
1381
|
+
decisions: z10.array(scopeReadDecisionSchema),
|
|
1382
|
+
canDecide: z10.boolean(),
|
|
1383
|
+
replanLine: z10.string().min(1).optional()
|
|
1298
1384
|
}).strict();
|
|
1299
|
-
var scopeReadSchema =
|
|
1385
|
+
var scopeReadSchema = z10.union([scopeReadNotPlannedSchema, scopeReadPlannedSchema]);
|
|
1300
1386
|
|
|
1301
|
-
// ../events/dist/
|
|
1302
|
-
import { z as
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
var
|
|
1307
|
-
var
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
ears: z9.boolean()
|
|
1387
|
+
// ../events/dist/observed-changes.js
|
|
1388
|
+
import { z as z12 } from "zod";
|
|
1389
|
+
|
|
1390
|
+
// ../events/dist/code-link.js
|
|
1391
|
+
import { z as z11 } from "zod";
|
|
1392
|
+
var codeLinkAddressSchema = z11.string().regex(GITHUB_REPOSITORY_ADDRESS, { message: "must be a GitHub repository address: https://github.com/<owner>/<repo>" }).refine((v) => !looksLikeSecret(v), { message: "looks like a password or key, so it is not sent" });
|
|
1393
|
+
var codeLinkFactsSchema = z11.object({
|
|
1394
|
+
repositoryAddress: codeLinkAddressSchema.nullable(),
|
|
1395
|
+
headOnGitHub: z11.boolean()
|
|
1396
|
+
}).strict().refine((v) => !(v.headOnGitHub && v.repositoryAddress === null), {
|
|
1397
|
+
message: "cannot be true when the code is not on GitHub",
|
|
1398
|
+
path: ["headOnGitHub"]
|
|
1399
|
+
});
|
|
1400
|
+
var PART_CODE_LINK_SCOPES = ["part", "phase"];
|
|
1401
|
+
var PART_CODE_LINK_RANGE_REASONS = ["not-github", "not-pushed"];
|
|
1402
|
+
var PART_CODE_LINK_URL_PREFIX = "https://github.com/";
|
|
1403
|
+
var partCodeLinkGithubSchema = z11.object({
|
|
1404
|
+
kind: z11.literal("github"),
|
|
1405
|
+
scope: z11.enum(PART_CODE_LINK_SCOPES),
|
|
1406
|
+
url: z11.string().startsWith(PART_CODE_LINK_URL_PREFIX, { message: "must start with https://github.com/" })
|
|
1322
1407
|
}).strict();
|
|
1323
|
-
var
|
|
1324
|
-
"
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
"
|
|
1331
|
-
|
|
1332
|
-
|
|
1408
|
+
var partCodeLinkRangeSchema = z11.object({
|
|
1409
|
+
kind: z11.literal("range"),
|
|
1410
|
+
why: z11.enum(PART_CODE_LINK_RANGE_REASONS),
|
|
1411
|
+
from: closeCommitSchema,
|
|
1412
|
+
to: closeCommitSchema
|
|
1413
|
+
}).strict();
|
|
1414
|
+
var partCodeLinkNoneSchema = z11.object({
|
|
1415
|
+
kind: z11.literal("none")
|
|
1416
|
+
}).strict();
|
|
1417
|
+
var partCodeLinkSchema = z11.discriminatedUnion("kind", [
|
|
1418
|
+
partCodeLinkGithubSchema,
|
|
1419
|
+
partCodeLinkRangeSchema,
|
|
1420
|
+
partCodeLinkNoneSchema
|
|
1333
1421
|
]);
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
tier: crewTierSchema,
|
|
1348
|
-
// How this member's face is drawn. The same face on every project, so a
|
|
1349
|
-
// returning client recognises a member before reading the name.
|
|
1350
|
-
face: crewFaceSchema
|
|
1351
|
-
}).strict();
|
|
1352
|
-
var CREW_ROSTER = [
|
|
1353
|
-
// ── analysts and architects ─────────────────────────────────────────────────
|
|
1354
|
-
{
|
|
1355
|
-
callsign: "SOFIA",
|
|
1356
|
-
group: "analyst-architect",
|
|
1357
|
-
role: "business-analyst",
|
|
1358
|
-
discipline: "business analyst",
|
|
1359
|
-
tier: "deep",
|
|
1360
|
-
face: { head: "gable", antenna: "stalk", eyes: "dots", mouth: "wave", ears: false }
|
|
1361
|
-
},
|
|
1362
|
-
{
|
|
1363
|
-
callsign: "BEA",
|
|
1364
|
-
group: "analyst-architect",
|
|
1365
|
-
role: "business-analyst",
|
|
1366
|
-
discipline: "business analyst",
|
|
1367
|
-
tier: "standard",
|
|
1368
|
-
face: { head: "gable", antenna: "none", eyes: "visor", mouth: "line", ears: false }
|
|
1369
|
-
},
|
|
1370
|
-
{
|
|
1371
|
-
callsign: "WREN",
|
|
1372
|
-
group: "analyst-architect",
|
|
1373
|
-
role: "architect",
|
|
1374
|
-
discipline: "solution architect",
|
|
1375
|
-
tier: "deep",
|
|
1376
|
-
face: { head: "gable", antenna: "dish", eyes: "bars", mouth: "line", ears: true }
|
|
1377
|
-
},
|
|
1378
|
-
{
|
|
1379
|
-
callsign: "PEI",
|
|
1380
|
-
group: "analyst-architect",
|
|
1381
|
-
role: "architect",
|
|
1382
|
-
discipline: "technical architect",
|
|
1383
|
-
tier: "standard",
|
|
1384
|
-
face: { head: "gable", antenna: "twin", eyes: "cyclops", mouth: "dots", ears: false }
|
|
1385
|
-
},
|
|
1386
|
-
// ── builders: code ──────────────────────────────────────────────────────────
|
|
1387
|
-
{
|
|
1388
|
-
callsign: "ADA",
|
|
1389
|
-
group: "builder",
|
|
1390
|
-
role: "builder",
|
|
1391
|
-
discipline: "implementation",
|
|
1392
|
-
tier: "deep",
|
|
1393
|
-
face: { head: "sq", antenna: "stalk", eyes: "dots", mouth: "line", ears: false }
|
|
1394
|
-
},
|
|
1395
|
-
{
|
|
1396
|
-
callsign: "OTTO",
|
|
1397
|
-
group: "builder",
|
|
1398
|
-
role: "builder",
|
|
1399
|
-
discipline: "implementation",
|
|
1400
|
-
tier: "deep",
|
|
1401
|
-
face: { head: "sq", antenna: "twin", eyes: "bars", mouth: "grid", ears: true }
|
|
1402
|
-
},
|
|
1403
|
-
{
|
|
1404
|
-
callsign: "MILO",
|
|
1405
|
-
group: "builder",
|
|
1406
|
-
role: "builder",
|
|
1407
|
-
discipline: "implementation",
|
|
1408
|
-
tier: "standard",
|
|
1409
|
-
face: { head: "sqr", antenna: "stalk", eyes: "dots", mouth: "dots", ears: false }
|
|
1410
|
-
},
|
|
1411
|
-
{
|
|
1412
|
-
callsign: "NOVA",
|
|
1413
|
-
group: "builder",
|
|
1414
|
-
role: "builder",
|
|
1415
|
-
discipline: "implementation",
|
|
1416
|
-
tier: "standard",
|
|
1417
|
-
face: { head: "sq", antenna: "dish", eyes: "cyclops", mouth: "line", ears: false }
|
|
1418
|
-
},
|
|
1419
|
-
{
|
|
1420
|
-
callsign: "HUGO",
|
|
1421
|
-
group: "builder",
|
|
1422
|
-
role: "builder",
|
|
1423
|
-
discipline: "infrastructure",
|
|
1424
|
-
tier: "standard",
|
|
1425
|
-
face: { head: "sq", antenna: "twin", eyes: "dots", mouth: "grid", ears: true }
|
|
1426
|
-
},
|
|
1427
|
-
// ── builders: specs and docs ────────────────────────────────────────────────
|
|
1428
|
-
{
|
|
1429
|
-
callsign: "IRIS",
|
|
1430
|
-
group: "builder",
|
|
1431
|
-
role: "spec-writer",
|
|
1432
|
-
discipline: "feature spec",
|
|
1433
|
-
tier: "deep",
|
|
1434
|
-
face: { head: "dome", antenna: "stalk", eyes: "visor", mouth: "line", ears: false }
|
|
1435
|
-
},
|
|
1436
|
-
{
|
|
1437
|
-
callsign: "JUNO",
|
|
1438
|
-
group: "builder",
|
|
1439
|
-
role: "spec-writer",
|
|
1440
|
-
discipline: "feature spec",
|
|
1441
|
-
tier: "standard",
|
|
1442
|
-
face: { head: "dome", antenna: "none", eyes: "dots", mouth: "wave", ears: false }
|
|
1443
|
-
},
|
|
1444
|
-
{
|
|
1445
|
-
callsign: "LEX",
|
|
1446
|
-
group: "builder",
|
|
1447
|
-
role: "context-docs",
|
|
1448
|
-
discipline: "context & docs",
|
|
1449
|
-
tier: "fast",
|
|
1450
|
-
face: { head: "dome", antenna: "twin", eyes: "bars", mouth: "dots", ears: false }
|
|
1451
|
-
},
|
|
1452
|
-
// ── reviewers ───────────────────────────────────────────────────────────────
|
|
1453
|
-
{
|
|
1454
|
-
callsign: "VERA",
|
|
1455
|
-
group: "reviewer",
|
|
1456
|
-
role: "spec-reviewer",
|
|
1457
|
-
discipline: "spec consistency",
|
|
1458
|
-
tier: "deep",
|
|
1459
|
-
face: { head: "rnd", antenna: "stalk", eyes: "visor", mouth: "line", ears: false }
|
|
1460
|
-
},
|
|
1461
|
-
{
|
|
1462
|
-
callsign: "ODIN",
|
|
1463
|
-
group: "reviewer",
|
|
1464
|
-
role: "spec-reviewer",
|
|
1465
|
-
discipline: "cross-spec audit",
|
|
1466
|
-
tier: "deep",
|
|
1467
|
-
face: { head: "rnd", antenna: "dish", eyes: "cyclops", mouth: "line", ears: false }
|
|
1468
|
-
},
|
|
1469
|
-
{
|
|
1470
|
-
callsign: "CASS",
|
|
1471
|
-
group: "reviewer",
|
|
1472
|
-
role: "code-test-reviewer",
|
|
1473
|
-
discipline: "code review",
|
|
1474
|
-
tier: "deep",
|
|
1475
|
-
face: { head: "rnd", antenna: "none", eyes: "visor", mouth: "grid", ears: true }
|
|
1476
|
-
},
|
|
1477
|
-
{
|
|
1478
|
-
callsign: "THEO",
|
|
1479
|
-
group: "reviewer",
|
|
1480
|
-
role: "code-test-reviewer",
|
|
1481
|
-
discipline: "code review",
|
|
1482
|
-
tier: "standard",
|
|
1483
|
-
face: { head: "rnd", antenna: "twin", eyes: "bars", mouth: "line", ears: false }
|
|
1484
|
-
},
|
|
1485
|
-
{
|
|
1486
|
-
callsign: "KAI",
|
|
1487
|
-
group: "reviewer",
|
|
1488
|
-
role: "code-test-reviewer",
|
|
1489
|
-
discipline: "code review",
|
|
1490
|
-
tier: "standard",
|
|
1491
|
-
face: { head: "rnd", antenna: "none", eyes: "bars", mouth: "line", ears: true }
|
|
1492
|
-
},
|
|
1493
|
-
{
|
|
1494
|
-
callsign: "ECHO",
|
|
1495
|
-
group: "reviewer",
|
|
1496
|
-
role: "code-test-reviewer",
|
|
1497
|
-
discipline: "test quality",
|
|
1498
|
-
tier: "standard",
|
|
1499
|
-
face: { head: "rnd", antenna: "stalk", eyes: "dots", mouth: "wave", ears: false }
|
|
1500
|
-
},
|
|
1501
|
-
{
|
|
1502
|
-
callsign: "MAVIS",
|
|
1503
|
-
group: "reviewer",
|
|
1504
|
-
role: "code-test-reviewer",
|
|
1505
|
-
discipline: "suites & coverage",
|
|
1506
|
-
tier: "standard",
|
|
1507
|
-
face: { head: "rnd", antenna: "none", eyes: "visor", mouth: "dots", ears: false }
|
|
1508
|
-
},
|
|
1509
|
-
{
|
|
1510
|
-
callsign: "ZARA",
|
|
1511
|
-
group: "reviewer",
|
|
1512
|
-
role: "code-test-reviewer",
|
|
1513
|
-
discipline: "smoke & walk aid",
|
|
1514
|
-
tier: "standard",
|
|
1515
|
-
face: { head: "rnd", antenna: "dish", eyes: "bars", mouth: "wave", ears: false }
|
|
1516
|
-
},
|
|
1517
|
-
{
|
|
1518
|
-
callsign: "NORA",
|
|
1519
|
-
group: "reviewer",
|
|
1520
|
-
role: "code-test-reviewer",
|
|
1521
|
-
discipline: "evidence & provenance",
|
|
1522
|
-
tier: "fast",
|
|
1523
|
-
face: { head: "rnd", antenna: "twin", eyes: "dots", mouth: "line", ears: false }
|
|
1524
|
-
},
|
|
1525
|
-
// ── leads ───────────────────────────────────────────────────────────────────
|
|
1526
|
-
{
|
|
1527
|
-
callsign: "ARGUS",
|
|
1528
|
-
group: "lead",
|
|
1529
|
-
role: "quality-lead",
|
|
1530
|
-
discipline: "quality lead \xB7 every diff",
|
|
1531
|
-
tier: "standard",
|
|
1532
|
-
face: { head: "hex", antenna: "dish", eyes: "visor", mouth: "grid", ears: true }
|
|
1533
|
-
},
|
|
1534
|
-
{
|
|
1535
|
-
callsign: "ATLAS",
|
|
1536
|
-
group: "lead",
|
|
1537
|
-
role: "delivery-lead",
|
|
1538
|
-
discipline: "delivery lead",
|
|
1539
|
-
tier: "deep",
|
|
1540
|
-
face: { head: "hex", antenna: "twin", eyes: "cyclops", mouth: "line", ears: true }
|
|
1541
|
-
}
|
|
1542
|
-
];
|
|
1543
|
-
var CREW_ROSTER_SIZE = CREW_ROSTER.length;
|
|
1544
|
-
var CREW_CALLSIGNS = CREW_ROSTER.map((member) => member.callsign);
|
|
1545
|
-
var crewLayerSchema = methodLayerSchema.extract(["l0", "l1", "l2", "l3", "l4", "l5"]);
|
|
1546
|
-
var crewRoleLayersSchema = z9.object({
|
|
1547
|
-
leads: z9.array(crewLayerSchema),
|
|
1548
|
-
helps: z9.array(crewLayerSchema)
|
|
1549
|
-
}).strict();
|
|
1550
|
-
|
|
1551
|
-
// ../events/dist/build-record-v3.js
|
|
1552
|
-
import { z as z14 } from "zod";
|
|
1553
|
-
|
|
1554
|
-
// ../events/dist/board-vocabulary.js
|
|
1555
|
-
import { z as z10 } from "zod";
|
|
1556
|
-
var boardStepStateSchema = z10.enum([
|
|
1557
|
-
"not-instrumented",
|
|
1558
|
-
"done",
|
|
1559
|
-
"did-not-pass",
|
|
1560
|
-
"could-not-complete",
|
|
1561
|
-
"not-yet-available",
|
|
1562
|
-
"qualified"
|
|
1563
|
-
]);
|
|
1564
|
-
var boardGateNameSchema = z10.enum([
|
|
1565
|
-
"scope",
|
|
1566
|
-
"architecture",
|
|
1567
|
-
"specs",
|
|
1568
|
-
"taskgraph",
|
|
1569
|
-
"phase-close"
|
|
1570
|
-
]);
|
|
1571
|
-
|
|
1572
|
-
// ../events/dist/code-link.js
|
|
1573
|
-
import { z as z11 } from "zod";
|
|
1574
|
-
var codeLinkAddressSchema = z11.string().regex(GITHUB_REPOSITORY_ADDRESS, { message: "must be a GitHub repository address: https://github.com/<owner>/<repo>" }).refine((v) => !looksLikeSecret(v), { message: "looks like a password or key, so it is not sent" });
|
|
1575
|
-
var codeLinkFactsSchema = z11.object({
|
|
1576
|
-
repositoryAddress: codeLinkAddressSchema.nullable(),
|
|
1577
|
-
headOnGitHub: z11.boolean()
|
|
1578
|
-
}).strict().refine((v) => !(v.headOnGitHub && v.repositoryAddress === null), {
|
|
1579
|
-
message: "cannot be true when the code is not on GitHub",
|
|
1580
|
-
path: ["headOnGitHub"]
|
|
1581
|
-
});
|
|
1582
|
-
var PART_CODE_LINK_SCOPES = ["part", "phase"];
|
|
1583
|
-
var PART_CODE_LINK_RANGE_REASONS = ["not-github", "not-pushed"];
|
|
1584
|
-
var PART_CODE_LINK_URL_PREFIX = "https://github.com/";
|
|
1585
|
-
var partCodeLinkGithubSchema = z11.object({
|
|
1586
|
-
kind: z11.literal("github"),
|
|
1587
|
-
scope: z11.enum(PART_CODE_LINK_SCOPES),
|
|
1588
|
-
url: z11.string().startsWith(PART_CODE_LINK_URL_PREFIX, { message: "must start with https://github.com/" })
|
|
1589
|
-
}).strict();
|
|
1590
|
-
var partCodeLinkRangeSchema = z11.object({
|
|
1591
|
-
kind: z11.literal("range"),
|
|
1592
|
-
why: z11.enum(PART_CODE_LINK_RANGE_REASONS),
|
|
1593
|
-
from: closeCommitSchema,
|
|
1594
|
-
to: closeCommitSchema
|
|
1595
|
-
}).strict();
|
|
1596
|
-
var partCodeLinkNoneSchema = z11.object({
|
|
1597
|
-
kind: z11.literal("none")
|
|
1598
|
-
}).strict();
|
|
1599
|
-
var partCodeLinkSchema = z11.discriminatedUnion("kind", [
|
|
1600
|
-
partCodeLinkGithubSchema,
|
|
1601
|
-
partCodeLinkRangeSchema,
|
|
1602
|
-
partCodeLinkNoneSchema
|
|
1603
|
-
]);
|
|
1604
|
-
|
|
1605
|
-
// ../events/dist/observed-changes.js
|
|
1606
|
-
import { z as z12 } from "zod";
|
|
1607
|
-
var OBSERVED_PATHS_LISTED_MAX = 50;
|
|
1608
|
-
var OBSERVED_PATH_MAX = 300;
|
|
1609
|
-
var OBSERVED_COUNT_MAX = 1e6;
|
|
1610
|
-
var observedCountSchema = z12.number({ error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).int({ error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).min(0, { error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).max(OBSERVED_COUNT_MAX, { error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` });
|
|
1611
|
-
var observedDescriptionVersionSchema = z12.number().int().min(1);
|
|
1612
|
-
var observedPathSchema = z12.string().min(1, { message: "must not be empty" }).max(OBSERVED_PATH_MAX, { message: `must be at most ${OBSERVED_PATH_MAX} characters` });
|
|
1613
|
-
var observedPathListSchema = z12.array(observedPathSchema).max(OBSERVED_PATHS_LISTED_MAX, { message: `can list at most ${OBSERVED_PATHS_LISTED_MAX} paths` }).refine((paths) => new Set(paths).size === paths.length, { message: "must name each path once" });
|
|
1614
|
-
var observedMethodFilesSchema = z12.object({
|
|
1615
|
-
added: observedCountSchema,
|
|
1616
|
-
changed: observedCountSchema,
|
|
1617
|
-
removed: observedCountSchema
|
|
1422
|
+
|
|
1423
|
+
// ../events/dist/observed-changes.js
|
|
1424
|
+
var OBSERVED_PATHS_LISTED_MAX = 50;
|
|
1425
|
+
var OBSERVED_PATH_MAX = 300;
|
|
1426
|
+
var OBSERVED_COUNT_MAX = 1e6;
|
|
1427
|
+
var observedCountSchema = z12.number({ error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).int({ error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).min(0, { error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` }).max(OBSERVED_COUNT_MAX, { error: `must be a whole number from 0 to ${OBSERVED_COUNT_MAX}` });
|
|
1428
|
+
var observedDescriptionVersionSchema = z12.number().int().min(1);
|
|
1429
|
+
var observedPathSchema = z12.string().min(1, { message: "must not be empty" }).max(OBSERVED_PATH_MAX, { message: `must be at most ${OBSERVED_PATH_MAX} characters` });
|
|
1430
|
+
var observedPathListSchema = z12.array(observedPathSchema).max(OBSERVED_PATHS_LISTED_MAX, { message: `can list at most ${OBSERVED_PATHS_LISTED_MAX} paths` }).refine((paths) => new Set(paths).size === paths.length, { message: "must name each path once" });
|
|
1431
|
+
var observedMethodFilesSchema = z12.object({
|
|
1432
|
+
added: observedCountSchema,
|
|
1433
|
+
changed: observedCountSchema,
|
|
1434
|
+
removed: observedCountSchema
|
|
1618
1435
|
}).strict();
|
|
1619
1436
|
var observedFilesSchema = z12.object({
|
|
1620
1437
|
added: observedCountSchema,
|
|
@@ -1737,111 +1554,734 @@ var OBSERVE_NOT_SENT_REASONS = [
|
|
|
1737
1554
|
"refused",
|
|
1738
1555
|
"unreachable"
|
|
1739
1556
|
];
|
|
1740
|
-
var observeRunRecordedSchema = z12.object({ outcome: z12.literal("recorded") }).strict();
|
|
1741
|
-
var observeRunKeptSchema = z12.object({ outcome: z12.literal("kept") }).strict();
|
|
1742
|
-
var observeRunNotSentSchema = z12.object({
|
|
1743
|
-
outcome: z12.literal("not-sent"),
|
|
1744
|
-
reason: z12.enum(OBSERVE_NOT_SENT_REASONS)
|
|
1557
|
+
var observeRunRecordedSchema = z12.object({ outcome: z12.literal("recorded") }).strict();
|
|
1558
|
+
var observeRunKeptSchema = z12.object({ outcome: z12.literal("kept") }).strict();
|
|
1559
|
+
var observeRunNotSentSchema = z12.object({
|
|
1560
|
+
outcome: z12.literal("not-sent"),
|
|
1561
|
+
reason: z12.enum(OBSERVE_NOT_SENT_REASONS)
|
|
1562
|
+
}).strict();
|
|
1563
|
+
var observeRunResultSchema = z12.discriminatedUnion("outcome", [
|
|
1564
|
+
observeRunRecordedSchema,
|
|
1565
|
+
observeRunKeptSchema,
|
|
1566
|
+
observeRunNotSentSchema
|
|
1567
|
+
]);
|
|
1568
|
+
var observedChecksFiredSchema = z12.array(z12.string().min(1)).refine((names) => names.every((name, i) => i === 0 || names[i - 1] < name), {
|
|
1569
|
+
message: "must be sorted, each name once"
|
|
1570
|
+
});
|
|
1571
|
+
var observedCountingSchema = z12.discriminatedUnion("state", [
|
|
1572
|
+
z12.object({
|
|
1573
|
+
state: z12.literal("counted"),
|
|
1574
|
+
startCommit: closeCommitSchema,
|
|
1575
|
+
startRecordedAt: utcIso8601,
|
|
1576
|
+
headCommit: closeCommitSchema,
|
|
1577
|
+
headCommittedAt: utcIso8601,
|
|
1578
|
+
commits: observedCountSchema,
|
|
1579
|
+
countedAt: utcIso8601
|
|
1580
|
+
}).strict(),
|
|
1581
|
+
z12.object({
|
|
1582
|
+
state: z12.literal("not-counted-yet"),
|
|
1583
|
+
startCommit: closeCommitSchema,
|
|
1584
|
+
startRecordedAt: utcIso8601
|
|
1585
|
+
}).strict(),
|
|
1586
|
+
z12.object({
|
|
1587
|
+
state: z12.literal("cannot-count")
|
|
1588
|
+
}).strict()
|
|
1589
|
+
]);
|
|
1590
|
+
var observedPartSchema = z12.object({
|
|
1591
|
+
part: systemPartIdSchema,
|
|
1592
|
+
files: observedFilesSchema.nullable(),
|
|
1593
|
+
checksFired: observedChecksFiredSchema
|
|
1594
|
+
}).strict().refine((v) => v.files !== null && filesChanged(v.files) >= 1 || v.checksFired.length >= 1, {
|
|
1595
|
+
message: "a part is listed only when files changed under it or a check fired on one",
|
|
1596
|
+
path: ["files"]
|
|
1597
|
+
});
|
|
1598
|
+
var observedOutsideSchema = z12.object({
|
|
1599
|
+
files: observedFilesSchema.nullable(),
|
|
1600
|
+
paths: observedPathListSchema,
|
|
1601
|
+
checksFired: observedChecksFiredSchema
|
|
1602
|
+
}).strict().refine((v) => pathsFitTheCount(v.files, v.paths), {
|
|
1603
|
+
message: "lists more paths than files changed",
|
|
1604
|
+
path: ["paths"]
|
|
1605
|
+
});
|
|
1606
|
+
var observedChangesSchema = z12.object({
|
|
1607
|
+
phase: phaseNameSchema,
|
|
1608
|
+
counting: observedCountingSchema,
|
|
1609
|
+
descriptionVersion: observedDescriptionVersionSchema.nullable(),
|
|
1610
|
+
parts: z12.array(observedPartSchema).max(SYSTEM_PARTS_MAX),
|
|
1611
|
+
methodFiles: observedMethodFilesSchema.nullable(),
|
|
1612
|
+
outsideEveryPart: observedOutsideSchema,
|
|
1613
|
+
codeLink: codeLinkFactsSchema.nullable()
|
|
1614
|
+
}).strict().superRefine((v, ctx) => {
|
|
1615
|
+
checkPartsUnique(v.parts, ctx, ["parts"]);
|
|
1616
|
+
const counted2 = v.counting.state === "counted";
|
|
1617
|
+
const rule = counted2 ? "must be present when the phase is counted" : "must be null until the phase is counted";
|
|
1618
|
+
if (v.methodFiles !== null !== counted2)
|
|
1619
|
+
ctx.addIssue({ code: "custom", path: ["methodFiles"], message: rule });
|
|
1620
|
+
if (v.outsideEveryPart.files !== null !== counted2) {
|
|
1621
|
+
ctx.addIssue({ code: "custom", path: ["outsideEveryPart", "files"], message: rule });
|
|
1622
|
+
}
|
|
1623
|
+
if (v.codeLink !== null !== counted2)
|
|
1624
|
+
ctx.addIssue({ code: "custom", path: ["codeLink"], message: rule });
|
|
1625
|
+
v.parts.forEach((entry, i) => {
|
|
1626
|
+
if (entry.files !== null !== counted2)
|
|
1627
|
+
ctx.addIssue({ code: "custom", path: ["parts", i, "files"], message: rule });
|
|
1628
|
+
});
|
|
1629
|
+
if (counted2 && v.descriptionVersion === null) {
|
|
1630
|
+
ctx.addIssue({ code: "custom", path: ["descriptionVersion"], message: "must name the version the counts used" });
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
var partOutsideThePlanSchema = z12.object({
|
|
1634
|
+
part: systemPartIdSchema,
|
|
1635
|
+
name: systemPartSchema.shape.name,
|
|
1636
|
+
seen: observedFilesSchema.nullable(),
|
|
1637
|
+
tasks: z12.array(observedSaidSchema.extend({ id: buildTaskSchema.shape.id }).strict()).max(BUILD_SNAPSHOT_TASK_LIMIT)
|
|
1638
|
+
}).strict();
|
|
1639
|
+
function shortCommit(commit) {
|
|
1640
|
+
return commit.slice(0, 7);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// ../events/dist/work-record.js
|
|
1644
|
+
import { z as z14 } from "zod";
|
|
1645
|
+
|
|
1646
|
+
// ../events/dist/crew-tier.js
|
|
1647
|
+
import { z as z13 } from "zod";
|
|
1648
|
+
var crewTierSchema = z13.enum(["deep", "standard", "fast"]);
|
|
1649
|
+
|
|
1650
|
+
// ../events/dist/work-record.js
|
|
1651
|
+
var agentWorkText = statementText(STATEMENT_MAX);
|
|
1652
|
+
var WORK_FINDINGS_MAX = 100;
|
|
1653
|
+
var WORK_ANSWERS_MAX = 100;
|
|
1654
|
+
var WORK_ATTEMPT_LIMIT = 4;
|
|
1655
|
+
var WORK_CLAIM_CHECKS_MAX = 20;
|
|
1656
|
+
var findingIdSchema = z14.string().regex(/^F[1-9][0-9]?\.[AQ][1-9][0-9]{0,2}$/, { message: "must be a finding id such as F1.A1" });
|
|
1657
|
+
var WORK_STAGES = Object.freeze(["asked", "quality"]);
|
|
1658
|
+
var workStageSchema = z14.enum(WORK_STAGES);
|
|
1659
|
+
var workVerdictSchema = z14.enum(["pass", "fail"]);
|
|
1660
|
+
var WORK_FINDING_KINDS = Object.freeze([
|
|
1661
|
+
"asked",
|
|
1662
|
+
"quality",
|
|
1663
|
+
"unrecorded-call",
|
|
1664
|
+
"undeclared-listed-decision"
|
|
1665
|
+
]);
|
|
1666
|
+
var workFindingKindSchema = z14.enum(WORK_FINDING_KINDS);
|
|
1667
|
+
var WORK_ASKED_ONLY_FINDING_KINDS = Object.freeze([
|
|
1668
|
+
"unrecorded-call",
|
|
1669
|
+
"undeclared-listed-decision"
|
|
1670
|
+
]);
|
|
1671
|
+
var workOutcomeSchema = z14.enum(["fixed", "declined", "deferred"]);
|
|
1672
|
+
var DIAGNOSIS_CAUSES = Object.freeze([
|
|
1673
|
+
"spec",
|
|
1674
|
+
"ordering",
|
|
1675
|
+
"approach",
|
|
1676
|
+
"capability",
|
|
1677
|
+
"environment",
|
|
1678
|
+
"review"
|
|
1679
|
+
]);
|
|
1680
|
+
var diagnosisCauseSchema = z14.enum(DIAGNOSIS_CAUSES);
|
|
1681
|
+
var diagnosisNextSchema = z14.enum(["different-way", "stop", "ask-person"]);
|
|
1682
|
+
var callUndoableSchema = z14.enum(["yes", "no"]);
|
|
1683
|
+
var callKindSchema = z14.enum(["default", "listed"]);
|
|
1684
|
+
var commitShaSchema = closeCommitSchema;
|
|
1685
|
+
var workChangeIdSchema = z14.string().uuid({ message: "must be the change id Halfcycle gave" });
|
|
1686
|
+
var workTaskSubjectSchema = z14.object({
|
|
1687
|
+
kind: z14.literal("task"),
|
|
1688
|
+
phase: buildPhaseSchema,
|
|
1689
|
+
task: buildTaskIdSchema
|
|
1690
|
+
}).strict();
|
|
1691
|
+
var workChangeSubjectSchema = z14.object({
|
|
1692
|
+
kind: z14.literal("change"),
|
|
1693
|
+
change: workChangeIdSchema
|
|
1694
|
+
}).strict();
|
|
1695
|
+
var workPhaseSubjectSchema = z14.object({
|
|
1696
|
+
kind: z14.literal("phase"),
|
|
1697
|
+
phase: buildPhaseSchema
|
|
1698
|
+
}).strict();
|
|
1699
|
+
var workSubjectSchema = z14.discriminatedUnion("kind", [
|
|
1700
|
+
workTaskSubjectSchema,
|
|
1701
|
+
workChangeSubjectSchema,
|
|
1702
|
+
workPhaseSubjectSchema
|
|
1703
|
+
]);
|
|
1704
|
+
var workItemSubjectSchema = z14.discriminatedUnion("kind", [workTaskSubjectSchema, workChangeSubjectSchema]);
|
|
1705
|
+
var workFindingInputSchema = z14.object({
|
|
1706
|
+
kind: workFindingKindSchema,
|
|
1707
|
+
says: agentWorkText
|
|
1708
|
+
}).strict();
|
|
1709
|
+
var workReviewRecordSchema = z14.object({
|
|
1710
|
+
record: z14.literal("review"),
|
|
1711
|
+
subject: workItemSubjectSchema,
|
|
1712
|
+
stage: workStageSchema,
|
|
1713
|
+
verdict: workVerdictSchema,
|
|
1714
|
+
reviewer: agentNameSchema,
|
|
1715
|
+
builder: agentNameSchema,
|
|
1716
|
+
builderTier: crewTierSchema,
|
|
1717
|
+
head: commitShaSchema,
|
|
1718
|
+
findings: z14.array(workFindingInputSchema).max(WORK_FINDINGS_MAX, { message: `can carry at most ${WORK_FINDINGS_MAX} findings` }),
|
|
1719
|
+
retryReason: agentWorkText.optional(),
|
|
1720
|
+
diagnosis: z14.string().uuid({ message: "must be the diagnosis id Halfcycle gave" }).optional(),
|
|
1721
|
+
followsDiagnosis: z14.boolean().optional()
|
|
1722
|
+
}).strict().refine((r) => r.stage === "asked" || r.findings.every((f) => !WORK_ASKED_ONLY_FINDING_KINDS.includes(f.kind)), {
|
|
1723
|
+
message: "a review for quality cannot raise an unrecorded call or an undeclared listed decision",
|
|
1724
|
+
path: ["findings"]
|
|
1725
|
+
});
|
|
1726
|
+
var workAnswerSchema = z14.object({
|
|
1727
|
+
finding: findingIdSchema,
|
|
1728
|
+
outcome: workOutcomeSchema,
|
|
1729
|
+
reason: agentWorkText.optional()
|
|
1730
|
+
}).strict().refine((a) => a.outcome === "fixed" === (a.reason === void 0), {
|
|
1731
|
+
message: "a reason is given exactly when a finding is declined or deferred",
|
|
1732
|
+
path: ["reason"]
|
|
1733
|
+
});
|
|
1734
|
+
var workOutcomesRecordSchema = z14.object({
|
|
1735
|
+
record: z14.literal("outcomes"),
|
|
1736
|
+
subject: workItemSubjectSchema,
|
|
1737
|
+
by: agentNameSchema,
|
|
1738
|
+
answers: z14.array(workAnswerSchema).min(1, { message: "must answer at least one finding" }).max(WORK_ANSWERS_MAX, { message: `can carry at most ${WORK_ANSWERS_MAX} answers` })
|
|
1739
|
+
}).strict().refine((r) => new Set(r.answers.map((a) => a.finding)).size === r.answers.length, {
|
|
1740
|
+
message: "answers each finding once",
|
|
1741
|
+
path: ["answers"]
|
|
1742
|
+
});
|
|
1743
|
+
var workClaimsRecordSchema = z14.object({
|
|
1744
|
+
record: z14.literal("claims"),
|
|
1745
|
+
subject: workItemSubjectSchema,
|
|
1746
|
+
head: commitShaSchema,
|
|
1747
|
+
by: agentNameSchema,
|
|
1748
|
+
checks: z14.array(z14.object({ label: agentWorkText }).strict()).min(1, { message: "must name at least one check" }).max(WORK_CLAIM_CHECKS_MAX, { message: `can name at most ${WORK_CLAIM_CHECKS_MAX} checks` })
|
|
1749
|
+
}).strict().refine((r) => new Set(r.checks.map((c) => c.label)).size === r.checks.length, {
|
|
1750
|
+
message: "names each check once",
|
|
1751
|
+
path: ["checks"]
|
|
1752
|
+
});
|
|
1753
|
+
var workDiagnosisRecordSchema = z14.object({
|
|
1754
|
+
record: z14.literal("diagnosis"),
|
|
1755
|
+
subject: workItemSubjectSchema,
|
|
1756
|
+
afterAttempt: z14.number().int().min(2, { message: "must be attempt 2 or later" }).max(WORK_ATTEMPT_LIMIT - 1, { message: `must be attempt ${WORK_ATTEMPT_LIMIT - 1} or earlier` }),
|
|
1757
|
+
by: agentNameSchema,
|
|
1758
|
+
cause: diagnosisCauseSchema,
|
|
1759
|
+
says: agentWorkText,
|
|
1760
|
+
next: diagnosisNextSchema,
|
|
1761
|
+
change: agentWorkText.optional(),
|
|
1762
|
+
question: agentWorkText.optional(),
|
|
1763
|
+
answer: agentWorkText.optional()
|
|
1764
|
+
}).strict().refine((r) => r.next === "different-way" === (r.change !== void 0), {
|
|
1765
|
+
message: "says what will change exactly when the next step is to try a different way",
|
|
1766
|
+
path: ["change"]
|
|
1767
|
+
}).refine((r) => r.next === "ask-person" === (r.question !== void 0), {
|
|
1768
|
+
message: "carries a question exactly when the next step is to ask the person",
|
|
1769
|
+
path: ["question"]
|
|
1770
|
+
});
|
|
1771
|
+
var workCallRecordSchema = z14.object({
|
|
1772
|
+
record: z14.literal("call"),
|
|
1773
|
+
subject: workSubjectSchema,
|
|
1774
|
+
by: agentNameSchema,
|
|
1775
|
+
question: agentWorkText,
|
|
1776
|
+
chose: agentWorkText,
|
|
1777
|
+
statedDefault: agentWorkText,
|
|
1778
|
+
undoable: callUndoableSchema,
|
|
1779
|
+
how: agentWorkText.optional()
|
|
1780
|
+
}).strict().refine((r) => r.undoable === "yes" === (r.how !== void 0), {
|
|
1781
|
+
message: "says how to undo it exactly when it can be undone",
|
|
1782
|
+
path: ["how"]
|
|
1783
|
+
});
|
|
1784
|
+
var workRecordSchema = z14.discriminatedUnion("record", [
|
|
1785
|
+
workReviewRecordSchema,
|
|
1786
|
+
workOutcomesRecordSchema,
|
|
1787
|
+
workClaimsRecordSchema,
|
|
1788
|
+
workDiagnosisRecordSchema,
|
|
1789
|
+
workCallRecordSchema
|
|
1790
|
+
]);
|
|
1791
|
+
var WORK_STANDINGS = Object.freeze([
|
|
1792
|
+
"not-reviewed",
|
|
1793
|
+
"stopped",
|
|
1794
|
+
"held",
|
|
1795
|
+
"needs-diagnosis",
|
|
1796
|
+
"failed",
|
|
1797
|
+
"in-review",
|
|
1798
|
+
"findings-open",
|
|
1799
|
+
"passed"
|
|
1800
|
+
]);
|
|
1801
|
+
var workStandingSchema = z14.enum(WORK_STANDINGS);
|
|
1802
|
+
var workRecordResultSchema = z14.object({
|
|
1803
|
+
outcome: z14.enum(["recorded", "kept"]),
|
|
1804
|
+
attempt: z14.number().int().min(1).optional(),
|
|
1805
|
+
findings: z14.array(findingIdSchema).max(WORK_FINDINGS_MAX).optional(),
|
|
1806
|
+
diagnosis: z14.string().uuid().optional(),
|
|
1807
|
+
standing: workStandingSchema,
|
|
1808
|
+
says: z14.string().min(1)
|
|
1809
|
+
}).strict();
|
|
1810
|
+
var WORK_REFUSAL_STATUS = Object.freeze({
|
|
1811
|
+
"phase-not-open": 409,
|
|
1812
|
+
"unknown-task": 400,
|
|
1813
|
+
"unknown-change": 404,
|
|
1814
|
+
"change-finished": 409,
|
|
1815
|
+
"out-of-order": 409,
|
|
1816
|
+
"same-agent": 409,
|
|
1817
|
+
"already-recorded": 409,
|
|
1818
|
+
"already-answered": 409,
|
|
1819
|
+
"unknown-finding": 400,
|
|
1820
|
+
"findings-unanswered": 409,
|
|
1821
|
+
"listed-decision-passed": 400,
|
|
1822
|
+
"needs-diagnosis": 409,
|
|
1823
|
+
"no-diagnosis-due": 409,
|
|
1824
|
+
"not-fresh": 409,
|
|
1825
|
+
"graph-unchanged": 409,
|
|
1826
|
+
"no-graph": 400,
|
|
1827
|
+
"wrong-diagnosis": 409,
|
|
1828
|
+
"diagnosis-not-followed": 400,
|
|
1829
|
+
stopped: 409,
|
|
1830
|
+
held: 409,
|
|
1831
|
+
"attempt-limit": 409,
|
|
1832
|
+
"same-attempt": 409,
|
|
1833
|
+
"call-not-recorded": 409
|
|
1834
|
+
});
|
|
1835
|
+
var WORK_REFUSALS = Object.freeze(Object.keys(WORK_REFUSAL_STATUS));
|
|
1836
|
+
var workRefusalSchema = z14.enum(WORK_REFUSALS);
|
|
1837
|
+
var workRefusalErrorSchema = wireErrorSchema.extend({ error: workRefusalSchema }).strict().refine((e) => e.statusCode === WORK_REFUSAL_STATUS[e.error], {
|
|
1838
|
+
message: "carries the status its refusal is answered with",
|
|
1839
|
+
path: ["statusCode"]
|
|
1840
|
+
});
|
|
1841
|
+
var testCommandIdSchema = z14.string().regex(/^[0-9a-f]{16}$/, { message: "must be 16 lower-case hex characters" });
|
|
1842
|
+
var workCountSchema = z14.number().int().min(0);
|
|
1843
|
+
var testRunReportSchema = z14.object({
|
|
1844
|
+
runId: z14.string().uuid(),
|
|
1845
|
+
subject: workItemSubjectSchema,
|
|
1846
|
+
label: agentWorkText,
|
|
1847
|
+
when: z14.enum(["before", "after"]),
|
|
1848
|
+
commandId: testCommandIdSchema,
|
|
1849
|
+
head: commitShaSchema,
|
|
1850
|
+
changedOutsideTests: workCountSchema,
|
|
1851
|
+
uncommitted: workCountSchema,
|
|
1852
|
+
beforeRunId: z14.string().uuid().nullable(),
|
|
1853
|
+
changedSinceBefore: workCountSchema.nullable(),
|
|
1854
|
+
exitCode: z14.number().int().nullable(),
|
|
1855
|
+
timedOut: z14.boolean(),
|
|
1856
|
+
passed: workCountSchema.nullable(),
|
|
1857
|
+
failed: workCountSchema.nullable(),
|
|
1858
|
+
durationMs: workCountSchema,
|
|
1859
|
+
startedAt: utcIso8601,
|
|
1860
|
+
reason: agentWorkText.optional()
|
|
1861
|
+
}).strict().refine((r) => r.passed === null === (r.failed === null), {
|
|
1862
|
+
message: "counts both passed and failed, or neither",
|
|
1863
|
+
path: ["failed"]
|
|
1864
|
+
}).refine((r) => r.when === "after" || r.beforeRunId === null && r.changedSinceBefore === null, {
|
|
1865
|
+
message: "a run before the change is measured against no earlier run",
|
|
1866
|
+
path: ["beforeRunId"]
|
|
1867
|
+
}).refine((r) => !r.timedOut || r.exitCode === null, {
|
|
1868
|
+
message: "a run that timed out has no exit code",
|
|
1869
|
+
path: ["exitCode"]
|
|
1870
|
+
});
|
|
1871
|
+
var testRunResultSchema = z14.object({ outcome: z14.literal("recorded") }).strict();
|
|
1872
|
+
var TEST_PROOF_REASONS = Object.freeze([
|
|
1873
|
+
"no-run-before",
|
|
1874
|
+
"before-after-change",
|
|
1875
|
+
"not-counted",
|
|
1876
|
+
"passed-before",
|
|
1877
|
+
"no-run-after",
|
|
1878
|
+
"command-changed",
|
|
1879
|
+
"not-after-before",
|
|
1880
|
+
"nothing-changed",
|
|
1881
|
+
"failed-after",
|
|
1882
|
+
"after-not-at-claimed-head"
|
|
1883
|
+
]);
|
|
1884
|
+
var testProofReasonSchema = z14.enum(TEST_PROOF_REASONS);
|
|
1885
|
+
var testProofStateSchema = z14.enum(["proven", "not-proven", "unchecked"]);
|
|
1886
|
+
var testRunCountsSchema = z14.object({
|
|
1887
|
+
passed: workCountSchema.nullable(),
|
|
1888
|
+
failed: workCountSchema.nullable(),
|
|
1889
|
+
durationMs: workCountSchema,
|
|
1890
|
+
timedOut: z14.boolean()
|
|
1891
|
+
}).strict();
|
|
1892
|
+
var workTestSchema = z14.object({
|
|
1893
|
+
label: agentWorkText,
|
|
1894
|
+
state: testProofStateSchema,
|
|
1895
|
+
why: testProofReasonSchema.optional(),
|
|
1896
|
+
claimedBy: agentNameSchema,
|
|
1897
|
+
before: testRunCountsSchema.optional(),
|
|
1898
|
+
after: testRunCountsSchema.optional()
|
|
1899
|
+
}).strict().refine((t) => t.state === "not-proven" === (t.why !== void 0), {
|
|
1900
|
+
message: "gives a reason exactly when a check is not proven",
|
|
1901
|
+
path: ["why"]
|
|
1902
|
+
});
|
|
1903
|
+
var workFindingOutcomeSchema = z14.object({
|
|
1904
|
+
outcome: workOutcomeSchema,
|
|
1905
|
+
reason: agentWorkText.optional(),
|
|
1906
|
+
by: agentNameSchema
|
|
1907
|
+
}).strict().refine((o) => o.outcome === "fixed" === (o.reason === void 0), {
|
|
1908
|
+
message: "a reason is given exactly when a finding is declined or deferred",
|
|
1909
|
+
path: ["reason"]
|
|
1910
|
+
});
|
|
1911
|
+
var workFindingSchema = z14.object({
|
|
1912
|
+
id: findingIdSchema,
|
|
1913
|
+
kind: workFindingKindSchema,
|
|
1914
|
+
says: agentWorkText,
|
|
1915
|
+
outcome: workFindingOutcomeSchema.optional()
|
|
1916
|
+
}).strict();
|
|
1917
|
+
var workStageViewSchema = z14.object({
|
|
1918
|
+
reviewer: agentNameSchema,
|
|
1919
|
+
verdict: workVerdictSchema,
|
|
1920
|
+
findings: z14.array(workFindingSchema).max(WORK_FINDINGS_MAX)
|
|
1921
|
+
}).strict();
|
|
1922
|
+
var workAttemptSchema = z14.object({
|
|
1923
|
+
attempt: z14.number().int().min(1),
|
|
1924
|
+
builder: agentNameSchema,
|
|
1925
|
+
builderTier: crewTierSchema,
|
|
1926
|
+
head: commitShaSchema,
|
|
1927
|
+
retryReason: agentWorkText.optional(),
|
|
1928
|
+
diagnosis: z14.string().uuid().optional(),
|
|
1929
|
+
followsDiagnosis: z14.boolean().optional(),
|
|
1930
|
+
asked: workStageViewSchema.optional(),
|
|
1931
|
+
quality: workStageViewSchema.optional()
|
|
1932
|
+
}).strict();
|
|
1933
|
+
var workDiagnosisSchema = z14.object({
|
|
1934
|
+
id: z14.string().uuid(),
|
|
1935
|
+
afterAttempt: z14.number().int().min(2).max(WORK_ATTEMPT_LIMIT - 1),
|
|
1936
|
+
by: agentNameSchema,
|
|
1937
|
+
cause: diagnosisCauseSchema,
|
|
1938
|
+
says: agentWorkText,
|
|
1939
|
+
next: diagnosisNextSchema,
|
|
1940
|
+
change: agentWorkText.optional(),
|
|
1941
|
+
question: agentWorkText.optional(),
|
|
1942
|
+
answer: agentWorkText.optional()
|
|
1943
|
+
}).strict().refine((d) => d.next === "different-way" === (d.change !== void 0), {
|
|
1944
|
+
message: "says what will change exactly when the next step is to try a different way",
|
|
1945
|
+
path: ["change"]
|
|
1946
|
+
}).refine((d) => d.next === "ask-person" === (d.question !== void 0), {
|
|
1947
|
+
message: "carries a question exactly when the next step is to ask the person",
|
|
1948
|
+
path: ["question"]
|
|
1949
|
+
});
|
|
1950
|
+
var workCallSchema = z14.object({
|
|
1951
|
+
subject: workSubjectSchema,
|
|
1952
|
+
by: agentNameSchema,
|
|
1953
|
+
kind: callKindSchema,
|
|
1954
|
+
question: agentWorkText,
|
|
1955
|
+
chose: agentWorkText,
|
|
1956
|
+
statedDefault: agentWorkText,
|
|
1957
|
+
undoable: callUndoableSchema,
|
|
1958
|
+
how: agentWorkText.nullable(),
|
|
1959
|
+
at: utcIso8601
|
|
1960
|
+
}).strict().superRefine((c, ctx) => checkReadCallHow(c, ctx));
|
|
1961
|
+
function checkReadCallHow(c, ctx) {
|
|
1962
|
+
if (c.undoable === "yes" !== (c.how !== null)) {
|
|
1963
|
+
ctx.addIssue({ code: "custom", path: ["how"], message: "says how to undo it exactly when it can be undone" });
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
var workTaskViewSchema = z14.object({
|
|
1967
|
+
task: buildTaskIdSchema,
|
|
1968
|
+
standing: workStandingSchema,
|
|
1969
|
+
attempts: z14.array(workAttemptSchema),
|
|
1970
|
+
diagnoses: z14.array(workDiagnosisSchema),
|
|
1971
|
+
tests: z14.array(workTestSchema)
|
|
1972
|
+
}).strict();
|
|
1973
|
+
var WORK_CLAIM_ACTS = Object.freeze(["accept", "reject"]);
|
|
1974
|
+
var workClaimActSchema = z14.enum(WORK_CLAIM_ACTS);
|
|
1975
|
+
var workClaimAnswerSchema = z14.object({
|
|
1976
|
+
act: workClaimActSchema,
|
|
1977
|
+
note: z14.string().min(1).max(SCOPE_NOTE_MAX).nullable()
|
|
1978
|
+
}).strict().refine((a) => a.act === "reject" === (a.note !== null), {
|
|
1979
|
+
message: "carries the owner's note exactly on a reject",
|
|
1980
|
+
path: ["note"]
|
|
1981
|
+
});
|
|
1982
|
+
var workUncheckedClaimSchema = z14.object({
|
|
1983
|
+
task: buildTaskIdSchema,
|
|
1984
|
+
label: agentWorkText,
|
|
1985
|
+
head: commitShaSchema,
|
|
1986
|
+
claimedBy: agentNameSchema,
|
|
1987
|
+
answer: workClaimAnswerSchema.nullable()
|
|
1988
|
+
}).strict();
|
|
1989
|
+
var phaseWorkSchema = z14.object({
|
|
1990
|
+
phase: buildPhaseSchema,
|
|
1991
|
+
tasks: z14.array(workTaskViewSchema),
|
|
1992
|
+
calls: z14.array(workCallSchema),
|
|
1993
|
+
uncheckedClaims: z14.array(workUncheckedClaimSchema)
|
|
1994
|
+
}).strict();
|
|
1995
|
+
|
|
1996
|
+
// ../events/dist/crew.js
|
|
1997
|
+
import { z as z15 } from "zod";
|
|
1998
|
+
var crewGroupSchema = z15.enum(["analyst-architect", "builder", "reviewer", "lead"]);
|
|
1999
|
+
var CREW_DISCIPLINE_MAX = 64;
|
|
2000
|
+
var crewFaceHeadSchema = z15.enum(["sq", "sqr", "rnd", "dome", "hex", "gable"]);
|
|
2001
|
+
var crewFaceAntennaSchema = z15.enum(["none", "stalk", "twin", "dish"]);
|
|
2002
|
+
var crewFaceEyesSchema = z15.enum(["dots", "bars", "visor", "cyclops"]);
|
|
2003
|
+
var crewFaceMouthSchema = z15.enum(["line", "grid", "dots", "wave"]);
|
|
2004
|
+
var crewFaceSchema = z15.object({
|
|
2005
|
+
// The outline of the head. Members who do the same kind of work share one, so a
|
|
2006
|
+
// team is recognisable before any name is read.
|
|
2007
|
+
head: crewFaceHeadSchema,
|
|
2008
|
+
// What sits on top of the head, if anything.
|
|
2009
|
+
antenna: crewFaceAntennaSchema,
|
|
2010
|
+
// The eyes.
|
|
2011
|
+
eyes: crewFaceEyesSchema,
|
|
2012
|
+
// The mouth.
|
|
2013
|
+
mouth: crewFaceMouthSchema,
|
|
2014
|
+
// Whether this member is drawn with ears.
|
|
2015
|
+
ears: z15.boolean()
|
|
2016
|
+
}).strict();
|
|
2017
|
+
var crewRoleSchema = z15.enum([
|
|
2018
|
+
"business-analyst",
|
|
2019
|
+
"architect",
|
|
2020
|
+
"spec-writer",
|
|
2021
|
+
"builder",
|
|
2022
|
+
"context-docs",
|
|
2023
|
+
"spec-reviewer",
|
|
2024
|
+
"code-test-reviewer",
|
|
2025
|
+
"delivery-lead",
|
|
2026
|
+
"quality-lead"
|
|
2027
|
+
]);
|
|
2028
|
+
var crewMemberSchema = z15.object({
|
|
2029
|
+
// The agent's name. The same names on every project, so a name is a
|
|
2030
|
+
// vocabulary a returning client already knows.
|
|
2031
|
+
callsign: z15.string().min(1).max(32),
|
|
2032
|
+
// Which of the four teams this member belongs to.
|
|
2033
|
+
group: crewGroupSchema,
|
|
2034
|
+
// The part this member plays, which decides the stages it leads and helps with.
|
|
2035
|
+
role: crewRoleSchema,
|
|
2036
|
+
// The kind of work this member takes. A task names a discipline, and only
|
|
2037
|
+
// agents holding it can be dispatched to it.
|
|
2038
|
+
discipline: z15.string().min(1).max(CREW_DISCIPLINE_MAX),
|
|
2039
|
+
// How much thinking this member brings. There is no field naming the supplier
|
|
2040
|
+
// behind it, on this shape or on any other.
|
|
2041
|
+
tier: crewTierSchema,
|
|
2042
|
+
// How this member's face is drawn. The same face on every project, so a
|
|
2043
|
+
// returning client recognises a member before reading the name.
|
|
2044
|
+
face: crewFaceSchema
|
|
2045
|
+
}).strict();
|
|
2046
|
+
var CREW_ROSTER = [
|
|
2047
|
+
// ── analysts and architects ─────────────────────────────────────────────────
|
|
2048
|
+
{
|
|
2049
|
+
callsign: "SOFIA",
|
|
2050
|
+
group: "analyst-architect",
|
|
2051
|
+
role: "business-analyst",
|
|
2052
|
+
discipline: "business analyst",
|
|
2053
|
+
tier: "deep",
|
|
2054
|
+
face: { head: "gable", antenna: "stalk", eyes: "dots", mouth: "wave", ears: false }
|
|
2055
|
+
},
|
|
2056
|
+
{
|
|
2057
|
+
callsign: "BEA",
|
|
2058
|
+
group: "analyst-architect",
|
|
2059
|
+
role: "business-analyst",
|
|
2060
|
+
discipline: "business analyst",
|
|
2061
|
+
tier: "standard",
|
|
2062
|
+
face: { head: "gable", antenna: "none", eyes: "visor", mouth: "line", ears: false }
|
|
2063
|
+
},
|
|
2064
|
+
{
|
|
2065
|
+
callsign: "WREN",
|
|
2066
|
+
group: "analyst-architect",
|
|
2067
|
+
role: "architect",
|
|
2068
|
+
discipline: "solution architect",
|
|
2069
|
+
tier: "deep",
|
|
2070
|
+
face: { head: "gable", antenna: "dish", eyes: "bars", mouth: "line", ears: true }
|
|
2071
|
+
},
|
|
2072
|
+
{
|
|
2073
|
+
callsign: "PEI",
|
|
2074
|
+
group: "analyst-architect",
|
|
2075
|
+
role: "architect",
|
|
2076
|
+
discipline: "technical architect",
|
|
2077
|
+
tier: "standard",
|
|
2078
|
+
face: { head: "gable", antenna: "twin", eyes: "cyclops", mouth: "dots", ears: false }
|
|
2079
|
+
},
|
|
2080
|
+
// ── builders: code ──────────────────────────────────────────────────────────
|
|
2081
|
+
{
|
|
2082
|
+
callsign: "ADA",
|
|
2083
|
+
group: "builder",
|
|
2084
|
+
role: "builder",
|
|
2085
|
+
discipline: "implementation",
|
|
2086
|
+
tier: "deep",
|
|
2087
|
+
face: { head: "sq", antenna: "stalk", eyes: "dots", mouth: "line", ears: false }
|
|
2088
|
+
},
|
|
2089
|
+
{
|
|
2090
|
+
callsign: "OTTO",
|
|
2091
|
+
group: "builder",
|
|
2092
|
+
role: "builder",
|
|
2093
|
+
discipline: "implementation",
|
|
2094
|
+
tier: "deep",
|
|
2095
|
+
face: { head: "sq", antenna: "twin", eyes: "bars", mouth: "grid", ears: true }
|
|
2096
|
+
},
|
|
2097
|
+
{
|
|
2098
|
+
callsign: "MILO",
|
|
2099
|
+
group: "builder",
|
|
2100
|
+
role: "builder",
|
|
2101
|
+
discipline: "implementation",
|
|
2102
|
+
tier: "standard",
|
|
2103
|
+
face: { head: "sqr", antenna: "stalk", eyes: "dots", mouth: "dots", ears: false }
|
|
2104
|
+
},
|
|
2105
|
+
{
|
|
2106
|
+
callsign: "NOVA",
|
|
2107
|
+
group: "builder",
|
|
2108
|
+
role: "builder",
|
|
2109
|
+
discipline: "implementation",
|
|
2110
|
+
tier: "standard",
|
|
2111
|
+
face: { head: "sq", antenna: "dish", eyes: "cyclops", mouth: "line", ears: false }
|
|
2112
|
+
},
|
|
2113
|
+
{
|
|
2114
|
+
callsign: "HUGO",
|
|
2115
|
+
group: "builder",
|
|
2116
|
+
role: "builder",
|
|
2117
|
+
discipline: "infrastructure",
|
|
2118
|
+
tier: "standard",
|
|
2119
|
+
face: { head: "sq", antenna: "twin", eyes: "dots", mouth: "grid", ears: true }
|
|
2120
|
+
},
|
|
2121
|
+
// ── builders: specs and docs ────────────────────────────────────────────────
|
|
2122
|
+
{
|
|
2123
|
+
callsign: "IRIS",
|
|
2124
|
+
group: "builder",
|
|
2125
|
+
role: "spec-writer",
|
|
2126
|
+
discipline: "feature spec",
|
|
2127
|
+
tier: "deep",
|
|
2128
|
+
face: { head: "dome", antenna: "stalk", eyes: "visor", mouth: "line", ears: false }
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
callsign: "JUNO",
|
|
2132
|
+
group: "builder",
|
|
2133
|
+
role: "spec-writer",
|
|
2134
|
+
discipline: "feature spec",
|
|
2135
|
+
tier: "standard",
|
|
2136
|
+
face: { head: "dome", antenna: "none", eyes: "dots", mouth: "wave", ears: false }
|
|
2137
|
+
},
|
|
2138
|
+
{
|
|
2139
|
+
callsign: "LEX",
|
|
2140
|
+
group: "builder",
|
|
2141
|
+
role: "context-docs",
|
|
2142
|
+
discipline: "context & docs",
|
|
2143
|
+
tier: "fast",
|
|
2144
|
+
face: { head: "dome", antenna: "twin", eyes: "bars", mouth: "dots", ears: false }
|
|
2145
|
+
},
|
|
2146
|
+
// ── reviewers ───────────────────────────────────────────────────────────────
|
|
2147
|
+
{
|
|
2148
|
+
callsign: "VERA",
|
|
2149
|
+
group: "reviewer",
|
|
2150
|
+
role: "spec-reviewer",
|
|
2151
|
+
discipline: "spec consistency",
|
|
2152
|
+
tier: "deep",
|
|
2153
|
+
face: { head: "rnd", antenna: "stalk", eyes: "visor", mouth: "line", ears: false }
|
|
2154
|
+
},
|
|
2155
|
+
{
|
|
2156
|
+
callsign: "ODIN",
|
|
2157
|
+
group: "reviewer",
|
|
2158
|
+
role: "spec-reviewer",
|
|
2159
|
+
discipline: "cross-spec audit",
|
|
2160
|
+
tier: "deep",
|
|
2161
|
+
face: { head: "rnd", antenna: "dish", eyes: "cyclops", mouth: "line", ears: false }
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
callsign: "CASS",
|
|
2165
|
+
group: "reviewer",
|
|
2166
|
+
role: "code-test-reviewer",
|
|
2167
|
+
discipline: "code review",
|
|
2168
|
+
tier: "deep",
|
|
2169
|
+
face: { head: "rnd", antenna: "none", eyes: "visor", mouth: "grid", ears: true }
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
callsign: "THEO",
|
|
2173
|
+
group: "reviewer",
|
|
2174
|
+
role: "code-test-reviewer",
|
|
2175
|
+
discipline: "code review",
|
|
2176
|
+
tier: "standard",
|
|
2177
|
+
face: { head: "rnd", antenna: "twin", eyes: "bars", mouth: "line", ears: false }
|
|
2178
|
+
},
|
|
2179
|
+
{
|
|
2180
|
+
callsign: "KAI",
|
|
2181
|
+
group: "reviewer",
|
|
2182
|
+
role: "code-test-reviewer",
|
|
2183
|
+
discipline: "code review",
|
|
2184
|
+
tier: "standard",
|
|
2185
|
+
face: { head: "rnd", antenna: "none", eyes: "bars", mouth: "line", ears: true }
|
|
2186
|
+
},
|
|
2187
|
+
{
|
|
2188
|
+
callsign: "ECHO",
|
|
2189
|
+
group: "reviewer",
|
|
2190
|
+
role: "code-test-reviewer",
|
|
2191
|
+
discipline: "test quality",
|
|
2192
|
+
tier: "standard",
|
|
2193
|
+
face: { head: "rnd", antenna: "stalk", eyes: "dots", mouth: "wave", ears: false }
|
|
2194
|
+
},
|
|
2195
|
+
{
|
|
2196
|
+
callsign: "MAVIS",
|
|
2197
|
+
group: "reviewer",
|
|
2198
|
+
role: "code-test-reviewer",
|
|
2199
|
+
discipline: "suites & coverage",
|
|
2200
|
+
tier: "standard",
|
|
2201
|
+
face: { head: "rnd", antenna: "none", eyes: "visor", mouth: "dots", ears: false }
|
|
2202
|
+
},
|
|
2203
|
+
{
|
|
2204
|
+
callsign: "ZARA",
|
|
2205
|
+
group: "reviewer",
|
|
2206
|
+
role: "code-test-reviewer",
|
|
2207
|
+
discipline: "smoke & walk aid",
|
|
2208
|
+
tier: "standard",
|
|
2209
|
+
face: { head: "rnd", antenna: "dish", eyes: "bars", mouth: "wave", ears: false }
|
|
2210
|
+
},
|
|
2211
|
+
{
|
|
2212
|
+
callsign: "NORA",
|
|
2213
|
+
group: "reviewer",
|
|
2214
|
+
role: "code-test-reviewer",
|
|
2215
|
+
discipline: "evidence & provenance",
|
|
2216
|
+
tier: "fast",
|
|
2217
|
+
face: { head: "rnd", antenna: "twin", eyes: "dots", mouth: "line", ears: false }
|
|
2218
|
+
},
|
|
2219
|
+
// ── leads ───────────────────────────────────────────────────────────────────
|
|
2220
|
+
{
|
|
2221
|
+
callsign: "ARGUS",
|
|
2222
|
+
group: "lead",
|
|
2223
|
+
role: "quality-lead",
|
|
2224
|
+
discipline: "quality lead \xB7 every diff",
|
|
2225
|
+
tier: "standard",
|
|
2226
|
+
face: { head: "hex", antenna: "dish", eyes: "visor", mouth: "grid", ears: true }
|
|
2227
|
+
},
|
|
2228
|
+
{
|
|
2229
|
+
callsign: "ATLAS",
|
|
2230
|
+
group: "lead",
|
|
2231
|
+
role: "delivery-lead",
|
|
2232
|
+
discipline: "delivery lead",
|
|
2233
|
+
tier: "deep",
|
|
2234
|
+
face: { head: "hex", antenna: "twin", eyes: "cyclops", mouth: "line", ears: true }
|
|
2235
|
+
}
|
|
2236
|
+
];
|
|
2237
|
+
var CREW_ROSTER_SIZE = CREW_ROSTER.length;
|
|
2238
|
+
var CREW_CALLSIGNS = CREW_ROSTER.map((member) => member.callsign);
|
|
2239
|
+
var crewLayerSchema = methodLayerSchema.extract(["l0", "l1", "l2", "l3", "l4", "l5"]);
|
|
2240
|
+
var crewRoleLayersSchema = z15.object({
|
|
2241
|
+
leads: z15.array(crewLayerSchema),
|
|
2242
|
+
helps: z15.array(crewLayerSchema)
|
|
1745
2243
|
}).strict();
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
2244
|
+
|
|
2245
|
+
// ../events/dist/build-record-v3.js
|
|
2246
|
+
import { z as z18 } from "zod";
|
|
2247
|
+
|
|
2248
|
+
// ../events/dist/board-vocabulary.js
|
|
2249
|
+
import { z as z16 } from "zod";
|
|
2250
|
+
var boardStepStateSchema = z16.enum([
|
|
2251
|
+
"not-instrumented",
|
|
2252
|
+
"done",
|
|
2253
|
+
"did-not-pass",
|
|
2254
|
+
"could-not-complete",
|
|
2255
|
+
"not-yet-available",
|
|
2256
|
+
"qualified"
|
|
1750
2257
|
]);
|
|
1751
|
-
var
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
startCommit: closeCommitSchema,
|
|
1758
|
-
startRecordedAt: utcIso8601,
|
|
1759
|
-
headCommit: closeCommitSchema,
|
|
1760
|
-
headCommittedAt: utcIso8601,
|
|
1761
|
-
commits: observedCountSchema,
|
|
1762
|
-
countedAt: utcIso8601
|
|
1763
|
-
}).strict(),
|
|
1764
|
-
z12.object({
|
|
1765
|
-
state: z12.literal("not-counted-yet"),
|
|
1766
|
-
startCommit: closeCommitSchema,
|
|
1767
|
-
startRecordedAt: utcIso8601
|
|
1768
|
-
}).strict(),
|
|
1769
|
-
z12.object({
|
|
1770
|
-
state: z12.literal("cannot-count")
|
|
1771
|
-
}).strict()
|
|
2258
|
+
var boardGateNameSchema = z16.enum([
|
|
2259
|
+
"scope",
|
|
2260
|
+
"architecture",
|
|
2261
|
+
"specs",
|
|
2262
|
+
"taskgraph",
|
|
2263
|
+
"phase-close"
|
|
1772
2264
|
]);
|
|
1773
|
-
var observedPartSchema = z12.object({
|
|
1774
|
-
part: systemPartIdSchema,
|
|
1775
|
-
files: observedFilesSchema.nullable(),
|
|
1776
|
-
checksFired: observedChecksFiredSchema
|
|
1777
|
-
}).strict().refine((v) => v.files !== null && filesChanged(v.files) >= 1 || v.checksFired.length >= 1, {
|
|
1778
|
-
message: "a part is listed only when files changed under it or a check fired on one",
|
|
1779
|
-
path: ["files"]
|
|
1780
|
-
});
|
|
1781
|
-
var observedOutsideSchema = z12.object({
|
|
1782
|
-
files: observedFilesSchema.nullable(),
|
|
1783
|
-
paths: observedPathListSchema,
|
|
1784
|
-
checksFired: observedChecksFiredSchema
|
|
1785
|
-
}).strict().refine((v) => pathsFitTheCount(v.files, v.paths), {
|
|
1786
|
-
message: "lists more paths than files changed",
|
|
1787
|
-
path: ["paths"]
|
|
1788
|
-
});
|
|
1789
|
-
var observedChangesSchema = z12.object({
|
|
1790
|
-
phase: phaseNameSchema,
|
|
1791
|
-
counting: observedCountingSchema,
|
|
1792
|
-
descriptionVersion: observedDescriptionVersionSchema.nullable(),
|
|
1793
|
-
parts: z12.array(observedPartSchema).max(SYSTEM_PARTS_MAX),
|
|
1794
|
-
methodFiles: observedMethodFilesSchema.nullable(),
|
|
1795
|
-
outsideEveryPart: observedOutsideSchema,
|
|
1796
|
-
codeLink: codeLinkFactsSchema.nullable()
|
|
1797
|
-
}).strict().superRefine((v, ctx) => {
|
|
1798
|
-
checkPartsUnique(v.parts, ctx, ["parts"]);
|
|
1799
|
-
const counted2 = v.counting.state === "counted";
|
|
1800
|
-
const rule = counted2 ? "must be present when the phase is counted" : "must be null until the phase is counted";
|
|
1801
|
-
if (v.methodFiles !== null !== counted2)
|
|
1802
|
-
ctx.addIssue({ code: "custom", path: ["methodFiles"], message: rule });
|
|
1803
|
-
if (v.outsideEveryPart.files !== null !== counted2) {
|
|
1804
|
-
ctx.addIssue({ code: "custom", path: ["outsideEveryPart", "files"], message: rule });
|
|
1805
|
-
}
|
|
1806
|
-
if (v.codeLink !== null !== counted2)
|
|
1807
|
-
ctx.addIssue({ code: "custom", path: ["codeLink"], message: rule });
|
|
1808
|
-
v.parts.forEach((entry, i) => {
|
|
1809
|
-
if (entry.files !== null !== counted2)
|
|
1810
|
-
ctx.addIssue({ code: "custom", path: ["parts", i, "files"], message: rule });
|
|
1811
|
-
});
|
|
1812
|
-
if (counted2 && v.descriptionVersion === null) {
|
|
1813
|
-
ctx.addIssue({ code: "custom", path: ["descriptionVersion"], message: "must name the version the counts used" });
|
|
1814
|
-
}
|
|
1815
|
-
});
|
|
1816
|
-
var partOutsideThePlanSchema = z12.object({
|
|
1817
|
-
part: systemPartIdSchema,
|
|
1818
|
-
name: systemPartSchema.shape.name,
|
|
1819
|
-
seen: observedFilesSchema.nullable(),
|
|
1820
|
-
tasks: z12.array(observedSaidSchema.extend({ id: buildTaskSchema.shape.id }).strict()).max(BUILD_SNAPSHOT_TASK_LIMIT)
|
|
1821
|
-
}).strict();
|
|
1822
|
-
function shortCommit(commit) {
|
|
1823
|
-
return commit.slice(0, 7);
|
|
1824
|
-
}
|
|
1825
2265
|
|
|
1826
2266
|
// ../events/dist/phase-review.js
|
|
1827
|
-
import { z as
|
|
2267
|
+
import { z as z17 } from "zod";
|
|
1828
2268
|
var BUILT_PART_ACTS = Object.freeze(["accept", "question", "send-back"]);
|
|
1829
2269
|
var NOT_BUILT_PART_ACTS = Object.freeze(["carry", "drop"]);
|
|
1830
2270
|
var REVIEW_ACTS = Object.freeze([...BUILT_PART_ACTS, ...NOT_BUILT_PART_ACTS]);
|
|
1831
|
-
var reviewActSchema =
|
|
2271
|
+
var reviewActSchema = z17.enum(REVIEW_ACTS);
|
|
1832
2272
|
function reviewActsFor(built) {
|
|
1833
2273
|
return built ? BUILT_PART_ACTS : NOT_BUILT_PART_ACTS;
|
|
1834
2274
|
}
|
|
1835
2275
|
var REVIEW_NOTE_MAX = SCOPE_NOTE_MAX;
|
|
1836
|
-
var reviewNoteWireSchema =
|
|
1837
|
-
var reviewNoteSchema =
|
|
2276
|
+
var reviewNoteWireSchema = z17.string().max(REVIEW_NOTE_MAX);
|
|
2277
|
+
var reviewNoteSchema = z17.string().min(1).max(REVIEW_NOTE_MAX);
|
|
1838
2278
|
var REVIEW_ANSWER_MAX = 1e3;
|
|
1839
|
-
var reviewAgentAnswerSchema =
|
|
2279
|
+
var reviewAgentAnswerSchema = z17.string().min(1).max(REVIEW_ANSWER_MAX);
|
|
1840
2280
|
var REVIEW_PARTS_MAX = PHASE_PLAN_CHANGES_MAX * 2;
|
|
1841
2281
|
var REVIEW_PART_CHANGES = Object.freeze([...PHASE_PLAN_CHANGE_KINDS, "not-in-plan"]);
|
|
1842
|
-
var reviewPartChangeSchema =
|
|
2282
|
+
var reviewPartChangeSchema = z17.enum(REVIEW_PART_CHANGES);
|
|
1843
2283
|
var REVIEW_DECISIONS = Object.freeze(["accepted", "carried", "dropped"]);
|
|
1844
|
-
var reviewDecisionSchema =
|
|
2284
|
+
var reviewDecisionSchema = z17.enum(REVIEW_DECISIONS);
|
|
1845
2285
|
function actOf(decision) {
|
|
1846
2286
|
if (decision === "accepted")
|
|
1847
2287
|
return "accept";
|
|
@@ -1853,10 +2293,10 @@ var reviewCarriedToSchema = carriedPhaseSchema.nullable();
|
|
|
1853
2293
|
var reviewStepNameSchema = stepNameSchema.refine((v) => !stepIdSchema.safeParse(v.trim()).success, {
|
|
1854
2294
|
message: "must be the step's plain name"
|
|
1855
2295
|
});
|
|
1856
|
-
var reviewStepSchema =
|
|
2296
|
+
var reviewStepSchema = z17.object({
|
|
1857
2297
|
name: reviewStepNameSchema.nullable(),
|
|
1858
2298
|
state: unfinishedStepSchema.shape.state,
|
|
1859
|
-
judged:
|
|
2299
|
+
judged: z17.boolean()
|
|
1860
2300
|
}).strict();
|
|
1861
2301
|
function codeLinkLine(link) {
|
|
1862
2302
|
switch (link.kind) {
|
|
@@ -1873,41 +2313,41 @@ function codeLinkLine(link) {
|
|
|
1873
2313
|
function assertNever(value) {
|
|
1874
2314
|
throw new Error(`unexpected value: ${JSON.stringify(value)}`);
|
|
1875
2315
|
}
|
|
1876
|
-
var openReviewRequestSchema =
|
|
2316
|
+
var openReviewRequestSchema = z17.object({
|
|
1877
2317
|
actor: closeActorSchema,
|
|
1878
2318
|
acceptanceOutcome: acceptanceOutcomeSchema,
|
|
1879
2319
|
statements: closeStatementsSchema
|
|
1880
2320
|
}).strict();
|
|
1881
2321
|
var REVIEW_OPEN_TASKS_SHOWN_MAX = 10;
|
|
1882
|
-
var reviewOpenedSchema =
|
|
1883
|
-
outcome:
|
|
1884
|
-
round:
|
|
1885
|
-
parts:
|
|
1886
|
-
notBuilt:
|
|
1887
|
-
counted:
|
|
1888
|
-
typedReviewOffered:
|
|
2322
|
+
var reviewOpenedSchema = z17.object({
|
|
2323
|
+
outcome: z17.literal("opened"),
|
|
2324
|
+
round: z17.number().int().min(1),
|
|
2325
|
+
parts: z17.number().int().min(0).max(REVIEW_PARTS_MAX),
|
|
2326
|
+
notBuilt: z17.number().int().min(0).max(REVIEW_PARTS_MAX),
|
|
2327
|
+
counted: z17.boolean(),
|
|
2328
|
+
typedReviewOffered: z17.boolean()
|
|
1889
2329
|
}).strict().refine((v) => v.notBuilt <= v.parts, { message: "cannot exceed the parts in the round", path: ["notBuilt"] });
|
|
1890
|
-
var reviewTasksOpenSchema =
|
|
1891
|
-
outcome:
|
|
1892
|
-
open:
|
|
1893
|
-
more:
|
|
2330
|
+
var reviewTasksOpenSchema = z17.object({
|
|
2331
|
+
outcome: z17.literal("tasks-open"),
|
|
2332
|
+
open: z17.array(buildTaskSchema.shape.title).min(1).max(REVIEW_OPEN_TASKS_SHOWN_MAX),
|
|
2333
|
+
more: z17.number().int().min(0).max(BUILD_SNAPSHOT_TASK_LIMIT)
|
|
1894
2334
|
}).strict();
|
|
1895
|
-
var reviewOutstandingSchema =
|
|
1896
|
-
outcome:
|
|
1897
|
-
steps:
|
|
2335
|
+
var reviewOutstandingSchema = z17.object({
|
|
2336
|
+
outcome: z17.literal("outstanding"),
|
|
2337
|
+
steps: z17.array(reviewStepSchema).min(1)
|
|
1898
2338
|
}).strict();
|
|
1899
|
-
var reviewCleanOverFindingsSchema =
|
|
1900
|
-
outcome:
|
|
1901
|
-
findings:
|
|
2339
|
+
var reviewCleanOverFindingsSchema = z17.object({
|
|
2340
|
+
outcome: z17.literal("clean-over-findings"),
|
|
2341
|
+
findings: z17.number().int().min(1)
|
|
1902
2342
|
}).strict();
|
|
1903
|
-
var reviewRefusedSchema =
|
|
1904
|
-
outcome:
|
|
1905
|
-
problems:
|
|
2343
|
+
var reviewRefusedSchema = z17.object({
|
|
2344
|
+
outcome: z17.literal("refused"),
|
|
2345
|
+
problems: z17.array(systemDescriptionProblemSchema).min(1)
|
|
1906
2346
|
}).strict();
|
|
1907
2347
|
function bareReviewOutcome(outcome) {
|
|
1908
|
-
return
|
|
2348
|
+
return z17.object({ outcome: z17.literal(outcome) }).strict();
|
|
1909
2349
|
}
|
|
1910
|
-
var openReviewResultSchema =
|
|
2350
|
+
var openReviewResultSchema = z17.discriminatedUnion("outcome", [
|
|
1911
2351
|
reviewOpenedSchema,
|
|
1912
2352
|
reviewTasksOpenSchema,
|
|
1913
2353
|
bareReviewOutcome("no-build"),
|
|
@@ -1917,23 +2357,33 @@ var openReviewResultSchema = z13.discriminatedUnion("outcome", [
|
|
|
1917
2357
|
reviewRefusedSchema,
|
|
1918
2358
|
bareReviewOutcome("unavailable")
|
|
1919
2359
|
]);
|
|
1920
|
-
var reviewPhaseNotOpenSchema =
|
|
1921
|
-
statusCode:
|
|
1922
|
-
error:
|
|
1923
|
-
message:
|
|
1924
|
-
openPhase:
|
|
2360
|
+
var reviewPhaseNotOpenSchema = z17.object({
|
|
2361
|
+
statusCode: z17.literal(409),
|
|
2362
|
+
error: z17.literal("PhaseNotOpen"),
|
|
2363
|
+
message: z17.string().min(1),
|
|
2364
|
+
openPhase: z17.string().nullable()
|
|
1925
2365
|
}).strict();
|
|
1926
|
-
var openReviewAnswerSchema =
|
|
1927
|
-
var reviewDecisionEntrySchema =
|
|
2366
|
+
var openReviewAnswerSchema = z17.union([openReviewResultSchema, reviewPhaseNotOpenSchema]);
|
|
2367
|
+
var reviewDecisionEntrySchema = z17.object({
|
|
1928
2368
|
part: systemPartIdSchema,
|
|
1929
2369
|
act: reviewActSchema,
|
|
1930
2370
|
note: reviewNoteWireSchema.optional()
|
|
1931
2371
|
}).strict();
|
|
1932
|
-
var
|
|
1933
|
-
|
|
1934
|
-
|
|
2372
|
+
var reviewClaimActSchema = workClaimActSchema;
|
|
2373
|
+
var REVIEW_CLAIMS_MAX = BUILD_SNAPSHOT_TASK_LIMIT * WORK_CLAIM_CHECKS_MAX;
|
|
2374
|
+
var reviewClaimAnswerSchema = z17.object({
|
|
2375
|
+
task: buildTaskIdSchema,
|
|
2376
|
+
label: agentWorkText,
|
|
2377
|
+
head: commitShaSchema,
|
|
2378
|
+
act: reviewClaimActSchema,
|
|
2379
|
+
note: reviewNoteWireSchema.optional()
|
|
2380
|
+
}).strict();
|
|
2381
|
+
var reviewDecisionRequestSchema = z17.object({
|
|
2382
|
+
reviewVersion: z17.number().int().min(0),
|
|
2383
|
+
decisions: z17.array(reviewDecisionEntrySchema).max(REVIEW_PARTS_MAX),
|
|
2384
|
+
claims: z17.array(reviewClaimAnswerSchema).max(REVIEW_CLAIMS_MAX)
|
|
1935
2385
|
}).strict();
|
|
1936
|
-
var reviewDecidedSchema =
|
|
2386
|
+
var reviewDecidedSchema = z17.object({
|
|
1937
2387
|
part: systemPartIdSchema,
|
|
1938
2388
|
name: systemPartSchema.shape.name,
|
|
1939
2389
|
act: reviewActSchema,
|
|
@@ -1942,39 +2392,51 @@ var reviewDecidedSchema = z13.object({
|
|
|
1942
2392
|
message: "is present exactly on a carry",
|
|
1943
2393
|
path: ["carriedTo"]
|
|
1944
2394
|
});
|
|
1945
|
-
var reviewRecordedSchema =
|
|
1946
|
-
outcome:
|
|
1947
|
-
decided:
|
|
1948
|
-
waiting:
|
|
1949
|
-
closed:
|
|
1950
|
-
reviewVersion:
|
|
2395
|
+
var reviewRecordedSchema = z17.object({
|
|
2396
|
+
outcome: z17.literal("recorded"),
|
|
2397
|
+
decided: z17.array(reviewDecidedSchema).max(REVIEW_PARTS_MAX),
|
|
2398
|
+
waiting: z17.number().int().min(0).max(REVIEW_PARTS_MAX),
|
|
2399
|
+
closed: z17.boolean(),
|
|
2400
|
+
reviewVersion: z17.number().int().min(1)
|
|
1951
2401
|
}).strict().superRefine((v, ctx) => {
|
|
1952
2402
|
if (v.closed && v.waiting !== 0) {
|
|
1953
2403
|
ctx.addIssue({ code: "custom", path: ["waiting"], message: "must be 0 once the phase is closed" });
|
|
1954
2404
|
}
|
|
1955
|
-
if (v.decided.length === 0 && !v.closed) {
|
|
1956
|
-
ctx.addIssue({ code: "custom", path: ["decided"], message: "may be empty only when the phase closed" });
|
|
1957
|
-
}
|
|
1958
2405
|
});
|
|
1959
2406
|
var REVIEW_NOT_DECIDABLE_WHY = Object.freeze(["settled", "question-waiting", "sent-back"]);
|
|
1960
|
-
var reviewNotDecidablePartSchema =
|
|
2407
|
+
var reviewNotDecidablePartSchema = z17.object({
|
|
1961
2408
|
part: systemPartIdSchema,
|
|
1962
2409
|
name: systemPartSchema.shape.name,
|
|
1963
|
-
why:
|
|
2410
|
+
why: z17.enum(REVIEW_NOT_DECIDABLE_WHY)
|
|
2411
|
+
}).strict();
|
|
2412
|
+
var REVIEW_CLAIM_NOT_DECIDABLE_WHY = Object.freeze(["not-unchecked", "answered", "claim-changed"]);
|
|
2413
|
+
var reviewClaimNotDecidableWhySchema = z17.enum(REVIEW_CLAIM_NOT_DECIDABLE_WHY);
|
|
2414
|
+
var reviewNotDecidableClaimSchema = z17.object({
|
|
2415
|
+
task: buildTaskIdSchema,
|
|
2416
|
+
label: agentWorkText,
|
|
2417
|
+
why: reviewClaimNotDecidableWhySchema
|
|
1964
2418
|
}).strict();
|
|
1965
|
-
var reviewNotDecidableSchema =
|
|
1966
|
-
outcome:
|
|
1967
|
-
parts:
|
|
2419
|
+
var reviewNotDecidableSchema = z17.object({
|
|
2420
|
+
outcome: z17.literal("not-decidable"),
|
|
2421
|
+
parts: z17.array(reviewNotDecidablePartSchema).max(REVIEW_PARTS_MAX),
|
|
2422
|
+
claims: z17.array(reviewNotDecidableClaimSchema).max(REVIEW_CLAIMS_MAX)
|
|
2423
|
+
}).strict().refine((v) => v.parts.length + v.claims.length > 0, {
|
|
2424
|
+
message: "names at least one part or claim",
|
|
2425
|
+
path: ["parts"]
|
|
2426
|
+
});
|
|
2427
|
+
var reviewPartsNotDecidableSchema = z17.object({
|
|
2428
|
+
outcome: z17.literal("not-decidable"),
|
|
2429
|
+
parts: z17.array(reviewNotDecidablePartSchema).min(1).max(REVIEW_PARTS_MAX)
|
|
1968
2430
|
}).strict();
|
|
1969
|
-
var reviewCloseRefusedSchema =
|
|
1970
|
-
outcome:
|
|
1971
|
-
steps:
|
|
2431
|
+
var reviewCloseRefusedSchema = z17.object({
|
|
2432
|
+
outcome: z17.literal("close-refused"),
|
|
2433
|
+
steps: z17.array(reviewStepSchema)
|
|
1972
2434
|
}).strict();
|
|
1973
|
-
var reviewWalkChangedSchema =
|
|
1974
|
-
outcome:
|
|
1975
|
-
findings:
|
|
2435
|
+
var reviewWalkChangedSchema = z17.object({
|
|
2436
|
+
outcome: z17.literal("walk-changed"),
|
|
2437
|
+
findings: z17.number().int().min(1)
|
|
1976
2438
|
}).strict();
|
|
1977
|
-
var reviewDecisionResultSchema =
|
|
2439
|
+
var reviewDecisionResultSchema = z17.discriminatedUnion("outcome", [
|
|
1978
2440
|
reviewRecordedSchema,
|
|
1979
2441
|
bareReviewOutcome("review-changed"),
|
|
1980
2442
|
bareReviewOutcome("no-review"),
|
|
@@ -1986,33 +2448,33 @@ var reviewDecisionResultSchema = z13.discriminatedUnion("outcome", [
|
|
|
1986
2448
|
reviewRefusedSchema,
|
|
1987
2449
|
bareReviewOutcome("unavailable")
|
|
1988
2450
|
]);
|
|
1989
|
-
var reviewSentBackSchema =
|
|
1990
|
-
round:
|
|
2451
|
+
var reviewSentBackSchema = z17.object({
|
|
2452
|
+
round: z17.number().int().min(1),
|
|
1991
2453
|
note: reviewNoteSchema
|
|
1992
2454
|
}).strict();
|
|
1993
|
-
var reviewQuestionSchema =
|
|
2455
|
+
var reviewQuestionSchema = z17.object({
|
|
1994
2456
|
question: reviewNoteSchema,
|
|
1995
2457
|
agentAnswer: reviewAgentAnswerSchema.optional()
|
|
1996
2458
|
}).strict();
|
|
1997
|
-
var reviewTaskSchema =
|
|
2459
|
+
var reviewTaskSchema = z17.object({
|
|
1998
2460
|
title: buildTaskSchema.shape.title,
|
|
1999
2461
|
state: buildTaskStateSchema
|
|
2000
2462
|
}).strict();
|
|
2001
|
-
var reviewViewPartSchema =
|
|
2463
|
+
var reviewViewPartSchema = z17.object({
|
|
2002
2464
|
part: systemPartIdSchema,
|
|
2003
2465
|
name: systemPartSchema.shape.name,
|
|
2004
2466
|
change: reviewPartChangeSchema,
|
|
2005
|
-
built:
|
|
2006
|
-
builtWithoutApproval:
|
|
2007
|
-
decidable:
|
|
2008
|
-
waiting:
|
|
2467
|
+
built: z17.boolean(),
|
|
2468
|
+
builtWithoutApproval: z17.boolean(),
|
|
2469
|
+
decidable: z17.boolean(),
|
|
2470
|
+
waiting: z17.boolean(),
|
|
2009
2471
|
decision: reviewDecisionSchema.optional(),
|
|
2010
2472
|
reason: reviewNoteSchema.optional(),
|
|
2011
2473
|
carriedTo: reviewCarriedToSchema.optional(),
|
|
2012
|
-
sentBack:
|
|
2013
|
-
questions:
|
|
2014
|
-
tasks:
|
|
2015
|
-
said:
|
|
2474
|
+
sentBack: z17.array(reviewSentBackSchema),
|
|
2475
|
+
questions: z17.array(reviewQuestionSchema),
|
|
2476
|
+
tasks: z17.array(reviewTaskSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
2477
|
+
said: z17.array(observedSaidSchema).max(BUILD_SNAPSHOT_TASK_LIMIT),
|
|
2016
2478
|
codeLink: partCodeLinkSchema
|
|
2017
2479
|
}).strict().superRefine((v, ctx) => {
|
|
2018
2480
|
if (v.waiting !== (v.decision === void 0)) {
|
|
@@ -2035,29 +2497,29 @@ var reviewViewPartSchema = z13.object({
|
|
|
2035
2497
|
ctx.addIssue({ code: "custom", path: ["built"], message: "is always true for a part outside the plan" });
|
|
2036
2498
|
}
|
|
2037
2499
|
});
|
|
2038
|
-
var reviewPhaseNumberSchema =
|
|
2039
|
-
var phaseReviewNoneSchema =
|
|
2040
|
-
state:
|
|
2500
|
+
var reviewPhaseNumberSchema = z17.number().int().min(1).nullable();
|
|
2501
|
+
var phaseReviewNoneSchema = z17.object({
|
|
2502
|
+
state: z17.literal("none"),
|
|
2041
2503
|
phase: scopePhaseSchema,
|
|
2042
2504
|
number: reviewPhaseNumberSchema,
|
|
2043
|
-
closedWithoutReview:
|
|
2505
|
+
closedWithoutReview: z17.boolean()
|
|
2044
2506
|
}).strict();
|
|
2045
|
-
var reviewWalkSchema =
|
|
2507
|
+
var reviewWalkSchema = z17.object({
|
|
2046
2508
|
verdict: walkVerdictSchema,
|
|
2047
|
-
findings:
|
|
2509
|
+
findings: z17.number().int().min(0)
|
|
2048
2510
|
}).strict();
|
|
2049
2511
|
function reviewedViewSchema(state) {
|
|
2050
|
-
return
|
|
2051
|
-
state:
|
|
2512
|
+
return z17.object({
|
|
2513
|
+
state: z17.literal(state),
|
|
2052
2514
|
phase: scopePhaseSchema,
|
|
2053
2515
|
number: reviewPhaseNumberSchema,
|
|
2054
|
-
cycle:
|
|
2055
|
-
round:
|
|
2056
|
-
reviewVersion:
|
|
2057
|
-
typedReviewOffered:
|
|
2058
|
-
counted:
|
|
2516
|
+
cycle: z17.number().int().min(0),
|
|
2517
|
+
round: z17.number().int().min(1),
|
|
2518
|
+
reviewVersion: z17.number().int().min(1),
|
|
2519
|
+
typedReviewOffered: z17.boolean(),
|
|
2520
|
+
counted: z17.boolean(),
|
|
2059
2521
|
walk: reviewWalkSchema,
|
|
2060
|
-
parts:
|
|
2522
|
+
parts: z17.array(reviewViewPartSchema).max(REVIEW_PARTS_MAX),
|
|
2061
2523
|
observed: observedChangesSchema.nullable(),
|
|
2062
2524
|
description: systemDescriptionSchema
|
|
2063
2525
|
}).strict().superRefine((v, ctx) => {
|
|
@@ -2085,7 +2547,7 @@ function reviewedViewSchema(state) {
|
|
|
2085
2547
|
}
|
|
2086
2548
|
var phaseReviewOpenSchema = reviewedViewSchema("open");
|
|
2087
2549
|
var phaseReviewClosedSchema = reviewedViewSchema("closed");
|
|
2088
|
-
var phaseReviewViewSchema =
|
|
2550
|
+
var phaseReviewViewSchema = z17.discriminatedUnion("state", [
|
|
2089
2551
|
phaseReviewNoneSchema,
|
|
2090
2552
|
phaseReviewOpenSchema,
|
|
2091
2553
|
phaseReviewClosedSchema
|
|
@@ -2093,45 +2555,45 @@ var phaseReviewViewSchema = z13.discriminatedUnion("state", [
|
|
|
2093
2555
|
|
|
2094
2556
|
// ../events/dist/build-record-v3.js
|
|
2095
2557
|
var BUILD_RECORD_V3_FORMAT = "halfcycle-build-record/v3";
|
|
2096
|
-
var recordRoundStatedSchema =
|
|
2558
|
+
var recordRoundStatedSchema = z18.object({
|
|
2097
2559
|
actor: attestedCloseSchema.shape.actor,
|
|
2098
2560
|
statements: attestedStatementsSchema
|
|
2099
2561
|
}).strict();
|
|
2100
|
-
var recordReviewRoundSchema =
|
|
2101
|
-
round:
|
|
2562
|
+
var recordReviewRoundSchema = z18.object({
|
|
2563
|
+
round: z18.number().int().min(1),
|
|
2102
2564
|
openedAt: utcIso8601,
|
|
2103
2565
|
verdict: walkVerdictSchema,
|
|
2104
|
-
findings:
|
|
2566
|
+
findings: z18.number().int().min(0),
|
|
2105
2567
|
stated: recordRoundStatedSchema.optional()
|
|
2106
2568
|
}).strict();
|
|
2107
|
-
var recordReviewApprovalSchema =
|
|
2108
|
-
|
|
2109
|
-
kind:
|
|
2569
|
+
var recordReviewApprovalSchema = z18.discriminatedUnion("kind", [
|
|
2570
|
+
z18.object({
|
|
2571
|
+
kind: z18.literal("approved"),
|
|
2110
2572
|
planVersion: planVersionSchema,
|
|
2111
2573
|
givenIn: scopeGivenInSchema,
|
|
2112
2574
|
approvedAt: utcIso8601
|
|
2113
2575
|
}).strict(),
|
|
2114
|
-
|
|
2576
|
+
z18.object({ kind: z18.literal("none") }).strict()
|
|
2115
2577
|
]);
|
|
2116
|
-
var recordReviewGateSchema =
|
|
2578
|
+
var recordReviewGateSchema = z18.object({
|
|
2117
2579
|
gate: boardGateNameSchema,
|
|
2118
2580
|
state: boardStepStateSchema
|
|
2119
2581
|
}).strict();
|
|
2120
|
-
var recordReviewQuestionSchema =
|
|
2582
|
+
var recordReviewQuestionSchema = z18.object({
|
|
2121
2583
|
question: reviewNoteSchema,
|
|
2122
2584
|
agentAnswer: reviewAgentAnswerSchema
|
|
2123
2585
|
}).strict();
|
|
2124
|
-
var recordReviewPartSchema =
|
|
2586
|
+
var recordReviewPartSchema = z18.object({
|
|
2125
2587
|
part: systemPartIdSchema,
|
|
2126
2588
|
name: systemPartSchema.shape.name,
|
|
2127
2589
|
change: reviewPartChangeSchema,
|
|
2128
|
-
built:
|
|
2129
|
-
builtWithoutApproval:
|
|
2590
|
+
built: z18.boolean(),
|
|
2591
|
+
builtWithoutApproval: z18.boolean(),
|
|
2130
2592
|
decision: reviewDecisionSchema,
|
|
2131
2593
|
reason: reviewNoteSchema.optional(),
|
|
2132
2594
|
carriedTo: reviewCarriedToSchema.optional(),
|
|
2133
|
-
sentBack:
|
|
2134
|
-
questions:
|
|
2595
|
+
sentBack: z18.array(reviewSentBackSchema),
|
|
2596
|
+
questions: z18.array(recordReviewQuestionSchema),
|
|
2135
2597
|
codeLink: partCodeLinkSchema
|
|
2136
2598
|
}).strict().superRefine((v, ctx) => {
|
|
2137
2599
|
const carriedOrDropped = v.decision === "carried" || v.decision === "dropped";
|
|
@@ -2143,23 +2605,24 @@ var recordReviewPartSchema = z14.object({
|
|
|
2143
2605
|
}
|
|
2144
2606
|
});
|
|
2145
2607
|
var SPINE_ORDER = boardGateNameSchema.options;
|
|
2146
|
-
var recordReviewGatesSchema =
|
|
2608
|
+
var recordReviewGatesSchema = z18.array(recordReviewGateSchema).superRefine((gates, ctx) => {
|
|
2147
2609
|
const inOrder = gates.length === SPINE_ORDER.length && gates.every((g, i) => g.gate === SPINE_ORDER[i]);
|
|
2148
2610
|
if (!inOrder) {
|
|
2149
2611
|
ctx.addIssue({ code: "custom", message: `must be exactly the five checkpoints in order: ${SPINE_ORDER.join(", ")}` });
|
|
2150
2612
|
}
|
|
2151
2613
|
});
|
|
2152
|
-
var recordReviewSchema =
|
|
2153
|
-
sequence:
|
|
2154
|
-
cycle:
|
|
2155
|
-
rounds:
|
|
2614
|
+
var recordReviewSchema = z18.object({
|
|
2615
|
+
sequence: z18.number().int().min(1),
|
|
2616
|
+
cycle: z18.number().int().min(0),
|
|
2617
|
+
rounds: z18.array(recordReviewRoundSchema).min(1),
|
|
2156
2618
|
approval: recordReviewApprovalSchema,
|
|
2157
2619
|
planVersion: planVersionSchema.nullable(),
|
|
2158
2620
|
descriptionVersion: observedDescriptionVersionSchema,
|
|
2159
2621
|
gates: recordReviewGatesSchema,
|
|
2160
2622
|
observed: observedChangesSchema.nullable(),
|
|
2161
|
-
parts:
|
|
2162
|
-
}).strict().superRefine((v, ctx) =>
|
|
2623
|
+
parts: z18.array(recordReviewPartSchema).max(REVIEW_PARTS_MAX)
|
|
2624
|
+
}).strict().superRefine((v, ctx) => checkRecordReview(v, ctx));
|
|
2625
|
+
function checkRecordReview(v, ctx) {
|
|
2163
2626
|
v.rounds.forEach((r, i) => {
|
|
2164
2627
|
if (r.round !== i + 1) {
|
|
2165
2628
|
ctx.addIssue({ code: "custom", path: ["rounds", i, "round"], message: "rounds must be numbered 1, 2, 3 \u2026 in order with no gap" });
|
|
@@ -2177,12 +2640,13 @@ var recordReviewSchema = z14.object({
|
|
|
2177
2640
|
ctx.addIssue({ code: "custom", path: ["parts", i, "codeLink"], message: "must be none when nothing was observed" });
|
|
2178
2641
|
}
|
|
2179
2642
|
});
|
|
2180
|
-
}
|
|
2181
|
-
var buildRecordV3Schema =
|
|
2643
|
+
}
|
|
2644
|
+
var buildRecordV3Schema = z18.object({
|
|
2182
2645
|
...buildRecordV2Schema.shape,
|
|
2183
|
-
format:
|
|
2646
|
+
format: z18.literal(BUILD_RECORD_V3_FORMAT),
|
|
2184
2647
|
review: recordReviewSchema
|
|
2185
|
-
}).strict().superRefine((record2, ctx) =>
|
|
2648
|
+
}).strict().superRefine((record2, ctx) => checkReviewedRecord(record2, ctx));
|
|
2649
|
+
function checkReviewedRecord(record2, ctx) {
|
|
2186
2650
|
checkRecordHalves(record2, ctx);
|
|
2187
2651
|
const closes = record2.observed.closes;
|
|
2188
2652
|
const newest = closes[closes.length - 1].sequence;
|
|
@@ -2208,24 +2672,11 @@ var buildRecordV3Schema = z14.object({
|
|
|
2208
2672
|
if (record2.review.observed !== null && record2.review.observed.phase !== record2.phase) {
|
|
2209
2673
|
ctx.addIssue({ code: "custom", path: ["review", "observed", "phase"], message: "must be this record's phase" });
|
|
2210
2674
|
}
|
|
2211
|
-
});
|
|
2212
|
-
var buildRecordSchema = z14.discriminatedUnion("format", [buildRecordV2Schema, buildRecordV3Schema]);
|
|
2213
|
-
function removalsOf(record2) {
|
|
2214
|
-
if (record2.format !== BUILD_RECORD_V3_FORMAT)
|
|
2215
|
-
return [];
|
|
2216
|
-
const out = [];
|
|
2217
|
-
for (const p of record2.review.parts) {
|
|
2218
|
-
if (p.change === "add" && p.decision === "dropped")
|
|
2219
|
-
out.push({ part: p.part, name: p.name, act: "dropped" });
|
|
2220
|
-
else if (p.change === "remove" && p.decision === "accepted")
|
|
2221
|
-
out.push({ part: p.part, name: p.name, act: "removed" });
|
|
2222
|
-
}
|
|
2223
|
-
return out;
|
|
2224
2675
|
}
|
|
2225
2676
|
|
|
2226
2677
|
// ../events/dist/device-auth.js
|
|
2227
|
-
import { z as
|
|
2228
|
-
var utcIso86012 =
|
|
2678
|
+
import { z as z19 } from "zod";
|
|
2679
|
+
var utcIso86012 = z19.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/, "must be a UTC ISO-8601 timestamp ending in Z");
|
|
2229
2680
|
var DEVICE_AUTH_STATUS = {
|
|
2230
2681
|
/** The poll: minted, nobody has acted yet. Keep polling. 200. */
|
|
2231
2682
|
PENDING: "pending",
|
|
@@ -2266,25 +2717,25 @@ var DEVICE_POLL_REFUSALS = [
|
|
|
2266
2717
|
DEVICE_AUTH_STATUS.EXPIRED,
|
|
2267
2718
|
DEVICE_AUTH_STATUS.UNKNOWN
|
|
2268
2719
|
];
|
|
2269
|
-
var deviceAuthStartResponseSchema =
|
|
2270
|
-
deviceCode:
|
|
2271
|
-
userCode:
|
|
2272
|
-
verificationUrl:
|
|
2720
|
+
var deviceAuthStartResponseSchema = z19.object({
|
|
2721
|
+
deviceCode: z19.string().min(1),
|
|
2722
|
+
userCode: z19.string().min(1),
|
|
2723
|
+
verificationUrl: z19.string().min(1),
|
|
2273
2724
|
expiresAt: utcIso86012,
|
|
2274
|
-
pollIntervalMs:
|
|
2725
|
+
pollIntervalMs: z19.number().int().positive()
|
|
2275
2726
|
}).strict();
|
|
2276
|
-
var devicePollPendingSchema =
|
|
2277
|
-
status:
|
|
2278
|
-
pollIntervalMs:
|
|
2727
|
+
var devicePollPendingSchema = z19.object({
|
|
2728
|
+
status: z19.literal(DEVICE_AUTH_STATUS.PENDING),
|
|
2729
|
+
pollIntervalMs: z19.number().int().positive()
|
|
2279
2730
|
}).strict();
|
|
2280
|
-
var devicePollApprovedSchema =
|
|
2281
|
-
status:
|
|
2282
|
-
accountId:
|
|
2283
|
-
credential:
|
|
2731
|
+
var devicePollApprovedSchema = z19.object({
|
|
2732
|
+
status: z19.literal(DEVICE_AUTH_STATUS.APPROVED),
|
|
2733
|
+
accountId: z19.string().min(1),
|
|
2734
|
+
credential: z19.string().min(1),
|
|
2284
2735
|
expiresAt: utcIso86012
|
|
2285
2736
|
}).strict();
|
|
2286
|
-
var deviceAuthRefusalSchema =
|
|
2287
|
-
status:
|
|
2737
|
+
var deviceAuthRefusalSchema = z19.object({
|
|
2738
|
+
status: z19.enum([
|
|
2288
2739
|
DEVICE_AUTH_STATUS.DECLINED,
|
|
2289
2740
|
DEVICE_AUTH_STATUS.EXPIRED,
|
|
2290
2741
|
DEVICE_AUTH_STATUS.UNKNOWN,
|
|
@@ -2295,25 +2746,25 @@ var deviceAuthRefusalSchema = z15.object({
|
|
|
2295
2746
|
DEVICE_AUTH_STATUS.ALREADY_DECIDED,
|
|
2296
2747
|
DEVICE_AUTH_STATUS.TERMS_REQUIRED
|
|
2297
2748
|
]),
|
|
2298
|
-
message:
|
|
2749
|
+
message: z19.string().min(1)
|
|
2299
2750
|
}).strict();
|
|
2300
|
-
var devicePollResponseSchema =
|
|
2751
|
+
var devicePollResponseSchema = z19.union([
|
|
2301
2752
|
devicePollPendingSchema,
|
|
2302
2753
|
devicePollApprovedSchema,
|
|
2303
2754
|
deviceAuthRefusalSchema
|
|
2304
2755
|
]);
|
|
2305
|
-
var deviceConfirmRequestSchema =
|
|
2306
|
-
userCode:
|
|
2307
|
-
decision:
|
|
2308
|
-
externalAuthId:
|
|
2309
|
-
email:
|
|
2310
|
-
acceptTerms:
|
|
2756
|
+
var deviceConfirmRequestSchema = z19.object({
|
|
2757
|
+
userCode: z19.string().min(1),
|
|
2758
|
+
decision: z19.enum(["approve", "decline"]),
|
|
2759
|
+
externalAuthId: z19.string().min(1).optional(),
|
|
2760
|
+
email: z19.string().optional(),
|
|
2761
|
+
acceptTerms: z19.boolean().optional()
|
|
2311
2762
|
}).strict();
|
|
2312
|
-
var deviceConfirmRecordedSchema =
|
|
2313
|
-
status:
|
|
2314
|
-
accountId:
|
|
2763
|
+
var deviceConfirmRecordedSchema = z19.object({
|
|
2764
|
+
status: z19.literal(DEVICE_AUTH_STATUS.RECORDED),
|
|
2765
|
+
accountId: z19.string().min(1).optional()
|
|
2315
2766
|
}).strict();
|
|
2316
|
-
var deviceConfirmResponseSchema =
|
|
2767
|
+
var deviceConfirmResponseSchema = z19.union([
|
|
2317
2768
|
deviceConfirmRecordedSchema,
|
|
2318
2769
|
deviceAuthRefusalSchema
|
|
2319
2770
|
]);
|
|
@@ -2325,20 +2776,20 @@ function projectPageUrl(engagementId) {
|
|
|
2325
2776
|
}
|
|
2326
2777
|
|
|
2327
2778
|
// ../events/dist/credential-wire.js
|
|
2328
|
-
import { z as
|
|
2329
|
-
var engagementCredentialResponseSchema =
|
|
2330
|
-
engagementId:
|
|
2331
|
-
sessionToken:
|
|
2332
|
-
mcpUrl:
|
|
2333
|
-
guardUrl:
|
|
2334
|
-
controlTelemetryUrl:
|
|
2335
|
-
methodVersion:
|
|
2336
|
-
consoleUrl:
|
|
2779
|
+
import { z as z20 } from "zod";
|
|
2780
|
+
var engagementCredentialResponseSchema = z20.object({
|
|
2781
|
+
engagementId: z20.string(),
|
|
2782
|
+
sessionToken: z20.string(),
|
|
2783
|
+
mcpUrl: z20.string(),
|
|
2784
|
+
guardUrl: z20.string(),
|
|
2785
|
+
controlTelemetryUrl: z20.string(),
|
|
2786
|
+
methodVersion: z20.string().optional(),
|
|
2787
|
+
consoleUrl: z20.string().optional()
|
|
2337
2788
|
}).strict();
|
|
2338
|
-
var ciTokenExchangeResponseSchema =
|
|
2339
|
-
token:
|
|
2789
|
+
var ciTokenExchangeResponseSchema = z20.object({
|
|
2790
|
+
token: z20.string(),
|
|
2340
2791
|
expiresAt: utcIso8601,
|
|
2341
|
-
engagementId:
|
|
2792
|
+
engagementId: z20.string()
|
|
2342
2793
|
}).strict();
|
|
2343
2794
|
var NO_CREDENTIAL_PLACEHOLDER = "halfcycle:no-credential";
|
|
2344
2795
|
var NOT_THIS_ACCOUNT_PLACEHOLDER = "halfcycle:not-this-account";
|
|
@@ -2355,42 +2806,118 @@ var PLACEHOLDER_SENTENCES = Object.freeze({
|
|
|
2355
2806
|
});
|
|
2356
2807
|
|
|
2357
2808
|
// ../events/dist/phase-record.js
|
|
2358
|
-
import { z as
|
|
2359
|
-
|
|
2809
|
+
import { z as z22 } from "zod";
|
|
2810
|
+
|
|
2811
|
+
// ../events/dist/build-record-v4.js
|
|
2812
|
+
import { z as z21 } from "zod";
|
|
2813
|
+
var BUILD_RECORD_V4_FORMAT = "halfcycle-build-record/v4";
|
|
2814
|
+
var recordReviewClaimSchema = z21.object({
|
|
2815
|
+
...reviewClaimAnswerSchema.shape,
|
|
2816
|
+
note: reviewNoteSchema.nullable()
|
|
2817
|
+
}).strict().superRefine((c, ctx) => {
|
|
2818
|
+
if (c.act === "accept" !== (c.note === null)) {
|
|
2819
|
+
ctx.addIssue({ code: "custom", path: ["note"], message: "carries the owner's note exactly on a reject" });
|
|
2820
|
+
}
|
|
2821
|
+
});
|
|
2822
|
+
var recordCallSchema = z21.object(workCallSchema.shape).omit({ at: true }).strict().superRefine((c, ctx) => checkReadCallHow(c, ctx));
|
|
2823
|
+
var recordReviewV4Schema = z21.object({
|
|
2824
|
+
...recordReviewSchema.shape,
|
|
2825
|
+
claims: z21.array(recordReviewClaimSchema).max(REVIEW_CLAIMS_MAX),
|
|
2826
|
+
calls: z21.array(recordCallSchema)
|
|
2827
|
+
}).strict().superRefine((v, ctx) => checkRecordReview(v, ctx));
|
|
2828
|
+
var buildRecordV4Schema = z21.object({
|
|
2829
|
+
...buildRecordV3Schema.shape,
|
|
2830
|
+
format: z21.literal(BUILD_RECORD_V4_FORMAT),
|
|
2831
|
+
path: phasePathSchema,
|
|
2832
|
+
review: recordReviewV4Schema
|
|
2833
|
+
}).strict().superRefine((record2, ctx) => checkReviewedRecord(record2, ctx));
|
|
2834
|
+
var buildRecordSchema = z21.discriminatedUnion("format", [
|
|
2835
|
+
buildRecordV2Schema,
|
|
2836
|
+
buildRecordV3Schema,
|
|
2837
|
+
buildRecordV4Schema
|
|
2838
|
+
]);
|
|
2839
|
+
var OWNER_REVIEW_FORMATS = Object.freeze([BUILD_RECORD_V3_FORMAT, BUILD_RECORD_V4_FORMAT]);
|
|
2840
|
+
function hasOwnerReview(record2) {
|
|
2841
|
+
return OWNER_REVIEW_FORMATS.includes(record2.format);
|
|
2842
|
+
}
|
|
2843
|
+
function keptClaimsOf(record2) {
|
|
2844
|
+
return record2.format === BUILD_RECORD_V4_FORMAT ? record2.review.claims : null;
|
|
2845
|
+
}
|
|
2846
|
+
function keptCallsOf(record2) {
|
|
2847
|
+
return record2.format === BUILD_RECORD_V4_FORMAT ? record2.review.calls : null;
|
|
2848
|
+
}
|
|
2849
|
+
function keptPathOf(record2) {
|
|
2850
|
+
return record2.format === BUILD_RECORD_V4_FORMAT ? record2.path : null;
|
|
2851
|
+
}
|
|
2852
|
+
function removalsOf(record2) {
|
|
2853
|
+
if (!hasOwnerReview(record2))
|
|
2854
|
+
return [];
|
|
2855
|
+
const out = [];
|
|
2856
|
+
for (const p of record2.review.parts) {
|
|
2857
|
+
if (p.change === "add" && p.decision === "dropped")
|
|
2858
|
+
out.push({ part: p.part, name: p.name, act: "dropped" });
|
|
2859
|
+
else if (p.change === "remove" && p.decision === "accepted")
|
|
2860
|
+
out.push({ part: p.part, name: p.name, act: "removed" });
|
|
2861
|
+
}
|
|
2862
|
+
return out;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
// ../events/dist/phase-record.js
|
|
2866
|
+
var phaseRecordRefusalReasonSchema = z22.enum([
|
|
2360
2867
|
"still-open",
|
|
2361
2868
|
"reopened",
|
|
2362
2869
|
"never-opened",
|
|
2363
2870
|
"never-closed",
|
|
2364
2871
|
"closed-before-records"
|
|
2365
2872
|
]);
|
|
2366
|
-
var phaseRecordRecordSchema =
|
|
2367
|
-
outcome:
|
|
2873
|
+
var phaseRecordRecordSchema = z22.object({
|
|
2874
|
+
outcome: z22.literal("record"),
|
|
2368
2875
|
phase: phaseNameSchema,
|
|
2369
2876
|
record: buildRecordSchema
|
|
2370
2877
|
}).strict().refine((body) => body.record.phase === body.phase, {
|
|
2371
2878
|
message: "the record is for a different phase than the one asked for",
|
|
2372
2879
|
path: ["record", "phase"]
|
|
2373
2880
|
});
|
|
2374
|
-
var phaseRecordWithheldSchema =
|
|
2375
|
-
outcome:
|
|
2881
|
+
var phaseRecordWithheldSchema = z22.object({
|
|
2882
|
+
outcome: z22.literal("withheld"),
|
|
2376
2883
|
phase: phaseNameSchema,
|
|
2377
|
-
sequence:
|
|
2884
|
+
sequence: z22.number().int().min(1),
|
|
2378
2885
|
closedAt: utcIso8601,
|
|
2379
|
-
message:
|
|
2886
|
+
message: z22.string()
|
|
2380
2887
|
}).strict();
|
|
2381
2888
|
var phaseRecordRefusedSchema = wireErrorSchema.extend({
|
|
2382
|
-
outcome:
|
|
2889
|
+
outcome: z22.literal("refused"),
|
|
2383
2890
|
phase: phaseNameSchema,
|
|
2384
|
-
statusCode:
|
|
2385
|
-
error:
|
|
2891
|
+
statusCode: z22.literal(409),
|
|
2892
|
+
error: z22.literal("PhaseRecordRefused"),
|
|
2386
2893
|
reason: phaseRecordRefusalReasonSchema
|
|
2387
2894
|
}).strict();
|
|
2388
|
-
var phaseRecordResponseSchema =
|
|
2895
|
+
var phaseRecordResponseSchema = z22.discriminatedUnion("outcome", [
|
|
2389
2896
|
phaseRecordRecordSchema,
|
|
2390
2897
|
phaseRecordWithheldSchema,
|
|
2391
2898
|
phaseRecordRefusedSchema
|
|
2392
2899
|
]);
|
|
2393
2900
|
|
|
2901
|
+
// ../events/dist/work-words.js
|
|
2902
|
+
var CALLS_HEADING = "Calls made without asking you";
|
|
2903
|
+
var CALLS_EXPLAINED = "These are the decisions the agents recorded taking on their own, each against a stated default. Halfcycle lists what they recorded; it cannot see a call an agent did not record.";
|
|
2904
|
+
function callMadeLine(call) {
|
|
2905
|
+
return `${call.by} decided "${call.question}": chose "${call.chose}". The stated default was "${call.statedDefault}".`;
|
|
2906
|
+
}
|
|
2907
|
+
function callUndoLine(call) {
|
|
2908
|
+
return call.undoable === "yes" ? `${call.by} says this can be undone: "${call.how ?? ""}"` : `${call.by} says this cannot be undone.`;
|
|
2909
|
+
}
|
|
2910
|
+
var NO_CALLS_LINE = "No agent recorded a call made without asking in this phase.";
|
|
2911
|
+
var UNCHECKED_CLAIMS_HEADING = "Checks nobody ran";
|
|
2912
|
+
function claimSaidLine(claim) {
|
|
2913
|
+
return `Task ${claim.task}: an agent said "${claim.label}" passes at commit ${claim.head}, and Halfcycle never ran it.`;
|
|
2914
|
+
}
|
|
2915
|
+
function recordedClaimLine(claim) {
|
|
2916
|
+
const said = claimSaidLine(claim);
|
|
2917
|
+
return claim.act === "accept" ? `${said} Accepted by the project's owner.` : `${said} Rejected by the project's owner: "${claim.note ?? ""}"`;
|
|
2918
|
+
}
|
|
2919
|
+
var NO_UNCHECKED_CLAIMS_LINE = "No agent said a check passes that Halfcycle never ran.";
|
|
2920
|
+
|
|
2394
2921
|
// dist/engagement-credential.js
|
|
2395
2922
|
import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2396
2923
|
import { platform as platform2 } from "node:os";
|
|
@@ -2860,8 +3387,12 @@ function parseManifest(text) {
|
|
|
2860
3387
|
"eventsCreated",
|
|
2861
3388
|
"hooksCreated",
|
|
2862
3389
|
"permissionsCreated",
|
|
2863
|
-
"denyCreated"
|
|
3390
|
+
"denyCreated",
|
|
3391
|
+
"statusLineSha256"
|
|
2864
3392
|
], '"settings"');
|
|
3393
|
+
if (s["statusLineSha256"] !== void 0 && (typeof s["statusLineSha256"] !== "string" || !HEX64.test(s["statusLineSha256"]))) {
|
|
3394
|
+
throw new UnreadableManifestError('"settings.statusLineSha256" is not a hash');
|
|
3395
|
+
}
|
|
2865
3396
|
const settings = {
|
|
2866
3397
|
created: bool(s["created"], "settings.created"),
|
|
2867
3398
|
adopted: bool(s["adopted"], "settings.adopted"),
|
|
@@ -2871,7 +3402,8 @@ function parseManifest(text) {
|
|
|
2871
3402
|
eventsCreated: stringArray(s["eventsCreated"], "settings.eventsCreated"),
|
|
2872
3403
|
hooksCreated: bool(s["hooksCreated"], "settings.hooksCreated"),
|
|
2873
3404
|
permissionsCreated: bool(s["permissionsCreated"], "settings.permissionsCreated"),
|
|
2874
|
-
denyCreated: bool(s["denyCreated"], "settings.denyCreated")
|
|
3405
|
+
denyCreated: bool(s["denyCreated"], "settings.denyCreated"),
|
|
3406
|
+
...typeof s["statusLineSha256"] === "string" ? { statusLineSha256: s["statusLineSha256"] } : {}
|
|
2875
3407
|
};
|
|
2876
3408
|
let mcp;
|
|
2877
3409
|
if (raw["mcp"] !== void 0) {
|
|
@@ -2949,6 +3481,7 @@ function recordSettings(draft, observed) {
|
|
|
2949
3481
|
draft.settings = observed;
|
|
2950
3482
|
return;
|
|
2951
3483
|
}
|
|
3484
|
+
const statusLineSha256 = observed.statusLineSha256 ?? prev.statusLineSha256;
|
|
2952
3485
|
draft.settings = {
|
|
2953
3486
|
created: prev.created,
|
|
2954
3487
|
adopted: prev.adopted,
|
|
@@ -2958,7 +3491,8 @@ function recordSettings(draft, observed) {
|
|
|
2958
3491
|
eventsCreated: union(prev.eventsCreated, observed.eventsCreated),
|
|
2959
3492
|
hooksCreated: prev.hooksCreated,
|
|
2960
3493
|
permissionsCreated: prev.permissionsCreated,
|
|
2961
|
-
denyCreated: prev.denyCreated
|
|
3494
|
+
denyCreated: prev.denyCreated,
|
|
3495
|
+
...statusLineSha256 !== void 0 ? { statusLineSha256 } : {}
|
|
2962
3496
|
};
|
|
2963
3497
|
}
|
|
2964
3498
|
function recordDenyRetired(draft, hashes) {
|
|
@@ -3052,7 +3586,7 @@ function withoutHalfcycleCommands(entry, halfcycleCommands) {
|
|
|
3052
3586
|
const remaining = entry.hooks.filter((h) => !isHalfcycleCommand(h, halfcycleCommands));
|
|
3053
3587
|
return remaining.length > 0 ? { ...entry, hooks: remaining } : null;
|
|
3054
3588
|
}
|
|
3055
|
-
function mergeSettings(existing, generated, retiredOurs) {
|
|
3589
|
+
function mergeSettings(existing, generated, retiredOurs, statusLine) {
|
|
3056
3590
|
const merged = { ...existing };
|
|
3057
3591
|
if (generated.$schema !== void 0) {
|
|
3058
3592
|
merged.$schema = generated.$schema;
|
|
@@ -3075,6 +3609,9 @@ function mergeSettings(existing, generated, retiredOurs) {
|
|
|
3075
3609
|
}
|
|
3076
3610
|
merged.hooks = mergedHooks;
|
|
3077
3611
|
merged.permissions = mergePermissions(existing.permissions, generated.permissions, retiredOurs);
|
|
3612
|
+
if (statusLine !== void 0 && !("statusLine" in existing)) {
|
|
3613
|
+
merged.statusLine = { ...statusLine };
|
|
3614
|
+
}
|
|
3078
3615
|
return merged;
|
|
3079
3616
|
}
|
|
3080
3617
|
function mergePermissions(existing, generated, retiredOurs) {
|
|
@@ -3284,7 +3821,8 @@ function closedWriteSet() {
|
|
|
3284
3821
|
GITATTRIBUTES_HEADER,
|
|
3285
3822
|
...lfRules([...Object.keys(OWNED_GENERATED_HEADERS), ...RETIRED_WRITE_SET_FILES])
|
|
3286
3823
|
]),
|
|
3287
|
-
generatedSha256: sha256OfWhatThisVersionWrites(commands)
|
|
3824
|
+
generatedSha256: sha256OfWhatThisVersionWrites(commands),
|
|
3825
|
+
statusLineSha256: /* @__PURE__ */ new Set([canonicalSha256(HALFCYCLE_STATUS_LINE)])
|
|
3288
3826
|
};
|
|
3289
3827
|
}
|
|
3290
3828
|
function sha256OfWhatThisVersionWrites(commands) {
|
|
@@ -3319,7 +3857,7 @@ function noteFile(draft, targetRepo, rel, outcome) {
|
|
|
3319
3857
|
}
|
|
3320
3858
|
recordInstalledFile(draft, rel, readFileSync4(join5(targetRepo, rel)));
|
|
3321
3859
|
}
|
|
3322
|
-
function recordSettingsMerge(draft, existing, generated, preexisted) {
|
|
3860
|
+
function recordSettingsMerge(draft, existing, generated, preexisted, merged) {
|
|
3323
3861
|
const generatedHooks = generated.hooks ?? {};
|
|
3324
3862
|
const hookCommands = Object.values(generatedHooks).flatMap((entries) => entries.flatMap((entry) => entry.hooks.map((h) => h.command)));
|
|
3325
3863
|
const ours = /* @__PURE__ */ new Set([...hookCommands, ...HALFCYCLE_HOOK_COMMANDS]);
|
|
@@ -3336,9 +3874,16 @@ function recordSettingsMerge(draft, existing, generated, preexisted) {
|
|
|
3336
3874
|
eventsCreated: Object.keys(generatedHooks).filter((event) => !(existingHooks && event in existingHooks)),
|
|
3337
3875
|
hooksCreated: existing.hooks === void 0,
|
|
3338
3876
|
permissionsCreated: existing.permissions === void 0,
|
|
3339
|
-
denyCreated: existing.permissions?.deny === void 0
|
|
3877
|
+
denyCreated: existing.permissions?.deny === void 0,
|
|
3878
|
+
...ourStatusLineSha256(merged) !== void 0 ? { statusLineSha256: ourStatusLineSha256(merged) } : {}
|
|
3340
3879
|
});
|
|
3341
3880
|
}
|
|
3881
|
+
function ourStatusLineSha256(settings) {
|
|
3882
|
+
if (!("statusLine" in settings))
|
|
3883
|
+
return void 0;
|
|
3884
|
+
const hash = canonicalSha256(settings["statusLine"]);
|
|
3885
|
+
return hash === canonicalSha256(HALFCYCLE_STATUS_LINE) ? hash : void 0;
|
|
3886
|
+
}
|
|
3342
3887
|
function recordMcpMerge(draft, existingText, writtenText) {
|
|
3343
3888
|
const before = existingText === null ? void 0 : JSON.parse(existingText);
|
|
3344
3889
|
const servers = isPlainObject(before) ? before["mcpServers"] : void 0;
|
|
@@ -3589,6 +4134,29 @@ function settingsParseRefusal(targetRepo, err) {
|
|
|
3589
4134
|
return `${file} could not be read as JSON${where} \u2014 fix it and run "npx halfcycle" again.`;
|
|
3590
4135
|
}
|
|
3591
4136
|
var SETTINGS_SCHEMA = "https://json.schemastore.org/claude-code-settings.json";
|
|
4137
|
+
var HALFCYCLE_STATUS_LINE = Object.freeze({
|
|
4138
|
+
type: "command",
|
|
4139
|
+
command: 'bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/guard-runner.sh statusline'
|
|
4140
|
+
});
|
|
4141
|
+
function statusLineSetElsewhere(targetRepo, home = homedir2(), env = process.env) {
|
|
4142
|
+
const places = [join5(targetRepo, ".claude", "settings.local.json"), join5(home, ".claude", "settings.json")];
|
|
4143
|
+
const configDir = env["CLAUDE_CONFIG_DIR"];
|
|
4144
|
+
if (configDir !== void 0 && configDir !== "") {
|
|
4145
|
+
const expanded = configDir === "~" ? home : configDir.startsWith("~/") ? join5(home, configDir.slice(2)) : configDir;
|
|
4146
|
+
places.push(join5(isAbsolute2(expanded) ? expanded : resolve(expanded), "settings.json"));
|
|
4147
|
+
}
|
|
4148
|
+
return places.some((path) => {
|
|
4149
|
+
if (!existsSync3(path))
|
|
4150
|
+
return false;
|
|
4151
|
+
let value;
|
|
4152
|
+
try {
|
|
4153
|
+
value = JSON.parse(readFileSync4(path, "utf-8"));
|
|
4154
|
+
} catch {
|
|
4155
|
+
return true;
|
|
4156
|
+
}
|
|
4157
|
+
return !isPlainObject(value) || "statusLine" in value;
|
|
4158
|
+
});
|
|
4159
|
+
}
|
|
3592
4160
|
function generateSettingsJson() {
|
|
3593
4161
|
const hooks = {};
|
|
3594
4162
|
for (const { event, matcher, timeout, command } of HALFCYCLE_HOOK_WIRING) {
|
|
@@ -4050,7 +4618,7 @@ function generateMcpRegistration(existing, mcpOrigin) {
|
|
|
4050
4618
|
};
|
|
4051
4619
|
return JSON.stringify(base, null, 2) + "\n";
|
|
4052
4620
|
}
|
|
4053
|
-
var REQUIRED_GITIGNORE_ENTRIES = [".halfcycle/state.json", `${ZONE_B_DIR}
|
|
4621
|
+
var REQUIRED_GITIGNORE_ENTRIES = [".halfcycle/state.json", `${ZONE_B_DIR}/`, ".claude/worktrees/"];
|
|
4054
4622
|
var GITIGNORE_HEADER = "# Halfcycle \u2014 machine-local secrets/state and Zone-B (never push to client remote)";
|
|
4055
4623
|
function adoptBlockUnderHeader(before, header, claimable) {
|
|
4056
4624
|
const claimed = [];
|
|
@@ -4323,9 +4891,10 @@ async function install(options) {
|
|
|
4323
4891
|
throw new SettingsParseRefused(settingsParseRefusal(targetRepo, err));
|
|
4324
4892
|
}
|
|
4325
4893
|
const retiredOurs = retiredRulesThisInstallAdded(draft.previous);
|
|
4326
|
-
|
|
4894
|
+
const statusLine = statusLineSetElsewhere(targetRepo, home, options.env) ? void 0 : HALFCYCLE_STATUS_LINE;
|
|
4895
|
+
const mergedSettings = mergeSettings(existingSettings, generatedSettings, retiredOurs, statusLine);
|
|
4896
|
+
recordSettingsMerge(draft, existingSettings, generatedSettings, settingsPreexisted, mergedSettings);
|
|
4327
4897
|
recordDenyRetired(draft, retiredOurs.map((rule) => sha256Hex(rule)));
|
|
4328
|
-
const mergedSettings = mergeSettings(existingSettings, generatedSettings, retiredOurs);
|
|
4329
4898
|
const mergedSettingsText = inLineEndingOf(readFileOrNull(settingsPath), JSON.stringify(mergedSettings, null, 2) + "\n");
|
|
4330
4899
|
mkdirSync4(dirname3(settingsPath), { recursive: true });
|
|
4331
4900
|
writeFileSync4(settingsPath, mergedSettingsText, "utf-8");
|
|
@@ -5248,6 +5817,10 @@ var HEADER_CHECKS = "Halfcycle's checks are automatic rules drawn from the ways
|
|
|
5248
5817
|
var HEADER_KEPT = "Halfcycle derived this record and kept a copy of it when the phase closed. It changes that copy afterwards in one way only. If an account that closed this phase is later deleted, its email is removed, and so is the name given at any close Halfcycle recorded as made by that account. The client's Halfcycle command-line tool wrote this file from the kept copy, when the phase closed or when the record was fetched again. So a later deletion reaches this file the next time the record is fetched. The same record, as data, is in the .json file of the same name beside this one. If the phase is closed again, this file is replaced by a new record that describes every close, this one included.";
|
|
5249
5818
|
var HEADER_HIDDEN = "Some text in this record contains characters that do not print. Each is shown as U+ and its code of four or more hex digits; the .json file holds the text exactly.";
|
|
5250
5819
|
var OBSERVED_LABEL = "**Observed by Halfcycle**";
|
|
5820
|
+
var PATH_LINE = Object.freeze({
|
|
5821
|
+
mini: "Path: mini phase",
|
|
5822
|
+
full: "Path: full phase"
|
|
5823
|
+
});
|
|
5251
5824
|
var STATED_LABEL = "**Stated by the client** \u2014 Halfcycle did not check these.";
|
|
5252
5825
|
var MISMATCHED_HALVES = "This Build Record could not be written: its two parts describe different closes.";
|
|
5253
5826
|
function renderChecks(checks, p) {
|
|
@@ -5495,6 +6068,30 @@ function renderReview(record2, p) {
|
|
|
5495
6068
|
blocks.push(removals);
|
|
5496
6069
|
return blocks;
|
|
5497
6070
|
}
|
|
6071
|
+
function renderCalls(calls, p) {
|
|
6072
|
+
if (calls.length === 0)
|
|
6073
|
+
return [`## ${CALLS_HEADING}`, NO_CALLS_LINE];
|
|
6074
|
+
const lines = calls.flatMap((c) => {
|
|
6075
|
+
const by = p.itemStart(c.by);
|
|
6076
|
+
return [
|
|
6077
|
+
`- ${callMadeLine({ by, question: p.text(c.question), chose: p.text(c.chose), statedDefault: p.text(c.statedDefault) })}`,
|
|
6078
|
+
` - ${callUndoLine({ by: p.text(c.by), undoable: c.undoable, how: c.how === null ? null : p.text(c.how) })}`
|
|
6079
|
+
];
|
|
6080
|
+
});
|
|
6081
|
+
return [`## ${CALLS_HEADING}`, CALLS_EXPLAINED, lines.join("\n")];
|
|
6082
|
+
}
|
|
6083
|
+
function renderClaims(claims, p) {
|
|
6084
|
+
if (claims.length === 0)
|
|
6085
|
+
return [`## ${UNCHECKED_CLAIMS_HEADING}`, NO_UNCHECKED_CLAIMS_LINE];
|
|
6086
|
+
const lines = claims.map((c) => `- ${recordedClaimLine({
|
|
6087
|
+
task: p.text(c.task),
|
|
6088
|
+
label: p.text(c.label),
|
|
6089
|
+
head: shortCommit(c.head),
|
|
6090
|
+
act: c.act,
|
|
6091
|
+
note: c.note === null ? null : p.text(c.note)
|
|
6092
|
+
})}`);
|
|
6093
|
+
return [`## ${UNCHECKED_CLAIMS_HEADING}`, lines.join("\n")];
|
|
6094
|
+
}
|
|
5498
6095
|
var EARLIER_ROUNDS_LABEL = `${STATED_LABEL} What was said each time the owner's review was asked for, before the round that closed the phase. What was said for that last round is under the close above. If the account that asked for a round is later deleted, the name given for that round is removed.`;
|
|
5499
6096
|
function renderRoundStated(round, stated, p) {
|
|
5500
6097
|
const label = "> - Acceptance walk (the finished work tried as a user would, by someone other than its builder): ";
|
|
@@ -5539,7 +6136,8 @@ function renderBuildRecordV2Markdown(record2) {
|
|
|
5539
6136
|
const closes = [...record2.observed.closes].sort((a, b) => a.sequence - b.sequence);
|
|
5540
6137
|
const total = closes.length;
|
|
5541
6138
|
const latest = closes[total - 1];
|
|
5542
|
-
const rounds = record2
|
|
6139
|
+
const rounds = hasOwnerReview(record2) ? record2.review.rounds : [];
|
|
6140
|
+
const path = keptPathOf(record2);
|
|
5543
6141
|
const roundsAfter = rounds.length <= 1 ? null : `after ${String(rounds.length)} rounds of the owner's review.${rounds.some((r) => r.stated !== void 0) ? ' What was said for each earlier round is under "Earlier rounds of the review".' : ""}`;
|
|
5544
6142
|
const body = [
|
|
5545
6143
|
`Phase: ${phase} (the name the client gave it)`,
|
|
@@ -5547,14 +6145,23 @@ function renderBuildRecordV2Markdown(record2) {
|
|
|
5547
6145
|
[
|
|
5548
6146
|
`- Method version: ${p.text(record2.observed.methodVersion)}. The Halfcycle method is updated from time to time, and each update has its own version number. This is the one the phase was run under. A project moves to a newer version only between phases.`,
|
|
5549
6147
|
`- Project identifier: ${p.text(record2.observed.engagementId)}. Halfcycle keeps this project's records under this identifier.`,
|
|
5550
|
-
`- Record format: ${p.text(record2.format)}. This names the layout this file and the .json file beside it follow, for software that reads them
|
|
6148
|
+
`- Record format: ${p.text(record2.format)}. This names the layout this file and the .json file beside it follow, for software that reads them.`,
|
|
6149
|
+
...path === null ? [] : [`- ${PATH_LINE[path]}`]
|
|
5551
6150
|
].join("\n"),
|
|
5552
6151
|
total === 1 ? roundsAfter === null ? "This phase was closed once." : `This phase was closed once, ${roundsAfter}` : `This phase was closed ${String(total)} times. The latest close is described first; each earlier close follows, as it was recorded when it was made.${roundsAfter === null ? "" : ` The latest close came ${roundsAfter}`}`,
|
|
5553
6152
|
...renderChecks(record2.observed.checks, p),
|
|
5554
6153
|
...renderClose(total === 1 ? "## The close" : `## The latest close (close ${String(latest.sequence)} of ${String(total)})`, latest, attestedBySequence.get(latest.sequence), record2.observed.checks.state, p, rounds.length > 1)
|
|
5555
6154
|
];
|
|
5556
|
-
if (record2
|
|
5557
|
-
body.push(...renderReview(record2, p)
|
|
6155
|
+
if (hasOwnerReview(record2))
|
|
6156
|
+
body.push(...renderReview(record2, p));
|
|
6157
|
+
const calls = keptCallsOf(record2);
|
|
6158
|
+
if (calls !== null)
|
|
6159
|
+
body.push(...renderCalls(calls, p));
|
|
6160
|
+
const claims = keptClaimsOf(record2);
|
|
6161
|
+
if (claims !== null)
|
|
6162
|
+
body.push(...renderClaims(claims, p));
|
|
6163
|
+
if (hasOwnerReview(record2))
|
|
6164
|
+
body.push(...renderEarlierRounds(record2, p));
|
|
5558
6165
|
if (total > 1) {
|
|
5559
6166
|
body.push("## Earlier closes");
|
|
5560
6167
|
for (const close of closes.slice(0, -1)) {
|
|
@@ -5569,16 +6176,11 @@ function renderBuildRecordV2Markdown(record2) {
|
|
|
5569
6176
|
}
|
|
5570
6177
|
|
|
5571
6178
|
// dist/build-record/write.js
|
|
5572
|
-
import {
|
|
5573
|
-
import { basename, join as join8, resolve, relative as relative2, isAbsolute as
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
const isPlainFilename = rel !== "" && rel !== ".." && !isAbsolute2(rel) && rel === basename(rel);
|
|
5578
|
-
if (!isPlainFilename) {
|
|
5579
|
-
throw new InvalidPhaseIdentityError(identity, BUILD_RECORD_DIR);
|
|
5580
|
-
}
|
|
5581
|
-
}
|
|
6179
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, rmSync as rmSync4 } from "node:fs";
|
|
6180
|
+
import { basename, join as join8, resolve as resolve2, relative as relative2, isAbsolute as isAbsolute3 } from "node:path";
|
|
6181
|
+
|
|
6182
|
+
// dist/build-record/pair-io.js
|
|
6183
|
+
import { closeSync, openSync, readFileSync as readFileSync7, renameSync as renameSync2, rmSync as rmSync3, writeSync } from "node:fs";
|
|
5582
6184
|
function createExclusiveOnDisk(path, data) {
|
|
5583
6185
|
const bytes = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
|
|
5584
6186
|
const fd = openSync(path, "wx");
|
|
@@ -5614,6 +6216,41 @@ function readIfPresent(path) {
|
|
|
5614
6216
|
return null;
|
|
5615
6217
|
}
|
|
5616
6218
|
}
|
|
6219
|
+
function createPairExclusive(io, jsonPath, jsonText, mdPath, mdText) {
|
|
6220
|
+
let createdJson = false;
|
|
6221
|
+
try {
|
|
6222
|
+
io.createExclusive(jsonPath, jsonText);
|
|
6223
|
+
createdJson = true;
|
|
6224
|
+
io.createExclusive(mdPath, mdText);
|
|
6225
|
+
return "created";
|
|
6226
|
+
} catch (err) {
|
|
6227
|
+
if (createdJson)
|
|
6228
|
+
rmSync3(jsonPath, { force: true });
|
|
6229
|
+
if (!isEexist(err))
|
|
6230
|
+
throw err;
|
|
6231
|
+
return "exists";
|
|
6232
|
+
}
|
|
6233
|
+
}
|
|
6234
|
+
function replaceOne(io, tmp, finalPath, text) {
|
|
6235
|
+
rmSync3(tmp, { force: true });
|
|
6236
|
+
try {
|
|
6237
|
+
io.createExclusive(tmp, text);
|
|
6238
|
+
io.rename(tmp, finalPath);
|
|
6239
|
+
} catch (err) {
|
|
6240
|
+
rmSync3(tmp, { force: true });
|
|
6241
|
+
throw err;
|
|
6242
|
+
}
|
|
6243
|
+
}
|
|
6244
|
+
|
|
6245
|
+
// dist/build-record/write.js
|
|
6246
|
+
var BUILD_RECORD_DIR = join8("docs", "build-records");
|
|
6247
|
+
function assertInsideOutDir(outDir, candidate, identity) {
|
|
6248
|
+
const rel = relative2(outDir, resolve2(candidate));
|
|
6249
|
+
const isPlainFilename = rel !== "" && rel !== ".." && !isAbsolute3(rel) && rel === basename(rel);
|
|
6250
|
+
if (!isPlainFilename) {
|
|
6251
|
+
throw new InvalidPhaseIdentityError(identity, BUILD_RECORD_DIR);
|
|
6252
|
+
}
|
|
6253
|
+
}
|
|
5617
6254
|
function isOwnEarlierRecord(existingText, served) {
|
|
5618
6255
|
let parsedJson;
|
|
5619
6256
|
try {
|
|
@@ -5642,7 +6279,7 @@ function writeRecordPair(repoRoot, phase, rawRecord, record2, io = NODE_RECORD_P
|
|
|
5642
6279
|
if (!isValidPhaseIdentity(phase)) {
|
|
5643
6280
|
throw new InvalidPhaseIdentityError(phase, BUILD_RECORD_DIR);
|
|
5644
6281
|
}
|
|
5645
|
-
const outDir =
|
|
6282
|
+
const outDir = resolve2(repoRoot, BUILD_RECORD_DIR);
|
|
5646
6283
|
const segment = renderPhaseSegment(phase);
|
|
5647
6284
|
const jsonPath = join8(outDir, `${segment}.json`);
|
|
5648
6285
|
const mdPath = join8(outDir, `${segment}.md`);
|
|
@@ -5654,17 +6291,8 @@ function writeRecordPair(repoRoot, phase, rawRecord, record2, io = NODE_RECORD_P
|
|
|
5654
6291
|
const jsonText = serialiseServedRecord(rawRecord);
|
|
5655
6292
|
const mdText = renderBuildRecordV2Markdown(record2);
|
|
5656
6293
|
mkdirSync6(outDir, { recursive: true });
|
|
5657
|
-
|
|
5658
|
-
try {
|
|
5659
|
-
io.createExclusive(jsonPath, jsonText);
|
|
5660
|
-
createdJson = true;
|
|
5661
|
-
io.createExclusive(mdPath, mdText);
|
|
6294
|
+
if (createPairExclusive(io, jsonPath, jsonText, mdPath, mdText) === "created") {
|
|
5662
6295
|
return { kind: "created", jsonPath, mdPath };
|
|
5663
|
-
} catch (err) {
|
|
5664
|
-
if (createdJson)
|
|
5665
|
-
rmSync3(jsonPath, { force: true });
|
|
5666
|
-
if (!isEexist(err))
|
|
5667
|
-
throw err;
|
|
5668
6296
|
}
|
|
5669
6297
|
const existingJson = readIfPresent(jsonPath);
|
|
5670
6298
|
if (existingJson === null) {
|
|
@@ -5684,22 +6312,12 @@ function writeRecordPair(repoRoot, phase, rawRecord, record2, io = NODE_RECORD_P
|
|
|
5684
6312
|
try {
|
|
5685
6313
|
replaceOne(io, jsonTmp, jsonPath, existingJson);
|
|
5686
6314
|
} catch {
|
|
5687
|
-
|
|
6315
|
+
rmSync4(jsonPath, { force: true });
|
|
5688
6316
|
}
|
|
5689
6317
|
throw err;
|
|
5690
6318
|
}
|
|
5691
6319
|
return { kind: "replaced", jsonPath, mdPath };
|
|
5692
6320
|
}
|
|
5693
|
-
function replaceOne(io, tmp, finalPath, text) {
|
|
5694
|
-
rmSync3(tmp, { force: true });
|
|
5695
|
-
try {
|
|
5696
|
-
io.createExclusive(tmp, text);
|
|
5697
|
-
io.rename(tmp, finalPath);
|
|
5698
|
-
} catch (err) {
|
|
5699
|
-
rmSync3(tmp, { force: true });
|
|
5700
|
-
throw err;
|
|
5701
|
-
}
|
|
5702
|
-
}
|
|
5703
6321
|
|
|
5704
6322
|
// dist/build-record/obtain.js
|
|
5705
6323
|
import { relative as relative3 } from "node:path";
|