codex-genesis-harness 0.1.8 → 0.1.9

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 (45) hide show
  1. package/.codebase/CURRENT_STATE.md +7 -33
  2. package/.codebase/KNOWN_PROBLEMS.md +20 -1
  3. package/.codebase/MODULE_INDEX.md +15 -2
  4. package/.codebase/PIPELINE_FLOW.md +10 -2
  5. package/.codebase/RECOVERY_POINTS.md +63 -0
  6. package/.codebase/TEST_MATRIX.md +5 -1
  7. package/.codebase/memories/lessons_learned.md +42 -0
  8. package/.codebase/state.json +130 -12
  9. package/.codex/skills/genesis-harness/SKILL.md +10 -1
  10. package/.codex/skills/genesis-harness/agents/openai.yaml +1 -2
  11. package/.codex/skills/genesis-harness/references/state-machine.md +4 -1
  12. package/.codex/skills/genesis-harness/references/workflows.md +7 -1
  13. package/.codex/skills/genesis-harness/scripts/init-planning.sh +245 -13
  14. package/.codex/skills/genesis-pipeline-orchestration/SKILL.md +15 -3
  15. package/.codex-plugin/plugin.json +4 -2
  16. package/CHANGELOG.md +21 -0
  17. package/README.EN.md +44 -2
  18. package/README.VI.md +44 -2
  19. package/README.md +80 -2
  20. package/VERSION +1 -2
  21. package/bin/genesis-harness.js +2121 -21
  22. package/contracts/features/project-registry-schema.json +37 -0
  23. package/contracts/observability/agent-run-schema.json +6 -1
  24. package/features/REGISTRY.md +9 -7
  25. package/fixtures/pipeline/end-to-end-project-lifecycle-fixture.md +39 -0
  26. package/fixtures/pipeline/feature-completion-fixture.md +26 -0
  27. package/fixtures/pipeline/run-to-feature-execution-fixture.md +20 -0
  28. package/package.json +7 -2
  29. package/scripts/check-repository-hygiene.js +48 -0
  30. package/scripts/run-evals.sh +36 -3
  31. package/scripts/schema/001-init.sql +129 -0
  32. package/scripts/schema/002-story-verify.sql +9 -0
  33. package/scripts/schema/003-tool-registry.sql +15 -0
  34. package/scripts/schema/004-intervention.sql +15 -0
  35. package/scripts/transition_state.sh +32 -8
  36. package/scripts/validation_gates.sh +2 -80
  37. package/scripts/verify.sh +3 -1
  38. package/tests/fixtures/fixture-index.md +5 -0
  39. package/tests/integration/cli-smoke.test.js +403 -0
  40. package/tests/unit/repository_hygiene.test.js +17 -0
  41. package/tests/unit/state_metadata.test.js +76 -0
  42. package/tests/unit/verify_gate.test.js +25 -0
  43. package/tests/unit/workflow_contracts.test.js +90 -0
  44. package/fixtures/tts/tts-fixture-template.md +0 -14
  45. package/fixtures/videos/video-fixture-template.md +0 -14
@@ -0,0 +1,37 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "description": "Contract for .planning/FEATURE_REGISTRY.json generated by the lifecycle pipeline.",
4
+ "required_root_fields": [
5
+ "version",
6
+ "updated_at",
7
+ "project_status",
8
+ "project_verification",
9
+ "features"
10
+ ],
11
+ "required_feature_fields": [
12
+ "id",
13
+ "status",
14
+ "title",
15
+ "path",
16
+ "verify_cmd",
17
+ "evidence",
18
+ "started_at",
19
+ "verified_at",
20
+ "attempts",
21
+ "last_error"
22
+ ],
23
+ "valid_statuses": [
24
+ "planned",
25
+ "in-progress",
26
+ "done",
27
+ "verified",
28
+ "deprecated"
29
+ ],
30
+ "valid_project_statuses": [
31
+ "implementation",
32
+ "verification",
33
+ "release-ready",
34
+ "completed"
35
+ ],
36
+ "completion_rule": "A feature may become verified only after verify_cmd exits 0 and explicit evidence is persisted. A project may become completed only after all features are verified and project verification has passed."
37
+ }
@@ -14,7 +14,7 @@
14
14
  "session_id": "string — unique identifier for the agent session (e.g. UUID or date-prefixed slug)",
