tickmarkr 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +347 -0
- package/dist/adapters/claude-code.d.ts +4 -0
- package/dist/adapters/claude-code.js +191 -0
- package/dist/adapters/codex.d.ts +8 -0
- package/dist/adapters/codex.js +257 -0
- package/dist/adapters/cursor-agent.d.ts +4 -0
- package/dist/adapters/cursor-agent.js +62 -0
- package/dist/adapters/fake.d.ts +45 -0
- package/dist/adapters/fake.js +115 -0
- package/dist/adapters/grok.d.ts +4 -0
- package/dist/adapters/grok.js +122 -0
- package/dist/adapters/model-lints.d.ts +6 -0
- package/dist/adapters/model-lints.js +130 -0
- package/dist/adapters/opencode.d.ts +3 -0
- package/dist/adapters/opencode.js +108 -0
- package/dist/adapters/pi.d.ts +3 -0
- package/dist/adapters/pi.js +191 -0
- package/dist/adapters/prompt.d.ts +6 -0
- package/dist/adapters/prompt.js +84 -0
- package/dist/adapters/registry.d.ts +31 -0
- package/dist/adapters/registry.js +165 -0
- package/dist/adapters/types.d.ts +98 -0
- package/dist/adapters/types.js +56 -0
- package/dist/cli/commands/approve.d.ts +1 -0
- package/dist/cli/commands/approve.js +72 -0
- package/dist/cli/commands/compile.d.ts +1 -0
- package/dist/cli/commands/compile.js +23 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +103 -0
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +32 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.js +101 -0
- package/dist/cli/commands/profile.d.ts +1 -0
- package/dist/cli/commands/profile.js +56 -0
- package/dist/cli/commands/report.d.ts +4 -0
- package/dist/cli/commands/report.js +306 -0
- package/dist/cli/commands/resume.d.ts +1 -0
- package/dist/cli/commands/resume.js +11 -0
- package/dist/cli/commands/run.d.ts +1 -0
- package/dist/cli/commands/run.js +35 -0
- package/dist/cli/commands/scope.d.ts +3 -0
- package/dist/cli/commands/scope.js +22 -0
- package/dist/cli/commands/status.d.ts +9 -0
- package/dist/cli/commands/status.js +162 -0
- package/dist/cli/commands/unlock.d.ts +1 -0
- package/dist/cli/commands/unlock.js +11 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.js +65 -0
- package/dist/compile/collateral.d.ts +6 -0
- package/dist/compile/collateral.js +128 -0
- package/dist/compile/common.d.ts +12 -0
- package/dist/compile/common.js +56 -0
- package/dist/compile/gsd.d.ts +3 -0
- package/dist/compile/gsd.js +222 -0
- package/dist/compile/index.d.ts +4 -0
- package/dist/compile/index.js +33 -0
- package/dist/compile/native.d.ts +4 -0
- package/dist/compile/native.js +196 -0
- package/dist/compile/prd.d.ts +2 -0
- package/dist/compile/prd.js +64 -0
- package/dist/compile/speckit.d.ts +2 -0
- package/dist/compile/speckit.js +66 -0
- package/dist/config/config.d.ts +184 -0
- package/dist/config/config.js +329 -0
- package/dist/drivers/herdr.d.ts +44 -0
- package/dist/drivers/herdr.js +394 -0
- package/dist/drivers/index.d.ts +3 -0
- package/dist/drivers/index.js +13 -0
- package/dist/drivers/subprocess.d.ts +25 -0
- package/dist/drivers/subprocess.js +106 -0
- package/dist/drivers/types.d.ts +61 -0
- package/dist/drivers/types.js +77 -0
- package/dist/gates/acceptance.d.ts +19 -0
- package/dist/gates/acceptance.js +92 -0
- package/dist/gates/baseline.d.ts +12 -0
- package/dist/gates/baseline.js +97 -0
- package/dist/gates/evidence.d.ts +4 -0
- package/dist/gates/evidence.js +12 -0
- package/dist/gates/llm.d.ts +25 -0
- package/dist/gates/llm.js +101 -0
- package/dist/gates/review.d.ts +12 -0
- package/dist/gates/review.js +80 -0
- package/dist/gates/run-gates.d.ts +34 -0
- package/dist/gates/run-gates.js +105 -0
- package/dist/gates/scope.d.ts +8 -0
- package/dist/gates/scope.js +32 -0
- package/dist/gates/types.d.ts +6 -0
- package/dist/gates/types.js +1 -0
- package/dist/graph/graph.d.ts +20 -0
- package/dist/graph/graph.js +148 -0
- package/dist/graph/schema.d.ts +185 -0
- package/dist/graph/schema.js +141 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/plan/prompt.d.ts +4 -0
- package/dist/plan/prompt.js +31 -0
- package/dist/plan/scope.d.ts +17 -0
- package/dist/plan/scope.js +141 -0
- package/dist/report/cost.d.ts +24 -0
- package/dist/report/cost.js +89 -0
- package/dist/route/preference.d.ts +27 -0
- package/dist/route/preference.js +49 -0
- package/dist/route/profile.d.ts +65 -0
- package/dist/route/profile.js +197 -0
- package/dist/route/router.d.ts +26 -0
- package/dist/route/router.js +200 -0
- package/dist/run/consult.d.ts +23 -0
- package/dist/run/consult.js +80 -0
- package/dist/run/daemon.d.ts +23 -0
- package/dist/run/daemon.js +728 -0
- package/dist/run/git.d.ts +12 -0
- package/dist/run/git.js +56 -0
- package/dist/run/journal.d.ts +91 -0
- package/dist/run/journal.js +287 -0
- package/dist/run/lock.d.ts +29 -0
- package/dist/run/lock.js +182 -0
- package/dist/run/merge.d.ts +12 -0
- package/dist/run/merge.js +44 -0
- package/dist/run/reconcile.d.ts +4 -0
- package/dist/run/reconcile.js +95 -0
- package/package.json +39 -0
- package/schema/rungraph.schema.json +306 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DrovrConfig } from "../config/config.js";
|
|
2
|
+
export declare function integrationBranch(cfg: DrovrConfig, runId: string): string;
|
|
3
|
+
export declare function ensureIntegration(repo: string, branch: string, baseRef: string): Promise<string>;
|
|
4
|
+
export declare function integrationHead(intWt: string): Promise<string>;
|
|
5
|
+
export declare function mergeTask(intWt: string, taskBranch: string, message: string, gatedCommit: string): Promise<{
|
|
6
|
+
ok: boolean;
|
|
7
|
+
conflict?: string;
|
|
8
|
+
tipMoved?: {
|
|
9
|
+
gatedCommit: string;
|
|
10
|
+
branchTip: string;
|
|
11
|
+
};
|
|
12
|
+
}>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { shq } from "../adapters/types.js";
|
|
4
|
+
import { drovrDir } from "../graph/graph.js";
|
|
5
|
+
import { gitHead, resolveIntegrationBranch, sh, shOk } from "./git.js";
|
|
6
|
+
export function integrationBranch(cfg, runId) {
|
|
7
|
+
return `tickmarkr/${runId}`;
|
|
8
|
+
}
|
|
9
|
+
const sanitize = (branch) => branch.replace(/[^\w.-]+/g, "-");
|
|
10
|
+
export async function ensureIntegration(repo, branch, baseRef) {
|
|
11
|
+
branch = await resolveIntegrationBranch(repo, branch);
|
|
12
|
+
const dir = join(drovrDir(repo), "worktrees", sanitize(branch));
|
|
13
|
+
if (existsSync(join(dir, ".git")))
|
|
14
|
+
return dir; // resume: keep existing tip
|
|
15
|
+
const exists = (await sh(`git rev-parse --verify refs/heads/${shq(branch)}`, repo)).code === 0;
|
|
16
|
+
if (exists) {
|
|
17
|
+
await shOk(`git worktree add ${shq(dir)} ${shq(branch)}`, repo);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
await shOk(`git worktree add -b ${shq(branch)} ${shq(dir)} ${shq(baseRef)}`, repo);
|
|
21
|
+
}
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
export function integrationHead(intWt) {
|
|
25
|
+
return gitHead(intWt);
|
|
26
|
+
}
|
|
27
|
+
export async function mergeTask(intWt, taskBranch, message, gatedCommit) {
|
|
28
|
+
const tip = await sh(`git rev-parse --verify ${shq(`refs/heads/${taskBranch}`)}`, intWt);
|
|
29
|
+
if (tip.code !== 0)
|
|
30
|
+
return { ok: false, conflict: tip.stderr || tip.stdout };
|
|
31
|
+
const branchTip = tip.stdout.trim();
|
|
32
|
+
if (branchTip !== gatedCommit)
|
|
33
|
+
return { ok: false, tipMoved: { gatedCommit, branchTip } };
|
|
34
|
+
// Merge the verified hash, not the mutable branch name: a move after the comparison cannot land ungated content.
|
|
35
|
+
const r = await sh(`git merge --no-ff ${shq(gatedCommit)} -m ${shq(message)}`, intWt);
|
|
36
|
+
if (r.code === 0)
|
|
37
|
+
return { ok: true };
|
|
38
|
+
const conflict = (await sh("git status --porcelain", intWt)).stdout
|
|
39
|
+
.split("\n")
|
|
40
|
+
.filter((l) => l.startsWith("UU") || l.startsWith("AA"))
|
|
41
|
+
.join("\n") || r.stderr || r.stdout;
|
|
42
|
+
await sh("git merge --abort", intWt);
|
|
43
|
+
return { ok: false, conflict };
|
|
44
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { isForeignName, panesToClose, parseOwnedName } from "../drivers/types.js";
|
|
2
|
+
import type { JournalEvent } from "./journal.js";
|
|
3
|
+
export { isForeignName, panesToClose, parseOwnedName };
|
|
4
|
+
export declare function desiredPanes(rows: JournalEvent[], runId: string): Set<string>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { formatOwnedName, isForeignName, panesToClose, parseOwnedName } from "../drivers/types.js";
|
|
2
|
+
export { isForeignName, panesToClose, parseOwnedName };
|
|
3
|
+
// T1: pure fold over journal rows — the exact set of drovr-owned pane/tab names that SHOULD exist
|
|
4
|
+
// right now for a live run. No I/O: the caller supplies rows (Journal.read()) and a live pane listing
|
|
5
|
+
// separately. Anything owned (parseOwnedName succeeds) but not in this set is garbage to close;
|
|
6
|
+
// anything foreign (parseOwnedName fails) is never a candidate, no matter what state it's in.
|
|
7
|
+
export function desiredPanes(rows, runId) {
|
|
8
|
+
const desired = new Set();
|
|
9
|
+
const worker = new Map();
|
|
10
|
+
const judge = new Map();
|
|
11
|
+
const review = new Map();
|
|
12
|
+
const clearTask = (taskId) => {
|
|
13
|
+
for (const m of [worker, judge, review]) {
|
|
14
|
+
const name = m.get(taskId);
|
|
15
|
+
if (name)
|
|
16
|
+
desired.delete(name);
|
|
17
|
+
m.delete(taskId);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
for (const row of rows) {
|
|
21
|
+
switch (row.event) {
|
|
22
|
+
case "run-start":
|
|
23
|
+
case "run-resume": {
|
|
24
|
+
// OBS-17 fix (2): a killed daemon can't close its slots — nothing tracked before this
|
|
25
|
+
// point is still live once the daemon (re)starts; resume re-dispatches at a fresh attempt.
|
|
26
|
+
for (const taskId of new Set([...worker.keys(), ...judge.keys(), ...review.keys()]))
|
|
27
|
+
clearTask(taskId);
|
|
28
|
+
desired.add(formatOwnedName({ role: "watch", taskId: "run", attempt: 0, runId }));
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case "task-dispatch": {
|
|
32
|
+
const taskId = row.taskId;
|
|
33
|
+
const attempt = Number(row.data.attempt ?? 0);
|
|
34
|
+
// OBS-17 fix (1): a new dispatch (retry, escalation, OR quota-failover) supersedes the
|
|
35
|
+
// old attempt's pane — the failover path re-dispatches through this same event.
|
|
36
|
+
const prev = worker.get(taskId);
|
|
37
|
+
if (prev)
|
|
38
|
+
desired.delete(prev);
|
|
39
|
+
const name = formatOwnedName({ role: "worker", taskId, attempt, runId });
|
|
40
|
+
worker.set(taskId, name);
|
|
41
|
+
desired.add(name);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case "worker-result": {
|
|
45
|
+
const taskId = row.taskId;
|
|
46
|
+
const name = formatOwnedName({ role: "judge", taskId, attempt: 0, runId });
|
|
47
|
+
judge.set(taskId, name);
|
|
48
|
+
desired.add(name);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case "judge-retry": {
|
|
52
|
+
const taskId = row.taskId;
|
|
53
|
+
const prev = judge.get(taskId);
|
|
54
|
+
if (prev)
|
|
55
|
+
desired.delete(prev);
|
|
56
|
+
const name = formatOwnedName({ role: "judge", taskId, attempt: 1, runId });
|
|
57
|
+
judge.set(taskId, name);
|
|
58
|
+
desired.add(name);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "gate-result": {
|
|
62
|
+
const taskId = row.taskId;
|
|
63
|
+
if (row.data.gate === "acceptance") {
|
|
64
|
+
const j = judge.get(taskId);
|
|
65
|
+
if (j) {
|
|
66
|
+
desired.delete(j);
|
|
67
|
+
judge.delete(taskId);
|
|
68
|
+
}
|
|
69
|
+
if (row.data.pass) {
|
|
70
|
+
const name = formatOwnedName({ role: "review", taskId, attempt: 0, runId });
|
|
71
|
+
review.set(taskId, name);
|
|
72
|
+
desired.add(name);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else if (row.data.gate === "review") {
|
|
76
|
+
const r = review.get(taskId);
|
|
77
|
+
if (r) {
|
|
78
|
+
desired.delete(r);
|
|
79
|
+
review.delete(taskId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "task-done":
|
|
85
|
+
case "task-failed":
|
|
86
|
+
case "task-human":
|
|
87
|
+
clearTask(row.taskId);
|
|
88
|
+
break;
|
|
89
|
+
case "run-end":
|
|
90
|
+
desired.clear();
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return desired;
|
|
95
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tickmarkr",
|
|
3
|
+
"version": "1.30.0",
|
|
4
|
+
"description": "Spec in, verified work out.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"tickmarkr": "dist/cli/index.js",
|
|
12
|
+
"drovr": "dist/cli/index.js",
|
|
13
|
+
"drover": "dist/cli/index.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"schema"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:coverage": "vitest run --coverage",
|
|
23
|
+
"schema": "tsx scripts/emit-schema.ts",
|
|
24
|
+
"e2e": "DROVR_E2E=1 vitest run tests/e2e --testTimeout 900000"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"picomatch": "^4.0.2",
|
|
28
|
+
"yaml": "^2.5.0",
|
|
29
|
+
"zod": "^4.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.14.0",
|
|
33
|
+
"@types/picomatch": "^4.0.0",
|
|
34
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
35
|
+
"tsx": "^4.19.0",
|
|
36
|
+
"typescript": "^5.6.0",
|
|
37
|
+
"vitest": "^3.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"properties": {
|
|
5
|
+
"version": {
|
|
6
|
+
"type": "number",
|
|
7
|
+
"const": 1
|
|
8
|
+
},
|
|
9
|
+
"spec": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"source": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"enum": [
|
|
15
|
+
"speckit",
|
|
16
|
+
"gsd",
|
|
17
|
+
"prd",
|
|
18
|
+
"native",
|
|
19
|
+
"taskmaster"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"paths": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"items": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"hash": {
|
|
29
|
+
"type": "string"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"required": [
|
|
33
|
+
"source",
|
|
34
|
+
"paths",
|
|
35
|
+
"hash"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"tasks": {
|
|
39
|
+
"minItems": 1,
|
|
40
|
+
"type": "array",
|
|
41
|
+
"items": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"id": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"maxLength": 64,
|
|
47
|
+
"pattern": "^[A-Za-z][A-Za-z0-9_-]*$"
|
|
48
|
+
},
|
|
49
|
+
"title": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"minLength": 1
|
|
52
|
+
},
|
|
53
|
+
"goal": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"minLength": 1
|
|
56
|
+
},
|
|
57
|
+
"shape": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": [
|
|
60
|
+
"plan",
|
|
61
|
+
"spec",
|
|
62
|
+
"implement",
|
|
63
|
+
"tests",
|
|
64
|
+
"docs",
|
|
65
|
+
"migration",
|
|
66
|
+
"ui",
|
|
67
|
+
"refactor",
|
|
68
|
+
"chore"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"complexity": {
|
|
72
|
+
"type": "integer",
|
|
73
|
+
"minimum": 1,
|
|
74
|
+
"maximum": 10
|
|
75
|
+
},
|
|
76
|
+
"deps": {
|
|
77
|
+
"default": [],
|
|
78
|
+
"type": "array",
|
|
79
|
+
"items": {
|
|
80
|
+
"type": "string"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"files": {
|
|
84
|
+
"default": [],
|
|
85
|
+
"type": "array",
|
|
86
|
+
"items": {
|
|
87
|
+
"type": "string"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"context": {
|
|
91
|
+
"default": [],
|
|
92
|
+
"type": "array",
|
|
93
|
+
"items": {
|
|
94
|
+
"type": "string"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"acceptance": {
|
|
98
|
+
"minItems": 1,
|
|
99
|
+
"type": "array",
|
|
100
|
+
"items": {
|
|
101
|
+
"anyOf": [
|
|
102
|
+
{
|
|
103
|
+
"type": "string",
|
|
104
|
+
"minLength": 1
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "object",
|
|
108
|
+
"properties": {
|
|
109
|
+
"oracle": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"const": "command"
|
|
112
|
+
},
|
|
113
|
+
"command": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"minLength": 1
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"required": [
|
|
119
|
+
"oracle",
|
|
120
|
+
"command"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"type": "object",
|
|
125
|
+
"properties": {
|
|
126
|
+
"oracle": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"const": "test"
|
|
129
|
+
},
|
|
130
|
+
"test": {
|
|
131
|
+
"type": "string",
|
|
132
|
+
"minLength": 1
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"required": [
|
|
136
|
+
"oracle",
|
|
137
|
+
"test"
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"type": "object",
|
|
142
|
+
"properties": {
|
|
143
|
+
"oracle": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"const": "judge"
|
|
146
|
+
},
|
|
147
|
+
"text": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"minLength": 1
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"required": [
|
|
153
|
+
"oracle",
|
|
154
|
+
"text"
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"scopeHints": {
|
|
161
|
+
"type": "array",
|
|
162
|
+
"items": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"properties": {
|
|
165
|
+
"paths": {
|
|
166
|
+
"type": "array",
|
|
167
|
+
"items": {
|
|
168
|
+
"type": "string"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"confidence": {
|
|
172
|
+
"type": "number",
|
|
173
|
+
"minimum": 0,
|
|
174
|
+
"maximum": 1
|
|
175
|
+
},
|
|
176
|
+
"reason": {
|
|
177
|
+
"type": "string"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"required": [
|
|
181
|
+
"paths"
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"gates": {
|
|
186
|
+
"default": [
|
|
187
|
+
"build",
|
|
188
|
+
"test",
|
|
189
|
+
"lint",
|
|
190
|
+
"evidence",
|
|
191
|
+
"scope",
|
|
192
|
+
"acceptance",
|
|
193
|
+
"review"
|
|
194
|
+
],
|
|
195
|
+
"type": "array",
|
|
196
|
+
"items": {
|
|
197
|
+
"type": "string",
|
|
198
|
+
"enum": [
|
|
199
|
+
"build",
|
|
200
|
+
"test",
|
|
201
|
+
"lint",
|
|
202
|
+
"evidence",
|
|
203
|
+
"scope",
|
|
204
|
+
"acceptance",
|
|
205
|
+
"review"
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
"routingHints": {
|
|
210
|
+
"type": "object",
|
|
211
|
+
"properties": {
|
|
212
|
+
"pin": {
|
|
213
|
+
"type": "object",
|
|
214
|
+
"properties": {
|
|
215
|
+
"via": {
|
|
216
|
+
"type": "string"
|
|
217
|
+
},
|
|
218
|
+
"model": {
|
|
219
|
+
"type": "string"
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"required": [
|
|
223
|
+
"via",
|
|
224
|
+
"model"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
"floor": {
|
|
228
|
+
"type": "string",
|
|
229
|
+
"enum": [
|
|
230
|
+
"cheap",
|
|
231
|
+
"mid",
|
|
232
|
+
"frontier"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
"source": {
|
|
236
|
+
"type": "string"
|
|
237
|
+
},
|
|
238
|
+
"escalate": {
|
|
239
|
+
"type": "boolean"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"humanGate": {
|
|
244
|
+
"default": false,
|
|
245
|
+
"type": "boolean"
|
|
246
|
+
},
|
|
247
|
+
"status": {
|
|
248
|
+
"default": "pending",
|
|
249
|
+
"type": "string",
|
|
250
|
+
"enum": [
|
|
251
|
+
"pending",
|
|
252
|
+
"running",
|
|
253
|
+
"gated",
|
|
254
|
+
"failed",
|
|
255
|
+
"done",
|
|
256
|
+
"human"
|
|
257
|
+
]
|
|
258
|
+
},
|
|
259
|
+
"evidence": {
|
|
260
|
+
"default": {
|
|
261
|
+
"commits": [],
|
|
262
|
+
"artifacts": [],
|
|
263
|
+
"gateResults": []
|
|
264
|
+
},
|
|
265
|
+
"type": "object",
|
|
266
|
+
"properties": {
|
|
267
|
+
"commits": {
|
|
268
|
+
"default": [],
|
|
269
|
+
"type": "array",
|
|
270
|
+
"items": {
|
|
271
|
+
"type": "string"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"artifacts": {
|
|
275
|
+
"default": [],
|
|
276
|
+
"type": "array",
|
|
277
|
+
"items": {
|
|
278
|
+
"type": "string"
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
"gateResults": {
|
|
282
|
+
"default": [],
|
|
283
|
+
"type": "array",
|
|
284
|
+
"items": {}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"required": [
|
|
290
|
+
"id",
|
|
291
|
+
"title",
|
|
292
|
+
"goal",
|
|
293
|
+
"shape",
|
|
294
|
+
"complexity",
|
|
295
|
+
"acceptance"
|
|
296
|
+
]
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"required": [
|
|
301
|
+
"version",
|
|
302
|
+
"spec",
|
|
303
|
+
"tasks"
|
|
304
|
+
],
|
|
305
|
+
"$comment": "Structural schema only; duplicate-id/unknown-dep/cycle checks live in validateGraph()."
|
|
306
|
+
}
|