@lamentis/naome 1.3.15 → 1.3.17
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-cli/src/architecture_commands.rs +5 -3
- package/crates/naome-cli/src/architecture_init/infer.rs +131 -0
- package/crates/naome-cli/src/architecture_init/render.rs +56 -0
- package/crates/naome-cli/src/architecture_init/repository.rs +59 -0
- package/crates/naome-cli/src/architecture_init.rs +17 -0
- package/crates/naome-cli/src/main.rs +1 -0
- package/crates/naome-cli/tests/architecture_cli.rs +75 -0
- package/crates/naome-core/Cargo.toml +1 -1
- package/crates/naome-core/src/architecture/config_findings/configuration/coverage.rs +81 -0
- package/crates/naome-core/src/architecture/config_findings/configuration/overlap.rs +117 -0
- package/crates/naome-core/src/architecture/config_findings/configuration.rs +12 -0
- package/crates/naome-core/src/architecture/config_findings/imports.rs +30 -0
- package/crates/naome-core/src/architecture/config_findings.rs +50 -0
- package/crates/naome-core/src/architecture/explain.rs +45 -0
- package/crates/naome-core/src/architecture/output.rs +59 -36
- package/crates/naome-core/src/architecture/rules.rs +5 -1
- package/crates/naome-core/src/architecture/scan/cache.rs +1 -1
- package/crates/naome-core/src/architecture/scan/imports/resolver/candidates.rs +71 -0
- package/crates/naome-core/src/architecture/scan/imports/resolver/js_ts_alias.rs +241 -0
- package/crates/naome-core/src/architecture/scan/imports/resolver.rs +162 -91
- package/crates/naome-core/src/architecture/scan.rs +20 -6
- package/crates/naome-core/src/architecture.rs +6 -2
- package/crates/naome-core/src/lib.rs +8 -7
- package/crates/naome-core/tests/architecture.rs +30 -0
- package/crates/naome-core/tests/architecture_acceptance.rs +304 -0
- package/crates/naome-core/tests/architecture_aliases.rs +101 -0
- package/crates/naome-core/tests/architecture_cache.rs +57 -0
- package/crates/naome-core/tests/architecture_config.rs +154 -0
- package/crates/naome-core/tests/architecture_rules.rs +32 -0
- package/crates/naome-core/tests/architecture_unresolved.rs +36 -0
- package/native/darwin-arm64/naome +0 -0
- package/native/linux-x64/naome +0 -0
- package/package.json +1 -1
- package/templates/naome-root/.naome/bin/check-harness-health.js +1 -0
- package/templates/naome-root/.naome/bin/check-task-state.js +1 -0
- package/templates/naome-root/.naome/manifest.json +1 -1
- package/templates/naome-root/.naome/verification.json +6 -1
- package/templates/naome-root/docs/naome/architecture-fitness.md +68 -51
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
use naome_core::{validate_architecture, ArchitectureScanOptions};
|
|
2
|
+
|
|
3
|
+
mod architecture_support;
|
|
4
|
+
|
|
5
|
+
use architecture_support::FixtureRepo;
|
|
6
|
+
|
|
7
|
+
#[test]
|
|
8
|
+
fn missing_rust_local_imports_remain_unresolved() {
|
|
9
|
+
let repo = FixtureRepo::new();
|
|
10
|
+
repo.write("src/lib.rs", "pub mod domain;\n");
|
|
11
|
+
repo.write(
|
|
12
|
+
"src/domain/mod.rs",
|
|
13
|
+
"use crate::missing::Thing;\nuse self::missing::Local;\npub mod service;\n",
|
|
14
|
+
);
|
|
15
|
+
repo.write("src/domain/service.rs", "use super::missing::Parent;\n");
|
|
16
|
+
|
|
17
|
+
let report = validate_architecture(repo.path(), ArchitectureScanOptions::default()).unwrap();
|
|
18
|
+
let unresolved = report
|
|
19
|
+
.config_findings
|
|
20
|
+
.iter()
|
|
21
|
+
.filter(|finding| finding.id == "arch.import.unresolved")
|
|
22
|
+
.map(|finding| finding.message.as_str())
|
|
23
|
+
.collect::<Vec<_>>();
|
|
24
|
+
|
|
25
|
+
for specifier in [
|
|
26
|
+
"crate::missing::Thing",
|
|
27
|
+
"self::missing::Local",
|
|
28
|
+
"super::missing::Parent",
|
|
29
|
+
] {
|
|
30
|
+
assert!(
|
|
31
|
+
unresolved.iter().any(|message| message.contains(specifier)),
|
|
32
|
+
"{specifier}: {:?}",
|
|
33
|
+
unresolved
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
Binary file
|
package/native/linux-x64/naome
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ const expectedMachineOwnedIntegrity = Object.freeze({
|
|
|
17
17
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
18
18
|
"AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",
|
|
19
19
|
"docs/naome/agent-workflow.md": "sha256:0be1c29adfbcd3fd73c4f904080ffc67237692fe413871a30243538c4db38ac7",
|
|
20
|
+
"docs/naome/architecture-fitness.md": "sha256:5067f57787f0cac0be4b0d49079f03b595fdab6e4fba4b8bdde4bc3cfc0d1de1",
|
|
20
21
|
"docs/naome/context-economy.md": "sha256:3ed5075815ecf4ada46a5e65438769310307c35759fcd46b13dc0b96e02bebd9",
|
|
21
22
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
22
23
|
"docs/naome/first-run.md": "sha256:1466ce8c65e19a1514885f917db14e8a772350e3f6d1c03a66326963365919e1",
|
|
@@ -17,6 +17,7 @@ const expectedMachineOwnedIntegrity = Object.freeze({
|
|
|
17
17
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
18
18
|
"AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",
|
|
19
19
|
"docs/naome/agent-workflow.md": "sha256:0be1c29adfbcd3fd73c4f904080ffc67237692fe413871a30243538c4db38ac7",
|
|
20
|
+
"docs/naome/architecture-fitness.md": "sha256:5067f57787f0cac0be4b0d49079f03b595fdab6e4fba4b8bdde4bc3cfc0d1de1",
|
|
20
21
|
"docs/naome/context-economy.md": "sha256:3ed5075815ecf4ada46a5e65438769310307c35759fcd46b13dc0b96e02bebd9",
|
|
21
22
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
22
23
|
"docs/naome/first-run.md": "sha256:1466ce8c65e19a1514885f917db14e8a772350e3f6d1c03a66326963365919e1",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
10
10
|
"AGENTS.md": "sha256:e8b2fc786c1c72b69ba8f2b2ffce4f459e799c7453ce9ff4a9f6448a8f9e6b4f",
|
|
11
11
|
"docs/naome/agent-workflow.md": "sha256:0be1c29adfbcd3fd73c4f904080ffc67237692fe413871a30243538c4db38ac7",
|
|
12
|
-
"docs/naome/architecture-fitness.md": "sha256:
|
|
12
|
+
"docs/naome/architecture-fitness.md": "sha256:5067f57787f0cac0be4b0d49079f03b595fdab6e4fba4b8bdde4bc3cfc0d1de1",
|
|
13
13
|
"docs/naome/context-economy.md": "sha256:3ed5075815ecf4ada46a5e65438769310307c35759fcd46b13dc0b96e02bebd9",
|
|
14
14
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
15
15
|
"docs/naome/first-run.md": "sha256:1466ce8c65e19a1514885f917db14e8a772350e3f6d1c03a66326963365919e1",
|
|
@@ -107,5 +107,10 @@
|
|
|
107
107
|
}
|
|
108
108
|
],
|
|
109
109
|
"changeTypes": [],
|
|
110
|
-
"releaseGates": [
|
|
110
|
+
"releaseGates": [
|
|
111
|
+
{
|
|
112
|
+
"checkId": "architecture-fitness-check",
|
|
113
|
+
"requiredWhen": "Before release or any source, manifest, alias, config, or structure change that can affect architecture."
|
|
114
|
+
}
|
|
115
|
+
]
|
|
111
116
|
}
|
|
@@ -7,7 +7,7 @@ facts instead of prompt text.
|
|
|
7
7
|
|
|
8
8
|
## Commands
|
|
9
9
|
|
|
10
|
-
- `naome arch init` writes a starter `naome.arch.yaml`.
|
|
10
|
+
- `naome arch init` writes a repository-aware starter `naome.arch.yaml`.
|
|
11
11
|
- `naome arch explain` prints inferred layers, contexts, rules, and extractors.
|
|
12
12
|
- `naome arch scan --json` emits the normalized graph.
|
|
13
13
|
- `naome arch scan --write` writes `.naome/architecture-graph.json`.
|
|
@@ -34,70 +34,40 @@ extractor name, raw origin data, stable ID, and a human-readable label.
|
|
|
34
34
|
Ignored paths require a reason so agents cannot silently suppress architecture
|
|
35
35
|
ownership.
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
layers
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
contexts:
|
|
47
|
-
billing:
|
|
48
|
-
paths:
|
|
49
|
-
- "src/billing/**"
|
|
50
|
-
public_api:
|
|
51
|
-
- "src/billing/index.ts"
|
|
37
|
+
`naome arch init` starts from the files already present in the repository. It
|
|
38
|
+
recognizes common `src/**` layers, Swift/iOS `Sources/**` layouts, feature
|
|
39
|
+
directories under `src/`, and public API entrypoints such as `index.*` or
|
|
40
|
+
`Public/**`. Repositories without recognizable source roots still receive the
|
|
41
|
+
safe generic starter.
|
|
42
|
+
|
|
43
|
+
Core configuration sections are `layers`, `contexts`, `rules`,
|
|
44
|
+
`allowed_dependencies`, `external_dependencies`, and `ignore`. Typical rules are
|
|
45
|
+
enabled as:
|
|
52
46
|
|
|
47
|
+
```yaml
|
|
53
48
|
rules:
|
|
54
49
|
no_forbidden_layer_dependencies:
|
|
55
50
|
enabled: true
|
|
56
51
|
severity: error
|
|
57
|
-
no_cross_context_internal_imports:
|
|
58
|
-
enabled: true
|
|
59
|
-
severity: error
|
|
60
52
|
public_api_boundary:
|
|
61
53
|
enabled: true
|
|
62
54
|
severity: error
|
|
63
55
|
no_cycles:
|
|
64
56
|
enabled: true
|
|
65
57
|
severity: error
|
|
66
|
-
no_transitive_forbidden_layer_dependencies:
|
|
67
|
-
enabled: true
|
|
68
|
-
severity: error
|
|
69
58
|
max_imports_per_file:
|
|
70
59
|
enabled: true
|
|
71
60
|
value: 20
|
|
72
61
|
severity: warning
|
|
73
|
-
max_fan_out:
|
|
74
|
-
enabled: true
|
|
75
|
-
value: 20
|
|
76
|
-
severity: warning
|
|
77
|
-
external_dependency_policy:
|
|
78
|
-
enabled: true
|
|
79
|
-
severity: error
|
|
80
62
|
max_file_lines:
|
|
81
63
|
enabled: true
|
|
82
64
|
value: 400
|
|
83
65
|
severity: warning
|
|
84
|
-
|
|
85
|
-
enabled: true
|
|
86
|
-
severity: error
|
|
87
|
-
|
|
88
|
-
allowed_dependencies:
|
|
89
|
-
domain:
|
|
90
|
-
infrastructure:
|
|
91
|
-
- domain
|
|
66
|
+
```
|
|
92
67
|
|
|
93
|
-
|
|
94
|
-
domain:
|
|
95
|
-
allow: []
|
|
96
|
-
infrastructure:
|
|
97
|
-
allow:
|
|
98
|
-
- "stripe"
|
|
99
|
-
- "@supabase/*"
|
|
68
|
+
Use explicit ignore reasons, for example:
|
|
100
69
|
|
|
70
|
+
```yaml
|
|
101
71
|
ignore:
|
|
102
72
|
- path: "generated/**"
|
|
103
73
|
reason: "Generated code is not architecture-owned."
|
|
@@ -132,6 +102,24 @@ repair loops. It also reports `changedOnlyMode` and
|
|
|
132
102
|
`changedOnlyDegradationReason`, so agents can distinguish an incremental cache
|
|
133
103
|
run from a deliberate full-scan fallback.
|
|
134
104
|
|
|
105
|
+
Agent feedback is intentionally compact. Dependency repair entries include the
|
|
106
|
+
source file and target file when both are known, plus direct `must_not_do`
|
|
107
|
+
constraints for layer-boundary violations. Configuration findings also surface
|
|
108
|
+
unresolved imports as repairable feedback so agents do not treat missing graph
|
|
109
|
+
edges as clean architecture.
|
|
110
|
+
|
|
111
|
+
## Configuration Findings
|
|
112
|
+
|
|
113
|
+
Validation can pass while still reporting configuration findings. These are
|
|
114
|
+
non-blocking warnings about weak architecture policy, such as:
|
|
115
|
+
|
|
116
|
+
- broad catch-all layers or contexts overlapping narrower boundaries;
|
|
117
|
+
- layers or contexts whose path patterns match no files;
|
|
118
|
+
- unresolved imports that could hide real dependency edges.
|
|
119
|
+
|
|
120
|
+
Use `naome arch explain --json` or `naome arch validate --json` to inspect
|
|
121
|
+
`configFindings` deterministically in CI or agent loops.
|
|
122
|
+
|
|
135
123
|
## Incremental Cache
|
|
136
124
|
|
|
137
125
|
NAOME stores architecture file facts in `.naome/cache/architecture/cache.json`.
|
|
@@ -145,6 +133,10 @@ Changed-only validation is sound by construction:
|
|
|
145
133
|
- config changes perform a full scan with reason `config_changed`;
|
|
146
134
|
- added or deleted repository files perform a full scan with reason
|
|
147
135
|
`file_set_changed`;
|
|
136
|
+
- manifest and resolver-context changes such as `package.json`,
|
|
137
|
+
`tsconfig.json`, `jsconfig.json`, `Cargo.toml`, `go.mod`, `Package.swift`,
|
|
138
|
+
Gradle, Maven, CocoaPods, Carthage, or Xcode project files perform a full
|
|
139
|
+
scan with reason `resolver_context_changed`;
|
|
148
140
|
- when config and file set are unchanged, NAOME reuses cached facts for
|
|
149
141
|
untouched files, rescans changed files, rebuilds the full graph, and runs all
|
|
150
142
|
graph-level rules against that graph.
|
|
@@ -156,14 +148,23 @@ The command is deterministic in both cache-backed and fallback modes; CI can
|
|
|
156
148
|
inspect the JSON fields above when it needs to distinguish performance from
|
|
157
149
|
soundness fallbacks.
|
|
158
150
|
|
|
151
|
+
For v1.4 readiness, architecture fitness is a release gate whenever source,
|
|
152
|
+
manifest, alias, config, or structure changes can alter dependency edges. Treat
|
|
153
|
+
error-level violations as blocking. Warning-level config findings are advisory
|
|
154
|
+
unless the repository chooses stricter policy, but unresolved imports should be
|
|
155
|
+
triaged before claiming a clean architecture result.
|
|
156
|
+
|
|
159
157
|
## Language Support
|
|
160
158
|
|
|
161
|
-
The v1.3.
|
|
159
|
+
The v1.3.17 foundation classifies TypeScript, JavaScript, Rust, Python, Go,
|
|
162
160
|
Java, Kotlin, and Swift files by path extension. It extracts import facts for
|
|
163
|
-
TypeScript, JavaScript, Rust, Python, Go, and Swift
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
TypeScript, JavaScript, Rust, Python, Go, and Swift. It resolves relative
|
|
162
|
+
imports, repository-absolute aliases, TypeScript/JavaScript `paths` aliases
|
|
163
|
+
from nearby `tsconfig.json` or `jsconfig.json`, Python package imports with
|
|
164
|
+
local `__init__.py` roots, Go module imports, SwiftPM target imports, and Rust
|
|
165
|
+
crate/self/super module paths where possible.
|
|
166
|
+
Unresolved imports are represented explicitly as graph nodes instead of
|
|
167
|
+
dropping them. Swift and iOS app repositories get Apple framework imports, SwiftPM
|
|
167
168
|
manifests, and Xcode Swift package references represented in the normalized
|
|
168
169
|
graph; Apple SDK frameworks are treated as platform APIs for external policy.
|
|
169
170
|
It also extracts package and dependency facts from `package.json`,
|
|
@@ -175,9 +176,25 @@ Architecture rules now cover layers, bounded contexts, public APIs, cycles,
|
|
|
175
176
|
transitive layer reach, import/fan-out budgets, and external dependency
|
|
176
177
|
policies.
|
|
177
178
|
|
|
179
|
+
## Acceptance Coverage
|
|
180
|
+
|
|
181
|
+
v1.4 readiness is covered with deterministic fixture repositories for
|
|
182
|
+
TypeScript/JavaScript aliases, Rust crate paths, Python package roots, Go
|
|
183
|
+
modules, Swift/iOS targets, and mixed monorepos. These fixtures assert both
|
|
184
|
+
positive local-edge resolution and negative forbidden-dependency findings.
|
|
185
|
+
|
|
178
186
|
## Limitations
|
|
179
187
|
|
|
180
188
|
This release intentionally keeps validation file-graph based. Manifest
|
|
181
189
|
extractors are dependency-owner oriented and do not yet parse every build-tool
|
|
182
|
-
feature.
|
|
183
|
-
|
|
190
|
+
feature. Deep symbol-level call analysis and SARIF output remain follow-up work.
|
|
191
|
+
|
|
192
|
+
## v1.4 Migration Checklist
|
|
193
|
+
|
|
194
|
+
1. Run `naome arch init` and review inferred layers and contexts.
|
|
195
|
+
2. Run `naome arch explain --json` and address ineffective config findings.
|
|
196
|
+
3. Run `naome arch validate --json` and fix error-level violations first.
|
|
197
|
+
4. Treat unresolved imports as incomplete architecture evidence, not as passes.
|
|
198
|
+
5. Add explicit `ignore` entries only with reasons for generated or vendor code.
|
|
199
|
+
6. Enable the CI gate with `naome arch validate --changed-only` once the full
|
|
200
|
+
repository has no error-level violations.
|