@miller-tech/uap 1.46.7 → 1.47.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.
Files changed (33) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/bin/cli.js +8 -0
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/cli/deliver.d.ts +14 -0
  5. package/dist/cli/deliver.d.ts.map +1 -1
  6. package/dist/cli/deliver.js +204 -11
  7. package/dist/cli/deliver.js.map +1 -1
  8. package/dist/delivery/agentic-executor.d.ts +8 -0
  9. package/dist/delivery/agentic-executor.d.ts.map +1 -1
  10. package/dist/delivery/agentic-executor.js +12 -2
  11. package/dist/delivery/agentic-executor.js.map +1 -1
  12. package/dist/delivery/applier.d.ts +8 -0
  13. package/dist/delivery/applier.d.ts.map +1 -1
  14. package/dist/delivery/applier.js +35 -1
  15. package/dist/delivery/applier.js.map +1 -1
  16. package/dist/delivery/auto-optimizer.d.ts +11 -0
  17. package/dist/delivery/auto-optimizer.d.ts.map +1 -1
  18. package/dist/delivery/auto-optimizer.js +11 -2
  19. package/dist/delivery/auto-optimizer.js.map +1 -1
  20. package/dist/delivery/ci-watcher.d.ts +72 -0
  21. package/dist/delivery/ci-watcher.d.ts.map +1 -0
  22. package/dist/delivery/ci-watcher.js +221 -0
  23. package/dist/delivery/ci-watcher.js.map +1 -0
  24. package/dist/delivery/deploy-dev-gate.d.ts +44 -0
  25. package/dist/delivery/deploy-dev-gate.d.ts.map +1 -0
  26. package/dist/delivery/deploy-dev-gate.js +175 -0
  27. package/dist/delivery/deploy-dev-gate.js.map +1 -0
  28. package/dist/delivery/verifier-ladder.d.ts +77 -0
  29. package/dist/delivery/verifier-ladder.d.ts.map +1 -1
  30. package/dist/delivery/verifier-ladder.js +225 -3
  31. package/dist/delivery/verifier-ladder.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * CI watcher: the commit/push boundary between local convergence and CI/CD.
