@nurix/etna 0.19.48 → 0.19.50
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/bin/etna.js +1 -1
- package/data/harness-index.json +1 -1
- package/data/harnesses/apollo/harness.json +2 -2
- package/data/harnesses/apollo/hooks/hooks.json +2 -1
- package/data/harnesses/apollo/skills/testing/SKILL.md +22 -0
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/hooks.json +2 -1
- package/data/harnesses/code/skills/testing/SKILL.md +22 -0
- package/package.json +2 -2
package/bin/etna.js
CHANGED
|
@@ -318,7 +318,7 @@ function mergeHooks(targetDir, bundledHooksJson) {
|
|
|
318
318
|
const settings = readJson(settingsPath);
|
|
319
319
|
settings.hooks = settings.hooks || {};
|
|
320
320
|
let added = 0;
|
|
321
|
-
// Harness-shipped permission defaults (e.g. Edit
|
|
321
|
+
// Harness-shipped permission defaults (e.g. Edit on docs/** flows without prompts —
|
|
322
322
|
// the deny hooks still hard-block frozen/protected paths underneath). Additive, idempotent.
|
|
323
323
|
for (const rule of bundled.permissions?.allow || []) {
|
|
324
324
|
settings.permissions = settings.permissions || {};
|
package/data/harness-index.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "apollo",
|
|
3
3
|
"name": "apollo",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
"docs/history/backlog.md",
|
|
15
15
|
"docs/memory/main.md"
|
|
16
16
|
],
|
|
17
|
-
"digest": "
|
|
17
|
+
"digest": "ed426da3ca34"
|
|
18
18
|
}
|
|
@@ -50,6 +50,28 @@ Derive the stack first, then place tests: a placement argument that starts "this
|
|
|
50
50
|
|
|
51
51
|
Why this is the cheap strategy at the horizon: layering makes cost **additive** — a new API behavior costs one layer-2 test and maybe a layer-3 edge, zero frontend tests; a new UI state costs one layer-7 test, zero backend tests. A flat suite pays N×M, because every top-layer path implicitly re-verifies every behavior beneath it.
|
|
52
52
|
|
|
53
|
+
## The tree
|
|
54
|
+
|
|
55
|
+
The directory layout follows the strata, so a test's home states its layer and the runner split is mechanical, not per-file judgment:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
tests/
|
|
59
|
+
schema/ L1 — infrastructure-bound runner (real engine)
|
|
60
|
+
domain/ L2 — infrastructure-bound runner (real storage, modeled ports)
|
|
61
|
+
routes/ L3 — infrastructure-bound runner (in-process app)
|
|
62
|
+
contract/ L4 — no runner; typed fixtures + interception handlers
|
|
63
|
+
client/ L5 — plain unit runner
|
|
64
|
+
view/ L6 — plain unit runner
|
|
65
|
+
component/ L7 — unit runner + DOM environment (per-file opt-in)
|
|
66
|
+
helpers/ shared seeds, fakes, and builders — owned by no stratum
|
|
67
|
+
e2e/ L8 — its own config, never mixed into the unit runner's glob
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **A stratum the app lacks gets no directory** — an empty `component/` in a backend service is a lie about the app's shape.
|
|
71
|
+
- **One shared glob list, imported by both runner configs** — the infrastructure-bound runner *includes* `schema|domain|routes`, the unit runner *excludes* them. Two hand-maintained lists drift; one imported constant cannot.
|
|
72
|
+
- **Which concrete runner, framework, and DOM environment fill these slots is `testing.md`'s per-stack table** — this skill names the slot, never the brand, so the two files cannot disagree.
|
|
73
|
+
- **Contract modules the provider binds** (the layer-4 source types) live in the app's shared source zone — importable by both provider and consumer builds — not in the test tree; `tests/contract/` holds only the fixtures and fakes compiled from them.
|
|
74
|
+
|
|
53
75
|
## Bridge to the obligation ledger
|
|
54
76
|
|
|
55
77
|
The `test-plan` skill's ledger assigns each obligation a runner altitude — `unit` / `component` / `integration` / `e2e`. Those are coarse names for where a test *runs*; the strata here say what it may *assert*. The mapping:
|
|
@@ -50,6 +50,28 @@ Derive the stack first, then place tests: a placement argument that starts "this
|
|
|
50
50
|
|
|
51
51
|
Why this is the cheap strategy at the horizon: layering makes cost **additive** — a new API behavior costs one layer-2 test and maybe a layer-3 edge, zero frontend tests; a new UI state costs one layer-7 test, zero backend tests. A flat suite pays N×M, because every top-layer path implicitly re-verifies every behavior beneath it.
|
|
52
52
|
|
|
53
|
+
## The tree
|
|
54
|
+
|
|
55
|
+
The directory layout follows the strata, so a test's home states its layer and the runner split is mechanical, not per-file judgment:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
tests/
|
|
59
|
+
schema/ L1 — infrastructure-bound runner (real engine)
|
|
60
|
+
domain/ L2 — infrastructure-bound runner (real storage, modeled ports)
|
|
61
|
+
routes/ L3 — infrastructure-bound runner (in-process app)
|
|
62
|
+
contract/ L4 — no runner; typed fixtures + interception handlers
|
|
63
|
+
client/ L5 — plain unit runner
|
|
64
|
+
view/ L6 — plain unit runner
|
|
65
|
+
component/ L7 — unit runner + DOM environment (per-file opt-in)
|
|
66
|
+
helpers/ shared seeds, fakes, and builders — owned by no stratum
|
|
67
|
+
e2e/ L8 — its own config, never mixed into the unit runner's glob
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **A stratum the app lacks gets no directory** — an empty `component/` in a backend service is a lie about the app's shape.
|
|
71
|
+
- **One shared glob list, imported by both runner configs** — the infrastructure-bound runner *includes* `schema|domain|routes`, the unit runner *excludes* them. Two hand-maintained lists drift; one imported constant cannot.
|
|
72
|
+
- **Which concrete runner, framework, and DOM environment fill these slots is `testing.md`'s per-stack table** — this skill names the slot, never the brand, so the two files cannot disagree.
|
|
73
|
+
- **Contract modules the provider binds** (the layer-4 source types) live in the app's shared source zone — importable by both provider and consumer builds — not in the test tree; `tests/contract/` holds only the fixtures and fakes compiled from them.
|
|
74
|
+
|
|
53
75
|
## Bridge to the obligation ledger
|
|
54
76
|
|
|
55
77
|
The `test-plan` skill's ledger assigns each obligation a runner altitude — `unit` / `component` / `integration` / `e2e`. Those are coarse names for where a test *runs*; the strata here say what it may *assert*. The mapping:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nurix/etna",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.50",
|
|
4
4
|
"description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"agent",
|
|
43
43
|
"plugin"
|
|
44
44
|
],
|
|
45
|
-
"etnaFingerprint": "
|
|
45
|
+
"etnaFingerprint": "21e5266250ca"
|
|
46
46
|
}
|