@sun-asterisk/sungen 3.2.2-beta.6 → 3.2.2-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/gate.d.ts +3 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +83 -0
- package/dist/cli/commands/gate.js.map +1 -0
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +5 -1
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/harness/journey.d.ts +32 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +116 -5
- package/dist/harness/journey.js.map +1 -1
- package/package.json +2 -2
- package/src/cli/commands/gate.ts +44 -0
- package/src/cli/commands/journey.ts +6 -2
- package/src/cli/index.ts +2 -0
- package/src/harness/journey.ts +140 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0B1D"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerGateCommand = registerGateCommand;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const journey_1 = require("../../harness/journey");
|
|
40
|
+
function findScreenDir(name) {
|
|
41
|
+
const candidates = [
|
|
42
|
+
path.join(process.cwd(), 'qa', 'screens', name),
|
|
43
|
+
path.join(process.cwd(), 'qa', 'flows', name),
|
|
44
|
+
path.join(process.cwd(), 'qa', 'api', name),
|
|
45
|
+
];
|
|
46
|
+
for (const c of candidates)
|
|
47
|
+
if (fs.existsSync(c))
|
|
48
|
+
return c;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const PHASES = ['create', 'run', 'deliver'];
|
|
52
|
+
function registerGateCommand(program) {
|
|
53
|
+
program
|
|
54
|
+
.command('gate')
|
|
55
|
+
.description('Inter-phase HALT gate (#381): a phase boundary passes only when its required obligations are satisfied or explicitly waived. Exit 2 = HALT (no silent bad output crosses the boundary).')
|
|
56
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
57
|
+
.option('-p, --phase <phase>', `Phase boundary: ${PHASES.join(' | ')}`)
|
|
58
|
+
.option('--json', 'Output the raw verdict')
|
|
59
|
+
.action((options) => {
|
|
60
|
+
try {
|
|
61
|
+
const name = options.screen;
|
|
62
|
+
if (!name)
|
|
63
|
+
throw new Error('Provide --screen <name>');
|
|
64
|
+
const phase = options.phase;
|
|
65
|
+
if (!PHASES.includes(phase))
|
|
66
|
+
throw new Error(`Provide --phase <${PHASES.join('|')}>`);
|
|
67
|
+
if (!findScreenDir(name))
|
|
68
|
+
throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
69
|
+
const verdict = (0, journey_1.runGate)(process.cwd(), name, phase);
|
|
70
|
+
if (options.json)
|
|
71
|
+
console.log(JSON.stringify(verdict, null, 2));
|
|
72
|
+
else
|
|
73
|
+
console.log((0, journey_1.renderGate)(verdict));
|
|
74
|
+
// Exit 2 on HALT — usable in CI / the orchestration loop to block the next phase.
|
|
75
|
+
process.exit(verdict.status === 'halt' ? 2 : 0);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/cli/commands/gate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,kDA0BC;AA1CD,2CAA6B;AAC7B,uCAAyB;AACzB,mDAAuE;AAEvE,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC;KAC5C,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,MAAM,GAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAEzD,SAAgB,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yLAAyL,CAAC;SACtM,MAAM,CAAC,qBAAqB,EAAE,+BAA+B,CAAC;SAC9D,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;SACtE,MAAM,CAAC,QAAQ,EAAE,wBAAwB,CAAC;SAC1C,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAkB,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,cAAc,IAAI,eAAe,IAAI,EAAE,CAAC,CAAC;YAEhH,MAAM,OAAO,GAAG,IAAA,iBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,OAAO,CAAC,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;;gBAC3D,OAAO,CAAC,GAAG,CAAC,IAAA,oBAAU,EAAC,OAAO,CAAC,CAAC,CAAC;YAEtC,kFAAkF;YAClF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journey.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/journey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"journey.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/journey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsC7D"}
|
|
@@ -54,6 +54,8 @@ function registerJourneyCommand(program) {
|
|
|
54
54
|
.command('journey')
|
|
55
55
|
.description('Durable "you are here" board (#381): obligations + what-to-review + next, synthesised read-only from the audit report + ledger already on disk.')
|
|
56
56
|
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
57
|
+
.option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason')
|
|
58
|
+
.option('--reason <text>', 'The reason a waived obligation is acceptable (mandatory with --waive)')
|
|
57
59
|
.option('--json', 'Output the raw JSON report')
|
|
58
60
|
.action((options) => {
|
|
59
61
|
try {
|
|
@@ -62,7 +64,9 @@ function registerJourneyCommand(program) {
|
|
|
62
64
|
throw new Error('Provide --screen <name>');
|
|
63
65
|
if (!findScreenDir(name))
|
|
64
66
|
throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
65
|
-
const report =
|
|
67
|
+
const report = options.waive
|
|
68
|
+
? (0, journey_1.waive)(process.cwd(), name, options.waive, options.reason || '')
|
|
69
|
+
: (0, journey_1.runJourney)(process.cwd(), name);
|
|
66
70
|
const outDir = path.join(process.cwd(), '.sungen', 'journey');
|
|
67
71
|
fs.mkdirSync(outDir, { recursive: true });
|
|
68
72
|
const slug = (0, unit_paths_1.reportSlug)(name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journey.js","sourceRoot":"","sources":["../../../src/cli/commands/journey.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,
|
|
1
|
+
{"version":3,"file":"journey.js","sourceRoot":"","sources":["../../../src/cli/commands/journey.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -18,6 +18,7 @@ const dashboard_1 = require("./commands/dashboard");
|
|
|
18
18
|
const audit_1 = require("./commands/audit");
|
|
19
19
|
const depth_lint_1 = require("./commands/depth-lint");
|
|
20
20
|
const journey_1 = require("./commands/journey");
|
|
21
|
+
const gate_1 = require("./commands/gate");
|
|
21
22
|
const ingest_1 = require("./commands/ingest");
|
|
22
23
|
const eval_1 = require("./commands/eval");
|
|
23
24
|
const manifest_1 = require("./commands/manifest");
|
|
@@ -57,6 +58,7 @@ async function main() {
|
|
|
57
58
|
(0, audit_1.registerAuditCommand)(program);
|
|
58
59
|
(0, depth_lint_1.registerDepthLintCommand)(program);
|
|
59
60
|
(0, journey_1.registerJourneyCommand)(program);
|
|
61
|
+
(0, gate_1.registerGateCommand)(program);
|
|
60
62
|
(0, manifest_1.registerManifestCommand)(program);
|
|
61
63
|
(0, ledger_1.registerLedgerCommand)(program);
|
|
62
64
|
(0, feedback_1.registerFeedbackCommand)(program);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export type ObStatus = 'satisfied' | 'needs-work' | 'pending';
|
|
1
|
+
export type ObStatus = 'satisfied' | 'needs-work' | 'pending' | 'waived';
|
|
2
2
|
export interface Obligation {
|
|
3
3
|
id: string;
|
|
4
4
|
title: string;
|
|
5
5
|
status: ObStatus;
|
|
6
6
|
detail: string;
|
|
7
|
+
waivedReason?: string;
|
|
7
8
|
}
|
|
8
9
|
export interface JourneyReport {
|
|
9
10
|
unit: string;
|
|
@@ -16,6 +17,36 @@ export interface JourneyReport {
|
|
|
16
17
|
needsYou: string[];
|
|
17
18
|
nextSuggested: string;
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* The public entry: compute fresh, then RECONCILE with the persisted state —
|
|
22
|
+
* - auto-close is automatic (fresh recompute reflects the current artifacts);
|
|
23
|
+
* - an active waiver (evidence unchanged) sets status='waived' (carries the reason);
|
|
24
|
+
* - a STALE waiver (audit changed since it was waived) is re-surfaced for re-decision (anti-amnesia).
|
|
25
|
+
* Then persist the current evidence cursor.
|
|
26
|
+
*/
|
|
19
27
|
export declare function runJourney(projectRoot: string, unit: string): JourneyReport;
|
|
28
|
+
/**
|
|
29
|
+
* Waive an obligation — REQUIRES a reason (anti-amnesia: a waiver leaves a recorded "why").
|
|
30
|
+
* Records the current evidence cursor so reconcile can invalidate it if the audit changes.
|
|
31
|
+
*/
|
|
32
|
+
export declare function waive(projectRoot: string, unit: string, obId: string, reason: string): JourneyReport;
|
|
20
33
|
export declare function renderJourneyBoard(r: JourneyReport): string;
|
|
34
|
+
export type GatePhase = 'create' | 'run' | 'deliver';
|
|
35
|
+
export interface GateVerdict {
|
|
36
|
+
unit: string;
|
|
37
|
+
phase: GatePhase;
|
|
38
|
+
status: 'pass' | 'halt';
|
|
39
|
+
required: string[];
|
|
40
|
+
blockers: {
|
|
41
|
+
id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
detail: string;
|
|
44
|
+
}[];
|
|
45
|
+
waivedCredit: {
|
|
46
|
+
id: string;
|
|
47
|
+
title: string;
|
|
48
|
+
}[];
|
|
49
|
+
}
|
|
50
|
+
export declare function runGate(projectRoot: string, unit: string, phase: GatePhase): GateVerdict;
|
|
51
|
+
export declare function renderGate(v: GateVerdict): string;
|
|
21
52
|
//# sourceMappingURL=journey.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journey.d.ts","sourceRoot":"","sources":["../../src/harness/journey.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"journey.d.ts","sourceRoot":"","sources":["../../src/harness/journey.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AA0HD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAqB3E;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAepG;AAID,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAkB3D;AASD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,YAAY,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C;AAWD,wBAAgB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,CASxF;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAajD"}
|
package/dist/harness/journey.js
CHANGED
|
@@ -34,7 +34,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.runJourney = runJourney;
|
|
37
|
+
exports.waive = waive;
|
|
37
38
|
exports.renderJourneyBoard = renderJourneyBoard;
|
|
39
|
+
exports.runGate = runGate;
|
|
40
|
+
exports.renderGate = renderGate;
|
|
38
41
|
/**
|
|
39
42
|
* Journey board (epic #381, story S1) — the durable, read-only "you are here" view.
|
|
40
43
|
*
|
|
@@ -44,12 +47,14 @@ exports.renderJourneyBoard = renderJourneyBoard;
|
|
|
44
47
|
* the phase history ("you are here"). The output answers the three QA questions — what's next /
|
|
45
48
|
* what to review / what's doubtful — and persists `.sungen/journey/<slug>.{json,board.md}`.
|
|
46
49
|
*
|
|
47
|
-
* S1
|
|
48
|
-
* (
|
|
49
|
-
*
|
|
50
|
+
* S1 = the read-only synthesis. S2 (this file) adds the **writable lifecycle**: persisted
|
|
51
|
+
* waivers (reason-required, anti-amnesia), reconcile (auto-close satisfied; re-surface a waiver
|
|
52
|
+
* when its evidence changed), via `runJourney` + `waive`. Gate-bound predicates + inter-phase
|
|
53
|
+
* gates are S3. Pure-deterministic, no AI.
|
|
50
54
|
*/
|
|
51
55
|
const fs = __importStar(require("fs"));
|
|
52
56
|
const path = __importStar(require("path"));
|
|
57
|
+
const crypto = __importStar(require("crypto"));
|
|
53
58
|
const unit_paths_1 = require("./unit-paths");
|
|
54
59
|
function readJSON(p) {
|
|
55
60
|
try {
|
|
@@ -80,7 +85,7 @@ function isHumanFinding(f) {
|
|
|
80
85
|
return /@manual|MANUAL-|DEPTH-DEFERRED|UNSOURCEABLE|CAPABILITY-SUGGESTION|judgment|oracle|review/i.test(f);
|
|
81
86
|
}
|
|
82
87
|
const SAT = 0.8; // axis at/above this = satisfied (below = needs-work)
|
|
83
|
-
function
|
|
88
|
+
function computeFresh(projectRoot, unit) {
|
|
84
89
|
const slug = (0, unit_paths_1.reportSlug)(unit);
|
|
85
90
|
const audit = readJSON(path.join(projectRoot, '.sungen', 'reports', `${slug}-audit.json`));
|
|
86
91
|
const phases = readLedgerPhases(path.join(projectRoot, '.sungen', 'ledger', `${slug}.jsonl`));
|
|
@@ -148,7 +153,79 @@ function runJourney(projectRoot, unit) {
|
|
|
148
153
|
obligations, needsYou, nextSuggested,
|
|
149
154
|
};
|
|
150
155
|
}
|
|
151
|
-
|
|
156
|
+
function statePath(projectRoot, slug) {
|
|
157
|
+
return path.join(projectRoot, '.sungen', 'journey', `${slug}.state.json`);
|
|
158
|
+
}
|
|
159
|
+
/** Evidence cursor: the audit report's content hash. A waiver is invalidated when this changes. */
|
|
160
|
+
function auditHashOf(projectRoot, slug) {
|
|
161
|
+
const p = path.join(projectRoot, '.sungen', 'reports', `${slug}-audit.json`);
|
|
162
|
+
return fs.existsSync(p) ? crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex') : '';
|
|
163
|
+
}
|
|
164
|
+
function loadState(p) { return readJSON(p); }
|
|
165
|
+
function saveState(p, s) {
|
|
166
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
167
|
+
fs.writeFileSync(p, JSON.stringify(s, null, 2), 'utf-8');
|
|
168
|
+
}
|
|
169
|
+
/** Recompute nextSuggested AFTER waivers are applied (a waived obligation is not a gap). */
|
|
170
|
+
function computeNext(r, unit) {
|
|
171
|
+
const gap = r.obligations.find((o) => o.status !== 'satisfied' && o.status !== 'waived' && o.id !== 'OB-signoff');
|
|
172
|
+
if (gap)
|
|
173
|
+
return `Repair "${gap.title}" (${gap.detail}).`;
|
|
174
|
+
if (!r.phasesDone.some((s) => s === 'run' || s.startsWith('run')))
|
|
175
|
+
return `Quality satisfied — run \`/sungen:run-test ${unit}\`.`;
|
|
176
|
+
return `All obligations satisfied/waived — review the ${r.needsYou.length} queued item(s), then sign off & deliver.`;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The public entry: compute fresh, then RECONCILE with the persisted state —
|
|
180
|
+
* - auto-close is automatic (fresh recompute reflects the current artifacts);
|
|
181
|
+
* - an active waiver (evidence unchanged) sets status='waived' (carries the reason);
|
|
182
|
+
* - a STALE waiver (audit changed since it was waived) is re-surfaced for re-decision (anti-amnesia).
|
|
183
|
+
* Then persist the current evidence cursor.
|
|
184
|
+
*/
|
|
185
|
+
function runJourney(projectRoot, unit) {
|
|
186
|
+
const slug = (0, unit_paths_1.reportSlug)(unit);
|
|
187
|
+
const report = computeFresh(projectRoot, unit);
|
|
188
|
+
const sp = statePath(projectRoot, slug);
|
|
189
|
+
const state = loadState(sp) || { unit, auditHash: '', waivers: {} };
|
|
190
|
+
const curHash = auditHashOf(projectRoot, slug);
|
|
191
|
+
for (const ob of report.obligations) {
|
|
192
|
+
const w = state.waivers[ob.id];
|
|
193
|
+
if (!w)
|
|
194
|
+
continue;
|
|
195
|
+
if (w.auditHashAtWaive === curHash) {
|
|
196
|
+
ob.status = 'waived';
|
|
197
|
+
ob.waivedReason = w.reason;
|
|
198
|
+
ob.detail = `waived — ${w.reason}`;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
report.needsYou.unshift(`⚠️ Waiver on "${ob.title}" is STALE (evidence changed since ${w.at}) — re-decide. Was: ${w.reason}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
report.nextSuggested = computeNext(report, unit);
|
|
205
|
+
saveState(sp, { unit, auditHash: curHash, waivers: state.waivers });
|
|
206
|
+
return report;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Waive an obligation — REQUIRES a reason (anti-amnesia: a waiver leaves a recorded "why").
|
|
210
|
+
* Records the current evidence cursor so reconcile can invalidate it if the audit changes.
|
|
211
|
+
*/
|
|
212
|
+
function waive(projectRoot, unit, obId, reason) {
|
|
213
|
+
if (!reason || !reason.trim()) {
|
|
214
|
+
throw new Error('A reason is required to waive (anti-amnesia: a waiver must record WHY). Use --reason "...".');
|
|
215
|
+
}
|
|
216
|
+
const slug = (0, unit_paths_1.reportSlug)(unit);
|
|
217
|
+
const fresh = computeFresh(projectRoot, unit);
|
|
218
|
+
const valid = fresh.obligations.map((o) => o.id);
|
|
219
|
+
if (!valid.includes(obId)) {
|
|
220
|
+
throw new Error(`Unknown obligation "${obId}". Valid: ${valid.join(', ')}`);
|
|
221
|
+
}
|
|
222
|
+
const sp = statePath(projectRoot, slug);
|
|
223
|
+
const state = loadState(sp) || { unit, auditHash: '', waivers: {} };
|
|
224
|
+
state.waivers[obId] = { reason: reason.trim(), at: new Date().toISOString(), auditHashAtWaive: auditHashOf(projectRoot, slug) };
|
|
225
|
+
saveState(sp, state);
|
|
226
|
+
return runJourney(projectRoot, unit);
|
|
227
|
+
}
|
|
228
|
+
const ICON = { satisfied: '✅', 'needs-work': '⚠️ ', pending: '⏳', waived: '🚫' };
|
|
152
229
|
function renderJourneyBoard(r) {
|
|
153
230
|
const L = [];
|
|
154
231
|
L.push(`# Journey — ${r.unit}`);
|
|
@@ -173,4 +250,38 @@ function renderJourneyBoard(r) {
|
|
|
173
250
|
L.push('');
|
|
174
251
|
return L.join('\n');
|
|
175
252
|
}
|
|
253
|
+
const PHASE_REQUIRED = {
|
|
254
|
+
// post-create (design quality): spec + coverage + depth + traceability must hold.
|
|
255
|
+
create: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace'],
|
|
256
|
+
// post-run: the design gates + automation coverage.
|
|
257
|
+
run: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace', 'OB-automation'],
|
|
258
|
+
// pre-delivery: everything automated (human sign-off is the separate S5 gate).
|
|
259
|
+
deliver: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace', 'OB-automation'],
|
|
260
|
+
};
|
|
261
|
+
function runGate(projectRoot, unit, phase) {
|
|
262
|
+
const r = runJourney(projectRoot, unit);
|
|
263
|
+
const required = PHASE_REQUIRED[phase];
|
|
264
|
+
const reqObs = r.obligations.filter((o) => required.includes(o.id));
|
|
265
|
+
const blockers = reqObs
|
|
266
|
+
.filter((o) => o.status !== 'satisfied' && o.status !== 'waived')
|
|
267
|
+
.map((o) => ({ id: o.id, title: o.title, detail: o.detail }));
|
|
268
|
+
const waivedCredit = reqObs.filter((o) => o.status === 'waived').map((o) => ({ id: o.id, title: o.title }));
|
|
269
|
+
return { unit, phase, status: blockers.length ? 'halt' : 'pass', required, blockers, waivedCredit };
|
|
270
|
+
}
|
|
271
|
+
function renderGate(v) {
|
|
272
|
+
const L = [];
|
|
273
|
+
L.push('');
|
|
274
|
+
L.push(`━━━ Gate: ${v.unit} @ phase "${v.phase}" → ${v.status === 'pass' ? '✅ PASS' : '⛔ HALT'} ━━━`);
|
|
275
|
+
if (v.blockers.length) {
|
|
276
|
+
L.push(' Blocking obligations (must be satisfied or explicitly waived):');
|
|
277
|
+
for (const b of v.blockers)
|
|
278
|
+
L.push(` • ${b.id} ${b.title} — ${b.detail}`);
|
|
279
|
+
L.push(' → Self-correct (repair / run-test), or `sungen journey --screen ' + v.unit + ' --waive <OB> --reason "..."` if accepted.');
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
L.push(' All required obligations satisfied' + (v.waivedCredit.length ? ` (${v.waivedCredit.length} accepted via waiver)` : '') + '.');
|
|
283
|
+
}
|
|
284
|
+
L.push('');
|
|
285
|
+
return L.join('\n');
|
|
286
|
+
}
|
|
176
287
|
//# sourceMappingURL=journey.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journey.js","sourceRoot":"","sources":["../../src/harness/journey.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"journey.js","sourceRoot":"","sources":["../../src/harness/journey.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwKA,gCAqBC;AAMD,sBAeC;AAID,gDAkBC;AA6BD,0BASC;AAED,gCAaC;AA7RD;;;;;;;;;;;;;GAaG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,+CAAiC;AACjC,6CAA0C;AAwB1C,SAAS,QAAQ,CAAC,CAAS;IACzB,IAAI,CAAC;QAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1G,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAS;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,IAAI,CAAC,CAAC,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oGAAoG;AACpG,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,2FAA2F,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7G,CAAC;AAED,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,sDAAsD;AAEvE,SAAS,YAAY,CAAC,WAAmB,EAAE,IAAY;IACrD,MAAM,IAAI,GAAG,IAAA,uBAAU,EAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC;IAE9F,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC7E,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1E,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,0DAA0D;QAC1D,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gDAAgD,EAAE,CAAC,CAAC;QACjJ,OAAO;YACL,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;YACxF,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,2BAA2B,GAAG,IAAI,GAAG,aAAa;SACzF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/D,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC;IACrE,MAAM,EAAE,GAAG,CAAC,EAAU,EAAE,KAAa,EAAE,GAAuB,EAAE,GAAW,EAAE,MAAc,EAAc,EAAE,CAAC,CAAC;QAC3G,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;QAC/E,MAAM,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,MAAM,EAAE;KAC9G,CAAC,CAAC;IAEH,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,uCAAuC,CAAC,CAAC,CAAC;IACzG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,oBAAoB,EAAE,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,yBAAyB,CAAC,CAAC,CAAC;IACvG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,EAAE,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,yCAAyC,CAAC,CAAC,CAAC;IACjI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,+BAA+B,CAAC,CAAC,CAAC;IAEvH,kFAAkF;IAClF,MAAM,WAAW,GAAG,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,iBAAiB,CAAC,WAAW,GAAG,CAAC,CAAC;IACvF,WAAW,CAAC,IAAI,CAAC;QACf,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,qBAAqB;QACjD,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW;QAChD,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,iBAAiB,CAAC,WAAW,8CAA8C,CAAC,CAAC,CAAC,yCAAyC;KACvJ,CAAC,CAAC;IAEH,4FAA4F;IAC5F,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1E,WAAW,CAAC,IAAI,CAAC;QACf,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS;QAC5D,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,8DAA8D;KACzF,CAAC,CAAC;IAEH,kGAAkG;IAClG,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAAE,IAAI,cAAc,CAAC,CAAC,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChF,2DAA2D;IAC3D,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;IAC/D,IAAI,OAAO;QAAE,OAAO,CAAC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,qCAAqC,WAAW,sBAAsB,CAAC;IAEvH,iGAAiG;IACjG,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;IAC5F,IAAI,aAAqB,CAAC;IAC1B,IAAI,QAAQ;QAAE,aAAa,GAAG,WAAW,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,MAAM,IAAI,CAAC;SAC5E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,aAAa,GAAG,8CAA8C,IAAI,KAAK,CAAC;;QACzF,aAAa,GAAG,0CAA0C,QAAQ,CAAC,MAAM,2CAA2C,CAAC;IAE1H,OAAO;QACL,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM;QACzD,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI;QACzF,WAAW,EAAE,QAAQ,EAAE,aAAa;KACrC,CAAC;AACJ,CAAC;AAOD,SAAS,SAAS,CAAC,WAAmB,EAAE,IAAY;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,aAAa,CAAC,CAAC;AAC5E,CAAC;AACD,mGAAmG;AACnG,SAAS,WAAW,CAAC,WAAmB,EAAE,IAAY;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,aAAa,CAAC,CAAC;IAC7E,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtG,CAAC;AACD,SAAS,SAAS,CAAC,CAAS,IAAyB,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1E,SAAS,SAAS,CAAC,CAAS,EAAE,CAAe;IAC3C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,4FAA4F;AAC5F,SAAS,WAAW,CAAC,CAAgB,EAAE,IAAY;IACjD,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;IAClH,IAAI,GAAG;QAAE,OAAO,WAAW,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC;IACzD,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,8CAA8C,IAAI,KAAK,CAAC;IAClI,OAAO,iDAAiD,CAAC,CAAC,QAAQ,CAAC,MAAM,2CAA2C,CAAC;AACvH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,WAAmB,EAAE,IAAY;IAC1D,MAAM,IAAI,GAAG,IAAA,uBAAU,EAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACpE,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAE/C,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,CAAC,CAAC,gBAAgB,KAAK,OAAO,EAAE,CAAC;YACnC,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC;YACrB,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;YAC3B,EAAE,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,sCAAsC,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAChI,CAAC;IACH,CAAC;IACD,MAAM,CAAC,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,WAAmB,EAAE,IAAY,EAAE,IAAY,EAAE,MAAc;IACnF,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,uBAAU,EAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,aAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACpE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;IAChI,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACrB,OAAO,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,IAAI,GAA6B,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAE3G,SAAgB,kBAAkB,CAAC,CAAgB;IACjD,MAAM,CAAC,GAAa,EAAE,CAAC;IACvB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxH,IAAI,CAAC,CAAC,UAAU;QAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,eAAe,CAAC,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,CAAC;IACvF,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;QAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1F,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;QAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;;QAC5E,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACpB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAoBD,MAAM,cAAc,GAAgC;IAClD,kFAAkF;IAClF,MAAM,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,CAAC;IAC1D,oDAAoD;IACpD,GAAG,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC;IACxE,+EAA+E;IAC/E,OAAO,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC;CAC7E,CAAC;AAEF,SAAgB,OAAO,CAAC,WAAmB,EAAE,IAAY,EAAE,KAAgB;IACzE,MAAM,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,MAAM;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;SAChE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5G,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AACtG,CAAC;AAED,SAAgB,UAAU,CAAC,CAAc;IACvC,MAAM,CAAC,GAAa,EAAE,CAAC;IACvB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC;IACtG,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;QAC3E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;YAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC,CAAC,IAAI,CAAC,oEAAoE,GAAG,CAAC,CAAC,IAAI,GAAG,4CAA4C,CAAC,CAAC;IACvI,CAAC;SAAM,CAAC;QACN,CAAC,CAAC,IAAI,CAAC,sCAAsC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;IAC1I,CAAC;IACD,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "3.2.2-beta.
|
|
3
|
+
"version": "3.2.2-beta.8",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=18.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@sungen/driver-ui": "3.2.2-beta.
|
|
36
|
+
"@sungen/driver-ui": "3.2.2-beta.8",
|
|
37
37
|
"@anthropic-ai/sdk": "^0.71.0",
|
|
38
38
|
"@babel/parser": "^7.28.5",
|
|
39
39
|
"@babel/traverse": "^7.28.5",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { runGate, renderGate, GatePhase } from '../../harness/journey';
|
|
5
|
+
|
|
6
|
+
function findScreenDir(name: string): string | null {
|
|
7
|
+
const candidates = [
|
|
8
|
+
path.join(process.cwd(), 'qa', 'screens', name),
|
|
9
|
+
path.join(process.cwd(), 'qa', 'flows', name),
|
|
10
|
+
path.join(process.cwd(), 'qa', 'api', name),
|
|
11
|
+
];
|
|
12
|
+
for (const c of candidates) if (fs.existsSync(c)) return c;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const PHASES: GatePhase[] = ['create', 'run', 'deliver'];
|
|
17
|
+
|
|
18
|
+
export function registerGateCommand(program: Command): void {
|
|
19
|
+
program
|
|
20
|
+
.command('gate')
|
|
21
|
+
.description('Inter-phase HALT gate (#381): a phase boundary passes only when its required obligations are satisfied or explicitly waived. Exit 2 = HALT (no silent bad output crosses the boundary).')
|
|
22
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
23
|
+
.option('-p, --phase <phase>', `Phase boundary: ${PHASES.join(' | ')}`)
|
|
24
|
+
.option('--json', 'Output the raw verdict')
|
|
25
|
+
.action((options) => {
|
|
26
|
+
try {
|
|
27
|
+
const name = options.screen;
|
|
28
|
+
if (!name) throw new Error('Provide --screen <name>');
|
|
29
|
+
const phase = options.phase as GatePhase;
|
|
30
|
+
if (!PHASES.includes(phase)) throw new Error(`Provide --phase <${PHASES.join('|')}>`);
|
|
31
|
+
if (!findScreenDir(name)) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
32
|
+
|
|
33
|
+
const verdict = runGate(process.cwd(), name, phase);
|
|
34
|
+
if (options.json) console.log(JSON.stringify(verdict, null, 2));
|
|
35
|
+
else console.log(renderGate(verdict));
|
|
36
|
+
|
|
37
|
+
// Exit 2 on HALT — usable in CI / the orchestration loop to block the next phase.
|
|
38
|
+
process.exit(verdict.status === 'halt' ? 2 : 0);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
|
-
import { runJourney, renderJourneyBoard } from '../../harness/journey';
|
|
4
|
+
import { runJourney, waive, renderJourneyBoard } from '../../harness/journey';
|
|
5
5
|
import { reportSlug } from '../../harness/unit-paths';
|
|
6
6
|
|
|
7
7
|
function findScreenDir(name: string): string | null {
|
|
@@ -19,6 +19,8 @@ export function registerJourneyCommand(program: Command): void {
|
|
|
19
19
|
.command('journey')
|
|
20
20
|
.description('Durable "you are here" board (#381): obligations + what-to-review + next, synthesised read-only from the audit report + ledger already on disk.')
|
|
21
21
|
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
22
|
+
.option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason')
|
|
23
|
+
.option('--reason <text>', 'The reason a waived obligation is acceptable (mandatory with --waive)')
|
|
22
24
|
.option('--json', 'Output the raw JSON report')
|
|
23
25
|
.action((options) => {
|
|
24
26
|
try {
|
|
@@ -26,7 +28,9 @@ export function registerJourneyCommand(program: Command): void {
|
|
|
26
28
|
if (!name) throw new Error('Provide --screen <name>');
|
|
27
29
|
if (!findScreenDir(name)) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
28
30
|
|
|
29
|
-
const report =
|
|
31
|
+
const report = options.waive
|
|
32
|
+
? waive(process.cwd(), name, options.waive, options.reason || '')
|
|
33
|
+
: runJourney(process.cwd(), name);
|
|
30
34
|
|
|
31
35
|
const outDir = path.join(process.cwd(), '.sungen', 'journey');
|
|
32
36
|
fs.mkdirSync(outDir, { recursive: true });
|
package/src/cli/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { registerDashboardCommand } from './commands/dashboard';
|
|
|
17
17
|
import { registerAuditCommand } from './commands/audit';
|
|
18
18
|
import { registerDepthLintCommand } from './commands/depth-lint';
|
|
19
19
|
import { registerJourneyCommand } from './commands/journey';
|
|
20
|
+
import { registerGateCommand } from './commands/gate';
|
|
20
21
|
import { registerIngestCommand } from './commands/ingest';
|
|
21
22
|
import { registerEvalCommand } from './commands/eval';
|
|
22
23
|
import { registerManifestCommand } from './commands/manifest';
|
|
@@ -61,6 +62,7 @@ async function main() {
|
|
|
61
62
|
registerAuditCommand(program);
|
|
62
63
|
registerDepthLintCommand(program);
|
|
63
64
|
registerJourneyCommand(program);
|
|
65
|
+
registerGateCommand(program);
|
|
64
66
|
registerManifestCommand(program);
|
|
65
67
|
registerLedgerCommand(program);
|
|
66
68
|
registerFeedbackCommand(program);
|
package/src/harness/journey.ts
CHANGED
|
@@ -7,21 +7,24 @@
|
|
|
7
7
|
* the phase history ("you are here"). The output answers the three QA questions — what's next /
|
|
8
8
|
* what to review / what's doubtful — and persists `.sungen/journey/<slug>.{json,board.md}`.
|
|
9
9
|
*
|
|
10
|
-
* S1
|
|
11
|
-
* (
|
|
12
|
-
*
|
|
10
|
+
* S1 = the read-only synthesis. S2 (this file) adds the **writable lifecycle**: persisted
|
|
11
|
+
* waivers (reason-required, anti-amnesia), reconcile (auto-close satisfied; re-surface a waiver
|
|
12
|
+
* when its evidence changed), via `runJourney` + `waive`. Gate-bound predicates + inter-phase
|
|
13
|
+
* gates are S3. Pure-deterministic, no AI.
|
|
13
14
|
*/
|
|
14
15
|
import * as fs from 'fs';
|
|
15
16
|
import * as path from 'path';
|
|
17
|
+
import * as crypto from 'crypto';
|
|
16
18
|
import { reportSlug } from './unit-paths';
|
|
17
19
|
|
|
18
|
-
export type ObStatus = 'satisfied' | 'needs-work' | 'pending';
|
|
20
|
+
export type ObStatus = 'satisfied' | 'needs-work' | 'pending' | 'waived';
|
|
19
21
|
|
|
20
22
|
export interface Obligation {
|
|
21
23
|
id: string;
|
|
22
24
|
title: string;
|
|
23
25
|
status: ObStatus;
|
|
24
26
|
detail: string;
|
|
27
|
+
waivedReason?: string; // S2 — set when the QA explicitly waived this obligation
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export interface JourneyReport {
|
|
@@ -57,7 +60,7 @@ function isHumanFinding(f: string): boolean {
|
|
|
57
60
|
|
|
58
61
|
const SAT = 0.8; // axis at/above this = satisfied (below = needs-work)
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
function computeFresh(projectRoot: string, unit: string): JourneyReport {
|
|
61
64
|
const slug = reportSlug(unit);
|
|
62
65
|
const audit = readJSON(path.join(projectRoot, '.sungen', 'reports', `${slug}-audit.json`));
|
|
63
66
|
const phases = readLedgerPhases(path.join(projectRoot, '.sungen', 'ledger', `${slug}.jsonl`));
|
|
@@ -129,7 +132,85 @@ export function runJourney(projectRoot: string, unit: string): JourneyReport {
|
|
|
129
132
|
};
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
// ---------------- S2: writable lifecycle — persisted waivers + reconcile ----------------
|
|
136
|
+
|
|
137
|
+
interface Waiver { reason: string; at: string; auditHashAtWaive: string; }
|
|
138
|
+
interface JourneyState { unit: string; auditHash: string; waivers: Record<string, Waiver>; }
|
|
139
|
+
|
|
140
|
+
function statePath(projectRoot: string, slug: string): string {
|
|
141
|
+
return path.join(projectRoot, '.sungen', 'journey', `${slug}.state.json`);
|
|
142
|
+
}
|
|
143
|
+
/** Evidence cursor: the audit report's content hash. A waiver is invalidated when this changes. */
|
|
144
|
+
function auditHashOf(projectRoot: string, slug: string): string {
|
|
145
|
+
const p = path.join(projectRoot, '.sungen', 'reports', `${slug}-audit.json`);
|
|
146
|
+
return fs.existsSync(p) ? crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex') : '';
|
|
147
|
+
}
|
|
148
|
+
function loadState(p: string): JourneyState | null { return readJSON(p); }
|
|
149
|
+
function saveState(p: string, s: JourneyState): void {
|
|
150
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
151
|
+
fs.writeFileSync(p, JSON.stringify(s, null, 2), 'utf-8');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Recompute nextSuggested AFTER waivers are applied (a waived obligation is not a gap). */
|
|
155
|
+
function computeNext(r: JourneyReport, unit: string): string {
|
|
156
|
+
const gap = r.obligations.find((o) => o.status !== 'satisfied' && o.status !== 'waived' && o.id !== 'OB-signoff');
|
|
157
|
+
if (gap) return `Repair "${gap.title}" (${gap.detail}).`;
|
|
158
|
+
if (!r.phasesDone.some((s) => s === 'run' || s.startsWith('run'))) return `Quality satisfied — run \`/sungen:run-test ${unit}\`.`;
|
|
159
|
+
return `All obligations satisfied/waived — review the ${r.needsYou.length} queued item(s), then sign off & deliver.`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The public entry: compute fresh, then RECONCILE with the persisted state —
|
|
164
|
+
* - auto-close is automatic (fresh recompute reflects the current artifacts);
|
|
165
|
+
* - an active waiver (evidence unchanged) sets status='waived' (carries the reason);
|
|
166
|
+
* - a STALE waiver (audit changed since it was waived) is re-surfaced for re-decision (anti-amnesia).
|
|
167
|
+
* Then persist the current evidence cursor.
|
|
168
|
+
*/
|
|
169
|
+
export function runJourney(projectRoot: string, unit: string): JourneyReport {
|
|
170
|
+
const slug = reportSlug(unit);
|
|
171
|
+
const report = computeFresh(projectRoot, unit);
|
|
172
|
+
const sp = statePath(projectRoot, slug);
|
|
173
|
+
const state = loadState(sp) || { unit, auditHash: '', waivers: {} };
|
|
174
|
+
const curHash = auditHashOf(projectRoot, slug);
|
|
175
|
+
|
|
176
|
+
for (const ob of report.obligations) {
|
|
177
|
+
const w = state.waivers[ob.id];
|
|
178
|
+
if (!w) continue;
|
|
179
|
+
if (w.auditHashAtWaive === curHash) {
|
|
180
|
+
ob.status = 'waived';
|
|
181
|
+
ob.waivedReason = w.reason;
|
|
182
|
+
ob.detail = `waived — ${w.reason}`;
|
|
183
|
+
} else {
|
|
184
|
+
report.needsYou.unshift(`⚠️ Waiver on "${ob.title}" is STALE (evidence changed since ${w.at}) — re-decide. Was: ${w.reason}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
report.nextSuggested = computeNext(report, unit);
|
|
188
|
+
saveState(sp, { unit, auditHash: curHash, waivers: state.waivers });
|
|
189
|
+
return report;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Waive an obligation — REQUIRES a reason (anti-amnesia: a waiver leaves a recorded "why").
|
|
194
|
+
* Records the current evidence cursor so reconcile can invalidate it if the audit changes.
|
|
195
|
+
*/
|
|
196
|
+
export function waive(projectRoot: string, unit: string, obId: string, reason: string): JourneyReport {
|
|
197
|
+
if (!reason || !reason.trim()) {
|
|
198
|
+
throw new Error('A reason is required to waive (anti-amnesia: a waiver must record WHY). Use --reason "...".');
|
|
199
|
+
}
|
|
200
|
+
const slug = reportSlug(unit);
|
|
201
|
+
const fresh = computeFresh(projectRoot, unit);
|
|
202
|
+
const valid = fresh.obligations.map((o) => o.id);
|
|
203
|
+
if (!valid.includes(obId)) {
|
|
204
|
+
throw new Error(`Unknown obligation "${obId}". Valid: ${valid.join(', ')}`);
|
|
205
|
+
}
|
|
206
|
+
const sp = statePath(projectRoot, slug);
|
|
207
|
+
const state = loadState(sp) || { unit, auditHash: '', waivers: {} };
|
|
208
|
+
state.waivers[obId] = { reason: reason.trim(), at: new Date().toISOString(), auditHashAtWaive: auditHashOf(projectRoot, slug) };
|
|
209
|
+
saveState(sp, state);
|
|
210
|
+
return runJourney(projectRoot, unit);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const ICON: Record<ObStatus, string> = { satisfied: '✅', 'needs-work': '⚠️ ', pending: '⏳', waived: '🚫' };
|
|
133
214
|
|
|
134
215
|
export function renderJourneyBoard(r: JourneyReport): string {
|
|
135
216
|
const L: string[] = [];
|
|
@@ -150,3 +231,56 @@ export function renderJourneyBoard(r: JourneyReport): string {
|
|
|
150
231
|
L.push('');
|
|
151
232
|
return L.join('\n');
|
|
152
233
|
}
|
|
234
|
+
|
|
235
|
+
// ---------------- S3: inter-phase gate — obligations as HALT predicates (#398) ----------------
|
|
236
|
+
//
|
|
237
|
+
// A phase boundary is a deterministic gate: before the next phase may run, this phase's required
|
|
238
|
+
// obligations must each be `satisfied` OR `waived` (S2 — an explicit, reasoned human acceptance).
|
|
239
|
+
// A required obligation still `needs-work`/`pending` is a BLOCKER → HALT (no silent bad output
|
|
240
|
+
// crosses the boundary, §9). Reuses runJourney → obligations already reflect waivers/reconcile.
|
|
241
|
+
|
|
242
|
+
export type GatePhase = 'create' | 'run' | 'deliver';
|
|
243
|
+
|
|
244
|
+
export interface GateVerdict {
|
|
245
|
+
unit: string;
|
|
246
|
+
phase: GatePhase;
|
|
247
|
+
status: 'pass' | 'halt';
|
|
248
|
+
required: string[];
|
|
249
|
+
blockers: { id: string; title: string; detail: string }[];
|
|
250
|
+
waivedCredit: { id: string; title: string }[]; // required obligations accepted via an explicit waiver
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const PHASE_REQUIRED: Record<GatePhase, string[]> = {
|
|
254
|
+
// post-create (design quality): spec + coverage + depth + traceability must hold.
|
|
255
|
+
create: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace'],
|
|
256
|
+
// post-run: the design gates + automation coverage.
|
|
257
|
+
run: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace', 'OB-automation'],
|
|
258
|
+
// pre-delivery: everything automated (human sign-off is the separate S5 gate).
|
|
259
|
+
deliver: ['OB-spec', 'OB-coverage', 'OB-depth', 'OB-trace', 'OB-automation'],
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export function runGate(projectRoot: string, unit: string, phase: GatePhase): GateVerdict {
|
|
263
|
+
const r = runJourney(projectRoot, unit);
|
|
264
|
+
const required = PHASE_REQUIRED[phase];
|
|
265
|
+
const reqObs = r.obligations.filter((o) => required.includes(o.id));
|
|
266
|
+
const blockers = reqObs
|
|
267
|
+
.filter((o) => o.status !== 'satisfied' && o.status !== 'waived')
|
|
268
|
+
.map((o) => ({ id: o.id, title: o.title, detail: o.detail }));
|
|
269
|
+
const waivedCredit = reqObs.filter((o) => o.status === 'waived').map((o) => ({ id: o.id, title: o.title }));
|
|
270
|
+
return { unit, phase, status: blockers.length ? 'halt' : 'pass', required, blockers, waivedCredit };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function renderGate(v: GateVerdict): string {
|
|
274
|
+
const L: string[] = [];
|
|
275
|
+
L.push('');
|
|
276
|
+
L.push(`━━━ Gate: ${v.unit} @ phase "${v.phase}" → ${v.status === 'pass' ? '✅ PASS' : '⛔ HALT'} ━━━`);
|
|
277
|
+
if (v.blockers.length) {
|
|
278
|
+
L.push(' Blocking obligations (must be satisfied or explicitly waived):');
|
|
279
|
+
for (const b of v.blockers) L.push(` • ${b.id} ${b.title} — ${b.detail}`);
|
|
280
|
+
L.push(' → Self-correct (repair / run-test), or `sungen journey --screen ' + v.unit + ' --waive <OB> --reason "..."` if accepted.');
|
|
281
|
+
} else {
|
|
282
|
+
L.push(' All required obligations satisfied' + (v.waivedCredit.length ? ` (${v.waivedCredit.length} accepted via waiver)` : '') + '.');
|
|
283
|
+
}
|
|
284
|
+
L.push('');
|
|
285
|
+
return L.join('\n');
|
|
286
|
+
}
|