@lamentis/naome 1.3.1 → 1.3.2

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/Cargo.lock CHANGED
@@ -76,7 +76,7 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
76
76
 
77
77
  [[package]]
78
78
  name = "naome-cli"
79
- version = "1.3.1"
79
+ version = "1.3.2"
80
80
  dependencies = [
81
81
  "naome-core",
82
82
  "serde_json",
@@ -84,7 +84,7 @@ dependencies = [
84
84
 
85
85
  [[package]]
86
86
  name = "naome-core"
87
- version = "1.3.1"
87
+ version = "1.3.2"
88
88
  dependencies = [
89
89
  "serde",
90
90
  "serde_json",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "naome-cli"
3
- version = "1.3.1"
3
+ version = "1.3.2"
4
4
  edition.workspace = true
5
5
  license.workspace = true
6
6
  repository.workspace = true
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "naome-core"
3
- version = "1.3.1"
3
+ version = "1.3.2"
4
4
  edition.workspace = true
5
5
  license.workspace = true
6
6
  repository.workspace = true
@@ -0,0 +1,38 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_ACTIVE_BLOCKED: Policy = (
4
+ "block_unowned_diff",
5
+ false,
6
+ "The active task is blocked by out-of-scope changes.",
7
+ "Resolve the scope blocker before interpreting new work.",
8
+ );
9
+ pub(crate) const POLICY_ACTIVE_CANCEL: Policy = (
10
+ "cancel_current_task",
11
+ false,
12
+ "The prompt asks to cancel the active task.",
13
+ "Cancel or review the active task before starting another.",
14
+ );
15
+ pub(crate) const POLICY_ACTIVE_CONTINUE: Policy = (
16
+ "continue_current_task",
17
+ true,
18
+ "A task is active and the prompt appears to continue or finish it.",
19
+ "Continue the current task and keep proof current.",
20
+ );
21
+ pub(crate) const POLICY_ACTIVE_NEW_BLOCK: Policy = (
22
+ "block_ambiguous_intent",
23
+ false,
24
+ "A task is already active and the prompt appears to ask for a distinct new goal.",
25
+ "Complete, revise, or cancel the active task before starting another.",
26
+ );
27
+ pub(crate) const POLICY_ACTIVE_NO_COMMIT: Policy = (
28
+ "continue_current_task_without_commit",
29
+ true,
30
+ "A task is active and the prompt blocks committing.",
31
+ "Continue the active task without baselining.",
32
+ );
33
+ pub(crate) const POLICY_ACTIVE_REVIEW: Policy = (
34
+ "review_current_task_diff",
35
+ false,
36
+ "The prompt asks to review the active task diff.",
37
+ "Review the active task before mutating it further.",
38
+ );
@@ -0,0 +1,44 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_BASELINE_BLOCK: Policy = (
4
+ "block_unowned_diff",
5
+ false,
6
+ "Setup, upgrade, or repair changes must be resolved before task routing.",
7
+ "Resolve the harness baseline decision before accepting feature work.",
8
+ );
9
+ pub(crate) const POLICY_BASELINE_CANCEL: Policy = (
10
+ "cancel_upgrade_baseline",
11
+ false,
12
+ "The prompt explicitly asks to cancel setup, upgrade, or repair changes.",
13
+ "Cancel or review the NAOME diff before feature work.",
14
+ );
15
+ pub(crate) const POLICY_BASELINE_COMMIT_UPGRADE: Policy = (
16
+ "commit_upgrade_baseline",
17
+ true,
18
+ "The prompt asks to baseline pending setup, upgrade, or repair changes.",
19
+ "Run the appropriate NAOME baseline flow before feature work.",
20
+ );
21
+ pub(crate) const POLICY_BASELINE_NEW_REFRESH: Policy = (
22
+ "auto_commit_harness_refresh_then_create_new_task",
23
+ true,
24
+ "The prompt asks for a new goal and the only blocker is a deterministic harness refresh.",
25
+ "Baseline the harness refresh automatically, rerun admission, then create the new task in the same worktree.",
26
+ );
27
+ pub(crate) const POLICY_BASELINE_NEW_UPGRADE: Policy = (
28
+ "auto_commit_upgrade_baseline_then_create_new_task",
29
+ true,
30
+ "The prompt asks for a new goal and the only blocker is a completed NAOME setup, upgrade, or repair diff.",
31
+ "Baseline the NAOME diff automatically, rerun admission, then create the new task.",
32
+ );
33
+ pub(crate) const POLICY_BASELINE_NO_COMMIT: Policy = (
34
+ "block_auto_baseline_due_to_no_commit",
35
+ false,
36
+ "The prompt explicitly blocks committing, so NAOME will not auto-baseline setup or repair changes.",
37
+ "Review, cancel, or manually resolve the setup diff before feature work.",
38
+ );
39
+ pub(crate) const POLICY_BASELINE_REVIEW: Policy = (
40
+ "review_diff_first",
41
+ false,
42
+ "The prompt explicitly asks to review setup, upgrade, or repair changes.",
43
+ "Review the NAOME diff before any baseline or new task.",
44
+ );
@@ -0,0 +1,56 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_COMPLETED_CANCEL: Policy = (
4
+ "cancel_task_changes",
5
+ false,
6
+ "The prompt explicitly asks to cancel the completed task changes.",
7
+ "Cancel or review the completed task diff before any new task.",
8
+ );
9
+ pub(crate) const POLICY_COMPLETED_COMMIT: Policy = (
10
+ "commit_task_baseline",
11
+ true,
12
+ "The prompt asks to baseline the completed task diff.",
13
+ "Run the NAOME commit baseline flow for the completed task.",
14
+ );
15
+ pub(crate) const POLICY_COMPLETED_NEW_INVALID: Policy = (
16
+ "block_unsafe_intent",
17
+ false,
18
+ "The prompt asks for a new task, but the current completed task is not safe to auto-baseline.",
19
+ "Review the completed diff and proof before starting new work.",
20
+ );
21
+ pub(crate) const POLICY_COMPLETED_NEW_ISOLATED: Policy = (
22
+ "auto_commit_completed_task_then_create_isolated_task_worktree",
23
+ true,
24
+ "The completed task is valid, and unrelated user edits are present.",
25
+ "Baseline only the completed task paths, preserve unrelated user edits, and create an isolated worktree for the next task.",
26
+ );
27
+ pub(crate) const POLICY_COMPLETED_NEW_REFRESH: Policy = (
28
+ "auto_commit_harness_refresh_then_completed_task_then_create_new_task",
29
+ true,
30
+ "The completed task is valid after separating deterministic harness refresh changes.",
31
+ "Baseline the harness refresh first, then baseline the completed task and create the next task.",
32
+ );
33
+ pub(crate) const POLICY_COMPLETED_NEW_VALID: Policy = (
34
+ "auto_commit_completed_task_then_create_new_task",
35
+ true,
36
+ "The completed task is valid and the prompt asks for a distinct new goal.",
37
+ "Baseline the completed task first, then create the next task.",
38
+ );
39
+ pub(crate) const POLICY_COMPLETED_NO_COMMIT: Policy = (
40
+ "block_auto_baseline_due_to_no_commit",
41
+ false,
42
+ "The prompt explicitly blocks committing, so NAOME will not auto-baseline the completed task.",
43
+ "Review, revise, cancel, or manually resolve the completed task diff.",
44
+ );
45
+ pub(crate) const POLICY_COMPLETED_REVIEW: Policy = (
46
+ "review_task_diff",
47
+ false,
48
+ "The prompt explicitly asks to review the completed task diff.",
49
+ "Review the completed task diff before any baseline or new task.",
50
+ );
51
+ pub(crate) const POLICY_COMPLETED_REVISION: Policy = (
52
+ "reopen_completed_task_revision",
53
+ true,
54
+ "The prompt refers to follow-up correction on the unbaselined completed task.",
55
+ "Reopen the same task as a revision and mark proof stale before editing.",
56
+ );
@@ -0,0 +1,32 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_DIRTY_BLOCK: Policy = (
4
+ "block_unowned_diff",
5
+ false,
6
+ "The repository has unowned changes that must be resolved first.",
7
+ "NAOME will not commit unowned changes. Review them, or route a new task so NAOME can isolate task work in a separate worktree.",
8
+ );
9
+ pub(crate) const POLICY_DIRTY_COMMIT_USER: Policy = (
10
+ "commit_user_diff_with_quality_gate",
11
+ true,
12
+ "The prompt asks to commit unowned user changes.",
13
+ "Run NAOME's user-diff quality gate, then commit only the current changed paths if every required check passes.",
14
+ );
15
+ pub(crate) const POLICY_DIRTY_NEW_ISOLATED: Policy = (
16
+ "auto_commit_harness_refresh_then_create_isolated_task_worktree",
17
+ true,
18
+ "The repository has deterministic harness refresh changes plus unrelated user edits.",
19
+ "Baseline only the harness refresh first, then create an isolated task worktree without touching user edits.",
20
+ );
21
+ pub(crate) const POLICY_DIRTY_NEW_REFRESH: Policy = (
22
+ "auto_commit_harness_refresh_then_create_new_task",
23
+ true,
24
+ "The repository has only deterministic harness refresh changes.",
25
+ "Baseline the harness refresh first, then create the next task in the same worktree.",
26
+ );
27
+ pub(crate) const POLICY_DIRTY_NEW_WORKTREE: Policy = (
28
+ "create_isolated_task_worktree",
29
+ true,
30
+ "The repository has unrelated user changes, and the prompt asks for a new task.",
31
+ "Create an isolated NAOME task worktree so the new task can proceed without touching those user changes.",
32
+ );
@@ -0,0 +1,32 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_READY_COMMIT_BLOCK: Policy = (
4
+ "block_ambiguous_intent",
5
+ false,
6
+ "The repository is already ready for work; there is no open task diff to baseline.",
7
+ "Ask for the next concrete task or inspect status.",
8
+ );
9
+ pub(crate) const POLICY_READY_NEW: Policy = (
10
+ "create_new_task",
11
+ true,
12
+ "The repository is clean and the prompt asks for a new goal.",
13
+ "Create a NAOME task for the new request.",
14
+ );
15
+ pub(crate) const POLICY_READY_NO_COMMIT: Policy = (
16
+ "create_new_task_without_auto_baseline",
17
+ true,
18
+ "The repository is clean, so no commit is needed before the new task.",
19
+ "Create a NAOME task for the new request.",
20
+ );
21
+ pub(crate) const POLICY_READY_REVIEW_STATUS: Policy = (
22
+ "answer_status_only",
23
+ true,
24
+ "The prompt asks for review, but there is no open task diff.",
25
+ "Answer from the current NAOME status without editing files.",
26
+ );
27
+ pub(crate) const POLICY_READY_REVISION_BLOCK: Policy = (
28
+ "block_ambiguous_intent",
29
+ false,
30
+ "The prompt sounds like a correction, but there is no open task diff.",
31
+ "Ask whether this is a new task or a status question.",
32
+ );
@@ -0,0 +1,20 @@
1
+ use super::super::resolver_shared::Policy;
2
+
3
+ pub(crate) const POLICY_FIRST_RUN: Policy = (
4
+ "run_first_run_protocol",
5
+ false,
6
+ "First-run intake must finish before feature work.",
7
+ "Run the NAOME first-run protocol.",
8
+ );
9
+ pub(crate) const POLICY_HARNESS_UNHEALTHY: Policy = (
10
+ "repair_harness_only",
11
+ false,
12
+ "The harness is unhealthy, so normal task work is blocked.",
13
+ "Repair or review the harness before accepting feature work.",
14
+ );
15
+ pub(crate) const POLICY_UPGRADE: Policy = (
16
+ "run_upgrade_protocol",
17
+ false,
18
+ "A NAOME upgrade is pending before feature work.",
19
+ "Run the NAOME upgrade protocol.",
20
+ );
@@ -1,167 +1,13 @@
1
- use super::resolver_shared::Policy;
1
+ mod active;
2
+ mod baseline;
3
+ mod completed;
4
+ mod dirty;
5
+ mod ready;
6
+ mod system;
2
7
 
3
- pub(crate) const POLICY_ACTIVE_BLOCKED: Policy = (
4
- "block_unowned_diff",
5
- false,
6
- "The active task is blocked by out-of-scope changes.",
7
- "Resolve the scope blocker before interpreting new work.",
8
- );
9
- pub(crate) const POLICY_ACTIVE_CANCEL: Policy = (
10
- "cancel_current_task",
11
- false,
12
- "The prompt asks to cancel the active task.",
13
- "Cancel or review the active task before starting another.",
14
- );
15
- pub(crate) const POLICY_ACTIVE_CONTINUE: Policy = (
16
- "continue_current_task",
17
- true,
18
- "A task is active and the prompt appears to continue or finish it.",
19
- "Continue the current task and keep proof current.",
20
- );
21
- pub(crate) const POLICY_ACTIVE_NEW_BLOCK: Policy = (
22
- "block_ambiguous_intent",
23
- false,
24
- "A task is already active and the prompt appears to ask for a distinct new goal.",
25
- "Complete, revise, or cancel the active task before starting another.",
26
- );
27
- pub(crate) const POLICY_ACTIVE_NO_COMMIT: Policy = (
28
- "continue_current_task_without_commit",
29
- true,
30
- "A task is active and the prompt blocks committing.",
31
- "Continue the active task without baselining.",
32
- );
33
- pub(crate) const POLICY_ACTIVE_REVIEW: Policy = (
34
- "review_current_task_diff",
35
- false,
36
- "The prompt asks to review the active task diff.",
37
- "Review the active task before mutating it further.",
38
- );
39
- pub(crate) const POLICY_BASELINE_BLOCK: Policy = (
40
- "block_unowned_diff",
41
- false,
42
- "Setup, upgrade, or repair changes must be resolved before task routing.",
43
- "Resolve the harness baseline decision before accepting feature work.",
44
- );
45
- pub(crate) const POLICY_BASELINE_CANCEL: Policy = (
46
- "cancel_upgrade_baseline",
47
- false,
48
- "The prompt explicitly asks to cancel setup, upgrade, or repair changes.",
49
- "Cancel or review the NAOME diff before feature work.",
50
- );
51
- pub(crate) const POLICY_BASELINE_COMMIT_UPGRADE: Policy = (
52
- "commit_upgrade_baseline",
53
- true,
54
- "The prompt asks to baseline pending setup, upgrade, or repair changes.",
55
- "Run the appropriate NAOME baseline flow before feature work.",
56
- );
57
- pub(crate) const POLICY_BASELINE_NEW_REFRESH: Policy = ("auto_commit_harness_refresh_then_create_new_task", true, "The prompt asks for a new goal and the only blocker is a deterministic harness refresh.", "Baseline the harness refresh automatically, rerun admission, then create the new task in the same worktree.");
58
- pub(crate) const POLICY_BASELINE_NEW_UPGRADE: Policy = ("auto_commit_upgrade_baseline_then_create_new_task", true, "The prompt asks for a new goal and the only blocker is a completed NAOME setup, upgrade, or repair diff.", "Baseline the NAOME diff automatically, rerun admission, then create the new task.");
59
- pub(crate) const POLICY_BASELINE_NO_COMMIT: Policy = ("block_auto_baseline_due_to_no_commit", false, "The prompt explicitly blocks committing, so NAOME will not auto-baseline setup or repair changes.", "Review, cancel, or manually resolve the setup diff before feature work.");
60
- pub(crate) const POLICY_BASELINE_REVIEW: Policy = (
61
- "review_diff_first",
62
- false,
63
- "The prompt explicitly asks to review setup, upgrade, or repair changes.",
64
- "Review the NAOME diff before any baseline or new task.",
65
- );
66
- pub(crate) const POLICY_COMPLETED_CANCEL: Policy = (
67
- "cancel_task_changes",
68
- false,
69
- "The prompt explicitly asks to cancel the completed task changes.",
70
- "Cancel or review the completed task diff before any new task.",
71
- );
72
- pub(crate) const POLICY_COMPLETED_COMMIT: Policy = (
73
- "commit_task_baseline",
74
- true,
75
- "The prompt asks to baseline the completed task diff.",
76
- "Run the NAOME commit baseline flow for the completed task.",
77
- );
78
- pub(crate) const POLICY_COMPLETED_NEW_INVALID: Policy = (
79
- "block_unsafe_intent",
80
- false,
81
- "The prompt asks for a new task, but the current completed task is not safe to auto-baseline.",
82
- "Review the completed diff and proof before starting new work.",
83
- );
84
- pub(crate) const POLICY_COMPLETED_NEW_ISOLATED: Policy = ("auto_commit_completed_task_then_create_isolated_task_worktree", true, "The completed task is valid, and unrelated user edits are present.", "Baseline only the completed task paths, preserve unrelated user edits, and create an isolated worktree for the next task.");
85
- pub(crate) const POLICY_COMPLETED_NEW_REFRESH: Policy = ("auto_commit_harness_refresh_then_completed_task_then_create_new_task", true, "The completed task is valid after separating deterministic harness refresh changes.", "Baseline the harness refresh first, then baseline the completed task and create the next task.");
86
- pub(crate) const POLICY_COMPLETED_NEW_VALID: Policy = (
87
- "auto_commit_completed_task_then_create_new_task",
88
- true,
89
- "The completed task is valid and the prompt asks for a distinct new goal.",
90
- "Baseline the completed task first, then create the next task.",
91
- );
92
- pub(crate) const POLICY_COMPLETED_NO_COMMIT: Policy = (
93
- "block_auto_baseline_due_to_no_commit",
94
- false,
95
- "The prompt explicitly blocks committing, so NAOME will not auto-baseline the completed task.",
96
- "Review, revise, cancel, or manually resolve the completed task diff.",
97
- );
98
- pub(crate) const POLICY_COMPLETED_REVIEW: Policy = (
99
- "review_task_diff",
100
- false,
101
- "The prompt explicitly asks to review the completed task diff.",
102
- "Review the completed task diff before any baseline or new task.",
103
- );
104
- pub(crate) const POLICY_COMPLETED_REVISION: Policy = (
105
- "reopen_completed_task_revision",
106
- true,
107
- "The prompt refers to follow-up correction on the unbaselined completed task.",
108
- "Reopen the same task as a revision and mark proof stale before editing.",
109
- );
110
- pub(crate) const POLICY_DIRTY_BLOCK: Policy = ("block_unowned_diff", false, "The repository has unowned changes that must be resolved first.", "NAOME will not commit unowned changes. Review them, or route a new task so NAOME can isolate task work in a separate worktree.");
111
- pub(crate) const POLICY_DIRTY_COMMIT_USER: Policy = ("commit_user_diff_with_quality_gate", true, "The prompt asks to commit unowned user changes.", "Run NAOME's user-diff quality gate, then commit only the current changed paths if every required check passes.");
112
- pub(crate) const POLICY_DIRTY_NEW_ISOLATED: Policy = ("auto_commit_harness_refresh_then_create_isolated_task_worktree", true, "The repository has deterministic harness refresh changes plus unrelated user edits.", "Baseline only the harness refresh first, then create an isolated task worktree without touching user edits.");
113
- pub(crate) const POLICY_DIRTY_NEW_REFRESH: Policy = (
114
- "auto_commit_harness_refresh_then_create_new_task",
115
- true,
116
- "The repository has only deterministic harness refresh changes.",
117
- "Baseline the harness refresh first, then create the next task in the same worktree.",
118
- );
119
- pub(crate) const POLICY_DIRTY_NEW_WORKTREE: Policy = ("create_isolated_task_worktree", true, "The repository has unrelated user changes, and the prompt asks for a new task.", "Create an isolated NAOME task worktree so the new task can proceed without touching those user changes.");
120
- pub(crate) const POLICY_FIRST_RUN: Policy = (
121
- "run_first_run_protocol",
122
- false,
123
- "First-run intake must finish before feature work.",
124
- "Run the NAOME first-run protocol.",
125
- );
126
- pub(crate) const POLICY_HARNESS_UNHEALTHY: Policy = (
127
- "repair_harness_only",
128
- false,
129
- "The harness is unhealthy, so normal task work is blocked.",
130
- "Repair or review the harness before accepting feature work.",
131
- );
132
- pub(crate) const POLICY_READY_COMMIT_BLOCK: Policy = (
133
- "block_ambiguous_intent",
134
- false,
135
- "The repository is already ready for work; there is no open task diff to baseline.",
136
- "Ask for the next concrete task or inspect status.",
137
- );
138
- pub(crate) const POLICY_READY_NEW: Policy = (
139
- "create_new_task",
140
- true,
141
- "The repository is clean and the prompt asks for a new goal.",
142
- "Create a NAOME task for the new request.",
143
- );
144
- pub(crate) const POLICY_READY_NO_COMMIT: Policy = (
145
- "create_new_task_without_auto_baseline",
146
- true,
147
- "The repository is clean, so no commit is needed before the new task.",
148
- "Create a NAOME task for the new request.",
149
- );
150
- pub(crate) const POLICY_READY_REVIEW_STATUS: Policy = (
151
- "answer_status_only",
152
- true,
153
- "The prompt asks for review, but there is no open task diff.",
154
- "Answer from the current NAOME status without editing files.",
155
- );
156
- pub(crate) const POLICY_READY_REVISION_BLOCK: Policy = (
157
- "block_ambiguous_intent",
158
- false,
159
- "The prompt sounds like a correction, but there is no open task diff.",
160
- "Ask whether this is a new task or a status question.",
161
- );
162
- pub(crate) const POLICY_UPGRADE: Policy = (
163
- "run_upgrade_protocol",
164
- false,
165
- "A NAOME upgrade is pending before feature work.",
166
- "Run the NAOME upgrade protocol.",
167
- );
8
+ pub(crate) use active::*;
9
+ pub(crate) use baseline::*;
10
+ pub(crate) use completed::*;
11
+ pub(crate) use dirty::*;
12
+ pub(crate) use ready::*;
13
+ pub(crate) use system::*;
@@ -156,50 +156,13 @@ impl HarnessFixture {
156
156
  write_file(
157
157
  &root,
158
158
  ".naome/manifest.json",
159
- &format!(
160
- "{}\n",
161
- serde_json::to_string_pretty(&json!({
162
- "name": "naome",
163
- "harnessVersion": "0.6.1",
164
- "profile": "standard",
165
- "installedAt": "2026-05-05T00:00:00.000Z",
166
- "machineOwned": MACHINE_OWNED_PATHS,
167
- "projectOwned": PROJECT_OWNED_PATHS,
168
- "integrity": integrity
169
- }))
170
- .unwrap()
171
- ),
172
- );
173
- write_file(
174
- &root,
175
- ".naome/task-state.json",
176
- &format!(
177
- "{}\n",
178
- serde_json::to_string_pretty(&json!({
179
- "schema": "naome.task-state.v1",
180
- "version": 1,
181
- "status": "idle",
182
- "activeTask": null,
183
- "blocker": null,
184
- "updatedAt": null
185
- }))
186
- .unwrap()
187
- ),
159
+ &pretty_json(manifest_fixture(&integrity)),
188
160
  );
161
+ write_file(&root, ".naome/task-state.json", "{}\n");
189
162
  write_file(
190
163
  &root,
191
164
  ".naome/upgrade-state.json",
192
- &format!(
193
- "{}\n",
194
- serde_json::to_string_pretty(&json!({
195
- "status": "complete",
196
- "fromVersion": null,
197
- "toVersion": "0.6.1",
198
- "pending": [],
199
- "completed": []
200
- }))
201
- .unwrap()
202
- ),
165
+ &pretty_json(complete_upgrade_state_fixture()),
203
166
  );
204
167
 
205
168
  Self { root, integrity }
@@ -214,6 +177,32 @@ impl HarnessFixture {
214
177
  }
215
178
  }
216
179
 
180
+ fn manifest_fixture(integrity: &HashMap<String, String>) -> serde_json::Value {
181
+ json!({
182
+ "name": "naome",
183
+ "harnessVersion": "0.6.1",
184
+ "profile": "standard",
185
+ "installedAt": "2026-05-05T00:00:00.000Z",
186
+ "machineOwned": MACHINE_OWNED_PATHS,
187
+ "projectOwned": PROJECT_OWNED_PATHS,
188
+ "integrity": integrity
189
+ })
190
+ }
191
+
192
+ fn complete_upgrade_state_fixture() -> serde_json::Value {
193
+ json!({
194
+ "status": "complete",
195
+ "fromVersion": null,
196
+ "toVersion": "0.6.1",
197
+ "pending": [],
198
+ "completed": []
199
+ })
200
+ }
201
+
202
+ fn pretty_json(value: serde_json::Value) -> String {
203
+ format!("{}\n", serde_json::to_string_pretty(&value).unwrap())
204
+ }
205
+
217
206
  fn machine_content(relative_path: &str) -> String {
218
207
  match relative_path {
219
208
  "AGENTS.md" => [
@@ -14,7 +14,9 @@ pub use routes::{
14
14
  try_route_readme_task,
15
15
  };
16
16
  pub use verification_values::{
17
- change_type, diff_check, quality_check, repository_quality_config_source,
17
+ change_type, check_missing_last_verified_fixture, diff_check,
18
+ placeholder_verification_contract_fixture, quality_check, repo_docs_verification_fixture,
19
+ repository_quality_config_source,
18
20
  repository_quality_config_value, semantic_repository_quality_fixture_source,
19
21
  verification_value,
20
22
  };
@@ -1,4 +1,4 @@
1
- use serde_json::json;
1
+ use serde_json::{json, Value};
2
2
 
3
3
  pub fn completed_task_state(admission_head: &str) -> serde_json::Value {
4
4
  json!({
@@ -67,6 +67,7 @@ pub fn verification_value(
67
67
  "schema": "naome.verification.v1",
68
68
  "version": 1,
69
69
  "status": status,
70
+ "lastUpdated": null,
70
71
  "checks": checks,
71
72
  "changeTypes": change_types,
72
73
  "releaseGates": []
@@ -118,6 +119,97 @@ pub fn change_type(
118
119
  })
119
120
  }
120
121
 
122
+ pub fn repo_docs_verification_fixture() -> Value {
123
+ json!({
124
+ "schema": "naome.verification.v1",
125
+ "version": 1,
126
+ "status": "ready",
127
+ "lastUpdated": "2026-05-05",
128
+ "checks": [
129
+ {
130
+ "id": "repo-docs",
131
+ "command": "npm run docs:test",
132
+ "cwd": ".",
133
+ "purpose": "Validate repository documentation.",
134
+ "cost": "fast",
135
+ "source": "repository intake",
136
+ "evidence": ["package.json"],
137
+ "lastVerified": null
138
+ }
139
+ ],
140
+ "changeTypes": [
141
+ {
142
+ "id": "repo-docs",
143
+ "description": "Repository documentation changes.",
144
+ "paths": ["docs/**"],
145
+ "requiredChecks": ["repo-docs"],
146
+ "recommendedChecks": [],
147
+ "humanReview": false
148
+ }
149
+ ],
150
+ "releaseGates": [
151
+ {
152
+ "checkId": "repo-docs",
153
+ "requiredWhen": "Before merging repository documentation changes."
154
+ }
155
+ ]
156
+ })
157
+ }
158
+
159
+ pub fn placeholder_verification_contract_fixture() -> Value {
160
+ json!({
161
+ "schema": "naome.verification.v1",
162
+ "version": 1,
163
+ "status": "ready",
164
+ "lastUpdated": "2026-05-05",
165
+ "checks": [
166
+ {
167
+ "id": "example-check",
168
+ "command": "replace with real command",
169
+ "cwd": ".",
170
+ "purpose": "Replace with what this proves.",
171
+ "cost": "fast",
172
+ "source": "replace with evidence source",
173
+ "evidence": [],
174
+ "lastVerified": null
175
+ }
176
+ ],
177
+ "changeTypes": [
178
+ {
179
+ "id": "docs",
180
+ "description": "Documentation changes.",
181
+ "paths": ["docs/**"],
182
+ "requiredChecks": ["missing-check"],
183
+ "recommendedChecks": [],
184
+ "humanReview": false
185
+ }
186
+ ],
187
+ "releaseGates": []
188
+ })
189
+ }
190
+
191
+ pub fn check_missing_last_verified_fixture() -> Value {
192
+ json!({
193
+ "schema": "naome.verification.v1",
194
+ "version": 1,
195
+ "status": "uninitialized",
196
+ "lastUpdated": null,
197
+ "checks": [
198
+ {
199
+ "id": "diff-check",
200
+ "command": "git diff --check",
201
+ "cwd": ".",
202
+ "purpose": "Reject whitespace errors.",
203
+ "cost": "fast",
204
+ "source": "git",
205
+ "evidence": []
206
+ }
207
+ ],
208
+ "changeTypes": [],
209
+ "releaseGates": []
210
+ })
211
+ }
212
+
121
213
  pub fn quality_check(
122
214
  id: &str,
123
215
  command: &str,
@@ -8,8 +8,8 @@ use naome_core::{
8
8
  };
9
9
  use serde_json::json;
10
10
  use task_state_support::{
11
- active_task, complete_task_state, idle_task_state, strict_health_options, successful_admission,
12
- successful_proof, TaskFixture,
11
+ active_task, complete_task_state, idle_task_state, ready_empty_verification_fixture,
12
+ strict_health_options, successful_admission, successful_proof, TaskFixture,
13
13
  };
14
14
 
15
15
  #[test]
@@ -137,15 +137,7 @@ fn commit_gate_allows_install_baseline_with_gitignore_and_project_owned_paths()
137
137
  repo.write("docs/naome/testing.md", "# Testing\n");
138
138
  repo.write_json(
139
139
  ".naome/verification.json",
140
- json!({
141
- "schema": "naome.verification.v1",
142
- "version": 1,
143
- "status": "ready",
144
- "lastUpdated": "2026-05-05",
145
- "checks": [],
146
- "changeTypes": [],
147
- "releaseGates": []
148
- }),
140
+ ready_empty_verification_fixture(),
149
141
  );
150
142
 
151
143
  let report = commit_gate_report(&repo);
@@ -292,7 +284,7 @@ fn commit_gate_ignores_unstaged_user_edits_outside_completed_task_scope() {
292
284
 
293
285
  #[test]
294
286
  fn progress_accepts_implementing_task_with_scoped_diff_without_proof() {
295
- let repo = TaskFixture::new(implementing_readme_task());
287
+ let repo = TaskFixture::new(implementing_readme_task_fixture());
296
288
  repo.init_git();
297
289
  repo.write("README.md", "# In progress\n");
298
290
 
@@ -303,7 +295,7 @@ fn progress_accepts_implementing_task_with_scoped_diff_without_proof() {
303
295
 
304
296
  #[test]
305
297
  fn progress_rejects_in_flight_work_outside_scope() {
306
- let repo = TaskFixture::new(implementing_readme_task());
298
+ let repo = TaskFixture::new(implementing_readme_task_fixture());
307
299
  repo.init_git();
308
300
  repo.write("src/session.js", "export const session = null;\n");
309
301
 
@@ -417,7 +409,7 @@ fn progress_report(repo: &TaskFixture) -> TaskStateReport {
417
409
  .unwrap()
418
410
  }
419
411
 
420
- fn implementing_readme_task() -> serde_json::Value {
412
+ fn implementing_readme_task_fixture() -> serde_json::Value {
421
413
  json!({
422
414
  "schema": "naome.task-state.v1",
423
415
  "version": 1,
@@ -11,7 +11,8 @@ use naome_core::{HarnessHealthOptions, MACHINE_OWNED_PATHS, PROJECT_OWNED_PATHS}
11
11
  use serde_json::{json, Value};
12
12
  use sha2::{Digest, Sha256};
13
13
  pub use states::{
14
- active_task, complete_task_state, idle_task_state, successful_admission, successful_proof,
14
+ active_task, complete_task_state, idle_task_state, ready_empty_verification_fixture,
15
+ successful_admission, successful_proof,
15
16
  };
16
17
 
17
18
  static FIXTURE_COUNTER: AtomicU64 = AtomicU64::new(0);
@@ -1,24 +1,25 @@
1
1
  use serde_json::{json, Value};
2
2
 
3
3
  pub fn idle_task_state() -> Value {
4
- json!({
5
- "schema": "naome.task-state.v1",
6
- "version": 1,
7
- "status": "idle",
8
- "activeTask": null,
9
- "blocker": null,
10
- "updatedAt": null
11
- })
4
+ task_state_record("idle", Value::Null, Value::Null)
12
5
  }
13
6
 
14
7
  pub fn complete_task_state(overrides: Value) -> Value {
8
+ task_state_record(
9
+ "complete",
10
+ active_task(overrides),
11
+ json!("2026-05-04T12:00:00.000Z"),
12
+ )
13
+ }
14
+
15
+ fn task_state_record(status: &str, active_task: Value, updated_at: Value) -> Value {
15
16
  json!({
16
17
  "schema": "naome.task-state.v1",
17
18
  "version": 1,
18
- "status": "complete",
19
- "activeTask": active_task(overrides),
19
+ "status": status,
20
+ "activeTask": active_task,
20
21
  "blocker": null,
21
- "updatedAt": "2026-05-04T12:00:00.000Z"
22
+ "updatedAt": updated_at
22
23
  })
23
24
  }
24
25
 
@@ -71,6 +72,22 @@ pub fn successful_proof(overrides: Value) -> Value {
71
72
  proof
72
73
  }
73
74
 
75
+ pub fn ready_empty_verification_fixture() -> Value {
76
+ serde_json::from_str(
77
+ r#"{
78
+ "schema": "naome.verification.v1",
79
+ "version": 1,
80
+ "status": "ready",
81
+ "lastUpdated": "2026-05-05",
82
+ "checks": [],
83
+ "changeTypes": [],
84
+ "releaseGates": [],
85
+ "phases": []
86
+ }"#,
87
+ )
88
+ .unwrap()
89
+ }
90
+
74
91
  fn merge_object(target: &mut Value, overrides: Value) {
75
92
  let Some(target_object) = target.as_object_mut() else {
76
93
  return;
@@ -2,30 +2,12 @@ use naome_core::seed_builtin_verification_checks;
2
2
 
3
3
  mod repo_support;
4
4
 
5
- use repo_support::{change_type, quality_check, verification_value, TestRepo};
5
+ use repo_support::{repo_docs_verification_fixture, TestRepo};
6
6
 
7
7
  #[test]
8
8
  fn seeds_builtin_checks_without_removing_repo_specific_checks() {
9
9
  let repo = TestRepo::new("verification-seed");
10
- repo.write_naome_json(
11
- "verification.json",
12
- verification_value(
13
- "ready",
14
- vec![quality_check(
15
- "repo-docs",
16
- "npm run docs:test",
17
- "Validate repository documentation.",
18
- "fast",
19
- vec!["package.json"],
20
- )],
21
- vec![change_type(
22
- "repo-docs",
23
- "Repository documentation changes.",
24
- vec!["docs/**"],
25
- vec!["repo-docs"],
26
- )],
27
- ),
28
- );
10
+ repo.write_naome_json("verification.json", repo_docs_verification_fixture());
29
11
 
30
12
  let changed = seed_builtin_verification_checks(repo.path()).unwrap();
31
13
 
@@ -3,7 +3,10 @@ use serde_json::json;
3
3
 
4
4
  mod repo_support;
5
5
 
6
- use repo_support::{change_type, diff_check, verification_value, TestRepo};
6
+ use repo_support::{
7
+ change_type, check_missing_last_verified_fixture, diff_check,
8
+ placeholder_verification_contract_fixture, verification_value, TestRepo,
9
+ };
7
10
 
8
11
  #[test]
9
12
  fn accepts_valid_contract_and_testing_map() {
@@ -39,35 +42,7 @@ fn rejects_missing_check_references_and_ready_placeholders() {
39
42
  repo.write_testing_markdown(default_testing_markdown());
40
43
  repo.write_naome_json(
41
44
  "verification.json",
42
- json!({
43
- "schema": "naome.verification.v1",
44
- "version": 1,
45
- "status": "ready",
46
- "lastUpdated": "2026-05-05",
47
- "checks": [
48
- {
49
- "id": "example-check",
50
- "command": "replace with real command",
51
- "cwd": ".",
52
- "purpose": "Replace with what this proves.",
53
- "cost": "fast",
54
- "source": "replace with evidence source",
55
- "evidence": [],
56
- "lastVerified": null
57
- }
58
- ],
59
- "changeTypes": [
60
- {
61
- "id": "docs",
62
- "description": "Documentation changes.",
63
- "paths": ["docs/**"],
64
- "requiredChecks": ["missing-check"],
65
- "recommendedChecks": [],
66
- "humanReview": false
67
- }
68
- ],
69
- "releaseGates": []
70
- }),
45
+ placeholder_verification_contract_fixture(),
71
46
  );
72
47
 
73
48
  let errors = validate_verification_contract(repo.path()).unwrap();
@@ -81,28 +56,7 @@ fn rejects_missing_check_references_and_ready_placeholders() {
81
56
  fn rejects_checks_without_explicit_last_verified_value() {
82
57
  let repo = TestRepo::new("verification-contract-last-verified");
83
58
  repo.write_testing_markdown(default_testing_markdown());
84
- repo.write_naome_json(
85
- "verification.json",
86
- json!({
87
- "schema": "naome.verification.v1",
88
- "version": 1,
89
- "status": "uninitialized",
90
- "lastUpdated": null,
91
- "checks": [
92
- {
93
- "id": "diff-check",
94
- "command": "git diff --check",
95
- "cwd": ".",
96
- "purpose": "Reject whitespace errors.",
97
- "cost": "fast",
98
- "source": "git",
99
- "evidence": []
100
- }
101
- ],
102
- "changeTypes": [],
103
- "releaseGates": []
104
- }),
105
- );
59
+ repo.write_naome_json("verification.json", check_missing_last_verified_fixture());
106
60
 
107
61
  let errors = validate_verification_contract(repo.path()).unwrap();
108
62
  let joined = errors.join("\n");
@@ -5,8 +5,7 @@ use std::fs;
5
5
  use naome_core::{
6
6
  refresh_integrity, summarize_command_output, verification_phase_plan, CommandCheckResult,
7
7
  };
8
- use serde_json::json;
9
- use workflow_support::{check, phase, WorkflowFixture};
8
+ use workflow_support::{phased_verification_fixture, WorkflowFixture};
10
9
 
11
10
  #[test]
12
11
  fn refresh_integrity_is_idempotent_and_repairs_manifest_hash() {
@@ -29,24 +28,7 @@ fn refresh_integrity_is_idempotent_and_repairs_manifest_hash() {
29
28
  #[test]
30
29
  fn failed_early_phase_withholds_expensive_recommendations() {
31
30
  let repo = WorkflowFixture::new("verification-phases");
32
- repo.write_verification(json!({
33
- "schema": "naome.verification.v1",
34
- "version": 1,
35
- "status": "ready",
36
- "lastUpdated": "2026-05-07",
37
- "checks": [
38
- check("naome-harness-health", "node .naome/bin/check-harness-health.js", "fast"),
39
- check("repository-quality-check", "node .naome/bin/naome.js quality check --changed", "fast"),
40
- check("package-dry-run", "npm run pack:dry-run", "medium")
41
- ],
42
- "phases": [
43
- phase("shape-health", 10, ["naome-harness-health"]),
44
- phase("quality", 20, ["repository-quality-check"]),
45
- phase("package-release", 50, ["package-dry-run"])
46
- ],
47
- "changeTypes": [],
48
- "releaseGates": []
49
- }));
31
+ repo.write_verification(phased_verification_fixture());
50
32
 
51
33
  let plan = verification_phase_plan(
52
34
  repo.path(),
@@ -80,17 +80,10 @@ impl WorkflowFixture {
80
80
  checks,
81
81
  git_text(&self.root, &["rev-parse", "HEAD"]),
82
82
  );
83
- self.write(
84
- ".naome/task-state.json",
85
- &pretty(json!({
86
- "schema": "naome.task-state.v2",
87
- "version": 2,
88
- "status": status,
89
- "activeTask": active_task,
90
- "blocker": null,
91
- "updatedAt": "2026-05-07T12:00:00.000Z"
92
- })),
93
- );
83
+ let mut task_state = task_state_template_fixture();
84
+ task_state["status"] = json!(status);
85
+ task_state["activeTask"] = active_task;
86
+ self.write(".naome/task-state.json", &pretty(task_state));
94
87
  }
95
88
 
96
89
  pub fn write_verification(&self, value: serde_json::Value) {
@@ -113,15 +106,32 @@ impl Drop for WorkflowFixture {
113
106
  }
114
107
 
115
108
  pub fn default_verification() -> serde_json::Value {
116
- json!({
117
- "schema": "naome.verification.v1",
118
- "version": 1,
119
- "status": "ready",
120
- "lastUpdated": "2026-05-07",
121
- "checks": [check("diff-check", "git diff --check", "fast")],
122
- "changeTypes": [],
123
- "releaseGates": []
124
- })
109
+ let mut value = verification_template_fixture();
110
+ value["checks"] = json!([check("diff-check", "git diff --check", "fast")]);
111
+ value
112
+ }
113
+
114
+ pub fn phased_verification_fixture() -> serde_json::Value {
115
+ let mut value = verification_template_fixture();
116
+ value["checks"] = json!([
117
+ check(
118
+ "naome-harness-health",
119
+ "node .naome/bin/check-harness-health.js",
120
+ "fast"
121
+ ),
122
+ check(
123
+ "repository-quality-check",
124
+ "node .naome/bin/naome.js quality check --changed",
125
+ "fast"
126
+ ),
127
+ check("package-dry-run", "npm run pack:dry-run", "medium")
128
+ ]);
129
+ value["phases"] = json!([
130
+ phase("shape-health", 10, ["naome-harness-health"]),
131
+ phase("quality", 20, ["repository-quality-check"]),
132
+ phase("package-release", 50, ["package-dry-run"])
133
+ ]);
134
+ value
125
135
  }
126
136
 
127
137
  pub fn check(id: &str, command: &str, cost: &str) -> serde_json::Value {
@@ -159,6 +169,35 @@ fn active_task_state(
159
169
  })
160
170
  }
161
171
 
172
+ fn task_state_template_fixture() -> serde_json::Value {
173
+ serde_json::from_str(
174
+ r#"{
175
+ "schema": "naome.task-state.v2",
176
+ "version": 2,
177
+ "status": null,
178
+ "activeTask": null,
179
+ "blocker": null,
180
+ "updatedAt": "2026-05-07T12:00:00.000Z"
181
+ }"#,
182
+ )
183
+ .unwrap()
184
+ }
185
+
186
+ fn verification_template_fixture() -> serde_json::Value {
187
+ serde_json::from_str(
188
+ r#"{
189
+ "schema": "naome.verification.v1",
190
+ "version": 1,
191
+ "status": "ready",
192
+ "lastUpdated": "2026-05-07",
193
+ "checks": [],
194
+ "changeTypes": [],
195
+ "releaseGates": []
196
+ }"#,
197
+ )
198
+ .unwrap()
199
+ }
200
+
162
201
  fn admission_record(git_head: String) -> serde_json::Value {
163
202
  json!({
164
203
  "command": "node .naome/bin/check-task-state.js --admission",
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lamentis/naome",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Native-first CLI for the NAOME agent harness.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",