@lamentis/naome 1.3.16 → 1.4.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.
- package/Cargo.lock +2 -2
- package/crates/naome-cli/Cargo.toml +1 -1
- package/crates/naome-cli/src/architecture_commands.rs +16 -2
- 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 +2 -1
- 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 +211 -155
- package/crates/naome-core/src/architecture/rules.rs +4 -3
- 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 +8 -3
- package/crates/naome-core/src/lib.rs +9 -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 +155 -1
- 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 +2 -2
- package/templates/naome-root/.naome/verification.json +6 -1
- package/templates/naome-root/docs/naome/architecture-fitness.md +76 -59
|
@@ -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:be38e0c6dea8b1ebeee3bfd4a2e4e17008829360b1b4649ef45f2ce61e7287bd",
|
|
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:be38e0c6dea8b1ebeee3bfd4a2e4e17008829360b1b4649ef45f2ce61e7287bd",
|
|
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",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"harnessVersion": "1.
|
|
2
|
+
"harnessVersion": "1.4.0",
|
|
3
3
|
"installedAt": null,
|
|
4
4
|
"integrity": {
|
|
5
5
|
".naome/bin/check-harness-health.js": "sha256:802d7419774981a6af1826b3882270ff8f41259d516f98c52a02b4ddc184c467",
|
|
@@ -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:be38e0c6dea8b1ebeee3bfd4a2e4e17008829360b1b4649ef45f2ce61e7287bd",
|
|
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,13 +7,15 @@ 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`.
|
|
14
14
|
- `naome arch validate` runs architecture rules with human output.
|
|
15
15
|
- `naome arch validate --json` emits stable machine-readable output.
|
|
16
16
|
- `naome arch validate --agent-feedback` emits compact repair instructions.
|
|
17
|
+
- `naome arch validate --sarif [--output architecture.sarif]` emits SARIF 2.1.0
|
|
18
|
+
for CI code-scanning while preserving failing exit codes.
|
|
17
19
|
- `naome arch validate --changed-only` uses changed paths with the persistent
|
|
18
20
|
architecture cache when available and safely degrades to a full scan when the
|
|
19
21
|
cache cannot prove graph-level soundness.
|
|
@@ -34,70 +36,40 @@ extractor name, raw origin data, stable ID, and a human-readable label.
|
|
|
34
36
|
Ignored paths require a reason so agents cannot silently suppress architecture
|
|
35
37
|
ownership.
|
|
36
38
|
|
|
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"
|
|
39
|
+
`naome arch init` starts from the files already present in the repository. It
|
|
40
|
+
recognizes common `src/**` layers, Swift/iOS `Sources/**` layouts, feature
|
|
41
|
+
directories under `src/`, and public API entrypoints such as `index.*` or
|
|
42
|
+
`Public/**`. Repositories without recognizable source roots still receive the
|
|
43
|
+
safe generic starter.
|
|
44
|
+
|
|
45
|
+
Core configuration sections are `layers`, `contexts`, `rules`,
|
|
46
|
+
`allowed_dependencies`, `external_dependencies`, and `ignore`. Typical rules are
|
|
47
|
+
enabled as:
|
|
52
48
|
|
|
49
|
+
```yaml
|
|
53
50
|
rules:
|
|
54
51
|
no_forbidden_layer_dependencies:
|
|
55
52
|
enabled: true
|
|
56
53
|
severity: error
|
|
57
|
-
no_cross_context_internal_imports:
|
|
58
|
-
enabled: true
|
|
59
|
-
severity: error
|
|
60
54
|
public_api_boundary:
|
|
61
55
|
enabled: true
|
|
62
56
|
severity: error
|
|
63
57
|
no_cycles:
|
|
64
58
|
enabled: true
|
|
65
59
|
severity: error
|
|
66
|
-
no_transitive_forbidden_layer_dependencies:
|
|
67
|
-
enabled: true
|
|
68
|
-
severity: error
|
|
69
60
|
max_imports_per_file:
|
|
70
61
|
enabled: true
|
|
71
62
|
value: 20
|
|
72
63
|
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
64
|
max_file_lines:
|
|
81
65
|
enabled: true
|
|
82
66
|
value: 400
|
|
83
67
|
severity: warning
|
|
84
|
-
|
|
85
|
-
enabled: true
|
|
86
|
-
severity: error
|
|
87
|
-
|
|
88
|
-
allowed_dependencies:
|
|
89
|
-
domain:
|
|
90
|
-
infrastructure:
|
|
91
|
-
- domain
|
|
68
|
+
```
|
|
92
69
|
|
|
93
|
-
|
|
94
|
-
domain:
|
|
95
|
-
allow: []
|
|
96
|
-
infrastructure:
|
|
97
|
-
allow:
|
|
98
|
-
- "stripe"
|
|
99
|
-
- "@supabase/*"
|
|
70
|
+
Use explicit ignore reasons, for example:
|
|
100
71
|
|
|
72
|
+
```yaml
|
|
101
73
|
ignore:
|
|
102
74
|
- path: "generated/**"
|
|
103
75
|
reason: "Generated code is not architecture-owned."
|
|
@@ -132,6 +104,23 @@ repair loops. It also reports `changedOnlyMode` and
|
|
|
132
104
|
`changedOnlyDegradationReason`, so agents can distinguish an incremental cache
|
|
133
105
|
run from a deliberate full-scan fallback.
|
|
134
106
|
|
|
107
|
+
Agent feedback is intentionally compact. Dependency repair entries include the
|
|
108
|
+
source file and target file when both are known, plus direct `must_not_do`
|
|
109
|
+
constraints for layer-boundary violations. Configuration findings also surface
|
|
110
|
+
unresolved imports as repairable feedback so agents do not treat missing graph
|
|
111
|
+
edges as clean architecture.
|
|
112
|
+
|
|
113
|
+
## Configuration Findings
|
|
114
|
+
|
|
115
|
+
Validation can pass while still reporting non-blocking configuration findings
|
|
116
|
+
about weak architecture policy, such as:
|
|
117
|
+
|
|
118
|
+
- broad catch-all layers or contexts overlapping narrower boundaries;
|
|
119
|
+
- layers or contexts whose path patterns match no files;
|
|
120
|
+
- unresolved imports that could hide real dependency edges.
|
|
121
|
+
|
|
122
|
+
Use JSON output to inspect `configFindings` deterministically in CI or agents.
|
|
123
|
+
|
|
135
124
|
## Incremental Cache
|
|
136
125
|
|
|
137
126
|
NAOME stores architecture file facts in `.naome/cache/architecture/cache.json`.
|
|
@@ -145,6 +134,10 @@ Changed-only validation is sound by construction:
|
|
|
145
134
|
- config changes perform a full scan with reason `config_changed`;
|
|
146
135
|
- added or deleted repository files perform a full scan with reason
|
|
147
136
|
`file_set_changed`;
|
|
137
|
+
- manifest and resolver-context changes such as `package.json`,
|
|
138
|
+
`tsconfig.json`, `jsconfig.json`, `Cargo.toml`, `go.mod`, `Package.swift`,
|
|
139
|
+
Gradle, Maven, CocoaPods, Carthage, or Xcode project files perform a full
|
|
140
|
+
scan with reason `resolver_context_changed`;
|
|
148
141
|
- when config and file set are unchanged, NAOME reuses cached facts for
|
|
149
142
|
untouched files, rescans changed files, rebuilds the full graph, and runs all
|
|
150
143
|
graph-level rules against that graph.
|
|
@@ -156,28 +149,52 @@ The command is deterministic in both cache-backed and fallback modes; CI can
|
|
|
156
149
|
inspect the JSON fields above when it needs to distinguish performance from
|
|
157
150
|
soundness fallbacks.
|
|
158
151
|
|
|
152
|
+
Use `node .naome/bin/naome.js arch validate --sarif --output architecture.sarif`
|
|
153
|
+
when CI can upload SARIF. It contains blocking violations, configuration
|
|
154
|
+
findings, unresolved imports, and `agentInstruction` properties for repair loops.
|
|
155
|
+
|
|
156
|
+
For v1.4.0, architecture fitness is a release gate whenever source,
|
|
157
|
+
manifest, alias, config, or structure changes can alter dependency edges. Treat
|
|
158
|
+
error-level violations as blocking. Warning-level config findings are advisory
|
|
159
|
+
unless the repository chooses stricter policy, but unresolved imports should be
|
|
160
|
+
triaged before claiming a clean architecture result.
|
|
161
|
+
|
|
159
162
|
## Language Support
|
|
160
163
|
|
|
161
|
-
The v1.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
manifests, and Xcode Swift package references
|
|
168
|
-
graph; Apple SDK frameworks are treated as platform APIs
|
|
169
|
-
|
|
170
|
-
`
|
|
171
|
-
|
|
172
|
-
manifest-identity package nodes and manifest-owned `DependsOn` edges to
|
|
173
|
-
external dependencies.
|
|
164
|
+
The v1.4.0 foundation classifies TypeScript, JavaScript, Rust, Python, Go, Java,
|
|
165
|
+
Kotlin, and Swift files by path extension. It extracts imports for TypeScript,
|
|
166
|
+
JavaScript, Rust, Python, Go, and Swift, resolving relative paths,
|
|
167
|
+
repository-absolute aliases, TS/JS `paths`, Python package roots, Go modules,
|
|
168
|
+
SwiftPM targets, and Rust crate/self/super module paths where possible.
|
|
169
|
+
Unresolved imports become explicit graph nodes. Swift/iOS repositories get Apple
|
|
170
|
+
framework imports, SwiftPM manifests, and Xcode Swift package references in the
|
|
171
|
+
normalized graph; Apple SDK frameworks are treated as platform APIs. Manifest
|
|
172
|
+
facts from `package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, lightweight
|
|
173
|
+
`pom.xml` / Gradle manifests, `Package.swift`, and `.xcodeproj/project.pbxproj`
|
|
174
|
+
emit manifest-identity package nodes and manifest-owned dependency edges.
|
|
174
175
|
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.0 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 remains 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.
|