@lamentis/naome 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/Cargo.lock +2 -2
  2. package/README.md +108 -47
  3. package/bin/naome-node.js +2 -1579
  4. package/bin/naome.js +34 -5
  5. package/crates/naome-cli/Cargo.toml +1 -1
  6. package/crates/naome-cli/src/dispatcher.rs +7 -2
  7. package/crates/naome-cli/src/main.rs +37 -22
  8. package/crates/naome-cli/src/quality_commands.rs +317 -10
  9. package/crates/naome-cli/src/workflow_commands.rs +21 -1
  10. package/crates/naome-core/Cargo.toml +1 -1
  11. package/crates/naome-core/src/decision/checks.rs +64 -0
  12. package/crates/naome-core/src/decision/idle.rs +67 -0
  13. package/crates/naome-core/src/decision/json.rs +36 -0
  14. package/crates/naome-core/src/decision/states.rs +165 -0
  15. package/crates/naome-core/src/decision.rs +131 -353
  16. package/crates/naome-core/src/git.rs +4 -2
  17. package/crates/naome-core/src/install_plan.rs +4 -0
  18. package/crates/naome-core/src/lib.rs +12 -6
  19. package/crates/naome-core/src/paths.rs +3 -1
  20. package/crates/naome-core/src/quality/adapter_support.rs +89 -0
  21. package/crates/naome-core/src/quality/adapters.rs +20 -67
  22. package/crates/naome-core/src/quality/baseline.rs +8 -0
  23. package/crates/naome-core/src/quality/cache.rs +153 -0
  24. package/crates/naome-core/src/quality/checks/duplicate_blocks.rs +25 -11
  25. package/crates/naome-core/src/quality/checks/near_duplicates.rs +4 -2
  26. package/crates/naome-core/src/quality/checks.rs +7 -8
  27. package/crates/naome-core/src/quality/cleanup.rs +48 -3
  28. package/crates/naome-core/src/quality/config.rs +8 -15
  29. package/crates/naome-core/src/quality/config_support.rs +24 -0
  30. package/crates/naome-core/src/quality/mod.rs +72 -6
  31. package/crates/naome-core/src/quality/scanner/analysis/normalize.rs +78 -0
  32. package/crates/naome-core/src/quality/scanner/analysis.rs +160 -0
  33. package/crates/naome-core/src/quality/scanner/repo_paths.rs +39 -3
  34. package/crates/naome-core/src/quality/scanner.rs +200 -215
  35. package/crates/naome-core/src/quality/semantic/checks.rs +134 -0
  36. package/crates/naome-core/src/quality/semantic/extract.rs +158 -0
  37. package/crates/naome-core/src/quality/semantic/model.rs +85 -0
  38. package/crates/naome-core/src/quality/semantic/route.rs +52 -0
  39. package/crates/naome-core/src/quality/semantic.rs +68 -0
  40. package/crates/naome-core/src/quality/structure/adapters.rs +84 -0
  41. package/crates/naome-core/src/quality/structure/checks/basic.rs +153 -0
  42. package/crates/naome-core/src/quality/structure/checks/directory.rs +134 -0
  43. package/crates/naome-core/src/quality/structure/checks/pairing.rs +63 -0
  44. package/crates/naome-core/src/quality/structure/checks.rs +124 -0
  45. package/crates/naome-core/src/quality/structure/classify/roles.rs +188 -0
  46. package/crates/naome-core/src/quality/structure/classify.rs +146 -0
  47. package/crates/naome-core/src/quality/structure/config.rs +89 -0
  48. package/crates/naome-core/src/quality/structure/defaults.rs +107 -0
  49. package/crates/naome-core/src/quality/structure/mod.rs +77 -0
  50. package/crates/naome-core/src/quality/structure/model.rs +131 -0
  51. package/crates/naome-core/src/quality/types.rs +43 -2
  52. package/crates/naome-core/src/route/builtin_checks.rs +141 -0
  53. package/crates/naome-core/src/route/builtin_context.rs +73 -0
  54. package/crates/naome-core/src/route/builtin_integrity.rs +49 -0
  55. package/crates/naome-core/src/route/builtin_require.rs +40 -0
  56. package/crates/naome-core/src/route/context.rs +180 -0
  57. package/crates/naome-core/src/route/execution.rs +96 -0
  58. package/crates/naome-core/src/route/execution_baselines.rs +146 -0
  59. package/crates/naome-core/src/route/execution_support.rs +57 -0
  60. package/crates/naome-core/src/route/execution_tasks.rs +71 -0
  61. package/crates/naome-core/src/route/git_ops.rs +72 -0
  62. package/crates/naome-core/src/route/quality_gate.rs +73 -0
  63. package/crates/naome-core/src/route/quality_gate_config.rs +126 -0
  64. package/crates/naome-core/src/route/quality_gate_snapshot.rs +69 -0
  65. package/crates/naome-core/src/route/worktree.rs +75 -0
  66. package/crates/naome-core/src/route/worktree_files.rs +32 -0
  67. package/crates/naome-core/src/route/worktree_plan.rs +131 -0
  68. package/crates/naome-core/src/route.rs +44 -1217
  69. package/crates/naome-core/src/verification.rs +1 -0
  70. package/crates/naome-core/src/workflow/doctor.rs +144 -0
  71. package/crates/naome-core/src/workflow/mod.rs +2 -0
  72. package/crates/naome-core/src/workflow/mutation.rs +1 -2
  73. package/crates/naome-core/tests/decision.rs +24 -118
  74. package/crates/naome-core/tests/harness_health.rs +2 -0
  75. package/crates/naome-core/tests/install_plan.rs +2 -0
  76. package/crates/naome-core/tests/quality.rs +26 -123
  77. package/crates/naome-core/tests/quality_performance.rs +231 -0
  78. package/crates/naome-core/tests/quality_structure.rs +116 -0
  79. package/crates/naome-core/tests/quality_structure_adapters.rs +98 -0
  80. package/crates/naome-core/tests/quality_structure_policy.rs +144 -0
  81. package/crates/naome-core/tests/quality_structure_support/mod.rs +249 -0
  82. package/crates/naome-core/tests/repo_support/mod.rs +16 -0
  83. package/crates/naome-core/tests/repo_support/repo.rs +113 -0
  84. package/crates/naome-core/tests/repo_support/repo_factories.rs +99 -0
  85. package/crates/naome-core/tests/repo_support/repo_helpers.rs +123 -0
  86. package/crates/naome-core/tests/repo_support/routes.rs +81 -0
  87. package/crates/naome-core/tests/repo_support/verification.rs +168 -0
  88. package/crates/naome-core/tests/repo_support/verification_values.rs +135 -0
  89. package/crates/naome-core/tests/route.rs +1 -1376
  90. package/crates/naome-core/tests/route_baseline.rs +86 -0
  91. package/crates/naome-core/tests/route_completion.rs +141 -0
  92. package/crates/naome-core/tests/route_harness_refresh.rs +135 -0
  93. package/crates/naome-core/tests/route_user_diff.rs +202 -0
  94. package/crates/naome-core/tests/route_worktree.rs +54 -0
  95. package/crates/naome-core/tests/semantic_legacy.rs +140 -0
  96. package/crates/naome-core/tests/task_state.rs +60 -432
  97. package/crates/naome-core/tests/task_state_compact_support/repo.rs +1 -1
  98. package/crates/naome-core/tests/task_state_support/mod.rs +163 -0
  99. package/crates/naome-core/tests/task_state_support/states.rs +84 -0
  100. package/crates/naome-core/tests/verification.rs +4 -45
  101. package/crates/naome-core/tests/verification_contract.rs +22 -78
  102. package/crates/naome-core/tests/workflow_doctor.rs +24 -0
  103. package/crates/naome-core/tests/workflow_policy.rs +6 -1
  104. package/crates/naome-core/tests/workflow_support/mod.rs +1 -1
  105. package/installer/agents.js +90 -0
  106. package/installer/context.js +67 -0
  107. package/installer/filesystem.js +166 -0
  108. package/installer/flows.js +84 -0
  109. package/installer/git-boundary.js +171 -0
  110. package/installer/git-hook-content.js +36 -0
  111. package/installer/git-hooks.js +134 -0
  112. package/installer/git-local.js +2 -0
  113. package/installer/git-shared.js +35 -0
  114. package/installer/harness-file-ops.js +140 -0
  115. package/installer/harness-files.js +56 -0
  116. package/installer/harness-verification.js +123 -0
  117. package/installer/install-plan.js +66 -0
  118. package/installer/main.js +25 -0
  119. package/installer/manifest-state.js +167 -0
  120. package/installer/native-build.js +24 -0
  121. package/installer/native-format.js +6 -0
  122. package/installer/native.js +162 -0
  123. package/installer/output.js +131 -0
  124. package/installer/version.js +32 -0
  125. package/native/darwin-arm64/naome +0 -0
  126. package/native/linux-x64/naome +0 -0
  127. package/package.json +2 -1
  128. package/templates/naome-root/.naome/bin/check-harness-health.js +3 -3
  129. package/templates/naome-root/.naome/bin/check-task-state.js +3 -3
  130. package/templates/naome-root/.naome/bin/naome.js +32 -21
  131. package/templates/naome-root/.naome/manifest.json +5 -3
  132. package/templates/naome-root/.naome/repository-structure.json +90 -0
  133. package/templates/naome-root/.naome/verification.json +1 -0
  134. package/templates/naome-root/.naomeignore +1 -0
  135. package/templates/naome-root/docs/naome/agent-workflow.md +16 -14
  136. package/templates/naome-root/docs/naome/index.md +4 -3
  137. package/templates/naome-root/docs/naome/repository-quality.md +66 -4
  138. package/templates/naome-root/docs/naome/repository-structure.md +51 -0
  139. package/templates/naome-root/docs/naome/testing.md +2 -1
