@lamentis/naome 1.4.0 → 1.4.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.
Files changed (64) hide show
  1. package/Cargo.lock +2 -2
  2. package/README.md +17 -122
  3. package/crates/naome-cli/Cargo.toml +1 -1
  4. package/crates/naome-cli/src/main.rs +13 -0
  5. package/crates/naome-cli/src/task_commands/can_edit.rs +116 -0
  6. package/crates/naome-cli/src/task_commands/check_run/output.rs +34 -0
  7. package/crates/naome-cli/src/task_commands/check_run/receipts.rs +155 -0
  8. package/crates/naome-cli/src/task_commands/check_run/verification.rs +165 -0
  9. package/crates/naome-cli/src/task_commands/check_run.rs +192 -0
  10. package/crates/naome-cli/src/task_commands/common.rs +70 -0
  11. package/crates/naome-cli/src/task_commands/complete.rs +43 -0
  12. package/crates/naome-cli/src/task_commands/loop_control.rs +55 -0
  13. package/crates/naome-cli/src/task_commands/readiness.rs +44 -0
  14. package/crates/naome-cli/src/task_commands/record.rs +236 -0
  15. package/crates/naome-cli/src/task_commands/repair.rs +77 -0
  16. package/crates/naome-cli/src/task_commands/scope_request.rs +24 -0
  17. package/crates/naome-cli/src/task_commands/timeline.rs +71 -0
  18. package/crates/naome-cli/src/task_commands.rs +80 -1
  19. package/crates/naome-cli/tests/task_cli.rs +58 -0
  20. package/crates/naome-cli/tests/task_cli_agent_controls.rs +210 -0
  21. package/crates/naome-cli/tests/task_cli_control.rs +126 -0
  22. package/crates/naome-cli/tests/task_cli_loop.rs +383 -0
  23. package/crates/naome-cli/tests/task_cli_loop_edit.rs +144 -0
  24. package/crates/naome-cli/tests/task_cli_support/mod.rs +178 -0
  25. package/crates/naome-core/Cargo.toml +1 -1
  26. package/crates/naome-core/src/lib.rs +7 -2
  27. package/crates/naome-core/src/task_state/evidence_fingerprint.rs +47 -0
  28. package/crates/naome-core/src/task_state/mod.rs +12 -0
  29. package/crates/naome-core/src/task_state/status/agent_model.rs +76 -0
  30. package/crates/naome-core/src/task_state/status/control/action.rs +87 -0
  31. package/crates/naome-core/src/task_state/status/control/exit_code.rs +32 -0
  32. package/crates/naome-core/src/task_state/status/control/loop_state.rs +70 -0
  33. package/crates/naome-core/src/task_state/status/control/policy.rs +31 -0
  34. package/crates/naome-core/src/task_state/status/control/proof_recording.rs +25 -0
  35. package/crates/naome-core/src/task_state/status/control/recovery.rs +19 -0
  36. package/crates/naome-core/src/task_state/status/control/repair.rs +125 -0
  37. package/crates/naome-core/src/task_state/status/control/shared.rs +25 -0
  38. package/crates/naome-core/src/task_state/status/control.rs +16 -0
  39. package/crates/naome-core/src/task_state/status/git.rs +133 -0
  40. package/crates/naome-core/src/task_state/status/model.rs +152 -0
  41. package/crates/naome-core/src/task_state/status/proof.rs +217 -0
  42. package/crates/naome-core/src/task_state/status/proof_read.rs +164 -0
  43. package/crates/naome-core/src/task_state/status/report.rs +148 -0
  44. package/crates/naome-core/src/task_state/status/report_context.rs +148 -0
  45. package/crates/naome-core/src/task_state/status/report_support.rs +117 -0
  46. package/crates/naome-core/src/task_state/status/scope.rs +111 -0
  47. package/crates/naome-core/src/task_state/status/transition.rs +101 -0
  48. package/crates/naome-core/src/task_state/status.rs +23 -0
  49. package/crates/naome-core/src/task_state/status_output.rs +103 -0
  50. package/crates/naome-core/tests/task_state_support/mod.rs +15 -1
  51. package/crates/naome-core/tests/task_state_support/states.rs +4 -0
  52. package/crates/naome-core/tests/task_status.rs +423 -0
  53. package/crates/naome-core/tests/task_status_git.rs +141 -0
  54. package/installer/context.js +1 -1
  55. package/installer/harness-verification.js +2 -6
  56. package/installer/manifest-state.js +2 -2
  57. package/installer/native.js +3 -31
  58. package/native/darwin-arm64/naome +0 -0
  59. package/native/linux-x64/naome +0 -0
  60. package/package.json +1 -1
  61. package/templates/naome-root/.naome/bin/check-harness-health.js +2 -2
  62. package/templates/naome-root/.naome/bin/check-task-state.js +4 -39
  63. package/templates/naome-root/.naome/bin/naome.js +2 -30
  64. package/templates/naome-root/.naome/manifest.json +2 -2