15
15
  "timestamp": "ISO 8601 string",
16
16
  "skill": "string — name of the genesis skill invoked",
17
- "phase": "string — one of: init, plan, execute, verify, handoff",
17
+ "phase": "string — one of: init, plan, execute, verify, handoff, release",
18
18
  "outcome": "string — one of: success, failure, partial, skipped",
19
19
  "evidence": "string — CLI output snippet or file path proving the outcome"
20
20
  },
@@ -25,6 +25,11 @@
25
25
  "recovery_needed": "boolean — whether a recovery point was consulted"
26
26
  },
27
27
  "changelog": [
28
+ {
29
+ "version": "1.1.0",
30
+ "date": "2026-06-12",
31
+ "change": "Added release phase for project completion records"
32
+ },
28
33
  {
29
34
  "version": "1.0.0",
30
35
  "date": "2026-06-03",
@@ -35,10 +35,12 @@
35
35
  | F013 | verified | Feature Registry as harness primitive (L08) | `node tests/unit/feature_registry.test.js` | genesis-harness-engineering |
36
36
  | F014 | verified | npm pack / tarball smoke test | `bash scripts/run-evals.sh` | genesis-release |
37
37
  | F015 | verified | spec-impact-engine propagation chain | `bash scripts/verify.sh .codex/skills/spec-impact-engine` | spec-impact-engine |
38
- | F016 | in-progress | Cold-start test automation (L03) | `node scripts/cold-start-check.js` | genesis-harness |
38
+ | F016 | verified | Cold-start test automation (L03) | `node scripts/cold-start-check.js` | genesis-harness |
39
39
  | F017 | planned | Per-session Time-to-First-Verification KPI (L06) | `node bin/genesis-harness.js status --ttfv` | genesis-harness |
40
- | F018 | planned | Scope ledger per task (L07) | `bash scripts/check-scope.sh` | genesis-harness |
41
- | F019 | verified | Demo Feature (Mockup + Contract + E2E) | `npm test` (or npx playwright test) | genesis-harness-engineering |
40
+ | F018 | verified | Scope ledger per task (L07) | `bash scripts/check-scope.sh` | genesis-harness |
41
+ | F019 | planned | Demo feature templates (mockup + contract + E2E) | `npx playwright test playwright/e2e/auth/login-screen.spec.js` | genesis-harness-engineering |
42
+ | F020 | verified | Stateful feature lifecycle (`next` → evidence-gated `complete-feature`) | `node tests/integration/cli-smoke.test.js` | genesis-pipeline-orchestration |
43
+ | F021 | verified | End-to-end multi-feature lifecycle with project verification, release-ready handoff, completion, event history, and audit | `node tests/integration/cli-smoke.test.js` | genesis-pipeline-orchestration |
42
44
 
43
45
  ---
44
46
 
@@ -47,10 +49,10 @@
47
49
  > Update this section after each CI run.
48
50
 
49
51
  ```
50
- Date: 2026-06-03T02:38:00Z
51
- scripts/verify.sh → verify passed
52
- scripts/run-evals.sh → evals passed
53
- feature_registry.test.jsfeature_registry tests passed
52
+ Date: 2026-06-12T09:50:17Z
53
+ scripts/verify.sh → verify passed
54
+ scripts/run-evals.sh → evals passed
55
+ genesis-harness verify-gate → passed
54
56
  ```
55
57
 
56
58
  ---
@@ -0,0 +1,39 @@
1
+ # End-to-End Project Lifecycle Fixture
2
+
3
+ ## Initial State
4
+
5
+ - One feature is `in-progress`.
6
+ - A second feature is added as `planned`.
7
+ - Project state is `IMPLEMENTATION`.
8
+
9
+ ## Lifecycle
10
+
11
+ ```text
12
+ complete active feature
13
+ -> mark active feature verified
14
+ -> promote next planned feature
15
+ -> keep project in IMPLEMENTATION
16
+
17
+ complete final feature
18
+ -> mark feature verified
19
+ -> clear active feature
20
+ -> move project to VERIFICATION
21
+
22
+ verify project
23
+ -> run every feature proof command
24
+ -> run project proof command
25
+ -> create project verification and handoff artifacts
26
+ -> move project to RELEASE_READY
27
+
28
+ complete project
29
+ -> require RELEASE_READY
30
+ -> append final lifecycle event
31
+ -> move project to COMPLETED
32
+ ```
33
+
34
+ ## Invariants
35
+
36
+ - Repeating a successful completion command is idempotent.
37
+ - A failed proof command blocks the transition and increments failure metrics.
38
+ - `pipeline-audit` fails on registry/state/artifact drift.
39
+ - Every accepted transition is appended to `.runs/<session-id>/EVENTS.jsonl`.
@@ -0,0 +1,26 @@
1
+ # Feature Completion Fixture
2
+
3
+ ## Given
4
+
5
+ - `.codebase/state.json` records one `active_feature`.
6
+ - `.planning/FEATURE_REGISTRY.json` records that feature as `in-progress`.
7
+ - The caller supplies a verification command and an evidence summary.
8
+
9
+ ## When
10
+
11
+ ```sh
12
+ genesis-harness complete-feature \
13
+ --verify-cmd "npm test" \
14
+ --evidence "All feature tests passed"
15
+ ```
16
+
17
+ ## Expected
18
+
19
+ - The verification command exits `0`.
20
+ - The registry feature status becomes `verified`.
21
+ - `.planning/FEATURE_INDEX.md` marks the feature `[x]`.
22
+ - State becomes `COMPLETED` and records feature lead-time metrics.
23
+ - An observability run record is written.
24
+ - The active `.runs/<session-id>` checkpoint is refreshed.
25
+
26
+ If verification exits non-zero, completion is blocked and `failed_gate_count` increments.
@@ -0,0 +1,20 @@
1
+ # Run To Feature Execution Fixture
2
+
3
+ ## Input
4
+
5
+ - Command: `genesis-harness run --idea "<brief>" --yes ...`
6
+ - Discovery answers: product approach, primary user, v1 outcome, QA owner, stack, deployment, and test strategy
7
+
8
+ ## Expected Output
9
+
10
+ - `.planning/features/<NNN>-<slug>/` exists
11
+ - `SPEC.md`, `PLAN.md`, `TEST_CONTRACT.md`, `TASKS.md`, `VERIFICATION.md`, and `DIAGRAM.mmd` are seeded for the first active slice
12
+ - `contracts/ui/<feature>/screen-contract.json` exists when the first slice is UI-capable
13
+ - `playwright/fixtures/<feature>-ui-fixture.md` exists when the first slice is UI-capable
14
+ - `contracts/api/<feature>/request.json` and `response.json` exist when the first slice is API-capable
15
+ - `fixtures/api/<feature>-api-fixture.md` exists when the first slice is API-capable
16
+ - `.planning/FEATURE_INDEX.md` registers the active slice
17
+ - `.planning/STATE.md` advances to `02 First Feature Execution`
18
+ - `.codebase/state.json` advances to `IMPLEMENTATION`
19
+ - `.runs/<session-id>/STATE.json` mirrors the same `IMPLEMENTATION` state and `active_feature`
20
+ - `genesis-harness resume` reports the active feature and the next implementation task
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-genesis-harness",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Hệ thống quản trị (Harness) dành cho AI Agent (Codex) với cơ chế FSM State Persistence, Validation Gates và Test-First Workflow. Đảm bảo agent không bị trôi context.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -29,8 +29,13 @@
29
29
  "playwright",
30
30
  "observability",
31
31
  "bin",
32
- "scripts",
32
+ "scripts/*.js",
33
+ "scripts/*.sh",
34
+ "scripts/README.md",
35
+ "scripts/schema",
33
36
  "README.md",
37
+ "README.EN.md",
38
+ "README.VI.md",
34
39
  "LICENSE",
35
40
  "VERSION",
36
41
  "CHANGELOG.md"
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const path = require("path");
5
+ const { spawnSync } = require("child_process");
6
+
7
+ const repoRoot = path.resolve(__dirname, "..");
8
+ const workTreeCheck = spawnSync("git", ["rev-parse", "--is-inside-work-tree"], {
9
+ cwd: repoRoot,
10
+ encoding: "utf8"
11
+ });
12
+
13
+ if (workTreeCheck.status !== 0) {
14
+ console.log("repository hygiene skipped: package is not inside a Git worktree");
15
+ process.exit(0);
16
+ }
17
+
18
+ const result = spawnSync("git", ["ls-files", "-z"], {
19
+ cwd: repoRoot,
20
+ encoding: "utf8"
21
+ });
22
+
23
+ if (result.status !== 0) {
24
+ console.error(result.stderr || "repository hygiene failed: git ls-files failed");
25
+ process.exit(result.status || 1);
26
+ }
27
+
28
+ const tracked = result.stdout.split("\0").filter(Boolean);
29
+ const forbidden = tracked.filter(file =>
30
+ file === "node_modules"
31
+ || file.startsWith("node_modules/")
32
+ || file === "dist"
33
+ || file.startsWith("dist/")
34
+ || file.endsWith(".tgz")
35
+ );
36
+
37
+ if (forbidden.length > 0) {
38
+ console.error("repository hygiene failed: generated or dependency artifacts are tracked:");
39
+ for (const file of forbidden.slice(0, 20)) {
40
+ console.error(`- ${file}`);
41
+ }
42
+ if (forbidden.length > 20) {
43
+ console.error(`- ... and ${forbidden.length - 20} more`);
44
+ }
45
+ process.exit(1);
46
+ }
47
+
48
+ console.log("repository hygiene passed");
@@ -58,6 +58,7 @@ assert_contains "$repo_root/.codex-plugin/plugin.json" '"skills"'
58
58
  assert_contains "$repo_root/.codex-plugin/plugin.json" '"genesis-skill-set"'
59
59
  assert_contains "$repo_root/.codex-plugin/plugin.json" '$genesis-pipeline-orchestration'
60
60
  assert_contains "$repo_root/.codex-plugin/plugin.json" '$genesis-api-contract'
61
+ assert_contains "$repo_root/.codex-plugin/plugin.json" 'implicit init'
61
62
  assert_not_contains "$repo_root/.codex-plugin/plugin.json" '$pipeline-orchestration-skill'
62
63
  assert_not_contains "$repo_root/.codex-plugin/plugin.json" '$api-contract-skill'
63
64
  assert_contains "$harness_dir/SKILL.md" '/genesis-init'
@@ -65,6 +66,13 @@ assert_contains "$repo_root/.codex/SKILLS_INDEX.md" '/genesis-init'
65
66
  assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness docs-gate'
66
67
  assert_contains "$repo_root/bin/genesis-harness.js" 'check-docs-sync.sh'
67
68
  assert_contains "$repo_root/bin/genesis-harness.js" 'npx genesis-harness docs-gate'
69
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness resume'
70
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness next'
71
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness add-feature'
72
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness complete-feature'
73
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness verify-project'
74
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness complete-project'
75
+ assert_contains "$repo_root/bin/genesis-harness.js" 'genesis-harness pipeline-audit'
68
76
  assert_contains "$harness_dir/scripts/check-docs-sync.sh" '.codebase/'
69
77
  assert_contains "$harness_dir/scripts/check-docs-sync.sh" 'README(\.[A-Z]{2})?\.md'
70
78
  assert_contains "$repo_root/.codebase/VISUAL_GRAPH.md" 'genesis-harness'
@@ -73,12 +81,23 @@ assert_contains "$repo_root/.codebase/PIPELINE_FLOW.md" 'contracts --> impl'
73
81
  assert_not_contains "$repo_root/.codebase/VISUAL_GRAPH.md" 'Đăng nhập'
74
82
  assert_not_contains "$repo_root/.codebase/VISUAL_GRAPH.md" 'src/auth.js'
75
83
  assert_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" 'Harness Drift Gate Hardening'
76
- assert_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" '2026-06-03'
77
84
  assert_not_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" '_[Name and reference]_'
78
85
  assert_not_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" 'Feature A'
79
86
  assert_not_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" 'YYYY-MM-DD'
80
- assert_contains "$repo_root/.codebase/state.json" '"completed_at": "2026-06-03'
81
- assert_contains "$repo_root/.codebase/CURRENT_STATE.md" '2026-06-03'
87
+ node - "$repo_root/.codebase/state.json" <<'NODE'
88
+ const fs = require("fs");
89
+ const state = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
90
+ if (state.current_state === "COMPLETED" && !state.completed_at) {
91
+ throw new Error("completed state must include completed_at");
92
+ }
93
+ if (state.current_state !== "COMPLETED" && Object.prototype.hasOwnProperty.call(state, "completed_at")) {
94
+ throw new Error("active state must not retain completed_at");
95
+ }
96
+ NODE
97
+ assert_contains "$repo_root/.codebase/CURRENT_STATE.md" '**Time**: '
98
+ assert_contains "$repo_root/.codebase/MODULE_INDEX.md" '.runs/'
99
+ assert_not_contains "$repo_root/.codebase/CURRENT_STATE.md" '110/110 perfect score'
100
+ assert_not_contains "$repo_root/.codebase/state.json" '"to": "EXECUTE"'
82
101
  assert_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" 'npm run eval'
83
102
  assert_not_contains "$repo_root/.codebase/IMPLEMENTATION_HANDOFF.md" 'rtk '
84
103
  assert_not_contains "$repo_root/.codebase/state.json" 'rtk '
@@ -106,6 +125,16 @@ assert_contains "$repo_root/package.json" '"playwright"'
106
125
  assert_contains "$repo_root/package.json" '"observability"'
107
126
  assert_contains "$repo_root/README.md" '.codex/skills/'
108
127
 
128
+ plugin_version=$(node -p "require('$repo_root/.codex-plugin/plugin.json').version")
129
+ package_version=$(node -p "require('$repo_root/package.json').version")
130
+ [ "$plugin_version" = "$package_version" ] || fail "plugin version ($plugin_version) must match package version ($package_version)"
131
+
132
+ [ "$(grep -c '^- `bin/genesis-harness.js`:' "$repo_root/.codebase/MODULE_INDEX.md")" -eq 1 ] \
133
+ || fail ".codebase/MODULE_INDEX.md must contain a single canonical bin/genesis-harness.js entry"
134
+
135
+ [ "$(grep -c '^- `tests/integration/cli-smoke.test.js`:' "$repo_root/.codebase/TEST_MATRIX.md")" -eq 1 ] \
136
+ || fail ".codebase/TEST_MATRIX.md must describe cli-smoke in one canonical entry"
137
+
109
138
  for skill_name in "${skill_names[@]}"; do
110
139
  assert_contains "$repo_root/bin/genesis-harness.js" "$skill_name"
111
140
  assert_contains "$repo_root/scripts/install.sh" "$skill_name"
@@ -193,6 +222,8 @@ pack_tmp="$(mktemp -d)"
193
222
  npm pack --pack-destination "$pack_tmp" >/dev/null
194
223
  tarball_path=$(ls "$pack_tmp"/*.tgz | head -n 1)
195
224
  [ -f "$tarball_path" ] || fail "npm pack failed to produce tarball"
225
+ tar tzf "$tarball_path" | grep -q '^package/scripts/bin/' \
226
+ && fail "packaged tarball must not include generated scripts/bin binaries"
196
227
  (
197
228
  cd "$pack_tmp"
198
229
  tar xzf "$tarball_path"
@@ -208,7 +239,9 @@ assert_contains "$repo_root/features/REGISTRY.md" "| id |"
208
239
  assert_contains "$repo_root/features/REGISTRY.md" "| status |"
209
240
  assert_contains "$repo_root/features/REGISTRY.md" "| verify_cmd |"
210
241
  assert_file "$repo_root/contracts/features/registry-schema.json"
242
+ assert_file "$repo_root/contracts/features/project-registry-schema.json"
211
243
  assert_contains "$repo_root/contracts/features/registry-schema.json" '"required_columns"'
244
+ assert_contains "$repo_root/contracts/features/project-registry-schema.json" '"completion_rule"'
212
245
  assert_contains "$repo_root/.codebase/MODULE_INDEX.md" "features/REGISTRY.md"
213
246
 
214
247
  # L11 — Observability Live Data
@@ -0,0 +1,129 @@
1
+ -- Harness v0 schema — migration 001
2
+ -- Durable layer for operational harness data.
3
+ -- Policy docs (HARNESS.md, FEATURE_INTAKE.md, ARCHITECTURE.md) stay as
4
+ -- human-readable references. This database stores the operational records
5
+ -- that agents produce and query during work.
6
+
7
+ PRAGMA journal_mode = WAL;
8
+ PRAGMA foreign_keys = ON;
9
+
10
+ ----------------------------------------------------------------------
11
+ -- Schema version
12
+ ----------------------------------------------------------------------
13
+ CREATE TABLE IF NOT EXISTS schema_version (
14
+ version INTEGER PRIMARY KEY,
15
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
16
+ );
17
+
18
+ INSERT INTO schema_version (version) VALUES (1);
19
+
20
+ ----------------------------------------------------------------------
21
+ -- Intake: classifying incoming work
22
+ ----------------------------------------------------------------------
23
+ CREATE TABLE intake (
24
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
25
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
26
+ input_type TEXT NOT NULL
27
+ CHECK(input_type IN (
28
+ 'new_spec','spec_slice','change_request',
29
+ 'new_initiative','maintenance','harness_improvement'
30
+ )),
31
+ summary TEXT NOT NULL,
32
+ risk_lane TEXT NOT NULL
33
+ CHECK(risk_lane IN ('tiny','normal','high_risk')),
34
+ risk_flags TEXT, -- JSON array, e.g. ["auth","data_model"]
35
+ affected_docs TEXT, -- JSON array of doc paths
36
+ story_id TEXT, -- links to story.id when one is created
37
+ notes TEXT
38
+ );
39
+
40
+ ----------------------------------------------------------------------
41
+ -- Story: work packets and their validation status
42
+ -- Replaces hand-edited TEST_MATRIX.md rows.
43
+ ----------------------------------------------------------------------
44
+ CREATE TABLE story (
45
+ id TEXT PRIMARY KEY, -- e.g. US-001
46
+ title TEXT NOT NULL,
47
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
48
+ risk_lane TEXT NOT NULL
49
+ CHECK(risk_lane IN ('tiny','normal','high_risk')),
50
+ contract_doc TEXT, -- path to product doc
51
+ status TEXT NOT NULL DEFAULT 'planned'
52
+ CHECK(status IN (
53
+ 'planned','in_progress','implemented','changed','retired'
54
+ )),
55
+ unit_proof INTEGER NOT NULL DEFAULT 0,
56
+ integration_proof INTEGER NOT NULL DEFAULT 0,
57
+ e2e_proof INTEGER NOT NULL DEFAULT 0,
58
+ platform_proof INTEGER NOT NULL DEFAULT 0,
59
+ evidence TEXT,
60
+ notes TEXT
61
+ );
62
+
63
+ ----------------------------------------------------------------------
64
+ -- Decision: durable records with optional verification
65
+ ----------------------------------------------------------------------
66
+ CREATE TABLE decision (
67
+ id TEXT PRIMARY KEY, -- e.g. 0001
68
+ title TEXT NOT NULL,
69
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
70
+ status TEXT NOT NULL DEFAULT 'proposed'
71
+ CHECK(status IN (
72
+ 'proposed','accepted','superseded','rejected'
73
+ )),
74
+ doc_path TEXT, -- path to the markdown ADR
75
+ verify_command TEXT, -- optional check command
76
+ last_verified_at TEXT,
77
+ last_verified_result TEXT
78
+ CHECK(last_verified_result IN ('pass','fail') OR
79
+ last_verified_result IS NULL),
80
+ predicted_impact TEXT,
81
+ actual_outcome TEXT,
82
+ notes TEXT
83
+ );
84
+
85
+ ----------------------------------------------------------------------
86
+ -- Backlog: harness improvement proposals with evidence loop
87
+ ----------------------------------------------------------------------
88
+ CREATE TABLE backlog (
89
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
90
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
91
+ title TEXT NOT NULL,
92
+ discovered_while TEXT,
93
+ current_pain TEXT,
94
+ suggested_improvement TEXT,
95
+ risk TEXT CHECK(risk IN ('tiny','normal','high_risk')),
96
+ status TEXT NOT NULL DEFAULT 'proposed'
97
+ CHECK(status IN (
98
+ 'proposed','accepted','implemented','rejected'
99
+ )),
100
+ predicted_impact TEXT,
101
+ actual_outcome TEXT,
102
+ implemented_at TEXT,
103
+ notes TEXT
104
+ );
105
+
106
+ ----------------------------------------------------------------------
107
+ -- Trace: agent task execution records (observability foundation)
108
+ ----------------------------------------------------------------------
109
+ CREATE TABLE trace (
110
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
111
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
112
+ task_summary TEXT NOT NULL,
113
+ intake_id INTEGER REFERENCES intake(id),
114
+ story_id TEXT REFERENCES story(id),
115
+ agent TEXT,
116
+ actions_taken TEXT, -- JSON array
117
+ files_read TEXT, -- JSON array
118
+ files_changed TEXT, -- JSON array
119
+ decisions_made TEXT, -- JSON array
120
+ errors TEXT, -- JSON array
121
+ outcome TEXT
122
+ CHECK(outcome IN (
123
+ 'completed','blocked','partial','failed'
124
+ )),
125
+ duration_seconds INTEGER,
126
+ token_estimate INTEGER,
127
+ harness_friction TEXT,
128
+ notes TEXT
129
+ );
@@ -0,0 +1,9 @@
1
+ -- Harness v0 schema - migration 002
2
+ -- Story-level mechanical verification.
3
+
4
+ ALTER TABLE story ADD COLUMN verify_command TEXT;
5
+ ALTER TABLE story ADD COLUMN last_verified_at TEXT;
6
+ ALTER TABLE story ADD COLUMN last_verified_result TEXT
7
+ CHECK(last_verified_result IN ('pass','fail') OR last_verified_result IS NULL);
8
+
9
+ INSERT INTO schema_version (version) VALUES (2);
@@ -0,0 +1,15 @@
1
+ -- Harness v0 schema - migration 003
2
+ -- Machine-readable registry for user-provided project tools.
3
+
4
+ CREATE TABLE tool (
5
+ name TEXT PRIMARY KEY,
6
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
7
+ provider TEXT NOT NULL DEFAULT 'custom',
8
+ command TEXT NOT NULL,
9
+ description TEXT NOT NULL,
10
+ args TEXT,
11
+ responsibility TEXT NOT NULL,
12
+ since TEXT NOT NULL DEFAULT 'registered'
13
+ );
14
+
15
+ INSERT INTO schema_version (version) VALUES (3);
@@ -0,0 +1,15 @@
1
+ -- Harness v0 schema - migration 004
2
+ -- Review, human, CI, or agent interventions separated from normal traces.
3
+
4
+ CREATE TABLE intervention (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
7
+ trace_id INTEGER REFERENCES trace(id),
8
+ story_id TEXT,
9
+ type TEXT NOT NULL CHECK(type IN ('correction','override','escalation','approval')),
10
+ description TEXT NOT NULL,
11
+ source TEXT NOT NULL CHECK(source IN ('human','reviewer','ci','agent')),
12
+ impact TEXT
13
+ );
14
+
15
+ INSERT INTO schema_version (version) VALUES (4);
@@ -1,5 +1,7 @@
1
1
  #!/bin/bash
2
2
 
3
+ set -euo pipefail
4
+
3
5
  if [ -z "$1" ]; then
4
6
  echo "Usage: bash scripts/transition_state.sh <NEW_STATE> [Reason]"
5
7
  exit 1
@@ -30,14 +32,16 @@ const fs = require('fs');
30
32
  const file = '$STATE_FILE';
31
33
  const newState = '$NEW_STATE';
32
34
  const reason = '$REASON';
35
+ const now = new Date().toISOString();
33
36
 
34
37
  const allowed = {
35
38
  'INIT': ['REQUIREMENTS_GATHERING', 'PLANNING'],
36
39
  'REQUIREMENTS_GATHERING': ['PLANNING'],
37
40
  'PLANNING': ['IMPLEMENTATION'],
38
41
  'IMPLEMENTATION': ['VERIFICATION', 'PLANNING'],
39
- 'VERIFICATION': ['COMPLETED', 'IMPLEMENTATION'],
40
- 'COMPLETED': ['INIT', 'REQUIREMENTS_GATHERING']
42
+ 'VERIFICATION': ['RELEASE_READY', 'IMPLEMENTATION'],
43
+ 'RELEASE_READY': ['COMPLETED', 'IMPLEMENTATION'],
44
+ 'COMPLETED': ['INIT', 'REQUIREMENTS_GATHERING', 'IMPLEMENTATION']
41
45
  };
42
46
 
43
47
  let data = JSON.parse(fs.readFileSync(file, 'utf8'));
@@ -45,8 +49,18 @@ const current = data.current_state || 'INIT';
45
49
 
46
50
  if (allowed[current] && allowed[current].includes(newState)) {
47
51
  data.history = data.history || [];
48
- data.history.push({ from: current, to: newState, reason: reason, timestamp: new Date().toISOString() });
52
+ data.history.push({ from: current, to: newState, reason: reason, timestamp: now, session_id: data.session_id || 'manual-transition' });
49
53
  data.current_state = newState;
54
+ data.session_started_at = data.session_started_at || now;
55
+ data.last_updated_at = now;
56
+ if (newState === 'COMPLETED') {
57
+ data.completed_at = now;
58
+ data.active_work = '';
59
+ data.pending_tasks = [];
60
+ data.latest_recovery_point = reason;
61
+ } else {
62
+ delete data.completed_at;
63
+ }
50
64
  fs.writeFileSync(file, JSON.stringify(data, null, 2));
51
65
  console.log('Transition successful: ' + current + ' -> ' + newState);
52
66
  } else {
@@ -56,11 +70,21 @@ if (allowed[current] && allowed[current].includes(newState)) {
56
70
  "
57
71
 
58
72
  if [ $? -eq 0 ]; then
59
- echo "# Current State: $NEW_STATE" > "$CURRENT_STATE_MD"
60
- echo "Last updated: $(date)" >> "$CURRENT_STATE_MD"
61
- echo "" >> "$CURRENT_STATE_MD"
62
- echo "## Reason" >> "$CURRENT_STATE_MD"
63
- echo "$REASON" >> "$CURRENT_STATE_MD"
73
+ SESSION_ID=$(node -p "JSON.parse(require('fs').readFileSync('$STATE_FILE', 'utf8')).session_id || 'manual-transition'")
74
+ TTFV_SECONDS=$(node -p "JSON.parse(require('fs').readFileSync('$STATE_FILE', 'utf8')).ttfv_seconds || 0")
75
+ cat > "$CURRENT_STATE_MD" <<EOF
76
+ # Current System State
77
+
78
+ **Time**: $(date +%F)
79
+ **Status**: \`$NEW_STATE\`
80
+ **Latest Session**: \`$SESSION_ID\`
81
+ **Time to First Verification (TTFV)**: ${TTFV_SECONDS}s
82
+
83
+ ## Latest Transition
84
+
85
+ - State changed to \`$NEW_STATE\`
86
+ - Reason: $REASON
87
+ EOF
64
88
  exit 0
65
89
  else
66
90
  exit 1