@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 +2 -2
- package/crates/naome-cli/Cargo.toml +1 -1
- package/crates/naome-core/Cargo.toml +1 -1
- package/crates/naome-core/src/intent/resolver_catalog/active.rs +38 -0
- package/crates/naome-core/src/intent/resolver_catalog/baseline.rs +44 -0
- package/crates/naome-core/src/intent/resolver_catalog/completed.rs +56 -0
- package/crates/naome-core/src/intent/resolver_catalog/dirty.rs +32 -0
- package/crates/naome-core/src/intent/resolver_catalog/ready.rs +32 -0
- package/crates/naome-core/src/intent/resolver_catalog/system.rs +20 -0
- package/crates/naome-core/src/intent/resolver_catalog.rs +12 -166
- package/crates/naome-core/tests/harness_health.rs +29 -40
- package/crates/naome-core/tests/repo_support/mod.rs +3 -1
- package/crates/naome-core/tests/repo_support/verification_values.rs +93 -1
- package/crates/naome-core/tests/task_state.rs +6 -14
- package/crates/naome-core/tests/task_state_support/mod.rs +2 -1
- package/crates/naome-core/tests/task_state_support/states.rs +28 -11
- package/crates/naome-core/tests/verification.rs +2 -20
- package/crates/naome-core/tests/verification_contract.rs +6 -52
- package/crates/naome-core/tests/workflow_integrity.rs +2 -20
- package/crates/naome-core/tests/workflow_support/mod.rs +59 -20
- package/native/darwin-arm64/naome +0 -0
- package/native/linux-x64/naome +0 -0
- package/package.json +1 -1
package/Cargo.lock
CHANGED
|
@@ -76,7 +76,7 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
|
76
76
|
|
|
77
77
|
[[package]]
|
|
78
78
|
name = "naome-cli"
|
|
79
|
-
version = "1.3.
|
|
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.
|
|
87
|
+
version = "1.3.2"
|
|
88
88
|
dependencies = [
|
|
89
89
|
"serde",
|
|
90
90
|
"serde_json",
|
|
@@ -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
|
-
|
|
1
|
+
mod active;
|
|
2
|
+
mod baseline;
|
|
3
|
+
mod completed;
|
|
4
|
+
mod dirty;
|
|
5
|
+
mod ready;
|
|
6
|
+
mod system;
|
|
2
7
|
|
|
3
|
-
pub(crate)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
&
|
|
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
|
-
&
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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,
|
|
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
|
-
|
|
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":
|
|
19
|
-
"activeTask": active_task
|
|
19
|
+
"status": status,
|
|
20
|
+
"activeTask": active_task,
|
|
20
21
|
"blocker": null,
|
|
21
|
-
"updatedAt":
|
|
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::{
|
|
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::{
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
package/native/linux-x64/naome
CHANGED
|
Binary file
|