@jevitate/cli 0.23.0 → 0.24.0
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/contracts/jevitate-catalog/v1/README.md +10 -0
- package/contracts/jevitate-catalog/v1/approval-hash-vectors.json +64 -0
- package/contracts/jevitate-catalog/v1/fixtures/invalid/jobs-unknown-field.json +12 -0
- package/contracts/jevitate-catalog/v1/fixtures/invalid/journey-unknown-field.json +15 -0
- package/contracts/jevitate-catalog/v1/fixtures/valid/jobs.json +11 -0
- package/contracts/jevitate-catalog/v1/fixtures/valid/journey.json +14 -0
- package/contracts/jevitate-catalog/v1/fixtures/valid/personas.json +7 -0
- package/contracts/jevitate-catalog/v1/manifest.json +69 -0
- package/contracts/jevitate-catalog/v1/schemas/job.schema.json +605 -0
- package/contracts/jevitate-catalog/v1/schemas/jobs.schema.json +28 -0
- package/contracts/jevitate-catalog/v1/schemas/journey.schema.json +10871 -0
- package/contracts/jevitate-catalog/v1/schemas/personas.schema.json +223 -0
- package/contracts/jevitate-catalog/v2/README.md +18 -0
- package/contracts/jevitate-catalog/v2/approval-hash-vectors.json +75 -0
- package/contracts/jevitate-catalog/v2/fixtures/invalid/jobs-unknown-field.json +12 -0
- package/contracts/jevitate-catalog/v2/fixtures/invalid/journey-unknown-field.json +15 -0
- package/contracts/jevitate-catalog/v2/fixtures/valid/jobs.json +11 -0
- package/contracts/jevitate-catalog/v2/fixtures/valid/journey.json +14 -0
- package/contracts/jevitate-catalog/v2/fixtures/valid/personas.json +7 -0
- package/contracts/jevitate-catalog/v2/manifest.json +78 -0
- package/contracts/jevitate-catalog/v2/schemas/job.schema.json +605 -0
- package/contracts/jevitate-catalog/v2/schemas/jobs.schema.json +28 -0
- package/contracts/jevitate-catalog/v2/schemas/journey.schema.json +10871 -0
- package/contracts/jevitate-catalog/v2/schemas/personas.schema.json +223 -0
- package/dist/bin.js +153 -68
- package/dist/build-info.generated.js +3 -3
- package/dist/catalog-bundle.d.ts +4 -2
- package/dist/catalog-bundle.js +8 -6
- package/dist/catalog-bundle.js.map +1 -1
- package/dist/catalog-contract-identity.d.ts +5 -0
- package/dist/catalog-contract-identity.js +7 -0
- package/dist/catalog-contract-identity.js.map +1 -0
- package/dist/catalog.js +18 -7
- package/dist/catalog.js.map +1 -1
- package/dist/journey-review.d.ts +3 -0
- package/dist/journey-review.js +13 -2
- package/dist/journey-review.js.map +1 -1
- package/dist/journey-stale-api.js +4 -4
- package/dist/journey-stale-api.js.map +1 -1
- package/package.json +14 -11
package/dist/bin.js
CHANGED
|
@@ -10,16 +10,36 @@ import { mkdir, stat } from "node:fs/promises";
|
|
|
10
10
|
|
|
11
11
|
// ../domain/dist/content-hash.js
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
|
-
function
|
|
13
|
+
function compareUtf16CodeUnits(a, b2) {
|
|
14
|
+
const length = Math.min(a.length, b2.length);
|
|
15
|
+
for (let index = 0; index < length; index += 1) {
|
|
16
|
+
const difference = a.charCodeAt(index) - b2.charCodeAt(index);
|
|
17
|
+
if (difference !== 0)
|
|
18
|
+
return difference < 0 ? -1 : 1;
|
|
19
|
+
}
|
|
20
|
+
return a.length === b2.length ? 0 : a.length < b2.length ? -1 : 1;
|
|
21
|
+
}
|
|
22
|
+
function canonicalJson(value) {
|
|
14
23
|
if (value === null || typeof value !== "object")
|
|
15
24
|
return JSON.stringify(value);
|
|
16
25
|
if (Array.isArray(value))
|
|
17
|
-
return `[${value.map(
|
|
26
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
27
|
+
const entries = Object.entries(value).sort(([a], [b2]) => compareUtf16CodeUnits(a, b2));
|
|
28
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(",")}}`;
|
|
29
|
+
}
|
|
30
|
+
function legacyCanonicalJson(value) {
|
|
31
|
+
if (value === null || typeof value !== "object")
|
|
32
|
+
return JSON.stringify(value);
|
|
33
|
+
if (Array.isArray(value))
|
|
34
|
+
return `[${value.map(legacyCanonicalJson).join(",")}]`;
|
|
18
35
|
const entries = Object.entries(value).sort(([a], [b2]) => a.localeCompare(b2));
|
|
19
|
-
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${
|
|
36
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${legacyCanonicalJson(v)}`).join(",")}}`;
|
|
20
37
|
}
|
|
21
38
|
function contentHash(value) {
|
|
22
|
-
return createHash("sha256").update(
|
|
39
|
+
return createHash("sha256").update(canonicalJson(value)).digest("hex");
|
|
40
|
+
}
|
|
41
|
+
function legacyContentHash(value) {
|
|
42
|
+
return createHash("sha256").update(legacyCanonicalJson(value)).digest("hex");
|
|
23
43
|
}
|
|
24
44
|
function sha256(text2) {
|
|
25
45
|
return createHash("sha256").update(text2, "utf8").digest("hex");
|
|
@@ -33945,18 +33965,18 @@ function stepIdsOf(rec) {
|
|
|
33945
33965
|
ids.add(s3.stepId);
|
|
33946
33966
|
return ids;
|
|
33947
33967
|
}
|
|
33948
|
-
function
|
|
33968
|
+
function canonicalJson2(v) {
|
|
33949
33969
|
if (Array.isArray(v))
|
|
33950
|
-
return `[${v.map(
|
|
33970
|
+
return `[${v.map(canonicalJson2).join(",")}]`;
|
|
33951
33971
|
if (v !== null && typeof v === "object") {
|
|
33952
33972
|
const o = v;
|
|
33953
|
-
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${
|
|
33973
|
+
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canonicalJson2(o[k])}`).join(",")}}`;
|
|
33954
33974
|
}
|
|
33955
33975
|
return JSON.stringify(v) ?? "null";
|
|
33956
33976
|
}
|
|
33957
33977
|
function seededRandom(rec) {
|
|
33958
33978
|
let h = 2166136261;
|
|
33959
|
-
const text2 =
|
|
33979
|
+
const text2 = canonicalJson2(rec);
|
|
33960
33980
|
for (let i = 0; i < text2.length; i++) {
|
|
33961
33981
|
h ^= text2.charCodeAt(i);
|
|
33962
33982
|
h = Math.imul(h, 16777619) >>> 0;
|
|
@@ -42172,6 +42192,7 @@ async function judgeGoalCompletion(judge, input2) {
|
|
|
42172
42192
|
...input2.signInFacts === void 0 ? [] : [`SIGN-IN (observed by code, trusted): ${input2.signInFacts}`],
|
|
42173
42193
|
...input2.saveFacts === void 0 ? [] : [`SAVE (observed by code, trusted): ${input2.saveFacts}`],
|
|
42174
42194
|
...input2.writeFacts === void 0 ? [] : [`WRITES (observed by code, trusted): ${input2.writeFacts}`],
|
|
42195
|
+
...input2.readBackFacts === void 0 ? [] : [`READ-BACK (observed by code, trusted): ${input2.readBackFacts}`],
|
|
42175
42196
|
...input2.pageStatus === void 0 || input2.pageStatus === "" ? [] : [`PAGE STATUS (untrusted): ${input2.pageStatus}`],
|
|
42176
42197
|
`VISIBLE PAGE TEXT (untrusted): ${input2.pageText.replace(/\s+/g, " ").slice(0, GOAL_TEXT_CHARS)}`,
|
|
42177
42198
|
...input2.fieldValues === void 0 || input2.fieldValues.length === 0 ? [] : [
|
|
@@ -45607,6 +45628,7 @@ var OBSERVED_PAGE_CHARS = 2e4;
|
|
|
45607
45628
|
var MIN_QUOTE_CHARS = 3;
|
|
45608
45629
|
var MAX_OBSERVED_FIELDS = 40;
|
|
45609
45630
|
var OBSERVED_FIELD_CHARS = 500;
|
|
45631
|
+
var MAX_READ_BACK_VALUES = 50;
|
|
45610
45632
|
var MAX_OBSERVED_CONTROLS = 120;
|
|
45611
45633
|
var HEADING_CHARS = 200;
|
|
45612
45634
|
function controlFields(controls) {
|
|
@@ -45696,6 +45718,21 @@ var ObservedPages = class {
|
|
|
45696
45718
|
this.#sourceRoute.set(v, pending.route);
|
|
45697
45719
|
}
|
|
45698
45720
|
}
|
|
45721
|
+
/**
|
|
45722
|
+
* #671: values the run typed into a field on one document load. A field holding one shows the run's
|
|
45723
|
+
* own entry, never what the app kept: retyping a sent message into its composer after a reload is
|
|
45724
|
+
* not a read-back.
|
|
45725
|
+
*/
|
|
45726
|
+
#typedOn = null;
|
|
45727
|
+
/** #671: the run typed `value` into a field (a message composer too) on document load `document`. */
|
|
45728
|
+
noteTypedOn(value, document2) {
|
|
45729
|
+
const v = fold(redactContext(value, this.secrets).slice(0, OBSERVED_FIELD_CHARS));
|
|
45730
|
+
if (document2 === void 0 || v === "")
|
|
45731
|
+
return;
|
|
45732
|
+
if (this.#typedOn?.document !== document2)
|
|
45733
|
+
this.#typedOn = { document: document2, values: /* @__PURE__ */ new Set() };
|
|
45734
|
+
this.#typedOn.values.add(v);
|
|
45735
|
+
}
|
|
45699
45736
|
/** #647: the run's sent values (folded) that no page loaded from the server since has shown. */
|
|
45700
45737
|
unreadWrites() {
|
|
45701
45738
|
return this.#unread;
|
|
@@ -45720,10 +45757,19 @@ var ObservedPages = class {
|
|
|
45720
45757
|
this.#sourceRoute.delete(v);
|
|
45721
45758
|
}
|
|
45722
45759
|
this.#readBackCount += back.length;
|
|
45760
|
+
for (const v of back)
|
|
45761
|
+
if (this.#readBackValues.length < MAX_READ_BACK_VALUES)
|
|
45762
|
+
this.#readBackValues.push(v);
|
|
45723
45763
|
return back;
|
|
45724
45764
|
}
|
|
45725
45765
|
/** #645: how many sent values a page loaded from the server has shown again. */
|
|
45726
45766
|
#readBackCount = 0;
|
|
45767
|
+
/** #667: the sent values (folded) read back so far, bounded. */
|
|
45768
|
+
#readBackValues = [];
|
|
45769
|
+
/** #667: the sent values (folded) a page loaded from the server has shown again. */
|
|
45770
|
+
readBackValues() {
|
|
45771
|
+
return this.#readBackValues;
|
|
45772
|
+
}
|
|
45727
45773
|
/**
|
|
45728
45774
|
* #645: the app was seen to keep what the run's writes sent — at least one value was read back and
|
|
45729
45775
|
* none is still unread. Code evidence the page judgment lacks (see `groundDone`).
|
|
@@ -45766,7 +45812,9 @@ var ObservedPages = class {
|
|
|
45766
45812
|
this.#topNav = nav;
|
|
45767
45813
|
}
|
|
45768
45814
|
this.#settleSent(page.text);
|
|
45769
|
-
this.
|
|
45815
|
+
const typed = this.#typedOn !== null && this.#typedOn.document === headings2.document ? [...this.#typedOn.values] : [];
|
|
45816
|
+
const appFields = kept.map((f2) => f2.value).filter((value) => !typed.some((t) => fold(value).includes(t)));
|
|
45817
|
+
this.readBack(headings2.document, [page.text, ...appFields].join("\n"), url2);
|
|
45770
45818
|
if (page.text.trim() === "" && kept.length === 0)
|
|
45771
45819
|
return;
|
|
45772
45820
|
const same = (p) => JSON.stringify(p.fields ?? []) === JSON.stringify(page.fields ?? []) && p.heading === page.heading && p.title === page.title && p.status === page.status && JSON.stringify(p.controls ?? []) === JSON.stringify(page.controls ?? []) && JSON.stringify(p.contentLinks ?? []) === JSON.stringify(page.contentLinks ?? []) && p.inventoryIncomplete === page.inventoryIncomplete;
|
|
@@ -46431,7 +46479,7 @@ var ABSENCE_GOAL = /\bwhether\b|\b(?:is|are) there\b|\bthere (?:is|are) (?:no|no
|
|
|
46431
46479
|
function goalAdmitsAbsence(goal) {
|
|
46432
46480
|
return ABSENCE_GOAL.test(goal);
|
|
46433
46481
|
}
|
|
46434
|
-
var WRITE_GOAL = /(?:^\s*|[.!?;:]\s+|\b(?:then|and|please)\s+)(?:record|save|create|add|invite|submit|send|post|publish|register|book|schedule)\b/i;
|
|
46482
|
+
var WRITE_GOAL = /(?:^\s*|[.!?;:]\s+|\b(?:then|and|please)\s+)(?:record|save|create|add|invite|submit|send|post|publish|register|book|schedule|import|upload|update|change|edit|rename|delete|remove)\b/i;
|
|
46435
46483
|
function goalAsksToWrite(goal) {
|
|
46436
46484
|
return WRITE_GOAL.test(goal);
|
|
46437
46485
|
}
|
|
@@ -48275,6 +48323,7 @@ function newStep(ctx, input2) {
|
|
|
48275
48323
|
if (proposedDone)
|
|
48276
48324
|
writes = jobWritesOf(ctx);
|
|
48277
48325
|
const writeFacts = writes !== void 0 && saved === null && writesAllSucceeded(writes) ? writes.facts : void 0;
|
|
48326
|
+
const readBackFacts = ctx.observed.readBackConfirmed() ? readBackFactsOf(ctx.observed.readBackValues(), pageText) : void 0;
|
|
48278
48327
|
const judged = await judgeGoalCompletion(cfg.judge, {
|
|
48279
48328
|
goal: cfg.goal,
|
|
48280
48329
|
url: snap.url,
|
|
@@ -48285,6 +48334,7 @@ function newStep(ctx, input2) {
|
|
|
48285
48334
|
...signIn === null ? {} : { signInFacts: signIn.facts },
|
|
48286
48335
|
...saved === null ? {} : { saveFacts: saved.facts },
|
|
48287
48336
|
...writeFacts === void 0 ? {} : { writeFacts },
|
|
48337
|
+
...readBackFacts === void 0 ? {} : { readBackFacts },
|
|
48288
48338
|
fieldValues: fieldValuesOf(snap.controls, ctx.isBound)
|
|
48289
48339
|
}).catch(() => ({ goalMet: null, goalIsSignIn: null, goalIsSave: null, goalIsWrites: null }));
|
|
48290
48340
|
goalMet = judged.goalMet;
|
|
@@ -48315,6 +48365,11 @@ function newStep(ctx, input2) {
|
|
|
48315
48365
|
};
|
|
48316
48366
|
return { ...input2, record: record2, signIn, pendingNote, acceptedBy, groundGoal };
|
|
48317
48367
|
}
|
|
48368
|
+
function readBackFactsOf(values2, pageText) {
|
|
48369
|
+
const text2 = pageText.toLowerCase();
|
|
48370
|
+
const shown2 = values2.filter((v) => text2.includes(v)).length;
|
|
48371
|
+
return `every value this run's writes sent (${values2.length}) was shown again on a page loaded from the server after the write \u2014 the app kept them; this page shows ${shown2} of them`;
|
|
48372
|
+
}
|
|
48318
48373
|
|
|
48319
48374
|
// ../explore/dist/goal-loop/min-effort.js
|
|
48320
48375
|
function deferEnding(ctx, step, ending) {
|
|
@@ -48444,6 +48499,7 @@ async function handleReport(ctx, step) {
|
|
|
48444
48499
|
}
|
|
48445
48500
|
|
|
48446
48501
|
// ../explore/dist/goal-loop/handle-done.js
|
|
48502
|
+
var NO_WRITE_YET = "no write of this run has succeeded yet \u2014 the goal asks for a change the app must receive: go back and press the control that submits it (Import, Save, Send\u2026)";
|
|
48447
48503
|
async function unreadWriteHold(ctx, step, outcome) {
|
|
48448
48504
|
if (outcome.status === "completed" && outcome.verifiedBy === "success-condition")
|
|
48449
48505
|
return null;
|
|
@@ -48535,12 +48591,13 @@ async function handleDone(ctx, step) {
|
|
|
48535
48591
|
}
|
|
48536
48592
|
}
|
|
48537
48593
|
ctx.doneRejections += 1;
|
|
48538
|
-
ctx.
|
|
48539
|
-
|
|
48594
|
+
const why = ctx.writeGoal && !ctx.wroteOk ? `${verdict.reason}; ${NO_WRITE_YET}` : verdict.reason;
|
|
48595
|
+
ctx.history.push(`done rejected: ${why} \u2014 keep working toward the goal`);
|
|
48596
|
+
record2(false, `done rejected (${ctx.doneRejections}/${MAX_DONE_REJECTIONS}): ${why}`, {
|
|
48540
48597
|
...judgments === void 0 ? {} : { judgments }
|
|
48541
48598
|
});
|
|
48542
48599
|
if (ctx.doneRejections >= MAX_DONE_REJECTIONS) {
|
|
48543
|
-
ctx.incomplete = `the model proposed done ${ctx.doneRejections} times, but ${
|
|
48600
|
+
ctx.incomplete = `the model proposed done ${ctx.doneRejections} times, but ${why}`;
|
|
48544
48601
|
ctx.endedOnRejectedDone = true;
|
|
48545
48602
|
ctx.stop = "done";
|
|
48546
48603
|
return "stop";
|
|
@@ -48922,6 +48979,7 @@ async function handleCodeTypedField(ctx, step) {
|
|
|
48922
48979
|
ctx.valueLog.typed(control.name || control.summary, value);
|
|
48923
48980
|
ctx.save.noteTyped(control.name || control.summary, value);
|
|
48924
48981
|
ctx.observed.noteOwnInput(value);
|
|
48982
|
+
ctx.observed.noteTypedOn(value, await documentOf(ctx.page));
|
|
48925
48983
|
ctx.noteMutation(`type ${control.name}`, control.descriptor, snap.signature, at3, { field: keyOf(control), value });
|
|
48926
48984
|
ctx.tracker.countAction();
|
|
48927
48985
|
ctx.cleared(control);
|
|
@@ -49484,6 +49542,7 @@ async function handleFill(ctx, step) {
|
|
|
49484
49542
|
ctx.typeProbe = { key: keyOf(control), label: quote(control.name || control.summary, 60), at: typedAt, background: typedBackground, state: typedState };
|
|
49485
49543
|
ctx.recorder.fill(control.descriptor, text2, at3);
|
|
49486
49544
|
ctx.valueLog.typed(control.name || control.summary, text2);
|
|
49545
|
+
ctx.observed.noteTypedOn(text2, await documentOf(ctx.page));
|
|
49487
49546
|
if (!ctx.isBound(control) && !isCredentialField(control) && !sendable(control)) {
|
|
49488
49547
|
ctx.save.noteTyped(control.name || control.summary, text2);
|
|
49489
49548
|
ctx.observed.noteOwnInput(text2);
|
|
@@ -53033,14 +53092,14 @@ function ownAssertion(s3) {
|
|
|
53033
53092
|
return { field: "resume", assertion: s3.resume };
|
|
53034
53093
|
return "expect" in s3 ? { field: "expect", assertion: s3.expect } : null;
|
|
53035
53094
|
}
|
|
53036
|
-
function
|
|
53095
|
+
function canonical(d) {
|
|
53037
53096
|
const sort = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b2]) => a.localeCompare(b2)).map(([k, x]) => [k, sort(x)])) : v;
|
|
53038
53097
|
return JSON.stringify(sort(d));
|
|
53039
53098
|
}
|
|
53040
53099
|
function isOwnTargetVisible(step) {
|
|
53041
53100
|
if (!("expect" in step) || !("target" in step))
|
|
53042
53101
|
return false;
|
|
53043
|
-
return step.expect.kind === "visible" &&
|
|
53102
|
+
return step.expect.kind === "visible" && canonical(step.expect.target) === canonical(step.target);
|
|
53044
53103
|
}
|
|
53045
53104
|
function isNoClaimExpect(step) {
|
|
53046
53105
|
if (!("expect" in step))
|
|
@@ -54930,10 +54989,10 @@ function bindParams(inputs, record2, request) {
|
|
|
54930
54989
|
return params;
|
|
54931
54990
|
}
|
|
54932
54991
|
function recordFingerprint(outputs, record2) {
|
|
54933
|
-
const
|
|
54992
|
+
const canonical6 = {};
|
|
54934
54993
|
for (const name of Object.keys(outputs.fields).sort())
|
|
54935
|
-
|
|
54936
|
-
return `sha256:${createHash5("sha256").update(JSON.stringify(
|
|
54994
|
+
canonical6[name] = record2[name] ?? null;
|
|
54995
|
+
return `sha256:${createHash5("sha256").update(JSON.stringify(canonical6)).digest("hex")}`;
|
|
54937
54996
|
}
|
|
54938
54997
|
function extractedNames(journey) {
|
|
54939
54998
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -63059,9 +63118,9 @@ function hostStarvedFailure(failure3, health) {
|
|
|
63059
63118
|
}
|
|
63060
63119
|
|
|
63061
63120
|
// src/build-info.generated.ts
|
|
63062
|
-
var GENERATED_COMMIT = "
|
|
63063
|
-
var GENERATED_TREE = "
|
|
63064
|
-
var GENERATED_BUILT_AT = "2026-10-
|
|
63121
|
+
var GENERATED_COMMIT = "e0f6f96";
|
|
63122
|
+
var GENERATED_TREE = "d0b472e";
|
|
63123
|
+
var GENERATED_BUILT_AT = "2026-10-24T16:37:57.792Z";
|
|
63065
63124
|
|
|
63066
63125
|
// src/version.ts
|
|
63067
63126
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
@@ -63083,13 +63142,13 @@ function readCliVersion() {
|
|
|
63083
63142
|
|
|
63084
63143
|
// src/engine.ts
|
|
63085
63144
|
function bundledCommit() {
|
|
63086
|
-
return true ? "
|
|
63145
|
+
return true ? "e0f6f96" : void 0;
|
|
63087
63146
|
}
|
|
63088
63147
|
function bundledBuiltAt() {
|
|
63089
|
-
return true ? "2026-10-
|
|
63148
|
+
return true ? "2026-10-24T16:37:57.792Z" : void 0;
|
|
63090
63149
|
}
|
|
63091
63150
|
function bundledTree() {
|
|
63092
|
-
return true ? "
|
|
63151
|
+
return true ? "d0b472e" : void 0;
|
|
63093
63152
|
}
|
|
63094
63153
|
function currentBuildTree() {
|
|
63095
63154
|
return bundledTree() ?? GENERATED_TREE;
|
|
@@ -63732,12 +63791,12 @@ function substituteDeep(v, sub) {
|
|
|
63732
63791
|
return v;
|
|
63733
63792
|
}
|
|
63734
63793
|
function fixtureSpecHash(spec, hooks) {
|
|
63735
|
-
return sha256(
|
|
63794
|
+
return sha256(canonical2({ spec: spec ?? null, hooks: hooks ?? null })).slice(0, 16);
|
|
63736
63795
|
}
|
|
63737
|
-
function
|
|
63738
|
-
if (Array.isArray(v)) return `[${v.map(
|
|
63796
|
+
function canonical2(v) {
|
|
63797
|
+
if (Array.isArray(v)) return `[${v.map(canonical2).join(",")}]`;
|
|
63739
63798
|
if (isRecord(v)) {
|
|
63740
|
-
return `{${Object.keys(v).sort().filter((k) => v[k] !== void 0).map((k) => `${JSON.stringify(k)}:${
|
|
63799
|
+
return `{${Object.keys(v).sort().filter((k) => v[k] !== void 0).map((k) => `${JSON.stringify(k)}:${canonical2(v[k])}`).join(",")}}`;
|
|
63741
63800
|
}
|
|
63742
63801
|
return JSON.stringify(v);
|
|
63743
63802
|
}
|
|
@@ -63859,7 +63918,7 @@ var MissionFixtures = class {
|
|
|
63859
63918
|
return redactUrl(redactText(text2, [...this.#opts.secrets ?? [], ...bound2, ...this.secrets()]));
|
|
63860
63919
|
}
|
|
63861
63920
|
identity() {
|
|
63862
|
-
return `fx-${sha256(
|
|
63921
|
+
return `fx-${sha256(canonical2({ spec: this.#specHash, outputs: this.publicOutputs(), secret: [...this.#secretNames].sort() })).slice(0, 16)}`;
|
|
63863
63922
|
}
|
|
63864
63923
|
record() {
|
|
63865
63924
|
return {
|
|
@@ -78957,14 +79016,14 @@ var GitSourceManager = class {
|
|
|
78957
79016
|
|
|
78958
79017
|
// ../sources/dist/hash.js
|
|
78959
79018
|
import { createHash as createHash9 } from "node:crypto";
|
|
78960
|
-
function
|
|
79019
|
+
function canonicalJson3(value) {
|
|
78961
79020
|
if (value === null)
|
|
78962
79021
|
return "null";
|
|
78963
79022
|
if (Array.isArray(value))
|
|
78964
|
-
return `[${value.map(
|
|
79023
|
+
return `[${value.map(canonicalJson3).join(",")}]`;
|
|
78965
79024
|
if (typeof value === "object") {
|
|
78966
79025
|
const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b2]) => a < b2 ? -1 : a > b2 ? 1 : 0);
|
|
78967
|
-
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${
|
|
79026
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson3(v)}`).join(",")}}`;
|
|
78968
79027
|
}
|
|
78969
79028
|
if (typeof value === "number") {
|
|
78970
79029
|
if (!Number.isFinite(value))
|
|
@@ -78975,7 +79034,7 @@ function canonicalJson2(value) {
|
|
|
78975
79034
|
}
|
|
78976
79035
|
function canonicalJourneyHash(file2) {
|
|
78977
79036
|
const validated = SharedJourneyFileSchema.parse(file2);
|
|
78978
|
-
const hex3 = createHash9("sha256").update(
|
|
79037
|
+
const hex3 = createHash9("sha256").update(canonicalJson3(validated), "utf8").digest("hex");
|
|
78979
79038
|
return `sha256:${hex3}`;
|
|
78980
79039
|
}
|
|
78981
79040
|
|
|
@@ -80681,6 +80740,15 @@ function journeyReviewHash(journey) {
|
|
|
80681
80740
|
for (const k of BOOKKEEPING) delete metadata[k];
|
|
80682
80741
|
return contentHash({ metadata, recording: journey.recording });
|
|
80683
80742
|
}
|
|
80743
|
+
function journeyLegacyReviewHash(journey) {
|
|
80744
|
+
const metadata = { ...journey.metadata };
|
|
80745
|
+
for (const k of BOOKKEEPING) delete metadata[k];
|
|
80746
|
+
return legacyContentHash({ metadata, recording: journey.recording });
|
|
80747
|
+
}
|
|
80748
|
+
function journeyApprovalMatches(journey) {
|
|
80749
|
+
const approved = journey.metadata.approval?.contentHash;
|
|
80750
|
+
return approved !== void 0 && (approved === journeyReviewHash(journey) || approved === journeyLegacyReviewHash(journey));
|
|
80751
|
+
}
|
|
80684
80752
|
function targetOf3(step) {
|
|
80685
80753
|
if (step.kind === "forEach") return step.items;
|
|
80686
80754
|
return "target" in step ? step.target : void 0;
|
|
@@ -80887,7 +80955,7 @@ function buildChange(journey, hash3, snapshot2, stepIdOnly) {
|
|
|
80887
80955
|
const idOnly = stepIdOnly ? { stepIdOnly: true } : {};
|
|
80888
80956
|
if (snapshot2 === null || snapshot2 === void 0) {
|
|
80889
80957
|
if (approval !== void 0) {
|
|
80890
|
-
return { kind: "snapshot-missing", approvedHash: approval.contentHash, approvedAt: approval.at, changed:
|
|
80958
|
+
return { kind: "snapshot-missing", approvedHash: approval.contentHash, approvedAt: approval.at, changed: !journeyApprovalMatches(journey), ...idOnly };
|
|
80891
80959
|
}
|
|
80892
80960
|
return journey.metadata.promoted ? { kind: "no-record" } : { kind: "first-approval" };
|
|
80893
80961
|
}
|
|
@@ -81241,9 +81309,9 @@ var UnknownCatalogItemError = class extends Error {
|
|
|
81241
81309
|
return this.kind === "persona" ? "E_UNKNOWN_PERSONA" : "E_UNKNOWN_JOB";
|
|
81242
81310
|
}
|
|
81243
81311
|
};
|
|
81244
|
-
function statusOf3(approval, hash3) {
|
|
81312
|
+
function statusOf3(approval, hash3, legacyHash) {
|
|
81245
81313
|
if (approval === void 0) return "draft";
|
|
81246
|
-
return approval.contentHash === hash3 ? "approved" : "stale";
|
|
81314
|
+
return approval.contentHash === hash3 || approval.contentHash === legacyHash ? "approved" : "stale";
|
|
81247
81315
|
}
|
|
81248
81316
|
async function readJsonFile(path2) {
|
|
81249
81317
|
const raw = await readFile8(path2, "utf8");
|
|
@@ -81308,7 +81376,7 @@ function catalogPersona(p, path2) {
|
|
|
81308
81376
|
hasLogin: p.fields.login !== void 0,
|
|
81309
81377
|
...approval === void 0 ? {} : { approval },
|
|
81310
81378
|
contentHash: hash3,
|
|
81311
|
-
status: statusOf3(approval, hash3)
|
|
81379
|
+
status: statusOf3(approval, hash3, personaLegacyContentHash(p.id, p.fields))
|
|
81312
81380
|
};
|
|
81313
81381
|
}
|
|
81314
81382
|
function personaContentHash(id, fields) {
|
|
@@ -81316,6 +81384,11 @@ function personaContentHash(id, fields) {
|
|
|
81316
81384
|
for (const [k, v] of Object.entries(fields)) if (k !== "approval" && !SESSION_KEYS.has(k)) described[k] = v;
|
|
81317
81385
|
return contentHash(described);
|
|
81318
81386
|
}
|
|
81387
|
+
function personaLegacyContentHash(id, fields) {
|
|
81388
|
+
const described = { id };
|
|
81389
|
+
for (const [k, v] of Object.entries(fields)) if (k !== "approval" && !SESSION_KEYS.has(k)) described[k] = v;
|
|
81390
|
+
return legacyContentHash(described);
|
|
81391
|
+
}
|
|
81319
81392
|
function jobList(raw, path2) {
|
|
81320
81393
|
if (Array.isArray(raw)) return raw;
|
|
81321
81394
|
if (isRecord(raw) && Array.isArray(raw.jobs)) return raw.jobs;
|
|
@@ -81338,13 +81411,17 @@ function catalogJobOf(job) {
|
|
|
81338
81411
|
personas: [.../* @__PURE__ */ new Set([...job.personas ?? [], ...job.persona === void 0 ? [] : [job.persona]])],
|
|
81339
81412
|
...job.approval === void 0 ? {} : { approval: job.approval },
|
|
81340
81413
|
contentHash: hash3,
|
|
81341
|
-
status: statusOf3(job.approval, hash3)
|
|
81414
|
+
status: statusOf3(job.approval, hash3, jobLegacyContentHash(job))
|
|
81342
81415
|
};
|
|
81343
81416
|
}
|
|
81344
81417
|
function jobContentHash(job) {
|
|
81345
81418
|
const { approval: _a3, ...rest } = job;
|
|
81346
81419
|
return contentHash(rest);
|
|
81347
81420
|
}
|
|
81421
|
+
function jobLegacyContentHash(job) {
|
|
81422
|
+
const { approval: _a3, ...rest } = job;
|
|
81423
|
+
return legacyContentHash(rest);
|
|
81424
|
+
}
|
|
81348
81425
|
function catalogJourney(journey) {
|
|
81349
81426
|
const m = journey.metadata;
|
|
81350
81427
|
const hash3 = journeyReviewHash(journey);
|
|
@@ -81357,7 +81434,7 @@ function catalogJourney(journey) {
|
|
|
81357
81434
|
...m.persona === void 0 ? {} : { personaText: m.persona },
|
|
81358
81435
|
...m.approval === void 0 ? {} : { approval: m.approval },
|
|
81359
81436
|
contentHash: hash3,
|
|
81360
|
-
changedSinceApproval: m.promoted && m.approval !== void 0 &&
|
|
81437
|
+
changedSinceApproval: m.promoted && m.approval !== void 0 && !journeyApprovalMatches(journey)
|
|
81361
81438
|
};
|
|
81362
81439
|
}
|
|
81363
81440
|
var CatalogLoader = class {
|
|
@@ -82860,12 +82937,12 @@ function healFloor(recorded, riskOf) {
|
|
|
82860
82937
|
}
|
|
82861
82938
|
return { floor: "healable", reason: "" };
|
|
82862
82939
|
}
|
|
82863
|
-
function
|
|
82940
|
+
function canonical3(v) {
|
|
82864
82941
|
if (Array.isArray(v))
|
|
82865
|
-
return `[${v.map(
|
|
82942
|
+
return `[${v.map(canonical3).join(",")}]`;
|
|
82866
82943
|
if (v !== null && typeof v === "object") {
|
|
82867
82944
|
const o = v;
|
|
82868
|
-
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${
|
|
82945
|
+
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canonical3(o[k])}`).join(",")}}`;
|
|
82869
82946
|
}
|
|
82870
82947
|
return JSON.stringify(v) ?? "undefined";
|
|
82871
82948
|
}
|
|
@@ -82887,7 +82964,7 @@ function assertProofUntouched(before, after) {
|
|
|
82887
82964
|
for (const k of /* @__PURE__ */ new Set([...Object.keys(b2), ...Object.keys(a)])) {
|
|
82888
82965
|
if (free.has(k))
|
|
82889
82966
|
continue;
|
|
82890
|
-
if (
|
|
82967
|
+
if (canonical3(b2[k]) !== canonical3(a[k]))
|
|
82891
82968
|
return { code: "proof-field-changed", detail: `the candidate changes the step's \`${k}\`` };
|
|
82892
82969
|
}
|
|
82893
82970
|
return null;
|
|
@@ -82898,15 +82975,15 @@ function assertRecordedProofUntouched(before, after) {
|
|
|
82898
82975
|
for (const k of /* @__PURE__ */ new Set([...Object.keys(b2), ...Object.keys(a)])) {
|
|
82899
82976
|
if (k === "step")
|
|
82900
82977
|
continue;
|
|
82901
|
-
if (
|
|
82978
|
+
if (canonical3(b2[k]) !== canonical3(a[k]))
|
|
82902
82979
|
return { code: "proof-field-changed", detail: `the candidate changes the recorded step's \`${k}\`` };
|
|
82903
82980
|
}
|
|
82904
|
-
return
|
|
82981
|
+
return canonical3(before.step) === canonical3(after.step) ? null : assertProofUntouched(before.step, after.step);
|
|
82905
82982
|
}
|
|
82906
82983
|
function assertRecordingProofUntouched(base, proposed) {
|
|
82907
82984
|
const { pages: bp, ...bRest } = base;
|
|
82908
82985
|
const { pages: pp, ...pRest } = proposed;
|
|
82909
|
-
if (
|
|
82986
|
+
if (canonical3(bRest) !== canonical3(pRest))
|
|
82910
82987
|
return { code: "proof-field-changed", detail: "the revision changes the recording's own fields" };
|
|
82911
82988
|
if (bp.length !== pp.length)
|
|
82912
82989
|
return { code: "shape-changed", detail: `the revision has ${pp.length} pages; the Journey has ${bp.length}` };
|
|
@@ -82914,7 +82991,7 @@ function assertRecordingProofUntouched(base, proposed) {
|
|
|
82914
82991
|
for (let i = 0; i < bp.length; i++) {
|
|
82915
82992
|
const { steps: bs, ...bPage } = bp[i];
|
|
82916
82993
|
const { steps: ps, ...pPage } = pp[i];
|
|
82917
|
-
if (
|
|
82994
|
+
if (canonical3(bPage) !== canonical3(pPage))
|
|
82918
82995
|
return { code: "proof-field-changed", detail: `the revision changes page ${i + 1}` };
|
|
82919
82996
|
if (bs.length !== ps.length)
|
|
82920
82997
|
return { code: "shape-changed", detail: `the revision has ${ps.length} steps on page ${i + 1}; the Journey has ${bs.length}` };
|
|
@@ -84500,11 +84577,11 @@ async function removeFile(path2) {
|
|
|
84500
84577
|
await assertNoSymlink(path2);
|
|
84501
84578
|
await rm4(path2, { force: true });
|
|
84502
84579
|
}
|
|
84503
|
-
function
|
|
84504
|
-
if (Array.isArray(v)) return `[${v.map(
|
|
84580
|
+
function canonical4(v) {
|
|
84581
|
+
if (Array.isArray(v)) return `[${v.map(canonical4).join(",")}]`;
|
|
84505
84582
|
if (v !== null && typeof v === "object") {
|
|
84506
84583
|
const o = v;
|
|
84507
|
-
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${
|
|
84584
|
+
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canonical4(o[k])}`).join(",")}}`;
|
|
84508
84585
|
}
|
|
84509
84586
|
return JSON.stringify(v) ?? "undefined";
|
|
84510
84587
|
}
|
|
@@ -84529,7 +84606,7 @@ function proposalFloorViolation(stored, proposed) {
|
|
|
84529
84606
|
for (let i = 0; i < after.length; i++) {
|
|
84530
84607
|
const b2 = before[i];
|
|
84531
84608
|
const a = after[i];
|
|
84532
|
-
if (b2 !== void 0 &&
|
|
84609
|
+
if (b2 !== void 0 && canonical4(b2.step) === canonical4(a.step)) continue;
|
|
84533
84610
|
for (const [which, rec] of [["before", b2?.recorded], ["after", a.recorded]]) {
|
|
84534
84611
|
if (rec === void 0) return `step ${i + 1} is not in the stored Journey`;
|
|
84535
84612
|
const floor = healFloor(rec, riskOf);
|
|
@@ -100811,14 +100888,14 @@ var CREDENTIAL_KEY2 = /pass|secret|token|otp|totp|pin|cvc|cvv|card|auth|session|
|
|
|
100811
100888
|
var MAX_DIGEST_BODY = 64e3;
|
|
100812
100889
|
var CredentialBody = class extends Error {
|
|
100813
100890
|
};
|
|
100814
|
-
function
|
|
100815
|
-
if (Array.isArray(v)) return v.map(
|
|
100891
|
+
function canonical5(v) {
|
|
100892
|
+
if (Array.isArray(v)) return v.map(canonical5);
|
|
100816
100893
|
if (v !== null && typeof v === "object") {
|
|
100817
100894
|
const out = {};
|
|
100818
100895
|
for (const k of Object.keys(v).sort()) {
|
|
100819
100896
|
if (CREDENTIAL_KEY2.test(k)) throw new CredentialBody();
|
|
100820
100897
|
if (VOLATILE_KEY.test(k)) continue;
|
|
100821
|
-
out[k] =
|
|
100898
|
+
out[k] = canonical5(v[k]);
|
|
100822
100899
|
}
|
|
100823
100900
|
return out;
|
|
100824
100901
|
}
|
|
@@ -100835,7 +100912,7 @@ function payloadDigest(method, endpoint2, body, secrets) {
|
|
|
100835
100912
|
value = Object.fromEntries(new URLSearchParams(body));
|
|
100836
100913
|
}
|
|
100837
100914
|
try {
|
|
100838
|
-
const canon = JSON.stringify(
|
|
100915
|
+
const canon = JSON.stringify(canonical5(value));
|
|
100839
100916
|
return createHash12("sha256").update(`${method.toUpperCase()} ${endpoint2}
|
|
100840
100917
|
${canon}`).digest("hex").slice(0, 32);
|
|
100841
100918
|
} catch {
|
|
@@ -104264,10 +104341,17 @@ import { existsSync as existsSync25 } from "node:fs";
|
|
|
104264
104341
|
import { copyFile as copyFile4, lstat as lstat4, mkdir as mkdir25, open as open3, readdir as readdir9, readFile as readFile24, rename as rename4, rm as rm10, writeFile as writeFile29 } from "node:fs/promises";
|
|
104265
104342
|
import { basename as basename15, dirname as dirname24, join as join56, resolve as resolve18, sep as sep7 } from "node:path";
|
|
104266
104343
|
|
|
104344
|
+
// src/catalog-contract-identity.ts
|
|
104345
|
+
var CATALOG_CONTRACT_IDENTITY = {
|
|
104346
|
+
"kind": "jevitate.catalog-contract",
|
|
104347
|
+
"version": "2.0.0",
|
|
104348
|
+
"manifestSha256": "c1292a8727d7dc0dbe1d63dc768d34b6cc94ae60fab3a67aeb0a53837e1735ad"
|
|
104349
|
+
};
|
|
104350
|
+
|
|
104267
104351
|
// src/catalog-bundle.ts
|
|
104268
104352
|
var BUNDLE_KIND = "journeeze.catalog-bundle";
|
|
104269
104353
|
var BUNDLE_VERSION = 1;
|
|
104270
|
-
var BUNDLE_MINOR =
|
|
104354
|
+
var BUNDLE_MINOR = 2;
|
|
104271
104355
|
var CatalogBundleInputError = class extends CatalogInputError {
|
|
104272
104356
|
constructor(issues) {
|
|
104273
104357
|
super(`the catalog cannot be exported as a Journeeze bundle (${issues.length} problem(s)): ${issues.join("; ")}`);
|
|
@@ -104632,7 +104716,7 @@ function bundleChecks(input2, journeys, warn) {
|
|
|
104632
104716
|
if (outcome.outcome !== "clean") why = `the run was ${outcome.outcome}, and a baseline comes only from a clean run`;
|
|
104633
104717
|
else if (journeyId === void 0 || journeyHash === void 0) why = "the item names no Journey review hash";
|
|
104634
104718
|
else if (cj === void 0) why = `Journey ${journeyId} is not in the bundle`;
|
|
104635
|
-
else if (cj.approval?.contentHash !== journeyHash || cj.
|
|
104719
|
+
else if (cj.approval?.contentHash !== journeyHash || cj.changedSinceApproval) why = `it was measured on a Journey revision (${journeyHash.slice(0, 12)}\u2026) that is not ${journeyId}'s approved one`;
|
|
104636
104720
|
else {
|
|
104637
104721
|
const b2 = bundleBaseline(item.baseline, cj.journey);
|
|
104638
104722
|
if ("drop" in b2) why = b2.drop;
|
|
@@ -104686,13 +104770,13 @@ function bundleDemos(input2, journeys, warn) {
|
|
|
104686
104770
|
warn.push(`${where}: its Journey is not in the bundle (not promoted, or left out) \u2014 the demo is left out`);
|
|
104687
104771
|
continue;
|
|
104688
104772
|
}
|
|
104689
|
-
const approved = ex.cj.approval !== void 0 && ex.cj.
|
|
104773
|
+
const approved = ex.cj.approval !== void 0 && !ex.cj.changedSinceApproval;
|
|
104690
104774
|
if (!approved) {
|
|
104691
104775
|
warn.push(`${where}: its Journey changed since it was approved \u2014 the demo is left out (approve the Journey and its demo again)`);
|
|
104692
104776
|
continue;
|
|
104693
104777
|
}
|
|
104694
|
-
if (d.renderedFrom !== ex.cj.contentHash) {
|
|
104695
|
-
warn.push(`${where}: rendered from another version of its Journey (${d.renderedFrom.slice(0, 12)}, approved ${ex.cj.contentHash.slice(0, 12)}) \u2014 the demo is left out (run \`jevitate demo approve\` again)`);
|
|
104778
|
+
if (d.renderedFrom !== ex.cj.approval.contentHash) {
|
|
104779
|
+
warn.push(`${where}: rendered from another version of its Journey (${d.renderedFrom.slice(0, 12)}, approved ${ex.cj.approval.contentHash.slice(0, 12)}) \u2014 the demo is left out (run \`jevitate demo approve\` again)`);
|
|
104696
104780
|
continue;
|
|
104697
104781
|
}
|
|
104698
104782
|
if (d.steps.length === 0 || d.steps.length > MEDIA_LIMITS.demoSteps) {
|
|
@@ -104844,6 +104928,7 @@ function buildCatalogBundle(input2) {
|
|
|
104844
104928
|
version: BUNDLE_VERSION,
|
|
104845
104929
|
minor: BUNDLE_MINOR,
|
|
104846
104930
|
producer: { tool: "jevitate", version: input2.producer.version, ...commit === void 0 ? {} : { commit } },
|
|
104931
|
+
catalogContract: CATALOG_CONTRACT_IDENTITY,
|
|
104847
104932
|
product: { name: input2.productName },
|
|
104848
104933
|
catalog: { personas, jobs, journeys: journeys.map((j) => j.entry) },
|
|
104849
104934
|
...shown2.demos.length === 0 ? {} : { demos: shown2.demos },
|
|
@@ -109807,8 +109892,8 @@ var jevReadinessAnalyzer = {
|
|
|
109807
109892
|
// src/journey-stale-api.ts
|
|
109808
109893
|
function isStepIdOnlyStale(journey, snapshot2) {
|
|
109809
109894
|
const approval = journey.metadata.approval;
|
|
109810
|
-
if (approval === void 0 ||
|
|
109811
|
-
if (snapshot2 !== null && journeyReviewHash(snapshot2)
|
|
109895
|
+
if (approval === void 0 || journeyApprovalMatches(journey)) return false;
|
|
109896
|
+
if (snapshot2 !== null && [journeyReviewHash(snapshot2), journeyLegacyReviewHash(snapshot2)].includes(approval.contentHash)) return isStepIdOnlyChange(snapshot2, journey);
|
|
109812
109897
|
return isStepIdOnlyChange(approval.contentHash, journey);
|
|
109813
109898
|
}
|
|
109814
109899
|
async function listStaleJourneys(req) {
|
|
@@ -109822,7 +109907,7 @@ async function listStaleJourneys(req) {
|
|
|
109822
109907
|
const approval = journey.metadata.approval;
|
|
109823
109908
|
if (approval === void 0) continue;
|
|
109824
109909
|
const contentHash2 = journeyReviewHash(journey);
|
|
109825
|
-
const hashStale =
|
|
109910
|
+
const hashStale = !journeyApprovalMatches(journey);
|
|
109826
109911
|
const links = journeyLinks(catalog, catalogJourney(journey));
|
|
109827
109912
|
const catalogStale = !hashStale && links.linked && [links.job?.status, links.persona?.status].includes("stale");
|
|
109828
109913
|
if (!hashStale && !catalogStale) continue;
|
|
@@ -120261,17 +120346,17 @@ function isDefectStatus(v) {
|
|
|
120261
120346
|
return typeof v === "string" && DEFECT_OUTCOME_STATUSES.includes(v);
|
|
120262
120347
|
}
|
|
120263
120348
|
function parseResultOutcome(missionOutcome, goalOutcome, defectStatus) {
|
|
120264
|
-
const
|
|
120265
|
-
if (
|
|
120349
|
+
const canonical6 = parseMissionOutcome(missionOutcome);
|
|
120350
|
+
if (canonical6 !== null) {
|
|
120266
120351
|
if (goalOutcome === void 0)
|
|
120267
|
-
return { outcome:
|
|
120352
|
+
return { outcome: canonical6 };
|
|
120268
120353
|
if (!isGoalOutcome(goalOutcome))
|
|
120269
120354
|
return null;
|
|
120270
120355
|
if (defectStatus === void 0)
|
|
120271
|
-
return foldGoalOutcome(goalOutcome) ===
|
|
120356
|
+
return foldGoalOutcome(goalOutcome) === canonical6 ? { outcome: canonical6, goalOutcome } : null;
|
|
120272
120357
|
if (!isDefectStatus(defectStatus))
|
|
120273
120358
|
return null;
|
|
120274
|
-
return goalMissionOutcome(goalOutcome, defectStatus) ===
|
|
120359
|
+
return goalMissionOutcome(goalOutcome, defectStatus) === canonical6 ? { outcome: canonical6, goalOutcome } : null;
|
|
120275
120360
|
}
|
|
120276
120361
|
if (goalOutcome === void 0 && typeof missionOutcome === "string" && Object.hasOwn(LEGACY_GOAL_OUTCOMES, missionOutcome)) {
|
|
120277
120362
|
return { outcome: LEGACY_GOAL_OUTCOMES[missionOutcome], goalOutcome: missionOutcome };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// this plain `tsc --build` dist (no bundler substitution), so it needs real committed values
|
|
6
6
|
// here instead. See ./engine.ts, which prefers the esbuild-injected value when present and
|
|
7
7
|
// falls back to these.
|
|
8
|
-
export const GENERATED_COMMIT = "
|
|
9
|
-
export const GENERATED_TREE = "
|
|
10
|
-
export const GENERATED_BUILT_AT = "2026-10-
|
|
8
|
+
export const GENERATED_COMMIT = "e0f6f96";
|
|
9
|
+
export const GENERATED_TREE = "d0b472e";
|
|
10
|
+
export const GENERATED_BUILT_AT = "2026-10-24T16:37:51.277Z";
|
|
11
11
|
//# sourceMappingURL=build-info.generated.js.map
|
package/dist/catalog-bundle.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { JOURNEY_RUN_OUTCOMES, type MissionOutcome } from "@jevitate/domain";
|
|
2
2
|
import { CatalogInputError, type Catalog } from "./catalog.js";
|
|
3
|
+
import { CATALOG_CONTRACT_IDENTITY } from "./catalog-contract-identity.js";
|
|
3
4
|
/**
|
|
4
5
|
* #464 (d464a) — the PURE builder of a Journeeze catalog bundle, version 1.0 (journeeze-saas
|
|
5
6
|
* `docs/contract/catalog-bundle-v1.md` at 61f8c92, schema `catalog-bundle.v1.json`). No I/O, no
|
|
@@ -40,8 +41,8 @@ import { CatalogInputError, type Catalog } from "./catalog.js";
|
|
|
40
41
|
*/
|
|
41
42
|
export declare const BUNDLE_KIND: "journeeze.catalog-bundle";
|
|
42
43
|
export declare const BUNDLE_VERSION: 1;
|
|
43
|
-
/**
|
|
44
|
-
export declare const BUNDLE_MINOR:
|
|
44
|
+
/** Minor 2 binds every new bundle to the exact immutable Jevitate catalog contract. */
|
|
45
|
+
export declare const BUNDLE_MINOR: 2;
|
|
45
46
|
export interface BundleApproval {
|
|
46
47
|
readonly contentHash: string;
|
|
47
48
|
readonly at: string;
|
|
@@ -198,6 +199,7 @@ export interface CatalogBundleV1 {
|
|
|
198
199
|
readonly version: string;
|
|
199
200
|
readonly commit?: string;
|
|
200
201
|
};
|
|
202
|
+
readonly catalogContract: typeof CATALOG_CONTRACT_IDENTITY;
|
|
201
203
|
readonly product: {
|
|
202
204
|
readonly name: string;
|
|
203
205
|
};
|