@@ -0,0 +1,162 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ chmodSync,
4
+ copyFileSync,
5
+ existsSync,
6
+ lstatSync,
7
+ mkdirSync,
8
+ readFileSync,
9
+ writeFileSync,
10
+ } from "node:fs";
11
+ import { dirname, join, resolve } from "node:path";
12
+
13
+ import { hasSymlinkInTargetPath } from "./filesystem.js";
14
+ import { buildNativeDecisionBinary } from "./native-build.js";
15
+ import { formatExpectedIntegrityBlock } from "./native-format.js";
16
+ import { printError } from "./output.js";
17
+
18
+ export function installNativeDecisionBinary(ctx) {
19
+ const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
20
+
21
+ if (hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath)) {
22
+ ctx.skipped.push(ctx.nativeBinaryRelativePath);
23
+ ctx.unsafeSkipped.push(ctx.nativeBinaryRelativePath);
24
+ return;
25
+ }
26
+
27
+ const sourcePath = findNativeDecisionBinary(ctx);
28
+ if (!sourcePath) {
29
+ printError(ctx, "NAOME native decision binary is unavailable.");
30
+ console.error("Install Cargo or provide NAOME_NATIVE_BIN with a built naome binary, then rerun naome sync.");
31
+ process.exit(1);
32
+ }
33
+
34
+ if (usesSourceNativeFallback(ctx)) {
35
+ patchNaomeCommandNativeIntegrity(ctx, "sha256:generated");
36
+ ctx.skipped.push(ctx.nativeBinaryRelativePath);
37
+ return;
38
+ }
39
+
40
+ mkdirSync(dirname(targetPath), { recursive: true });
41
+ const sourceHash = sha256(readFileSync(sourcePath));
42
+ const targetHash =
43
+ existsSync(targetPath) && lstatSync(targetPath).isFile()
44
+ ? sha256(readFileSync(targetPath))
45
+ : null;
46
+
47
+ if (sourceHash !== targetHash) {
48
+ copyFileSync(sourcePath, targetPath);
49
+ ctx.updated.push(ctx.nativeBinaryRelativePath);
50
+ } else {
51
+ ctx.skipped.push(ctx.nativeBinaryRelativePath);
52
+ }
53
+
54
+ chmodSync(targetPath, 0o755);
55
+ patchNaomeCommandNativeIntegrity(ctx, `sha256:${sourceHash}`);
56
+ }
57
+
58
+ export function findNativeDecisionBinary(ctx) {
59
+ const candidates = [];
60
+
61
+ if (process.env.NAOME_NATIVE_BIN) {
62
+ candidates.push(resolve(ctx.targetRoot, process.env.NAOME_NATIVE_BIN));
63
+ }
64
+
65
+ candidates.push(join(ctx.packageRoot, "native", `${process.platform}-${process.arch}`, ctx.nativeBinaryName));
66
+ candidates.push(join(ctx.packageRoot, "target", "release", ctx.nativeBinaryName));
67
+
68
+ for (const candidate of candidates) {
69
+ if (existsSync(candidate) && lstatSync(candidate).isFile()) {
70
+ return candidate;
71
+ }
72
+ }
73
+
74
+ return buildNativeDecisionBinary(ctx);
75
+ }
76
+
77
+ export function patchInstalledMachineOwnedIntegrity(ctx) {
78
+ const integrityBlock = formatExpectedIntegrityBlock(templateIntegrity(ctx));
79
+
80
+ for (const relativePath of [ctx.healthCheckerRelativePath, ctx.taskStateCheckerRelativePath]) {
81
+ const targetPath = join(ctx.targetRoot, relativePath);
82
+ if (!existsSync(targetPath) || hasSymlinkInTargetPath(ctx, relativePath)) {
83
+ continue;
84
+ }
85
+
86
+ const content = readFileSync(targetPath, "utf8");
87
+ const nextContent = content.replace(ctx.integrityBlockPattern, integrityBlock);
88
+ if (nextContent !== content) {
89
+ writeFileSync(targetPath, nextContent);
90
+ ctx.updated.push(relativePath);
91
+ }
92
+ }
93
+ }
94
+
95
+ export function usesSourceNativeFallback(ctx) {
96
+ return existsSync(join(ctx.targetRoot, "packages", "naome", "Cargo.toml"))
97
+ && existsSync(join(ctx.targetRoot, "packages", "naome", "crates", "naome-cli", "src", "main.rs"));
98
+ }
99
+
100
+ export function installedNativeBinaryHash(ctx) {
101
+ const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
102
+ if (
103
+ !existsSync(targetPath) ||
104
+ hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath) ||
105
+ !lstatSync(targetPath).isFile()
106
+ ) {
107
+ return null;
108
+ }
109
+
110
+ return sha256(readFileSync(targetPath));
111
+ }
112
+
113
+ export function templateIntegrity(ctx) {
114
+ const integrity = {};
115
+
116
+ for (const relativePath of ctx.machineOwnedPaths) {
117
+ const sourcePath = join(ctx.templateRoot, relativePath);
118
+ integrity[relativePath] = `sha256:${machineFileHash(ctx, relativePath, readFileSync(sourcePath))}`;
119
+ }
120
+
121
+ return integrity;
122
+ }
123
+
124
+ export function sha256(content) {
125
+ return createHash("sha256").update(content).digest("hex");
126
+ }
127
+
128
+ export function machineFileHash(ctx, relativePath, content) {
129
+ let normalized = content;
130
+
131
+ if (hasGeneratedIntegrity(ctx, relativePath)) {
132
+ normalized = normalized.toString("utf8").replace(ctx.integrityBlockPattern, ctx.normalizedIntegrityBlock);
133
+ }
134
+
135
+ if (relativePath === ctx.naomeCommandRelativePath) {
136
+ normalized = normalized.toString("utf8").replace(ctx.nativeIntegrityPattern, ctx.normalizedNativeIntegrity);
137
+ }
138
+
139
+ return sha256(normalized);
140
+ }
141
+
142
+ export function hasGeneratedIntegrity(ctx, relativePath) {
143
+ return relativePath === ctx.healthCheckerRelativePath || relativePath === ctx.taskStateCheckerRelativePath;
144
+ }
145
+
146
+ function patchNaomeCommandNativeIntegrity(ctx, expectedIntegrity) {
147
+ const commandPath = join(ctx.targetRoot, ctx.naomeCommandRelativePath);
148
+ if (!existsSync(commandPath) || hasSymlinkInTargetPath(ctx, ctx.naomeCommandRelativePath)) {
149
+ return;
150
+ }
151
+
152
+ const content = readFileSync(commandPath, "utf8");
153
+ const nextContent = content.replace(
154
+ ctx.nativeIntegrityPattern,
155
+ `const expectedNativeBinaryIntegrity = "${expectedIntegrity}";\n`,
156
+ );
157
+
158
+ if (nextContent !== content) {
159
+ writeFileSync(commandPath, nextContent);
160
+ ctx.updated.push(ctx.naomeCommandRelativePath);
161
+ }
162
+ }
@@ -0,0 +1,131 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ export function printHeader(ctx) {
5
+ console.log("");
6
+ console.log(`${ctx.color.bold("NAOME")} ${ctx.color.dim(`v${ctx.packageVersion}`)}`);
7
+ console.log(ctx.color.dim("AI coding-agent harness installer"));
8
+ console.log("");
9
+ console.log(`${ctx.color.dim("target ")} ${ctx.targetRoot}`);
10
+ }
11
+
12
+ export function printSection(ctx, title) {
13
+ console.log("");
14
+ console.log(ctx.color.bold(title));
15
+ }
16
+
17
+ export function printList(ctx, items, marker) {
18
+ for (const item of uniqueStrings(items)) {
19
+ console.log(`${ctx.color.dim(marker)} ${item}`);
20
+ }
21
+ }
22
+
23
+ export function uniqueStrings(items) {
24
+ return Array.from(new Set(items));
25
+ }
26
+
27
+ export function printError(ctx, message) {
28
+ console.error("");
29
+ console.error(`${ctx.color.red("x")} ${message}`);
30
+ }
31
+
32
+ export function printCancelled(ctx, message) {
33
+ console.log("");
34
+ console.log(`${ctx.color.yellow("-")} ${message}`);
35
+ }
36
+
37
+ export function printCommandFailure(ctx, message, result) {
38
+ printError(ctx, message);
39
+ if (result.stdout.trim()) {
40
+ console.error(result.stdout.trim());
41
+ }
42
+ if (result.stderr.trim()) {
43
+ console.error(result.stderr.trim());
44
+ }
45
+ process.exit(1);
46
+ }
47
+
48
+ export function printSummary(ctx, existingInstall) {
49
+ console.log("");
50
+ console.log(`${ctx.color.green("+")} ${ctx.summaryTitle}`);
51
+
52
+ const detailedOutput = shouldPrintDetailedSummary(ctx, existingInstall);
53
+ if (!detailedOutput) {
54
+ printCompactSummary(ctx);
55
+ }
56
+
57
+ printDetailedSummary(ctx, detailedOutput);
58
+ if (ctx.unsafeSkipped.length > 0) {
59
+ printSection(ctx, "Skipped unsafe symlinked paths");
60
+ printList(ctx, ctx.unsafeSkipped, "!");
61
+ }
62
+
63
+ if (isRepositoryInitialized(ctx)) {
64
+ console.log("");
65
+ return;
66
+ }
67
+
68
+ printSection(ctx, "Next step");
69
+ console.log("Copy this into your coding agent:");
70
+ console.log("");
71
+ console.log(ctx.color.dim("```"));
72
+ console.log(ctx.nextStepPrompt);
73
+ console.log(ctx.color.dim("```"));
74
+ console.log("");
75
+ }
76
+
77
+ function printDetailedSummary(ctx, detailedOutput) {
78
+ if (detailedOutput && ctx.installed.length > 0) {
79
+ const items = uniqueStrings(ctx.installed);
80
+ printSection(ctx, `Installed ${items.length} ${items.length === 1 ? "item" : "items"}`);
81
+ printList(ctx, ctx.installed, "+");
82
+ }
83
+
84
+ if (detailedOutput && ctx.updated.length > 0) {
85
+ const items = uniqueStrings(ctx.updated);
86
+ printSection(ctx, `Updated ${items.length} ${items.length === 1 ? "item" : "items"}`);
87
+ printList(ctx, ctx.updated, "~");
88
+ }
89
+
90
+ if (detailedOutput && ctx.archived.length > 0) {
91
+ printSection(ctx, "Archived");
92
+ for (const entry of ctx.archived) {
93
+ console.log(`${ctx.color.dim(">")} ${entry.from} -> ${entry.to}`);
94
+ }
95
+ }
96
+
97
+ if (detailedOutput && ctx.skipped.length > 0) {
98
+ const items = uniqueStrings(ctx.skipped);
99
+ printSection(ctx, `Skipped ${items.length} existing ${items.length === 1 ? "path" : "paths"}`);
100
+ printList(ctx, ctx.skipped, "-");
101
+ }
102
+ }
103
+
104
+ function shouldPrintDetailedSummary(ctx, existingInstall) {
105
+ return ctx.verboseOutput || !existingInstall;
106
+ }
107
+
108
+ function printCompactSummary(ctx) {
109
+ const installedCount = uniqueStrings(ctx.installed).length;
110
+ const updatedCount = uniqueStrings(ctx.updated).length;
111
+ const archivedCount = ctx.archived.length;
112
+
113
+ if (installedCount > 0) {
114
+ console.log(`${ctx.color.dim("installed")} ${installedCount}`);
115
+ }
116
+ if (updatedCount > 0) {
117
+ console.log(`${ctx.color.dim("updated")} ${updatedCount}`);
118
+ }
119
+ if (archivedCount > 0) {
120
+ console.log(`${ctx.color.dim("archived")} ${archivedCount}`);
121
+ }
122
+ }
123
+
124
+ function isRepositoryInitialized(ctx) {
125
+ try {
126
+ const initState = JSON.parse(readFileSync(join(ctx.targetRoot, ".naome", "init-state.json"), "utf8"));
127
+ return initState.initialized === true;
128
+ } catch {
129
+ return false;
130
+ }
131
+ }
@@ -0,0 +1,32 @@
1
+ import { printError } from "./output.js";
2
+
3
+ export function compareVersions(ctx, left, right) {
4
+ const leftParts = parseVersion(ctx, left);
5
+ const rightParts = parseVersion(ctx, right);
6
+
7
+ for (let index = 0; index < 3; index += 1) {
8
+ if (leftParts[index] > rightParts[index]) {
9
+ return 1;
10
+ }
11
+
12
+ if (leftParts[index] < rightParts[index]) {
13
+ return -1;
14
+ }
15
+ }
16
+
17
+ return 0;
18
+ }
19
+
20
+ export function isVersion(version) {
21
+ return typeof version === "string" && /^\d+\.\d+\.\d+$/.test(version);
22
+ }
23
+
24
+ function parseVersion(ctx, version) {
25
+ const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
26
+ if (!match) {
27
+ printError(ctx, `Invalid NAOME version: ${version}`);
28
+ process.exit(1);
29
+ }
30
+
31
+ return match.slice(1).map((part) => Number.parseInt(part, 10));
32
+ }
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lamentis/naome",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Native-first CLI for the NAOME agent harness.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -31,6 +31,7 @@
31
31
  "Cargo.lock",