@@ -0,0 +1,141 @@
1
+ #![allow(dead_code, unused_imports)]
2
+
3
+ use std::fs;
4
+
5
+ use naome_core::{task_status_exit_code, task_status_report};
6
+ use serde_json::json;
7
+
8
+ mod task_state_support;
9
+
10
+ use task_state_support::{active_task, task_state_with_status, TaskFixture};
11
+
12
+ #[test]
13
+ fn task_status_reports_git_recovery_findings() {
14
+ let repo = TaskFixture::new(task_state_with_status(
15
+ "implementing",
16
+ active_task(json!({
17
+ "allowedPaths": ["**"],
18
+ "requiredCheckIds": [],
19
+ "proofResults": []
20
+ })),
21
+ ));
22
+ repo.init_git();
23
+ repo.set_admission_head("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
24
+
25
+ let status = task_status_report(repo.path()).unwrap();
26
+
27
+ assert_eq!(status.git.admission_head_reachable, false);
28
+ assert!(status
29
+ .findings
30
+ .iter()
31
+ .any(|finding| finding.id == "task.git.admission_head_missing"));
32
+ }
33
+
34
+ #[test]
35
+ fn task_status_reports_unreachable_existing_admission_head() {
36
+ let repo = TaskFixture::new(task_state_with_status(
37
+ "implementing",
38
+ active_task(json!({})),
39
+ ));
40
+ repo.init_git();
41
+ let admission_head = repo.git(["rev-parse", "HEAD"]).trim().to_string();
42
+ repo.git(["checkout", "--orphan", "other"]);
43
+ repo.write("OTHER.md", "other\n");
44
+ repo.git(["add", "."]);
45
+ repo.git(["commit", "-m", "other"]);
46
+ repo.set_admission_head(&admission_head);
47
+
48
+ let status = task_status_report(repo.path()).unwrap();
49
+
50
+ assert!(status.findings.iter().any(|finding| {
51
+ finding.id == "task.git.admission_head_not_reachable"
52
+ && finding.suggested_fix.contains("Rebase")
53
+ }));
54
+ }
55
+
56
+ #[test]
57
+ fn task_status_reports_operation_in_progress_and_conflict_markers() {
58
+ let repo = TaskFixture::new(task_state_with_status(
59
+ "implementing",
60
+ active_task(json!({})),
61
+ ));
62
+ repo.init_git();
63
+ let merge_head = repo.git(["rev-parse", "--git-path", "MERGE_HEAD"]);
64
+ fs::write(repo.path().join(merge_head.trim()), "deadbeef\n").unwrap();
65
+
66
+ let status = task_status_report(repo.path()).unwrap();
67
+ assert!(status
68
+ .findings
69
+ .iter()
70
+ .any(|finding| finding.id == "task.git.operation_in_progress"));
71
+
72
+ fs::write(
73
+ repo.path().join(".naome/task-state.json"),
74
+ "<<<<<<< HEAD\n{}\n=======\n{}\n>>>>>>> branch\n",
75
+ )
76
+ .unwrap();
77
+ let status = task_status_report(repo.path()).unwrap();
78
+ assert!(status
79
+ .findings
80
+ .iter()
81
+ .any(|finding| finding.id == "task.state.conflict_markers"));
82
+ }
83
+
84
+ #[test]
85
+ fn task_status_reports_branch_divergence_when_upstream_split() {
86
+ let repo = TaskFixture::new(task_state_with_status(
87
+ "implementing",
88
+ active_task(json!({
89
+ "allowedPaths": ["**"],
90
+ "requiredCheckIds": [],
91
+ "proofResults": []
92
+ })),
93
+ ));
94
+ repo.init_git();
95
+ let remote = repo.path().join("remote.git");
96
+ let branch = repo.git(["rev-parse", "--abbrev-ref", "HEAD"]);
97
+ let branch = branch.trim();
98
+ repo.git(["init", "--bare", remote.to_str().unwrap()]);
99
+ repo.git(["remote", "add", "origin", remote.to_str().unwrap()]);
100
+ repo.git(["push", "-u", "origin", branch]);
101
+
102
+ repo.write("LOCAL.md", "local\n");
103
+ repo.git(["add", "."]);
104
+ repo.git(["commit", "-m", "local"]);
105
+
106
+ let clone = std::env::temp_dir().join(format!(
107
+ "naome-task-status-remote-work-{}",
108
+ std::process::id()
109
+ ));
110
+ let _ = fs::remove_dir_all(&clone);
111
+ repo.git(["clone", remote.to_str().unwrap(), clone.to_str().unwrap()]);
112
+ git_in(&clone, ["config", "user.email", "naome@example.com"]);
113
+ git_in(&clone, ["config", "user.name", "NAOME Test"]);
114
+ fs::write(clone.join("REMOTE.md"), "remote\n").unwrap();
115
+ git_in(&clone, ["add", "."]);
116
+ git_in(&clone, ["commit", "-m", "remote"]);
117
+ git_in(&clone, ["push"]);
118
+ repo.git(["fetch", "origin"]);
119
+
120
+ let status = task_status_report(repo.path()).unwrap();
121
+ assert_eq!(status.git.ahead, 1);
122
+ assert_eq!(status.git.behind, 1);
123
+ assert!(status
124
+ .findings
125
+ .iter()
126
+ .any(|finding| finding.id == "task.git.branch_diverged"));
127
+ assert_eq!(task_status_exit_code(&status.findings, &status.proof), 0);
128
+ }
129
+
130
+ fn git_in<const N: usize>(root: &std::path::Path, args: [&str; N]) {
131
+ let output = std::process::Command::new("git")
132
+ .args(args)
133
+ .current_dir(root)
134
+ .output()
135
+ .unwrap();
136
+ assert!(
137
+ output.status.success(),
138
+ "{}",
139
+ String::from_utf8_lossy(&output.stderr)
140
+ );
141
+ }
@@ -49,7 +49,7 @@ export function createInstallerContext() {
49
49
  normalizedIntegrityBlock:
50
50
  "const expectedMachineOwnedIntegrity = Object.freeze({\n __generated__: \"sha256:generated\"\n});\n",
51
51
  nativeIntegrityPattern:
52
- /^const expectedNativeBinaryIntegrity = "(?:sha256:[a-f0-9]{64}|sha256:generated)";\n/m,
52
+ /^const expectedNativeBinaryIntegrity = "sha256:[a-f0-9]{64}";\n/m,
53
53
  normalizedNativeIntegrity: 'const expectedNativeBinaryIntegrity = "sha256:generated";\n',
54
54
  executableMachineOwnedPaths: new Set([
55
55
  ".naome/bin/naome.js",
@@ -3,7 +3,6 @@ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, writeFile
3
3
  import { dirname, join } from "node:path";
4
4
 
5
5
  import { hasSymlinkInTargetPath, removeSkipped } from "./filesystem.js";
6
- import { findNativeDecisionBinary, usesSourceNativeFallback } from "./native.js";
7
6
  import { printCommandFailure, printError } from "./output.js";
8
7
 
9
8
  export function ensureBuiltInVerificationChecks(ctx) {
@@ -71,13 +70,10 @@ function ensureVerificationFileExists(ctx, relativePath, targetPath) {
71
70
  }
72
71
 
73
72
  function verificationSeederBinary(ctx) {
74
- const nativePath = usesSourceNativeFallback(ctx)
75
- ? findNativeDecisionBinary(ctx)
76
- : join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
73
+ const nativePath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
77
74
  if (
78
- !nativePath ||
79
75
  !existsSync(nativePath) ||
80
- (!usesSourceNativeFallback(ctx) && hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath)) ||
76
+ hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath) ||
81
77
  !lstatSync(nativePath).isFile()
82
78
  ) {
83
79
  printError(ctx, "NAOME native decision binary is unavailable for verification seeding.");
@@ -2,7 +2,7 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from "n
2
2
  import { dirname, join } from "node:path";
3
3
 
4
4
  import { hasSymlinkInTargetPath } from "./filesystem.js";
5
- import { installedMachineOwnedIntegrity, installedNativeBinaryHash, usesSourceNativeFallback } from "./native.js";
5
+ import { installedMachineOwnedIntegrity, installedNativeBinaryHash } from "./native.js";
6
6
  import { printError } from "./output.js";
7
7
  import { isVersion } from "./version.js";
8
8
 
@@ -121,7 +121,7 @@ function applyManifestHealthMetadata(ctx, manifest) {
121
121
  manifest.integrity = installedMachineOwnedIntegrity(ctx);
122
122
 
123
123
  const nativeHash = installedNativeBinaryHash(ctx);
124
- if (!usesSourceNativeFallback(ctx) && nativeHash) {
124
+ if (nativeHash) {
125
125
  if (!manifest.machineOwned.includes(ctx.nativeBinaryRelativePath)) {
126
126
  manifest.machineOwned.push(ctx.nativeBinaryRelativePath);
127
127
  }
@@ -6,7 +6,6 @@ import {
6
6
  lstatSync,
7
7
  mkdirSync,
8
8
  readFileSync,
9
- unlinkSync,
10
9
  writeFileSync,
11
10
  } from "node:fs";
12
11
  import { dirname, join, resolve } from "node:path";
@@ -32,12 +31,6 @@ export function installNativeDecisionBinary(ctx) {
32
31
  process.exit(1);
33
32
  }
34
33
 
35
- if (usesSourceNativeFallback(ctx)) {
36
- removeInstalledNativeDecisionBinary(ctx);
37
- patchInstalledNativeIntegrity(ctx, "sha256:generated");
38
- return;
39
- }
40
-
41
34
  mkdirSync(dirname(targetPath), { recursive: true });
42
35
  const sourceHash = sha256(readFileSync(sourcePath));
43
36
  const targetHash =
@@ -93,11 +86,6 @@ export function patchInstalledMachineOwnedIntegrity(ctx) {
93
86
  }
94
87
  }
95
88
 
96
- export function usesSourceNativeFallback(ctx) {
97
- return existsSync(join(ctx.targetRoot, "packages", "naome", "Cargo.toml"))
98
- && existsSync(join(ctx.targetRoot, "packages", "naome", "crates", "naome-cli", "src", "main.rs"));
99
- }
100
-
101
89
  export function installedNativeBinaryHash(ctx) {
102
90
  const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
103
91
  if (
@@ -111,23 +99,6 @@ export function installedNativeBinaryHash(ctx) {
111
99
  return sha256(readFileSync(targetPath));
112
100
  }
113
101
 
114
- function removeInstalledNativeDecisionBinary(ctx) {
115
- const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
116
- if (!existsSync(targetPath)) {
117
- ctx.skipped.push(ctx.nativeBinaryRelativePath);
118
- return;
119
- }
120
-
121
- if (hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath) || !lstatSync(targetPath).isFile()) {
122
- ctx.skipped.push(ctx.nativeBinaryRelativePath);
123
- ctx.unsafeSkipped.push(ctx.nativeBinaryRelativePath);
124
- return;
125
- }
126
-
127
- unlinkSync(targetPath);
128
- ctx.updated.push(ctx.nativeBinaryRelativePath);
129
- }
130
-
131
102
  export function templateIntegrity(ctx) {
132
103
  const integrity = {};
133
104
 
@@ -143,7 +114,7 @@ export function installedMachineOwnedIntegrity(ctx) {
143
114
  const integrity = templateIntegrity(ctx);
144
115
  const nativeHash = installedNativeBinaryHash(ctx);
145
116
 
146
- if (!usesSourceNativeFallback(ctx) && nativeHash) {
117
+ if (nativeHash) {
147
118
  integrity[ctx.nativeBinaryRelativePath] = `sha256:${nativeHash}`;
148
119
  }
149
120
 
@@ -181,6 +152,7 @@ export function hasGeneratedNativeIntegrity(ctx, relativePath) {
181
152
  }
182
153
 
183
154
  function patchInstalledNativeIntegrity(ctx, expectedIntegrity) {
155
+ const nativeIntegrityPatchPattern = /^const expectedNativeBinaryIntegrity = "(?:sha256:[a-f0-9]{64}|sha256:generated)";\n/m;
184
156
  const nativeIntegrityPaths = [
185
157
  ctx.healthCheckerRelativePath,
186
158
  ctx.taskStateCheckerRelativePath,
@@ -195,7 +167,7 @@ function patchInstalledNativeIntegrity(ctx, expectedIntegrity) {
195
167
 
196
168
  const content = readFileSync(targetPath, "utf8");
197
169
  const nextContent = content.replace(
198
- ctx.nativeIntegrityPattern,
170
+ nativeIntegrityPatchPattern,
199
171
  `const expectedNativeBinaryIntegrity = "${expectedIntegrity}";\n`,
200
172
  );
201
173
 
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lamentis/naome",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Native-first CLI for the NAOME agent harness.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,8 +11,8 @@ const expectedNativeBinaryIntegrity = "sha256:generated";
11
11
 
12
12
  const expectedMachineOwnedIntegrity = Object.freeze({
13
13
  ".naome/bin/check-harness-health.js": "sha256:802d7419774981a6af1826b3882270ff8f41259d516f98c52a02b4ddc184c467",
14
- ".naome/bin/check-task-state.js": "sha256:2612577b7e4ab45d9d39dd5ac54c8e7ed749d237d78f1a8d252f4dfa0b4eaaab",
15
- ".naome/bin/naome.js": "sha256:f129c580fb70b3a1d92d0ab0de9fa6c131b2fc51a8dcdebe9d6f5a812a3be61b",
14
+ ".naome/bin/check-task-state.js": "sha256:d1c12ba6d8a0ffc3fd28c6900b675c4bbc9c54b6bd287d219f6e9104bfb9621e",
15
+ ".naome/bin/naome.js": "sha256:8a9d9ed783981ef9750021fa30e92460283775bb4a0eacdea60b63041a9c6a05",
16
16
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
17
17
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
18
18
  "AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",
@@ -11,8 +11,8 @@ const expectedNativeBinaryIntegrity = "sha256:generated";
11
11
 
12
12
  const expectedMachineOwnedIntegrity = Object.freeze({
13
13
  ".naome/bin/check-harness-health.js": "sha256:802d7419774981a6af1826b3882270ff8f41259d516f98c52a02b4ddc184c467",
14
- ".naome/bin/check-task-state.js": "sha256:2612577b7e4ab45d9d39dd5ac54c8e7ed749d237d78f1a8d252f4dfa0b4eaaab",
15
- ".naome/bin/naome.js": "sha256:f129c580fb70b3a1d92d0ab0de9fa6c131b2fc51a8dcdebe9d6f5a812a3be61b",
14
+ ".naome/bin/check-task-state.js": "sha256:d1c12ba6d8a0ffc3fd28c6900b675c4bbc9c54b6bd287d219f6e9104bfb9621e",
15
+ ".naome/bin/naome.js": "sha256:8a9d9ed783981ef9750021fa30e92460283775bb4a0eacdea60b63041a9c6a05",
16
16
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
17
17
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
18
18
  "AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",
@@ -67,9 +67,7 @@ function resolveNativeDecisionBinary(root) {
67
67
  const expectedIntegrity = expectedNativeIntegrity();
68
68
  const candidates = [
69
69
  process.env.NAOME_NATIVE_BIN,
70
- join(root, nativeBinaryRelativePath),
71
- join(root, "packages", "naome", "target", "release", nativeBinaryName),
72
- join(root, "packages", "naome", "target", "debug", nativeBinaryName)
70
+ expectedIntegrity && join(root, nativeBinaryRelativePath)
73
71
  ].filter(Boolean);
74
72
 
75
73
  if (expectedIntegrity) {
@@ -82,12 +80,7 @@ function resolveNativeDecisionBinary(root) {
82
80
  fail(`No runnable NAOME native task-state binary matched ${expectedIntegrity}. Run naome sync again.`);
83
81
  }
84
82
 
85
- const built = buildSourceNativeBinary(root);
86
- if (built && isUsableNativeBinary(built, root, null)) {
87
- return built;
88
- }
89
-
90
- fail("NAOME native task-state binary is missing or incompatible. Run naome sync again.");
83
+ fail("NAOME native task-state binary is missing trusted integrity. Run naome sync again.");
91
84
  }
92
85
 
93
86
  function expectedNativeIntegrity() {
@@ -118,34 +111,6 @@ function isUsableNativeBinary(candidate, root, expectedIntegrity) {
118
111
  return !probe.error && probe.status !== null;
119
112
  }
120
113
 
121
- function buildSourceNativeBinary(root) {
122
- if (expectedNativeBinaryIntegrity !== "sha256:generated") {
123
- return null;
124
- }
125
-
126
- const packageRoot = join(root, "packages", "naome");
127
- const manifestPath = join(packageRoot, "Cargo.toml");
128
- if (!existsSync(manifestPath)) {
129
- return null;
130
- }
131
-
132
- const result = spawnSync(
133
- "cargo",
134
- ["build", "--release", "--manifest-path", manifestPath, "-p", "naome-cli"],
135
- {
136
- cwd: root,
137
- encoding: "utf8",
138
- stdio: "ignore"
139
- }
140
- );
141
- if (result.status !== 0) {
142
- return null;
143
- }
144
-
145
- const builtPath = join(packageRoot, "target", "release", nativeBinaryName);
146
- return existsSync(builtPath) ? builtPath : null;
147
- }
148
-
149
114
  function findHarnessRoot(startPath) {
150
115
  let current = resolve(startPath);
151
116
 
@@ -66,9 +66,7 @@ function spawnNative(root, args, options = {}) {
66
66
  function resolveNativeDecisionBinary(root) {
67
67
  const candidates = [
68
68
  process.env.NAOME_NATIVE_BIN,
69
- join(root, nativeBinaryRelativePath),
70
- join(root, "packages", "naome", "target", "release", nativeBinaryName),
71
- join(root, "packages", "naome", "target", "debug", nativeBinaryName)
69
+ expectedNativeBinaryIntegrity !== "sha256:generated" && join(root, nativeBinaryRelativePath)
72
70
  ].filter(Boolean);
73
71
 
74
72
  for (const candidate of candidates) {
@@ -77,11 +75,6 @@ function resolveNativeDecisionBinary(root) {
77
75
  }
78
76
  }
79
77
 
80
- const built = buildSourceNativeBinary(root);
81
- if (built && isUsableNativeBinary(built, root)) {
82
- return built;
83
- }
84
-
85
78
  fail("NAOME native decision binary is missing or incompatible. Run naome sync again, or set NAOME_NATIVE_BIN to a built naome binary.");
86
79
  }
87
80
 
@@ -91,7 +84,7 @@ function isUsableNativeBinary(candidate, root) {
91
84
  }
92
85
 
93
86
  if (expectedNativeBinaryIntegrity === "sha256:generated") {
94
- return isRunnableNativeBinary(candidate, root);
87
+ return candidate === process.env.NAOME_NATIVE_BIN && isRunnableNativeBinary(candidate, root);
95
88
  }
96
89
 
97
90
  const actual = `sha256:${createHash("sha256").update(readFileSync(candidate)).digest("hex")}`;
@@ -111,27 +104,6 @@ function isRunnableNativeBinary(candidate, root) {
111
104
  return !probe.error && probe.status !== null;
112
105
  }
113
106
 
114
- function buildSourceNativeBinary(root) {
115
- if (expectedNativeBinaryIntegrity !== "sha256:generated") {
116
- return null;
117
- }
118
-
119
- const sourcePath = (...parts) => join(root, "packages", "naome", ...parts);
120
- const manifestPath = sourcePath("Cargo.toml");
121
- if (!existsSync(manifestPath)) {
122
- return null;
123
- }
124
-
125
- const buildArgs = ["build", "--release", "--manifest-path", manifestPath, "-p", "naome-cli"];
126
- const result = spawnSync("cargo", buildArgs, { cwd: root, encoding: "utf8", stdio: "ignore" });
127
- if (result.status !== 0) {
128
- return null;
129
- }
130
-
131
- const builtPath = sourcePath("target", "release", nativeBinaryName);
132
- return existsSync(builtPath) ? builtPath : null;
133
- }
134
-
135
107
  function commit(args) {
136
108
  const root = findHarnessRoot(process.cwd());
137
109
  if (!root) {
@@ -3,8 +3,8 @@
3
3
  "installedAt": null,
4
4
  "integrity": {
5
5
  ".naome/bin/check-harness-health.js": "sha256:802d7419774981a6af1826b3882270ff8f41259d516f98c52a02b4ddc184c467",
6
- ".naome/bin/check-task-state.js": "sha256:2612577b7e4ab45d9d39dd5ac54c8e7ed749d237d78f1a8d252f4dfa0b4eaaab",
7
- ".naome/bin/naome.js": "sha256:f129c580fb70b3a1d92d0ab0de9fa6c131b2fc51a8dcdebe9d6f5a812a3be61b",
6
+ ".naome/bin/check-task-state.js": "sha256:d1c12ba6d8a0ffc3fd28c6900b675c4bbc9c54b6bd287d219f6e9104bfb9621e",
7
+ ".naome/bin/naome.js": "sha256:8a9d9ed783981ef9750021fa30e92460283775bb4a0eacdea60b63041a9c6a05",
8
8
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
9
9
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
10
10
  "AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",