3
+ *
4
+ * Once the convergence loop reaches local-green, this module commits the
5
+ * applied files on the current worktree branch, pushes (never force), resolves
6
+ * the CI run triggered for that exact commit (matched by head SHA, not "latest
7
+ * run"), watches it to a conclusion, and — on failure — converts the failed
8
+ * logs into sanitized convergence feedback so the loop can re-converge against
9
+ * what CI/staging/prod actually reported.
10
+ *
11
+ * Honors the repo conventions:
12
+ * - never pushes `master`/`main` directly (merge-to-master stays in the PR
13
+ * flow); a protected branch yields `status: 'skipped'`.
14
+ * - never force-pushes.
15
+ * - sanitizes secrets out of CI logs before they enter a model prompt.
16
+ */
17
+ import { execFile as execFileCb } from 'child_process';
18
+ const PROTECTED_BRANCHES = new Set(['master', 'main']);
19
+ const DEFAULT_POLL_MS = 15_000;
20
+ const DEFAULT_TIMEOUT_MS = 20 * 60_000;
21
+ const DEFAULT_RESOLVE_ATTEMPTS = 8;
22
+ const DEFAULT_TAIL_CHARS = 4_000;
23
+ const defaultExec = (command, args, opts = {}) => new Promise((resolve) => {
24
+ execFileCb(command, args, { cwd: opts.cwd, timeout: opts.timeoutMs, maxBuffer: 10 * 1024 * 1024, encoding: 'utf-8' }, (error, stdout, stderr) => {
25
+ const code = error && typeof error.code === 'number'
26
+ ? (error.code)
27
+ : error
28
+ ? 1
29
+ : 0;
30
+ resolve({ code, stdout: stdout ?? '', stderr: stderr ?? '' });
31
+ });
32
+ });
33
+ const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
34
+ /**
35
+ * Strip secrets out of CI logs before they are injected into a model prompt.
36
+ * Masks common token shapes and `KEY=secret` assignments for sensitive keys.
37
+ */
38
+ export function sanitizeCiLog(text) {
39
+ return (text
40
+ // GitHub tokens (PAT, OAuth, server, fine-grained) and generic gh* tokens
41
+ .replace(/\b(gh[pousr]|github_pat)_[A-Za-z0-9_]{20,}\b/g, '***')
42
+ // Provider tokens: Slack, Stripe, Google API, npm, OpenAI/Anthropic-style
43
+ .replace(/\bxox[baprs]-[A-Za-z0-9-]{10,}/g, '***')
44
+ .replace(/\bsk_(live|test)_[A-Za-z0-9]{16,}\b/g, '***')
45
+ .replace(/\bAIza[0-9A-Za-z_-]{35}\b/g, '***')
46
+ .replace(/\bnpm_[A-Za-z0-9]{36}\b/g, '***')
47
+ .replace(/\bsk-[A-Za-z0-9_-]{20,}\b/g, '***')
48
+ // JWTs (header.payload.signature) — contain '.'/'-', so the base64 rule misses them
49
+ .replace(/\beyJ[A-Za-z0-9._-]{20,}\b/g, '***')
50
+ // Bearer / token headers (allow base64 chars +/=)
51
+ .replace(/\b(Bearer|token)\s+[A-Za-z0-9._/+=-]{12,}/gi, '$1 ***')
52
+ // AWS access key ids
53
+ .replace(/\bAKIA[0-9A-Z]{16}\b/g, '***')
54
+ // KEY=value / KEY: value assignments for sensitive-looking keys
55
+ .replace(/\b([A-Z0-9_]*(?:API_?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PWD|CREDENTIAL|PRIVATE_KEY|AUTH|ACCESS_KEY)[A-Z0-9_]*)\s*[=:]\s*\S+/gi, '$1=***')
56
+ // long base64-ish blobs (>=40 chars) that look like encoded secrets
57
+ .replace(/\b[A-Za-z0-9+/]{40,}={0,2}\b/g, '***'));
58
+ }
59
+ function truncateTail(text, maxChars) {
60
+ const trimmed = text.trim();
61
+ if (trimmed.length <= maxChars)
62
+ return trimmed;
63
+ return `…(truncated)…\n${trimmed.slice(-maxChars)}`;
64
+ }
65
+ /**
66
+ * Commit applied files on the worktree branch, push (non-force), then watch the
67
+ * triggered CI run and report a status the convergence loop can act on.
68
+ */
69
+ export async function commitPushAndWatch(options) {
70
+ const exec = options.exec ?? defaultExec;
71
+ const sleep = options.sleep ?? defaultSleep;
72
+ const remote = options.remote ?? 'origin';
73
+ const cwd = options.projectRoot;
74
+ const progress = options.onProgress ?? (() => undefined);
75
+ const tailChars = options.outputTailChars ?? DEFAULT_TAIL_CHARS;
76
+ // 1. Resolve and guard the branch.
77
+ let branch = options.branch;
78
+ if (!branch) {
79
+ const head = await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd });
80
+ branch = head.stdout.trim();
81
+ }
82
+ if (!branch || PROTECTED_BRANCHES.has(branch)) {
83
+ return {
84
+ pushed: false,
85
+ runId: null,
86
+ status: 'skipped',
87
+ feedback: `CI watch skipped: refusing to push protected branch '${branch || '(unknown)'}'. Merge to master via the PR flow.`,
88
+ };
89
+ }
90
+ // 2. Commit (tolerate "nothing to commit").
91
+ if (options.files.length > 0) {
92
+ await exec('git', ['add', '--', ...options.files], { cwd });
93
+ }
94
+ else {
95
+ await exec('git', ['add', '-A'], { cwd });
96
+ }
97
+ const commit = await exec('git', ['commit', '-m', options.commitMessage], { cwd });
98
+ if (commit.code !== 0 && !/nothing to commit/i.test(`${commit.stdout}\n${commit.stderr}`)) {
99
+ return {
100
+ pushed: false,
101
+ runId: null,
102
+ status: 'skipped',
103
+ feedback: `CI watch skipped: commit failed — ${sanitizeCiLog(truncateTail(commit.stderr, 500))}`,
104
+ };
105
+ }
106
+ // 3. Resolve the head SHA we are about to push.
107
+ const sha = (await exec('git', ['rev-parse', 'HEAD'], { cwd })).stdout.trim();
108
+ // 4. Push (non-force, never force-with-lease).
109
+ progress(`Pushing ${branch} to ${remote}…`);
110
+ const push = await exec('git', ['push', remote, branch], { cwd });
111
+ if (push.code !== 0) {
112
+ return {
113
+ pushed: false,
114
+ runId: null,
115
+ status: 'skipped',
116
+ feedback: `CI watch skipped: push failed — ${sanitizeCiLog(truncateTail(push.stderr, 500))}`,
117
+ };
118
+ }
119
+ // 5. Resolve the run for this exact commit (match by head SHA).
120
+ const run = await resolveRun(exec, cwd, branch, sha, options.resolveAttempts ?? DEFAULT_RESOLVE_ATTEMPTS, sleep, options.pollIntervalMs ?? DEFAULT_POLL_MS, progress);
121
+ if (!run) {
122
+ return {
123
+ pushed: true,
124
+ runId: null,
125
+ status: 'no-run',
126
+ feedback: `Pushed ${sha.slice(0, 8)} to ${branch}, but no CI run was found for it. CI may be disabled for this branch.`,
127
+ };
128
+ }
129
+ // 6. Watch to conclusion.
130
+ return watchRun(exec, cwd, run, {
131
+ pollIntervalMs: options.pollIntervalMs ?? DEFAULT_POLL_MS,
132
+ timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
133
+ watchEnvironments: options.watchEnvironments,
134
+ tailChars,
135
+ sleep,
136
+ progress,
137
+ });
138
+ }
139
+ async function resolveRun(exec, cwd, branch, sha, attempts, sleep, pollMs, progress) {
140
+ for (let i = 0; i < attempts; i++) {
141
+ const res = await exec('gh', ['run', 'list', '--branch', branch, '--json', 'databaseId,headSha,status,url', '--limit', '20'], { cwd });
142
+ if (res.code === 0) {
143
+ try {
144
+ const runs = JSON.parse(res.stdout);
145
+ const match = runs.find((r) => r.headSha === sha);
146
+ if (match)
147
+ return match;
148
+ }
149
+ catch {
150
+ /* malformed json — retry */
151
+ }
152
+ }
153
+ progress(`Waiting for CI run on ${sha.slice(0, 8)} (attempt ${i + 1}/${attempts})…`);
154
+ if (i < attempts - 1)
155
+ await sleep(pollMs);
156
+ }
157
+ return null;
158
+ }
159
+ async function watchRun(exec, cwd, run, params) {
160
+ const runId = String(run.databaseId);
161
+ const deadline = params.timeoutMs;
162
+ let elapsed = 0;
163
+ for (;;) {
164
+ const res = await exec('gh', ['run', 'view', runId, '--json', 'status,conclusion,jobs,url'], { cwd });
165
+ let view = null;
166
+ if (res.code === 0) {
167
+ try {
168
+ view = JSON.parse(res.stdout);
169
+ }
170
+ catch {
171
+ view = null;
172
+ }
173
+ }
174
+ if (view && view.status === 'completed') {
175
+ const runUrl = view.url ?? run.url;
176
+ const envProblem = requiredEnvFailure(view.jobs ?? [], params.watchEnvironments);
177
+ if (view.conclusion === 'success' && !envProblem) {
178
+ return { pushed: true, runId, status: 'green', runUrl };
179
+ }
180
+ const feedback = await buildFailureFeedback(exec, cwd, runId, envProblem, params.tailChars);
181
+ return { pushed: true, runId, status: 'failed', feedback, runUrl };
182
+ }
183
+ if (elapsed >= deadline) {
184
+ return {
185
+ pushed: true,
186
+ runId,
187
+ status: 'timeout',
188
+ runUrl: view?.url ?? run.url,
189
+ feedback: `CI run ${runId} did not conclude within ${Math.round(deadline / 60000)} min. See ${view?.url ?? run.url ?? 'the run'} for status.`,
190
+ };
191
+ }
192
+ params.progress(`Watching CI run ${runId} (${view?.status ?? 'pending'})…`);
193
+ await params.sleep(params.pollIntervalMs);
194
+ elapsed += params.pollIntervalMs;
195
+ }
196
+ }
197
+ /** Returns a description when a required environment's deploy job is not green. */
198
+ function requiredEnvFailure(jobs, envs) {
199
+ if (!envs || envs.length === 0)
200
+ return null;
201
+ for (const env of envs) {
202
+ const jobName = `deploy-${env}`;
203
+ const job = jobs.find((j) => j.name === jobName || j.name.startsWith(`${jobName} `));
204
+ if (!job)
205
+ return `Required ${env} deploy job ('${jobName}') was not found in the CI run.`;
206
+ if (job.conclusion !== 'success') {
207
+ return `Required ${env} deploy job ('${jobName}') concluded '${job.conclusion ?? job.status}'.`;
208
+ }
209
+ }
210
+ return null;
211
+ }
212
+ async function buildFailureFeedback(exec, cwd, runId, envProblem, tailChars) {
213
+ const logs = await exec('gh', ['run', 'view', runId, '--log-failed'], { cwd });
214
+ const raw = logs.code === 0 ? logs.stdout : `${logs.stdout}\n${logs.stderr}`;
215
+ const sanitized = sanitizeCiLog(truncateTail(raw, tailChars));
216
+ const header = envProblem
217
+ ? `ci-feedback: ${envProblem}`
218
+ : 'ci-feedback: the CI run failed after the change was pushed. Fix the failure below so dev/staging/prod verification passes.';
219
+ return `${header}\n\nFailed CI logs:\n\`\`\`\n${sanitized || '(no log output captured)'}\n\`\`\``;
220
+ }
221
+ //# sourceMappingURL=ci-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-watcher.js","sourceRoot":"","sources":["../../src/delivery/ci-watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Local dev deploy + smoke gate (the `deploy-dev` tier).
3
+ *
4
+ * Runs a deploy-dev rung as a full lifecycle: optionally bring a docker-compose
5
+ * stack up (`docker compose up -d --wait`), run the smoke/health check, then
6
+ * ALWAYS tear the stack down (even on smoke failure or timeout). This gives the
7
+ * convergence loop real "does it actually run" feedback locally, before the
8
+ * change is ever committed.
9
+ *
10
+ * Safety:
11
+ * - When the rung needs docker and docker is unavailable, the tier is reported
12
+ * as SKIPPED (not failed) so a missing runtime never poisons convergence
13
+ * feedback or blocks delivery.
14
+ * - `UAP_DELIVER_NO_DEPLOY=1` force-skips the tier.
15
+ * - The deploy command inherits {@link sanitizedEnv} (secrets stripped,
16
+ * `CI=true`), exactly like the other gate rungs.
17
+ */
18
+ import { type GateRung, type LadderOptions, type LadderResult, type RungResult } from './verifier-ladder.js';
19
+ export interface DeployDevOptions {
20
+ /** Max chars of command output kept on failure (default 2000). */
21
+ outputTailChars?: number;
22
+ /** Compose bring-up timeout (default 120s). */
23
+ bringUpTimeoutMs?: number;
24
+ /** Teardown timeout (default 30s). */
25
+ teardownTimeoutMs?: number;
26
+ /**
27
+ * Override docker availability detection — primarily for tests. When
28
+ * undefined the runner probes `docker --version`.
29
+ */
30
+ dockerAvailable?: boolean;
31
+ }
32
+ /**
33
+ * Run one deploy-dev rung through its bring-up → smoke → teardown lifecycle.
34
+ * Teardown is best-effort and runs in `finally`; a teardown failure never
35
+ * flips a passing smoke result.
36
+ */
37
+ export declare function runDeployDevRung(rung: GateRung, projectRoot: string, options?: DeployDevOptions): RungResult;
38
+ /**
39
+ * LadderRunFn-compatible runner for the deploy-dev tier: runs each rung through
40
+ * {@link runDeployDevRung} and aggregates into a {@link LadderResult}. Wire this
41
+ * as `runTieredLadder`'s `deployDevRunner`.
42
+ */
43
+ export declare function runDeployDevLadder(rungs: GateRung[], projectRoot: string, options?: LadderOptions): LadderResult;
44
+ //# sourceMappingURL=deploy-dev-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-dev-gate.d.ts","sourceRoot":"","sources":["../../src/delivery/deploy-dev-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAKL,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA6BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,gBAAqB,GAC7B,UAAU,CAoGZ;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,EAAE,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAqBd"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Local dev deploy + smoke gate (the `deploy-dev` tier).
3
+ *
4
+ * Runs a deploy-dev rung as a full lifecycle: optionally bring a docker-compose
5
+ * stack up (`docker compose up -d --wait`), run the smoke/health check, then
6
+ * ALWAYS tear the stack down (even on smoke failure or timeout). This gives the
7
+ * convergence loop real "does it actually run" feedback locally, before the
8
+ * change is ever committed.
9
+ *
10
+ * Safety:
11
+ * - When the rung needs docker and docker is unavailable, the tier is reported
12
+ * as SKIPPED (not failed) so a missing runtime never poisons convergence
13
+ * feedback or blocks delivery.
14
+ * - `UAP_DELIVER_NO_DEPLOY=1` force-skips the tier.
15
+ * - The deploy command inherits {@link sanitizedEnv} (secrets stripped,
16
+ * `CI=true`), exactly like the other gate rungs.
17
+ */
18
+ import { spawnSync } from 'child_process';
19
+ import { DEFAULT_TAIL_CHARS, formatFeedback, sanitizedEnv, truncateTail, } from './verifier-ladder.js';
20
+ const DEFAULT_BRINGUP_TIMEOUT_MS = 120_000;
21
+ const DEFAULT_TEARDOWN_TIMEOUT_MS = 30_000;
22
+ /** True when the rung's bring-up or teardown shells out to docker. */
23
+ function needsDocker(rung) {
24
+ return rung.command === 'docker' || rung.teardown?.command === 'docker';
25
+ }
26
+ function dockerIsAvailable(override) {
27
+ if (typeof override === 'boolean')
28
+ return override;
29
+ try {
30
+ const res = spawnSync('docker', ['--version'], { timeout: 5_000, encoding: 'utf-8' });
31
+ return res.status === 0;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ function skipped(rung, note) {
38
+ return {
39
+ id: rung.id,
40
+ name: rung.name,
41
+ passed: false,
42
+ skipped: true,
43
+ exitCode: null,
44
+ durationMs: 0,
45
+ outputTail: note,
46
+ };
47
+ }
48
+ /**
49
+ * Run one deploy-dev rung through its bring-up → smoke → teardown lifecycle.
50
+ * Teardown is best-effort and runs in `finally`; a teardown failure never
51
+ * flips a passing smoke result.
52
+ */
53
+ export function runDeployDevRung(rung, projectRoot, options = {}) {
54
+ const tailChars = options.outputTailChars ?? DEFAULT_TAIL_CHARS;
55
+ if (process.env.UAP_DELIVER_NO_DEPLOY === '1') {
56
+ return skipped(rung, 'deploy-dev skipped (UAP_DELIVER_NO_DEPLOY=1)');
57
+ }
58
+ const usesDocker = needsDocker(rung);
59
+ if (usesDocker && !dockerIsAvailable(options.dockerAvailable)) {
60
+ // Missing runtime is not a code failure — degrade to skipped.
61
+ return skipped(rung, 'deploy-dev skipped (docker unavailable)');
62
+ }
63
+ const env = sanitizedEnv();
64
+ const start = Date.now();
65
+ const useCompose = usesDocker && !!rung.teardown;
66
+ try {
67
+ // 1. Bring up the compose stack (blocks on container healthchecks).
68
+ if (useCompose) {
69
+ const up = spawnSync('docker', ['compose', 'up', '-d', '--wait'], {
70
+ cwd: projectRoot,
71
+ encoding: 'utf-8',
72
+ timeout: options.bringUpTimeoutMs ?? DEFAULT_BRINGUP_TIMEOUT_MS,
73
+ maxBuffer: 16 * 1024 * 1024,
74
+ env,
75
+ });
76
+ if (up.status !== 0) {
77
+ const errCode = up.error?.code;
78
+ const timedOut = errCode === 'ETIMEDOUT' || (up.error && up.signal === 'SIGTERM');
79
+ const diag = timedOut
80
+ ? `Compose bring-up timed out after ${options.bringUpTimeoutMs ?? DEFAULT_BRINGUP_TIMEOUT_MS}ms.`
81
+ : 'Compose bring-up failed.';
82
+ return {
83
+ id: rung.id,
84
+ name: rung.name,
85
+ passed: false,
86
+ skipped: false,
87
+ exitCode: up.status,
88
+ failureReason: timedOut ? 'timeout' : 'exit',
89
+ durationMs: Date.now() - start,
90
+ outputTail: truncateTail(`${diag}\n${up.stdout ?? ''}\n${up.stderr ?? ''}`, tailChars),
91
+ };
92
+ }
93
+ }
94
+ // 2. Smoke / health check.
95
+ const smoke = spawnSync(rung.command, rung.args, {
96
+ cwd: projectRoot,
97
+ encoding: 'utf-8',
98
+ timeout: rung.timeoutMs,
99
+ maxBuffer: 16 * 1024 * 1024,
100
+ env,
101
+ });
102
+ const passed = smoke.status === 0;
103
+ let failureReason;
104
+ let diagnostic = '';
105
+ if (!passed) {
106
+ const errCode = smoke.error?.code;
107
+ if (errCode === 'ETIMEDOUT' || (smoke.error && smoke.signal === 'SIGTERM')) {
108
+ failureReason = 'timeout';
109
+ diagnostic = `Smoke check timed out after ${rung.timeoutMs}ms.`;
110
+ }
111
+ else if (smoke.error) {
112
+ failureReason = 'spawn-error';
113
+ diagnostic = `Smoke check could not run: ${smoke.error.message}`;
114
+ }
115
+ else if (smoke.signal) {
116
+ failureReason = 'signal';
117
+ diagnostic = `Smoke check killed by signal ${smoke.signal}.`;
118
+ }
119
+ else {
120
+ failureReason = 'exit';
121
+ }
122
+ }
123
+ return {
124
+ id: rung.id,
125
+ name: rung.name,
126
+ passed,
127
+ skipped: false,
128
+ exitCode: smoke.status,
129
+ failureReason,
130
+ durationMs: Date.now() - start,
131
+ outputTail: passed
132
+ ? ''
133
+ : truncateTail(`${diagnostic}\n${smoke.stdout ?? ''}\n${smoke.stderr ?? ''}`, tailChars),
134
+ };
135
+ }
136
+ finally {
137
+ // 3. Teardown — always, best-effort.
138
+ if (rung.teardown) {
139
+ try {
140
+ spawnSync(rung.teardown.command, rung.teardown.args, {
141
+ cwd: projectRoot,
142
+ encoding: 'utf-8',
143
+ timeout: options.teardownTimeoutMs ?? rung.teardown.timeoutMs ?? DEFAULT_TEARDOWN_TIMEOUT_MS,
144
+ maxBuffer: 16 * 1024 * 1024,
145
+ env,
146
+ });
147
+ }
148
+ catch {
149
+ /* teardown is best-effort; never flips the rung result */
150
+ }
151
+ }
152
+ }
153
+ }
154
+ /**
155
+ * LadderRunFn-compatible runner for the deploy-dev tier: runs each rung through
156
+ * {@link runDeployDevRung} and aggregates into a {@link LadderResult}. Wire this
157
+ * as `runTieredLadder`'s `deployDevRunner`.
158
+ */
159
+ export function runDeployDevLadder(rungs, projectRoot, options = {}) {
160
+ const tailChars = options.outputTailChars ?? DEFAULT_TAIL_CHARS;
161
+ const results = rungs.map((rung) => runDeployDevRung(rung, projectRoot, { outputTailChars: tailChars }));
162
+ // A skipped deploy-dev rung (docker missing / opted out) must not block
163
+ // delivery — treat it as a non-blocking pass for the gate aggregate.
164
+ const requiredRungs = rungs.filter((r) => r.required);
165
+ const requiredOk = requiredRungs.every((rung) => results.some((r) => r.id === rung.id && (r.passed || r.skipped)));
166
+ const passedCount = results.filter((r) => r.passed).length;
167
+ const score = results.length > 0 ? passedCount / results.length : 1;
168
+ return {
169
+ passed: requiredOk,
170
+ score,
171
+ results,
172
+ feedback: formatFeedback(results, rungs),
173
+ };
174
+ }
175
+ //# sourceMappingURL=deploy-dev-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-dev-gate.js","sourceRoot":"","sources":["../../src/delivery/deploy-dev-gate.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,16 @@
10
10
  * Detection is npm-centric (package.json scripts); callers targeting other
11
11
  * ecosystems can pass explicit rungs.
12
12
  */
13
+ /**
14
+ * Cheap-first promotion tiers. The convergence loop runs the cheapest tier
15
+ * first and only promotes to the next, more expensive tier once the prior is
16
+ * green. `fast` is the existing build/typecheck/unit-test/lint band; the
17
+ * `ci`/`deploy-staging`/`deploy-prod` bands are NEVER run locally — they are
18
+ * consumed after commit via the CI watcher (see ci-watcher.ts).
19
+ */
20
+ export type GateTier = 'fast' | 'integration' | 'deploy-dev' | 'ci' | 'deploy-staging' | 'deploy-prod';
21
+ /** Cheap → expensive promotion order. */
22
+ export declare const TIER_ORDER: GateTier[];
13
23
  export interface GateRung {
14
24
  /** Stable identifier, e.g. 'build', 'typecheck', 'test', 'lint' */
15
25
  id: string;
@@ -27,7 +37,24 @@ export interface GateRung {
27
37
  required: boolean;
28
38
  /** Per-rung timeout in milliseconds */
29
39
  timeoutMs: number;
40
+ /**
41
+ * Cheap-first promotion tier. Absent ⇒ 'fast' (back-compat: existing
42
+ * callers and detectors that predate tiering keep working).
43
+ */
44
+ tier?: GateTier;
45
+ /**
46
+ * Optional teardown run after the rung regardless of outcome (e.g. a
47
+ * deploy-dev compose down / server kill). Best-effort; a teardown failure
48
+ * never flips a passing rung to failed.
49
+ */
50
+ teardown?: {
51
+ command: string;
52
+ args: string[];
53
+ timeoutMs: number;
54
+ };
30
55
  }
56
+ /** Effective tier for a rung — absent tier means the original `fast` band. */
57
+ export declare function tierOf(rung: GateRung): GateTier;
31
58
  export type RungFailureReason = 'exit' | 'timeout' | 'signal' | 'spawn-error';
32
59
  export interface RungResult {
33
60
  id: string;
@@ -59,17 +86,37 @@ export interface LadderOptions {
59
86
  /** Default per-rung timeout in ms (default 300000) */
60
87
  timeoutMs?: number;
61
88
  }
89
+ export declare const DEFAULT_TAIL_CHARS = 2000;
90
+ export declare function sanitizedEnv(): NodeJS.ProcessEnv;
62
91
  /**
63
92
  * Detect the gate rungs available in a project from its package.json scripts.
64
93
  * Order matters: cheap/structural gates run before expensive ones so failure
65
94
  * feedback arrives fast.
66
95
  */
67
96
  export declare function detectRungs(projectRoot: string, timeoutMs?: number): GateRung[];
97
+ /**
98
+ * Detect integration / end-to-end suites: npm `test:integration` / `test:e2e`
99
+ * scripts, or a pytest project declaring an `integration` marker. These cost
100
+ * more than unit tests, so they live in the `integration` tier and only run
101
+ * after the fast tier passes.
102
+ */
103
+ export declare function detectIntegrationRungs(projectRoot: string, scripts: Record<string, string>, timeoutMs?: number): GateRung[];
104
+ /**
105
+ * Detect a local dev deploy+smoke gate. Priority:
106
+ * 1. an explicit `deploy:dev` / `smoke:dev` / `smoke` npm script;
107
+ * 2. a docker-compose file paired with a `smoke` script (compose brought up
108
+ * by the deploy-dev runner, torn down via the rung's teardown);
109
+ * Returns null when nothing is discoverable — the loop still converges on the
110
+ * fast + integration tiers. The deploy-dev tier is only RUN when the caller
111
+ * opts in (maxTier >= deploy-dev); detection is always safe.
112
+ */
113
+ export declare function detectDeployDevRung(projectRoot: string, scripts: Record<string, string>, timeoutMs?: number): GateRung | null;
68
114
  /**
69
115
  * Detect real gates in non-npm projects: a Makefile test/check/build target,
70
116
  * a pytest suite, or a conventional shell test script. Ordered cheap→expensive.
71
117
  */
72
118
  export declare function detectNonNpmRungs(projectRoot: string, timeoutMs?: number): GateRung[];
119
+ export declare function truncateTail(text: string, maxChars: number): string;
73
120
  /** Run a single rung synchronously in the project root. */
74
121
  export declare function runRung(rung: GateRung, projectRoot: string, tailChars?: number): RungResult;
75
122
  /**
@@ -80,4 +127,34 @@ export declare function runRung(rung: GateRung, projectRoot: string, tailChars?:
80
127
  export declare function formatFeedback(results: RungResult[], rungs: GateRung[]): string;
81
128
  /** Run the full ladder, honoring fail-fast for required rungs. */
82
129
  export declare function runLadder(rungs: GateRung[], projectRoot: string, options?: LadderOptions): LadderResult;
130
+ /** A ladder runner: turns a set of rungs into a result. May be async. */
131
+ export type LadderRunFn = (rungs: GateRung[], projectRoot: string, options?: LadderOptions) => LadderResult | Promise<LadderResult>;
132
+ export interface TieredLadderOptions extends LadderOptions {
133
+ /**
134
+ * Highest tier to run locally. Default 'deploy-dev'. The `ci`,
135
+ * `deploy-staging` and `deploy-prod` tiers are never run locally — they are
136
+ * verified after commit via the CI watcher — so they are skipped here.
137
+ */
138
+ maxTier?: GateTier;
139
+ /**
140
+ * Inner per-tier runner. Defaults to {@link runLadder}. Injecting this lets
141
+ * the convergence loop's integrity wrapper compose around the whole tiered
142
+ * run while reusing the standard rung execution underneath.
143
+ */
144
+ runner?: LadderRunFn;
145
+ /**
146
+ * Specialized runner for `deploy-dev` rungs (bring-up + smoke + teardown
147
+ * lifecycle). When absent, deploy-dev rungs fall back to {@link runner},
148
+ * which simply spawns the smoke command without managing a compose stack.
149
+ */
150
+ deployDevRunner?: LadderRunFn;
151
+ }
152
+ /**
153
+ * Cheap-first tiered ladder. Runs the cheapest tier first and only promotes to
154
+ * the next, more expensive tier once the prior tier's required rungs pass. The
155
+ * result is aggregated into a single {@link LadderResult} so the convergence
156
+ * loop's per-turn contract (one ladder result, one feedback string) is
157
+ * unchanged — tier failures flow back through the existing feedback channel.
158
+ */
159
+ export declare function runTieredLadder(rungs: GateRung[], projectRoot: string, options?: TieredLadderOptions): Promise<LadderResult>;
83
160
  //# sourceMappingURL=verifier-ladder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verifier-ladder.d.ts","sourceRoot":"","sources":["../../src/delivery/verifier-ladder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,QAAQ;IACvB,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;AAE9E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mEAAmE;IACnE,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,QAAQ,EAAE,CAwEnG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,QAAQ,EAAE,CA8DzG;AAQD,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B,GAAG,UAAU,CA+C/G;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAqB/E;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CACvB,KAAK,EAAE,QAAQ,EAAE,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CA8Cd"}
1
+ {"version":3,"file":"verifier-ladder.d.ts","sourceRoot":"","sources":["../../src/delivery/verifier-ladder.ts"],"names":[],"mappings":"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"}