32
32
  "Cargo.toml",
33
33
  "crates",
34
+ "installer",
34
35
  "native",
35
36
  "templates",
36
37
  "README.md"
@@ -11,14 +11,14 @@ const nativeBinaryName = process.platform === "win32" ? "naome.exe" : "naome";
11
11
  const expectedMachineOwnedIntegrity = Object.freeze({
12
12
  ".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
13
13
  ".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
14
- ".naome/bin/naome.js": "sha256:5675f729be6da3cbda1d8b9e0b36821cc98409aae95dff0603ed9161a5eb3b38",
14
+ ".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
15
15
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
16
16
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
17
17
  "AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
18
- "docs/naome/agent-workflow.md": "sha256:802eb34cf268fc9c5e7aefc28192efef4bf60302d30b3f78e5a61b876ce8a098",
18
+ "docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
19
19
  "docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
20
20
  "docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
21
- "docs/naome/index.md": "sha256:7d917f1fa368874653bb458384bd9d0b221529e19644028a3143db3d3c144213",
21
+ "docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
22
22
  "docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
23
23
  });
24
24
 
@@ -11,14 +11,14 @@ const nativeBinaryName = process.platform === "win32" ? "naome.exe" : "naome";
11
11
  const expectedMachineOwnedIntegrity = Object.freeze({
12
12
  ".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
13
13
  ".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
14
- ".naome/bin/naome.js": "sha256:5675f729be6da3cbda1d8b9e0b36821cc98409aae95dff0603ed9161a5eb3b38",
14
+ ".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
15
15
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
16
16
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
17
17
  "AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
18
- "docs/naome/agent-workflow.md": "sha256:802eb34cf268fc9c5e7aefc28192efef4bf60302d30b3f78e5a61b876ce8a098",
18
+ "docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
19
19
  "docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
20
20
  "docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
21
- "docs/naome/index.md": "sha256:7d917f1fa368874653bb458384bd9d0b221529e19644028a3143db3d3c144213",
21
+ "docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
22
22
  "docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
23
23
  });
