@llm-dev-ops/agentics-cli 2.7.37 → 2.7.39
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/adapters/base-adapter.d.ts.map +1 -1
- package/dist/adapters/base-adapter.js.map +1 -1
- package/dist/agents/repo-agent-runner.d.ts.map +1 -1
- package/dist/agents/repo-agent-runner.js +0 -2
- package/dist/agents/repo-agent-runner.js.map +1 -1
- package/dist/agents/system-prompts.d.ts.map +1 -1
- package/dist/agents/system-prompts.js +0 -19
- package/dist/agents/system-prompts.js.map +1 -1
- package/dist/commands/agents.d.ts +4 -24
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +6 -36
- package/dist/commands/agents.js.map +1 -1
- package/dist/pipeline/auto-chain.d.ts.map +1 -1
- package/dist/pipeline/auto-chain.js +82 -6
- package/dist/pipeline/auto-chain.js.map +1 -1
- package/dist/pipeline/exemplars.d.ts +34 -0
- package/dist/pipeline/exemplars.d.ts.map +1 -0
- package/dist/pipeline/exemplars.js +101 -0
- package/dist/pipeline/exemplars.js.map +1 -0
- package/dist/pipeline/output-validator.d.ts +38 -0
- package/dist/pipeline/output-validator.d.ts.map +1 -0
- package/dist/pipeline/output-validator.js +152 -0
- package/dist/pipeline/output-validator.js.map +1 -0
- package/dist/pipeline/phase2/phases/adr-generator.d.ts.map +1 -1
- package/dist/pipeline/phase2/phases/adr-generator.js +21 -3
- package/dist/pipeline/phase2/phases/adr-generator.js.map +1 -1
- package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.d.ts.map +1 -1
- package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.js +17 -5
- package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.js.map +1 -1
- package/dist/pipeline/phase7/deliverables-registry.js +1 -1
- package/dist/pipeline/phase7/deliverables-registry.js.map +1 -1
- package/dist/pipeline/ruflo-phase-executor.d.ts +2 -5
- package/dist/pipeline/ruflo-phase-executor.d.ts.map +1 -1
- package/dist/pipeline/ruflo-phase-executor.js +55 -66
- package/dist/pipeline/ruflo-phase-executor.js.map +1 -1
- package/dist/routing/domain-boundary.d.ts +4 -20
- package/dist/routing/domain-boundary.d.ts.map +1 -1
- package/dist/routing/domain-boundary.js +6 -81
- package/dist/routing/domain-boundary.js.map +1 -1
- package/dist/routing/graph-router.d.ts.map +1 -1
- package/dist/routing/graph-router.js +0 -22
- package/dist/routing/graph-router.js.map +1 -1
- package/docs/ecosystem.graph.json +15 -65
- package/docs/templates/ADR-Good-Example.md +787 -0
- package/docs/templates/Implementation-Prompts-Good-Example.md +1158 -0
- package/docs/templates/promotion-changelog.md +94 -0
- package/docs/templates/regression-changelog.md +86 -0
- package/docs/templates/sparc-specification-good-example.md +600 -0
- package/package.json +2 -1
- package/dist/config/qe-gating.d.ts +0 -81
- package/dist/config/qe-gating.d.ts.map +0 -1
- package/dist/config/qe-gating.js +0 -138
- package/dist/config/qe-gating.js.map +0 -1
- package/dist/pipeline/phase5-build/qe-gating-executor.d.ts +0 -73
- package/dist/pipeline/phase5-build/qe-gating-executor.d.ts.map +0 -1
- package/dist/pipeline/phase5-build/qe-gating-executor.js +0 -134
- package/dist/pipeline/phase5-build/qe-gating-executor.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qe-gating.d.ts","sourceRoot":"","sources":["../../src/config/qe-gating.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,UAAU,GAAG,KAAK,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,YAAmB,CAAC;AAC/C,eAAO,MAAM,YAAY,uBAAuB,CAAC;AACjD,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAA+B,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,KAAK,GAAG,WAAW,GAAG,SAAS,CAAC;IACxC,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAMD,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,yBAAyB,CAAU;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM;CAK1B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAG,wBAAwB,CAAU;;CAKnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,CAM7E;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,cAAmB,GAAG,iBAAiB,GAAG,IAAI,CAazF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAmB,GACxB,iBAAiB,CAoBnB;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE,cAAmB,GAAG,gBAAgB,CAiB/E;AAMD,wBAAgB,UAAU,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAE7D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAEnE;AAED,wBAAgB,WAAW,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAE9D"}
|
package/dist/config/qe-gating.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* QE Gating Config (ADR-PIPELINE-086)
|
|
3
|
-
*
|
|
4
|
-
* Resolves the AGENTICS_QE_GATING mode from either the env var or a persisted
|
|
5
|
-
* config file in ~/.agentics/qe-gating.json. Emits structured bypass records
|
|
6
|
-
* when the mode is not `on`.
|
|
7
|
-
*
|
|
8
|
-
* Source precedence (highest → lowest):
|
|
9
|
-
* 1. AGENTICS_QE_GATING env var
|
|
10
|
-
* 2. Persisted config at <configDir>/qe-gating.json
|
|
11
|
-
* 3. Default: `on`
|
|
12
|
-
*
|
|
13
|
-
* The persisted file is the mechanism on-call uses outside of env-var
|
|
14
|
-
* environments (e.g., managed deployments where env vars require a redeploy).
|
|
15
|
-
* Both paths require a non-empty reason when setting anything other than `on`
|
|
16
|
-
* — callers that persist without a reason will throw.
|
|
17
|
-
*/
|
|
18
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
19
|
-
import { homedir } from 'node:os';
|
|
20
|
-
import { join, dirname } from 'node:path';
|
|
21
|
-
export const DEFAULT_MODE = 'on';
|
|
22
|
-
export const ENV_VAR_NAME = 'AGENTICS_QE_GATING';
|
|
23
|
-
export const CONFIG_FILE = 'qe-gating.json';
|
|
24
|
-
export const DEFAULT_CONFIG_DIR = join(homedir(), '.agentics');
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Parsing
|
|
27
|
-
// ============================================================================
|
|
28
|
-
export class InvalidGatingValueError extends Error {
|
|
29
|
-
code = 'INVALID_QE_GATING_VALUE';
|
|
30
|
-
value;
|
|
31
|
-
constructor(value) {
|
|
32
|
-
super(`Invalid ${ENV_VAR_NAME} value "${value}" — must be one of: on, advisory, off`);
|
|
33
|
-
this.value = value;
|
|
34
|
-
this.name = 'InvalidGatingValueError';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export class EmptyReasonError extends Error {
|
|
38
|
-
code = 'EMPTY_QE_GATING_REASON';
|
|
39
|
-
constructor() {
|
|
40
|
-
super(`Non-empty reason is required when setting ${ENV_VAR_NAME} to advisory or off (ADR-086 §2 audit trail requirement)`);
|
|
41
|
-
this.name = 'EmptyReasonError';
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Parse a raw env-var value. Accepts exactly one of: on, advisory, off
|
|
46
|
-
* (case-insensitive; whitespace-trimmed). Empty / undefined returns null so
|
|
47
|
-
* callers can fall through to persisted / default resolution.
|
|
48
|
-
*/
|
|
49
|
-
export function parseGatingValue(raw) {
|
|
50
|
-
if (raw === undefined || raw === null)
|
|
51
|
-
return null;
|
|
52
|
-
const trimmed = raw.trim().toLowerCase();
|
|
53
|
-
if (trimmed === '')
|
|
54
|
-
return null;
|
|
55
|
-
if (trimmed === 'on' || trimmed === 'advisory' || trimmed === 'off')
|
|
56
|
-
return trimmed;
|
|
57
|
-
throw new InvalidGatingValueError(raw);
|
|
58
|
-
}
|
|
59
|
-
// ============================================================================
|
|
60
|
-
// Persisted config (file-backed)
|
|
61
|
-
// ============================================================================
|
|
62
|
-
function persistedPath(configDir) {
|
|
63
|
-
return join(configDir, CONFIG_FILE);
|
|
64
|
-
}
|
|
65
|
-
export function loadPersistedQeGating(opts = {}) {
|
|
66
|
-
const configDir = opts.configDir ?? DEFAULT_CONFIG_DIR;
|
|
67
|
-
const path = persistedPath(configDir);
|
|
68
|
-
if (!existsSync(path))
|
|
69
|
-
return null;
|
|
70
|
-
try {
|
|
71
|
-
const raw = readFileSync(path, 'utf-8');
|
|
72
|
-
const parsed = JSON.parse(raw);
|
|
73
|
-
// Round-trip validation: mode must be a legal value.
|
|
74
|
-
if (parseGatingValue(parsed.mode) === null)
|
|
75
|
-
return null;
|
|
76
|
-
return parsed;
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Persist a gating decision. Throws `EmptyReasonError` if mode is not `on`
|
|
84
|
-
* and reason is empty. Creates the config dir if missing.
|
|
85
|
-
*/
|
|
86
|
-
export function persistQeGating(mode, reason, opts = {}) {
|
|
87
|
-
if (mode !== 'on' && (!reason || reason.trim() === '')) {
|
|
88
|
-
throw new EmptyReasonError();
|
|
89
|
-
}
|
|
90
|
-
const configDir = opts.configDir ?? DEFAULT_CONFIG_DIR;
|
|
91
|
-
const path = persistedPath(configDir);
|
|
92
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
93
|
-
const now = opts.now ?? new Date();
|
|
94
|
-
const record = {
|
|
95
|
-
mode,
|
|
96
|
-
reason: reason.trim(),
|
|
97
|
-
applied_at: now.toISOString(),
|
|
98
|
-
...(opts.appliedBy !== undefined ? { applied_by: opts.appliedBy } : {}),
|
|
99
|
-
...(opts.correlationId !== undefined ? { correlation_id: opts.correlationId } : {}),
|
|
100
|
-
};
|
|
101
|
-
writeFileSync(path, JSON.stringify(record, null, 2) + '\n', 'utf-8');
|
|
102
|
-
return record;
|
|
103
|
-
}
|
|
104
|
-
// ============================================================================
|
|
105
|
-
// Resolution
|
|
106
|
-
// ============================================================================
|
|
107
|
-
/**
|
|
108
|
-
* Resolve the effective gating mode from env > persisted > default.
|
|
109
|
-
*/
|
|
110
|
-
export function resolveQeGatingMode(opts = {}) {
|
|
111
|
-
const env = opts.env ?? process.env;
|
|
112
|
-
const rawEnv = env[ENV_VAR_NAME];
|
|
113
|
-
const fromEnv = parseGatingValue(rawEnv);
|
|
114
|
-
if (fromEnv !== null) {
|
|
115
|
-
const result = { mode: fromEnv, source: 'env' };
|
|
116
|
-
if (rawEnv !== undefined)
|
|
117
|
-
result.rawEnv = rawEnv;
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
const persisted = loadPersistedQeGating(opts);
|
|
121
|
-
if (persisted !== null) {
|
|
122
|
-
return { mode: persisted.mode, source: 'persisted', reason: persisted.reason };
|
|
123
|
-
}
|
|
124
|
-
return { mode: DEFAULT_MODE, source: 'default' };
|
|
125
|
-
}
|
|
126
|
-
// ============================================================================
|
|
127
|
-
// Short-hand helpers
|
|
128
|
-
// ============================================================================
|
|
129
|
-
export function isGatingOn(opts = {}) {
|
|
130
|
-
return resolveQeGatingMode(opts).mode === 'on';
|
|
131
|
-
}
|
|
132
|
-
export function isGatingAdvisory(opts = {}) {
|
|
133
|
-
return resolveQeGatingMode(opts).mode === 'advisory';
|
|
134
|
-
}
|
|
135
|
-
export function isGatingOff(opts = {}) {
|
|
136
|
-
return resolveQeGatingMode(opts).mode === 'off';
|
|
137
|
-
}
|
|
138
|
-
//# sourceMappingURL=qe-gating.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qe-gating.js","sourceRoot":"","sources":["../../src/config/qe-gating.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQ1C,MAAM,CAAC,MAAM,YAAY,GAAiB,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAoC/D,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,IAAI,GAAG,yBAAkC,CAAC;IAC1C,KAAK,CAAS;IAEvB,YAAY,KAAa;QACvB,KAAK,CAAC,WAAW,YAAY,WAAW,KAAK,uCAAuC,CAAC,CAAC;QACtF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,GAAG,wBAAiC,CAAC;IAClD;QACE,KAAK,CAAC,6CAA6C,YAAY,0DAA0D,CAAC,CAAC;QAC3H,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,OAAO,CAAC;IACpF,MAAM,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAuB,EAAE;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACvD,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;QACpD,qDAAqD;QACrD,IAAI,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAkB,EAClB,MAAc,EACd,OAAuB,EAAE;IAEzB,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,gBAAgB,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACvD,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAsB;QAChC,IAAI;QACJ,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;QACrB,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;QAC7B,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpF,CAAC;IAEF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAuB,EAAE;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;IAEjC,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,GAAqB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAClE,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACjD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IACjF,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE;IAClD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAuB,EAAE;IACxD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAuB,EAAE;IACnD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC;AAClD,CAAC"}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* QE Gating Executor (ADR-PIPELINE-086)
|
|
3
|
-
*
|
|
4
|
-
* Encapsulates the phase-8-validation decision tree driven by the gating mode
|
|
5
|
-
* resolved from env / persisted config (see src/config/qe-gating.ts).
|
|
6
|
-
*
|
|
7
|
-
* Contract:
|
|
8
|
-
* on → run all mandatory QE agents; any failure halts the pipeline
|
|
9
|
-
* with exit code 141 (via Ruvector Acceptance Gate integration
|
|
10
|
-
* upstream). The executor returns `status: 'completed'` or throws.
|
|
11
|
-
* advisory → run all mandatory QE agents; failures become warnings in the
|
|
12
|
-
* output. Returns `status: 'completed_with_warnings'`.
|
|
13
|
-
* off → skip QE invocation entirely. Returns `status: 'bypassed'`.
|
|
14
|
-
*
|
|
15
|
-
* The executor is pure — it does not invoke agents itself; callers pass in an
|
|
16
|
-
* `invokeAgent` callback. This keeps the module testable without a live
|
|
17
|
-
* pipeline and independent of adapter implementation.
|
|
18
|
-
*/
|
|
19
|
-
import type { QeGatingMode, ResolvedQeGating } from '../../config/qe-gating.js';
|
|
20
|
-
export type Phase8Status = 'completed' | 'completed_with_warnings' | 'bypassed';
|
|
21
|
-
export interface QeAgentInvocation {
|
|
22
|
-
agent: string;
|
|
23
|
-
status: 200 | 502;
|
|
24
|
-
data?: Record<string, unknown>;
|
|
25
|
-
error?: string;
|
|
26
|
-
timing_ms?: number;
|
|
27
|
-
}
|
|
28
|
-
export interface QeExecutionOutcome {
|
|
29
|
-
status: Phase8Status;
|
|
30
|
-
mode: QeGatingMode;
|
|
31
|
-
source: ResolvedQeGating['source'];
|
|
32
|
-
invocations: readonly QeAgentInvocation[];
|
|
33
|
-
warnings: readonly string[];
|
|
34
|
-
bypassRecord?: BypassRecord;
|
|
35
|
-
/** Exit code upstream should propagate on failure (on mode only). */
|
|
36
|
-
exitCode?: number;
|
|
37
|
-
}
|
|
38
|
-
export interface BypassRecord {
|
|
39
|
-
timestamp: string;
|
|
40
|
-
mode: 'advisory' | 'off';
|
|
41
|
-
source: ResolvedQeGating['source'];
|
|
42
|
-
reason?: string;
|
|
43
|
-
correlation_id: string;
|
|
44
|
-
affected_agents: readonly string[];
|
|
45
|
-
}
|
|
46
|
-
export type InvokeAgentFn = (agentId: string) => Promise<QeAgentInvocation>;
|
|
47
|
-
export interface ExecuteOptions {
|
|
48
|
-
correlationId: string;
|
|
49
|
-
/** Explicit mode override (tests). If omitted, resolves from env/persisted. */
|
|
50
|
-
modeOverride?: ResolvedQeGating;
|
|
51
|
-
/** Clock override. */
|
|
52
|
-
now?: Date;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Run phase-8 QE validation per the gating mode.
|
|
56
|
-
*
|
|
57
|
-
* @param mandatoryAgents — list of agent IDs the phase requires (from ADR-083)
|
|
58
|
-
* @param invokeAgent — callback that dispatches a single agent invocation
|
|
59
|
-
* @param options — correlation id + optional mode override
|
|
60
|
-
*/
|
|
61
|
-
export declare function executePhase8Qe(mandatoryAgents: readonly string[], invokeAgent: InvokeAgentFn, options: ExecuteOptions): Promise<QeExecutionOutcome>;
|
|
62
|
-
/**
|
|
63
|
-
* Emit a structured JSON log line to stderr describing a gating bypass.
|
|
64
|
-
* Observatory consumes this via the standard stderr-to-metrics pipeline.
|
|
65
|
-
*/
|
|
66
|
-
export declare function emitBypassLog(record: BypassRecord, writeLine?: (s: string) => void): void;
|
|
67
|
-
/**
|
|
68
|
-
* Build the Markdown header block stamped onto VALIDATION_REPORT.md when a
|
|
69
|
-
* bypass occurs. Callers prepend this to the normal report body so reviewers
|
|
70
|
-
* see the bypass at the top.
|
|
71
|
-
*/
|
|
72
|
-
export declare function buildValidationReportBypassHeader(record: BypassRecord): string;
|
|
73
|
-
//# sourceMappingURL=qe-gating-executor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qe-gating-executor.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phase5-build/qe-gating-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAOhF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,yBAAyB,GAAG,UAAU,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;IACzB,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE5E,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,sBAAsB;IACtB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAMD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,WAAW,EAAE,aAAa,EAC1B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAuE7B;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAqC,GAAG,IAAI,CAMzH;AAMD;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAe9E"}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* QE Gating Executor (ADR-PIPELINE-086)
|
|
3
|
-
*
|
|
4
|
-
* Encapsulates the phase-8-validation decision tree driven by the gating mode
|
|
5
|
-
* resolved from env / persisted config (see src/config/qe-gating.ts).
|
|
6
|
-
*
|
|
7
|
-
* Contract:
|
|
8
|
-
* on → run all mandatory QE agents; any failure halts the pipeline
|
|
9
|
-
* with exit code 141 (via Ruvector Acceptance Gate integration
|
|
10
|
-
* upstream). The executor returns `status: 'completed'` or throws.
|
|
11
|
-
* advisory → run all mandatory QE agents; failures become warnings in the
|
|
12
|
-
* output. Returns `status: 'completed_with_warnings'`.
|
|
13
|
-
* off → skip QE invocation entirely. Returns `status: 'bypassed'`.
|
|
14
|
-
*
|
|
15
|
-
* The executor is pure — it does not invoke agents itself; callers pass in an
|
|
16
|
-
* `invokeAgent` callback. This keeps the module testable without a live
|
|
17
|
-
* pipeline and independent of adapter implementation.
|
|
18
|
-
*/
|
|
19
|
-
import { resolveQeGatingMode } from '../../config/qe-gating.js';
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// Execution
|
|
22
|
-
// ============================================================================
|
|
23
|
-
/**
|
|
24
|
-
* Run phase-8 QE validation per the gating mode.
|
|
25
|
-
*
|
|
26
|
-
* @param mandatoryAgents — list of agent IDs the phase requires (from ADR-083)
|
|
27
|
-
* @param invokeAgent — callback that dispatches a single agent invocation
|
|
28
|
-
* @param options — correlation id + optional mode override
|
|
29
|
-
*/
|
|
30
|
-
export async function executePhase8Qe(mandatoryAgents, invokeAgent, options) {
|
|
31
|
-
const resolved = options.modeOverride ?? resolveQeGatingMode();
|
|
32
|
-
const now = options.now ?? new Date();
|
|
33
|
-
if (resolved.mode === 'off') {
|
|
34
|
-
const bypass = {
|
|
35
|
-
timestamp: now.toISOString(),
|
|
36
|
-
mode: 'off',
|
|
37
|
-
source: resolved.source,
|
|
38
|
-
...(resolved.reason !== undefined ? { reason: resolved.reason } : {}),
|
|
39
|
-
correlation_id: options.correlationId,
|
|
40
|
-
affected_agents: [...mandatoryAgents],
|
|
41
|
-
};
|
|
42
|
-
emitBypassLog(bypass);
|
|
43
|
-
return {
|
|
44
|
-
status: 'bypassed',
|
|
45
|
-
mode: 'off',
|
|
46
|
-
source: resolved.source,
|
|
47
|
-
invocations: [],
|
|
48
|
-
warnings: [`QE gating bypassed (off): ${mandatoryAgents.length} mandatory agents skipped`],
|
|
49
|
-
bypassRecord: bypass,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
const invocations = [];
|
|
53
|
-
for (const agent of mandatoryAgents) {
|
|
54
|
-
invocations.push(await invokeAgent(agent));
|
|
55
|
-
}
|
|
56
|
-
const failures = invocations.filter(i => i.status !== 200);
|
|
57
|
-
if (resolved.mode === 'advisory') {
|
|
58
|
-
const bypass = {
|
|
59
|
-
timestamp: now.toISOString(),
|
|
60
|
-
mode: 'advisory',
|
|
61
|
-
source: resolved.source,
|
|
62
|
-
...(resolved.reason !== undefined ? { reason: resolved.reason } : {}),
|
|
63
|
-
correlation_id: options.correlationId,
|
|
64
|
-
affected_agents: failures.map(f => f.agent),
|
|
65
|
-
};
|
|
66
|
-
if (failures.length > 0)
|
|
67
|
-
emitBypassLog(bypass);
|
|
68
|
-
return {
|
|
69
|
-
status: failures.length > 0 ? 'completed_with_warnings' : 'completed',
|
|
70
|
-
mode: 'advisory',
|
|
71
|
-
source: resolved.source,
|
|
72
|
-
invocations,
|
|
73
|
-
warnings: failures.map(f => `QE agent "${f.agent}" failed (${f.error ?? 'status ' + f.status}); advisory mode — not blocking`),
|
|
74
|
-
...(failures.length > 0 ? { bypassRecord: bypass } : {}),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
// mode === 'on' — any failure is a halting condition.
|
|
78
|
-
if (failures.length > 0) {
|
|
79
|
-
return {
|
|
80
|
-
status: 'completed_with_warnings', // caller upgrades to halt via exit code
|
|
81
|
-
mode: 'on',
|
|
82
|
-
source: resolved.source,
|
|
83
|
-
invocations,
|
|
84
|
-
warnings: failures.map(f => `QE agent "${f.agent}" failed (${f.error ?? 'status ' + f.status})`),
|
|
85
|
-
exitCode: 141,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
status: 'completed',
|
|
90
|
-
mode: 'on',
|
|
91
|
-
source: resolved.source,
|
|
92
|
-
invocations,
|
|
93
|
-
warnings: [],
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
// ============================================================================
|
|
97
|
-
// Bypass logging
|
|
98
|
-
// ============================================================================
|
|
99
|
-
/**
|
|
100
|
-
* Emit a structured JSON log line to stderr describing a gating bypass.
|
|
101
|
-
* Observatory consumes this via the standard stderr-to-metrics pipeline.
|
|
102
|
-
*/
|
|
103
|
-
export function emitBypassLog(record, writeLine = (s) => process.stderr.write(s)) {
|
|
104
|
-
writeLine(JSON.stringify({
|
|
105
|
-
level: 'WARN',
|
|
106
|
-
event: 'qe_gating_bypass',
|
|
107
|
-
...record,
|
|
108
|
-
}) + '\n');
|
|
109
|
-
}
|
|
110
|
-
// ============================================================================
|
|
111
|
-
// VALIDATION_REPORT header for bypassed runs
|
|
112
|
-
// ============================================================================
|
|
113
|
-
/**
|
|
114
|
-
* Build the Markdown header block stamped onto VALIDATION_REPORT.md when a
|
|
115
|
-
* bypass occurs. Callers prepend this to the normal report body so reviewers
|
|
116
|
-
* see the bypass at the top.
|
|
117
|
-
*/
|
|
118
|
-
export function buildValidationReportBypassHeader(record) {
|
|
119
|
-
const modeLabel = record.mode === 'off' ? 'OFF (skipped)' : 'ADVISORY (warnings-only)';
|
|
120
|
-
const reasonLine = record.reason ? `> Reason: ${record.reason}` : '> Reason: (not provided)';
|
|
121
|
-
return [
|
|
122
|
-
'> ⚠️ **QE GATING BYPASSED**',
|
|
123
|
-
`> Mode: ${modeLabel}`,
|
|
124
|
-
`> Source: ${record.source} config`,
|
|
125
|
-
reasonLine,
|
|
126
|
-
`> Timestamp: ${record.timestamp}`,
|
|
127
|
-
`> Correlation: ${record.correlation_id}`,
|
|
128
|
-
`> Affected agents: ${record.affected_agents.length > 0 ? record.affected_agents.join(', ') : '(none — full bypass)'}`,
|
|
129
|
-
'>',
|
|
130
|
-
'> See ADR-PIPELINE-086 and `docs/runbooks/qe-gating-recovery-086.md` for recovery.',
|
|
131
|
-
'',
|
|
132
|
-
].join('\n');
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=qe-gating-executor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qe-gating-executor.js","sourceRoot":"","sources":["../../../src/pipeline/phase5-build/qe-gating-executor.ts"],"names":[],"mappings":"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"}
|