24
24
 
@@ -27,7 +27,7 @@ function main(argv) {
27
27
  return;
28
28
  }
29
29
 
30
- if (["status", "next", "intent", "route", "explain", "quality", "cleanup", "refresh-integrity", "workflow"].includes(command)) {
30
+ if (["status", "next", "intent", "route", "explain", "doctor", "quality", "semantic", "structure", "cleanup", "refresh-integrity", "workflow"].includes(command)) {
31
31
  runNativeDecisionCommand(command, args);
32
32
  return;
33
33
  }
@@ -349,26 +349,37 @@ function findAncestorWithMarker(startPath, markerParts) {
349
349
  }
350
350
 
351
351
  function printHelp() {
352
- console.log("Usage:");
353
- console.log(" naome status [--json]");
354
- console.log(" naome next [--json]");
355
- console.log(" naome intent --prompt-file <path> [--json]");
356
- console.log(" naome intent --prompt <text> [--json]");
357
- console.log(" naome route --prompt-file <path> [--execute] [--json]");
358
- console.log(" naome route --prompt <text> [--execute] [--json]");
359
- console.log(" naome explain --prompt-file <path> [--json]");
360
- console.log(" naome explain --prompt <text> [--json]");
361
- console.log(" naome quality init [--json]");
362
- console.log(" naome quality check --changed [--json]");
363
- console.log(" naome quality report [--json]");
364
- console.log(" naome cleanup plan [--json]");
365
- console.log(" naome cleanup route --path <path> [--json]");
366
- console.log(" naome refresh-integrity [--json]");
367
- console.log(" naome workflow search-profile|check-search|phases|processes|mutations [--json]");
368
- console.log(" naome install");
369
- console.log(" naome sync");
370
- console.log(" naome commit -m \"type(scope): message\"");
371
- console.log(" node .naome/bin/naome.js commit -m \"type(scope): message\"");
352
+ const commands = [
353
+ "naome status [--json]",
354
+ "naome next [--json]",
355
+ "naome intent --prompt-file <path> [--json]",
356
+ "naome intent --prompt <text> [--json]",
357
+ "naome route --prompt-file <path> [--execute] [--json]",
358
+ "naome route --prompt <text> [--execute] [--json]",
359
+ "naome explain --prompt-file <path> [--json]",
360
+ "naome explain --prompt <text> [--json]",
361
+ "naome doctor [--json]",
362
+ "naome quality init [--baseline|--deep-baseline] [--json]",
363
+ "naome quality check --changed [--include-scanned-paths] [--json]",
364
+ "naome quality report [--deep] [--include-scanned-paths] [--json]",
365
+ "naome quality cache status [--json]",
366
+ "naome quality cache clear",
367
+ "naome semantic report [--deep] [--json]",
368
+ "naome semantic check --changed [--json]",
369
+ "naome semantic route --finding <id> [--json]",
370
+ "naome semantic loop [--json]",
371
+ "naome structure report [--json]",
372
+ "naome structure explain --path <path> [--json]",
373
+ "naome cleanup plan [--json]",
374
+ "naome cleanup route --path <path> [--json]",
375
+ "naome refresh-integrity [--json]",
376
+ "naome workflow search-profile|check-search|phases|processes|mutations [--json]",
377
+ "naome install",
378
+ "naome sync",
379
+ "naome commit -m \"type(scope): message\"",
380
+ "node .naome/bin/naome.js commit -m \"type(scope): message\""
381
+ ];
382
+ console.log(["Usage:", ...commands.map((command) => ` ${command}`)].join("\n"));
372
383
  }
373
384
 
374
385
  function fail(message) {
@@ -4,14 +4,14 @@
4
4
  "integrity": {
5
5
  ".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
6
6
  ".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
7
- ".naome/bin/naome.js": "sha256:5675f729be6da3cbda1d8b9e0b36821cc98409aae95dff0603ed9161a5eb3b38",
7
+ ".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
8
8
  ".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
9
9
  ".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
10
10
  "AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
11
- "docs/naome/agent-workflow.md": "sha256:802eb34cf268fc9c5e7aefc28192efef4bf60302d30b3f78e5a61b876ce8a098",
11
+ "docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
12
12
  "docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
13
13
  "docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
14
- "docs/naome/index.md": "sha256:7d917f1fa368874653bb458384bd9d0b221529e19644028a3143db3d3c144213",
14
+ "docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
15
15
  "docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
16
16
  },
17
17
  "machineOwned": [
@@ -37,11 +37,13 @@
37
37
  ".naome/upgrade-state.json",
38
38
  ".naome/verification.json",
39
39
  ".naome/repository-quality.json",
40
+ ".naome/repository-structure.json",
40
41
  ".naome/repository-quality-baseline.json",
41
42
  "docs/naome/architecture.md",
42
43
  "docs/naome/decisions.md",
43
44
  "docs/naome/repo-profile.md",
44
45
  "docs/naome/repository-quality.md",
46
+ "docs/naome/repository-structure.md",
45
47
  "docs/naome/security.md",
46
48
  "docs/naome/testing.md"
47
49
  ]
@@ -0,0 +1,90 @@
1
+ {
2
+ "schema": "naome.repository-structure.v1",
3
+ "version": 1,
4
+ "status": "ready",
5
+ "enabledAdapters": [],
6
+ "sourceRoots": [
7
+ "src/**",
8
+ "app/**",
9
+ "apps/*/src/**",
10
+ "packages/*/src/**",
11
+ "crates/*/src/**",
12
+ "**/src/**",
13
+ "lib/**"
14
+ ],
15
+ "testRoots": [
16
+ "test/**",
17
+ "tests/**",
18
+ "__tests__/**",
19
+ "packages/*/test/**",
20
+ "packages/*/tests/**",
21
+ "crates/*/tests/**",
22
+ "**/tests/**",
23
+ "scripts/*.test.js"
24
+ ],
25
+ "docsRoots": [
26
+ "docs/**",
27
+ "doc/**"
28
+ ],
29
+ "generatedRoots": [
30
+ "**/generated/**",
31
+ "**/__generated__/**",
32
+ "**/codegen/**",
33
+ "**/*.generated.*"
34
+ ],
35
+ "artifactRoots": [
36
+ "dist/**",
37
+ "build/**",
38
+ "coverage/**",
39
+ ".next/**",
40
+ "target/**",
41
+ "**/dist/**",
42
+ "**/build/**"
43
+ ],
44
+ "moduleRoots": [
45
+ "src/**",
46
+ "app/**",
47
+ "packages/*/src/**",
48
+ "crates/*/src/**",
49
+ "**/src/**"
50
+ ],
51
+ "allowedRootFiles": [
52
+ "README.md",
53
+ "LICENSE",
54
+ "NOTICE",
55
+ "CHANGELOG.md",
56
+ "CONTRIBUTING.md",
57
+ "SECURITY.md",
58
+ "AGENTS.md",
59
+ "package.json",
60
+ "Cargo.toml",
61
+ "pyproject.toml",
62
+ "go.mod",
63
+ "go.sum",
64
+ "Makefile",
65
+ ".gitignore",
66
+ ".naomeignore"
67
+ ],
68
+ "directoryRoleRules": [],
69
+ "layerRules": [],
70
+ "ignoredPaths": [
71
+ ".git/**",
72
+ "node_modules/**",
73
+ "vendor/**",
74
+ "target/**",
75
+ "**/target/**",
76
+ "dist/**",
77
+ "build/**",
78
+ "coverage/**",
79
+ ".next/**"
80
+ ],
81
+ "disabledChecks": [],
82
+ "changedCodePolicy": "block",
83
+ "debtPolicy": "report",
84
+ "limits": {
85
+ "maxDirectoryFiles": 40,
86
+ "maxPathDepth": 10,
87
+ "maxDirectoryRoles": 2,
88
+ "maxDumpingGroundFiles": 12
89
+ }
90
+ }
@@ -48,6 +48,7 @@
48
48
  "source": "NAOME built-in",
49
49
  "evidence": [
50
50
  ".naome/repository-quality.json",
51
+ ".naome/repository-structure.json",
51
52
  ".naome/repository-quality-baseline.json"
52
53
  ],
53
54
  "lastVerified": null
@@ -2,3 +2,4 @@
2
2
  # Agents must not read, summarize, scan, import, or use these paths as context.
3
3
 
4
4
  .naome/archive/
5
+ .naome/cache/
@@ -20,37 +20,39 @@ Use this workflow after first-run intake is complete.
20
20
  debugging why a policy won.
21
21
  4. Run `node .naome/bin/naome.js status --json` when reporting state without
22
22
  routing a new request.
23
- 5. Run `node .naome/bin/check-harness-health.js`.
24
- 6. If harness health fails, do not start new feature work. Ask the user to
23
+ 5. Run `node .naome/bin/naome.js doctor --json` when state is unclear or a
24
+ gate blocks unexpectedly; use its `nextAction` as the first diagnostic.
25
+ 6. Run `node .naome/bin/check-harness-health.js`.
26
+ 7. If harness health fails, do not start new feature work. Ask the user to
25
27
  choose `repair_harness`, `review_harness_diff`, or
26
28
  `cancel_repair_baseline`.
27
- 7. Run `node .naome/bin/check-task-state.js --admission`.
28
- 8. If task admission fails for a natural-language work request, use
29
+ 8. Run `node .naome/bin/check-task-state.js --admission`.
30
+ 9. If task admission fails for a natural-language work request, use
29
31
  `naome route --execute --json`. Route may baseline valid completed setup or
30
32
  task diffs, create an isolated task worktree around unrelated user edits,
31
33
  baseline pure harness refreshes in the current worktree, and rerun
32
34
  admission. Ask the user only when `humanOptions` is non-empty,
33
35
  route blocks as unsafe/ambiguous, or automatic baselining fails.
34
- 9. If route blocks or returns no mutation, do not use raw `git commit`, IDE
36
+ 10. If route blocks or returns no mutation, do not use raw `git commit`, IDE
35
37
  commit, `git add`, or hook bypass commands as a fallback. Unowned changes
36
38
  are user-owned unless NAOME route explicitly isolates around them or
37
39
  baselines a deterministic harness/task diff. If the user explicitly asks to
38
40
  commit their own unowned changes, route must run the configured quality gate
39
41
  first, require committed verification coverage for every path, and commit
40
42
  only the final stabilized paths it evaluated.
41
- 10. Record the passed admission check in `.naome/task-state.json` when starting
43
+ 11. Record the passed admission check in `.naome/task-state.json` when starting
42
44
  the task.
43
- 11. Restate the task in concrete terms.
44
- 12. Read `.naomeignore`.
45
- 13. Exclude every path matched by `.naomeignore` from context gathering.
46
- 14. For broad searches, use `node .naome/bin/naome.js workflow search-profile`
45
+ 12. Restate the task in concrete terms.
46
+ 13. Read `.naomeignore`.
47
+ 14. Exclude every path matched by `.naomeignore` from context gathering.
48
+ 15. For broad searches, use `node .naome/bin/naome.js workflow search-profile`
47
49
  or equivalent excludes for `.git`, `.naome/archive`, dependencies, build
48
50
  outputs, caches, and `.naomeignore` paths.
49
- 15. Read only the `requiredContext` returned by route/status plus the smallest
51
+ 16. Read only the `requiredContext` returned by route/status plus the smallest
50
52
  task-relevant NAOME docs.
51
- 16. Inspect the existing code or docs before proposing changes.
52
- 17. Read `testing.md` and `.naome/verification.json`.
53
- 18. Identify the required proof before claiming success.
53
+ 17. Inspect the existing code or docs before proposing changes.
54
+ 18. Read `testing.md` and `.naome/verification.json`.
55
+ 19. Identify the required proof before claiming success.
54
56
 
55
57
  ## Instruction Boundaries
56
58
 
@@ -18,9 +18,10 @@ for the current step.
18
18
  11. `testing.md`
19
19
  12. `.naome/verification.json`
20
20
  13. `repository-quality.md`, when repository-quality checks or cleanup are relevant
21
- 14. `security.md`
22
- 15. `agent-workflow.md`
23
- 16. `decisions.md`, when changing durable project policy
21
+ 14. `repository-structure.md`, when path roles or structure cleanup are relevant
22
+ 15. `security.md`
23
+ 16. `agent-workflow.md`
24
+ 17. `decisions.md`, when changing durable project policy
24
25
 
25
26
  ## Source Types
26
27