@nurix/etna 0.19.87 → 0.19.88
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/data/harness-index.json +1 -1
- package/data/harnesses/code/docs/structure.md +11 -0
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/skills/documentation/SKILL.md +1 -0
- package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -0
- package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +66 -0
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/documentation/SKILL.md +1 -0
- package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -0
- package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +66 -0
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/documentation/SKILL.md +1 -0
- package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -0
- package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +66 -0
- package/package.json +2 -2
package/data/harness-index.json
CHANGED
|
@@ -16,6 +16,8 @@ Each topic has one canonical location. Read from here, not from plans or changel
|
|
|
16
16
|
| API surface | `docs/architecture/` | api.md |
|
|
17
17
|
| Security | `docs/architecture/` | security.md |
|
|
18
18
|
| Feature behavior | `docs/features/` | one `kebab-case.md` doc per feature |
|
|
19
|
+
| UX behavior — one surface | `docs/features/` | `{surface}-ux.md`, `type: ux` |
|
|
20
|
+
| UX behavior — cross-cutting (routing, information architecture, stream presentation) | `docs/architecture/` | `type: ux`, owns no code |
|
|
19
21
|
| Product specification (PRD, personas, journeys, information architecture) | `docs/architecture/` | prd.md, personas.md, journeys.md, information-architecture.md |
|
|
20
22
|
| Acceptance criteria | `docs/acceptance/` | one `kebab-case.md` doc per capability, `AC-n` keyed assert lines |
|
|
21
23
|
| Setup & development | `docs/operations/` | setup.md |
|
|
@@ -48,6 +50,15 @@ Every doc is a **truth document** (states current absolutes, topic-named, update
|
|
|
48
50
|
never by renumbering. Distinct from `docs/tests/`: acceptance criteria state what the product
|
|
49
51
|
promises up front; the checklists in `docs/tests/` are the verification gate's own driving
|
|
50
52
|
scripts, authored and maintained at the gate.
|
|
53
|
+
- **UX behavior** (`type: ux`) is placed by **scope, never by medium** — there is no `docs/ui/`.
|
|
54
|
+
One surface's observable behavior is a feature concern and lives beside its LLD as
|
|
55
|
+
`docs/features/{surface}-ux.md`; routing, information architecture, and the presentation
|
|
56
|
+
contracts every surface obeys are whole-product concerns the interface merely renders, so they
|
|
57
|
+
live in `docs/architecture/` and own no code. The genre exists because an LLD states what a
|
|
58
|
+
feature *is* — which stays plausibly true through a rewrite of the surface — while nothing else
|
|
59
|
+
states what a person *observes*, so a wire change lands, the interface absorbs it, and the
|
|
60
|
+
absorption reads as maintenance. This document is what such a change contradicts. It **decides**
|
|
61
|
+
behavior and is written before the code; the `docs/tests/` checklist only verifies it afterwards.
|
|
51
62
|
- `docs/tests/`: Testing strategy and test docs. Present when the repo has a test posture worth documenting.
|
|
52
63
|
- `docs/history/plans/`: Records. Must have `Status:` field. Never modify after completion.
|
|
53
64
|
- `docs/history/changelog/`: Records. One entry per unit of work (`YYYY-MM-DD-{three-words}.md`), written by whoever does the work and frozen inside the commit it describes. Entries carry the refinement context a diff cannot show — the ask in the user's words, iterations and rejections, skill survived/overridden verdicts, discoveries, pins. Format is the `documentation` skill's `templates/changelog-entry.md`; trigger and lifecycle are the `changelog` rule; distillation is the `retro` agent. Immutability begins at commit — a draft in the working tree is mutable until then, never after. Every entry appends a row to `docs/history/CHANGELOG.md`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "code",
|
|
3
3
|
"name": "code",
|
|
4
|
-
"version": "3.10.
|
|
4
|
+
"version": "3.10.12",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
"docs/memory/main.md",
|
|
16
16
|
".mcp.json"
|
|
17
17
|
],
|
|
18
|
-
"digest": "
|
|
18
|
+
"digest": "8b4f074b1311"
|
|
19
19
|
}
|
|
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
71
71
|
| Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
|
|
72
72
|
| Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
|
|
73
73
|
| Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
|
|
74
|
+
| What a person sees and can do on a surface (UX behavior) | [`templates/ux-behavior.md`](templates/ux-behavior.md) — decides observable behavior BEFORE the code; per-surface in `docs/features/{surface}-ux.md` owning the component globs, cross-cutting in `docs/architecture/`. Not the checklist, which only verifies it |
|
|
74
75
|
| Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
|
|
75
76
|
| Acceptance criteria for one capability (`docs/acceptance/{capability}.md`) | [`templates/acceptance-criteria.md`](templates/acceptance-criteria.md) — the promises the built product must keep, as stable `AC-n` keyed assert lines verification surfaces parse as claims |
|
|
76
77
|
| Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
|
|
@@ -15,6 +15,7 @@ One file per template. Every template is either a **truth document** (states cur
|
|
|
15
15
|
| Security overview | [security-overview.md](security-overview.md) | Truth |
|
|
16
16
|
| Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
|
|
17
17
|
| Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
|
|
18
|
+
| UX behavior | [ux-behavior.md](ux-behavior.md) | Truth |
|
|
18
19
|
| Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
|
|
19
20
|
| Implementation map | [implementation-map.md](implementation-map.md) | Truth |
|
|
20
21
|
| Bookkeeping ledger | [bookkeeping.md](bookkeeping.md) | Truth (work queue) |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# UX Behavior — template
|
|
2
|
+
|
|
3
|
+
**Truth document.** States what a person sees and can do on a surface, and what the surface promises never to do. Present tense, like every truth document.
|
|
4
|
+
|
|
5
|
+
**`type: ux`.**
|
|
6
|
+
|
|
7
|
+
**Why this genre exists.** A feature doc (LLD) states what a feature is, how its data flows, and which contracts it honours — all of which stay plausibly true through a rewrite of the surface. Nothing else in the repo states what a person *observes*. So a change to the wire lands, the interface absorbs it, and the absorption reads as maintenance: no test fails, no lint fires, no document is contradicted. This document is the thing a silent change contradicts.
|
|
8
|
+
|
|
9
|
+
**Not a test plan.** `docs/tests/{feature}.md` records that behavior was driven and holds `Pinned:` traces; this document *decides* the behavior it later verifies. Written after the code, it is a transcript. Write it first.
|
|
10
|
+
|
|
11
|
+
**Scope decides placement, not medium.**
|
|
12
|
+
|
|
13
|
+
| The behavior is… | Where it lives |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| One surface's — a panel, an editor, a dialog | `docs/features/{surface}-ux.md`, with `owns:` over that surface's component paths |
|
|
16
|
+
| Cross-cutting — routing, information architecture, the state vocabulary every surface obeys, presentation of streams | `docs/architecture/` — owns no code, like every architecture doc |
|
|
17
|
+
|
|
18
|
+
**Ownership: take the component globs only where they are unclaimed.** A surface's components are frequently already owned — by the page's LLD, by the feature behind one panel — and claiming them again is an ownership conflict, not protection. So: unclaimed globs go in `owns:`; otherwise the doc declares `owns: []` and is named in each owning LLD's **coordinated edits** row, phrased as *different axes, not a conflict* — the LLD owns the code, this document owns what a person observes.
|
|
19
|
+
|
|
20
|
+
That matters because a doc nothing implicates is a doc that rots, and a surface rewritten under an unimplicated document is the failure this genre exists to prevent. The coordinated-edit row is the weaker of the two bindings; prefer real ownership wherever the globs are free.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Required sections
|
|
25
|
+
|
|
26
|
+
### Purpose
|
|
27
|
+
|
|
28
|
+
One sentence: what a person comes to this surface to do. Then the sharper half — **what this surface is not for**, naming the neighbouring surface that is. A purpose that admits everything cannot refuse anything, and a surface that cannot refuse accretes.
|
|
29
|
+
|
|
30
|
+
### Anatomy
|
|
31
|
+
|
|
32
|
+
The regions, and what each is for. An ASCII sketch beats a paragraph. Name each region the way the interface names it, not the way the component tree does — a reader holds the screen, not the file list.
|
|
33
|
+
|
|
34
|
+
### States
|
|
35
|
+
|
|
36
|
+
**The complete set, exhaustively.** Every surface has more states than its happy path, and an unenumerated state is one the interface improvised — which is exactly how a surface starts lying. One row per state: what causes it, what a person sees, and what they can do from it.
|
|
37
|
+
|
|
38
|
+
| State | Entered when | The person sees | Can do |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
|
|
41
|
+
Never omit a state because it is rare or ugly. The failed, empty, and stale states are the ones a person meets on their worst day, and they are the ones no one designs.
|
|
42
|
+
|
|
43
|
+
### Affordances
|
|
44
|
+
|
|
45
|
+
What a person can do, and what each action does. A disabled control states why it is disabled — a control that is simply inert teaches nothing and gets clicked again.
|
|
46
|
+
|
|
47
|
+
### Promises
|
|
48
|
+
|
|
49
|
+
**What this surface never does**, stated as absolutes. This is the section the rest of the system is measured against: a backend change that would break one of these is a breaking change, whoever ships it. Write the ones that are easy to violate accidentally — never silently discard typed input, never show a completed state over incomplete work, never move a control under a cursor mid-interaction.
|
|
50
|
+
|
|
51
|
+
### Transitions
|
|
52
|
+
|
|
53
|
+
What moves the surface between states, and who causes each move — the person, the server, or elapsed time. Server-caused transitions are the ones worth naming precisely, because they are the ones a person did not ask for.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Optional sections
|
|
58
|
+
|
|
59
|
+
**Copy** — the exact words, where the wording is load-bearing (a refusal, an irreversible confirmation). **Density and rhythm** — where a surface deliberately differs from the design system's default. **Open questions** — decisions deliberately not yet made, so an implementer knows what to ask rather than guessing.
|
|
60
|
+
|
|
61
|
+
## Rules
|
|
62
|
+
|
|
63
|
+
- **Present tense, no history.** The journey lives in `docs/history/`; this document simply becomes correct.
|
|
64
|
+
- **Describe the observable, not the implementation.** "The rail shows every phase, the current one marked" — never "`railFromView` maps `view.phases`". Naming a component in a UX document is a boundary leak, and the name goes stale before the behavior does.
|
|
65
|
+
- **Every state gets a person-facing sentence.** If you cannot say what a person sees, the state is not designed yet — write it as an open question rather than eliding it.
|
|
66
|
+
- **No screenshots.** They rot invisibly and cannot be diffed.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "delivery",
|
|
3
3
|
"name": "delivery",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
8
8
|
".vscode/settings.json"
|
|
9
9
|
],
|
|
10
10
|
"seeds": [],
|
|
11
|
-
"digest": "
|
|
11
|
+
"digest": "a11ca1e20bd4"
|
|
12
12
|
}
|
|
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
71
71
|
| Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
|
|
72
72
|
| Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
|
|
73
73
|
| Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
|
|
74
|
+
| What a person sees and can do on a surface (UX behavior) | [`templates/ux-behavior.md`](templates/ux-behavior.md) — decides observable behavior BEFORE the code; per-surface in `docs/features/{surface}-ux.md` owning the component globs, cross-cutting in `docs/architecture/`. Not the checklist, which only verifies it |
|
|
74
75
|
| Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
|
|
75
76
|
| Acceptance criteria for one capability (`docs/acceptance/{capability}.md`) | [`templates/acceptance-criteria.md`](templates/acceptance-criteria.md) — the promises the built product must keep, as stable `AC-n` keyed assert lines verification surfaces parse as claims |
|
|
76
77
|
| Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
|
|
@@ -15,6 +15,7 @@ One file per template. Every template is either a **truth document** (states cur
|
|
|
15
15
|
| Security overview | [security-overview.md](security-overview.md) | Truth |
|
|
16
16
|
| Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
|
|
17
17
|
| Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
|
|
18
|
+
| UX behavior | [ux-behavior.md](ux-behavior.md) | Truth |
|
|
18
19
|
| Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
|
|
19
20
|
| Implementation map | [implementation-map.md](implementation-map.md) | Truth |
|
|
20
21
|
| Bookkeeping ledger | [bookkeeping.md](bookkeeping.md) | Truth (work queue) |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# UX Behavior — template
|
|
2
|
+
|
|
3
|
+
**Truth document.** States what a person sees and can do on a surface, and what the surface promises never to do. Present tense, like every truth document.
|
|
4
|
+
|
|
5
|
+
**`type: ux`.**
|
|
6
|
+
|
|
7
|
+
**Why this genre exists.** A feature doc (LLD) states what a feature is, how its data flows, and which contracts it honours — all of which stay plausibly true through a rewrite of the surface. Nothing else in the repo states what a person *observes*. So a change to the wire lands, the interface absorbs it, and the absorption reads as maintenance: no test fails, no lint fires, no document is contradicted. This document is the thing a silent change contradicts.
|
|
8
|
+
|
|
9
|
+
**Not a test plan.** `docs/tests/{feature}.md` records that behavior was driven and holds `Pinned:` traces; this document *decides* the behavior it later verifies. Written after the code, it is a transcript. Write it first.
|
|
10
|
+
|
|
11
|
+
**Scope decides placement, not medium.**
|
|
12
|
+
|
|
13
|
+
| The behavior is… | Where it lives |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| One surface's — a panel, an editor, a dialog | `docs/features/{surface}-ux.md`, with `owns:` over that surface's component paths |
|
|
16
|
+
| Cross-cutting — routing, information architecture, the state vocabulary every surface obeys, presentation of streams | `docs/architecture/` — owns no code, like every architecture doc |
|
|
17
|
+
|
|
18
|
+
**Ownership: take the component globs only where they are unclaimed.** A surface's components are frequently already owned — by the page's LLD, by the feature behind one panel — and claiming them again is an ownership conflict, not protection. So: unclaimed globs go in `owns:`; otherwise the doc declares `owns: []` and is named in each owning LLD's **coordinated edits** row, phrased as *different axes, not a conflict* — the LLD owns the code, this document owns what a person observes.
|
|
19
|
+
|
|
20
|
+
That matters because a doc nothing implicates is a doc that rots, and a surface rewritten under an unimplicated document is the failure this genre exists to prevent. The coordinated-edit row is the weaker of the two bindings; prefer real ownership wherever the globs are free.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Required sections
|
|
25
|
+
|
|
26
|
+
### Purpose
|
|
27
|
+
|
|
28
|
+
One sentence: what a person comes to this surface to do. Then the sharper half — **what this surface is not for**, naming the neighbouring surface that is. A purpose that admits everything cannot refuse anything, and a surface that cannot refuse accretes.
|
|
29
|
+
|
|
30
|
+
### Anatomy
|
|
31
|
+
|
|
32
|
+
The regions, and what each is for. An ASCII sketch beats a paragraph. Name each region the way the interface names it, not the way the component tree does — a reader holds the screen, not the file list.
|
|
33
|
+
|
|
34
|
+
### States
|
|
35
|
+
|
|
36
|
+
**The complete set, exhaustively.** Every surface has more states than its happy path, and an unenumerated state is one the interface improvised — which is exactly how a surface starts lying. One row per state: what causes it, what a person sees, and what they can do from it.
|
|
37
|
+
|
|
38
|
+
| State | Entered when | The person sees | Can do |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
|
|
41
|
+
Never omit a state because it is rare or ugly. The failed, empty, and stale states are the ones a person meets on their worst day, and they are the ones no one designs.
|
|
42
|
+
|
|
43
|
+
### Affordances
|
|
44
|
+
|
|
45
|
+
What a person can do, and what each action does. A disabled control states why it is disabled — a control that is simply inert teaches nothing and gets clicked again.
|
|
46
|
+
|
|
47
|
+
### Promises
|
|
48
|
+
|
|
49
|
+
**What this surface never does**, stated as absolutes. This is the section the rest of the system is measured against: a backend change that would break one of these is a breaking change, whoever ships it. Write the ones that are easy to violate accidentally — never silently discard typed input, never show a completed state over incomplete work, never move a control under a cursor mid-interaction.
|
|
50
|
+
|
|
51
|
+
### Transitions
|
|
52
|
+
|
|
53
|
+
What moves the surface between states, and who causes each move — the person, the server, or elapsed time. Server-caused transitions are the ones worth naming precisely, because they are the ones a person did not ask for.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Optional sections
|
|
58
|
+
|
|
59
|
+
**Copy** — the exact words, where the wording is load-bearing (a refusal, an irreversible confirmation). **Density and rhythm** — where a surface deliberately differs from the design system's default. **Open questions** — decisions deliberately not yet made, so an implementer knows what to ask rather than guessing.
|
|
60
|
+
|
|
61
|
+
## Rules
|
|
62
|
+
|
|
63
|
+
- **Present tense, no history.** The journey lives in `docs/history/`; this document simply becomes correct.
|
|
64
|
+
- **Describe the observable, not the implementation.** "The rail shows every phase, the current one marked" — never "`railFromView` maps `view.phases`". Naming a component in a UX document is a boundary leak, and the name goes stale before the behavior does.
|
|
65
|
+
- **Every state gets a person-facing sentence.** If you cannot say what a person sees, the state is not designed yet — write it as an open question rather than eliding it.
|
|
66
|
+
- **No screenshots.** They rot invisibly and cannot be diffed.
|
|
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
71
71
|
| Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
|
|
72
72
|
| Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
|
|
73
73
|
| Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
|
|
74
|
+
| What a person sees and can do on a surface (UX behavior) | [`templates/ux-behavior.md`](templates/ux-behavior.md) — decides observable behavior BEFORE the code; per-surface in `docs/features/{surface}-ux.md` owning the component globs, cross-cutting in `docs/architecture/`. Not the checklist, which only verifies it |
|
|
74
75
|
| Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
|
|
75
76
|
| Acceptance criteria for one capability (`docs/acceptance/{capability}.md`) | [`templates/acceptance-criteria.md`](templates/acceptance-criteria.md) — the promises the built product must keep, as stable `AC-n` keyed assert lines verification surfaces parse as claims |
|
|
76
77
|
| Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
|
|
@@ -15,6 +15,7 @@ One file per template. Every template is either a **truth document** (states cur
|
|
|
15
15
|
| Security overview | [security-overview.md](security-overview.md) | Truth |
|
|
16
16
|
| Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
|
|
17
17
|
| Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
|
|
18
|
+
| UX behavior | [ux-behavior.md](ux-behavior.md) | Truth |
|
|
18
19
|
| Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
|
|
19
20
|
| Implementation map | [implementation-map.md](implementation-map.md) | Truth |
|
|
20
21
|
| Bookkeeping ledger | [bookkeeping.md](bookkeeping.md) | Truth (work queue) |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# UX Behavior — template
|
|
2
|
+
|
|
3
|
+
**Truth document.** States what a person sees and can do on a surface, and what the surface promises never to do. Present tense, like every truth document.
|
|
4
|
+
|
|
5
|
+
**`type: ux`.**
|
|
6
|
+
|
|
7
|
+
**Why this genre exists.** A feature doc (LLD) states what a feature is, how its data flows, and which contracts it honours — all of which stay plausibly true through a rewrite of the surface. Nothing else in the repo states what a person *observes*. So a change to the wire lands, the interface absorbs it, and the absorption reads as maintenance: no test fails, no lint fires, no document is contradicted. This document is the thing a silent change contradicts.
|
|
8
|
+
|
|
9
|
+
**Not a test plan.** `docs/tests/{feature}.md` records that behavior was driven and holds `Pinned:` traces; this document *decides* the behavior it later verifies. Written after the code, it is a transcript. Write it first.
|
|
10
|
+
|
|
11
|
+
**Scope decides placement, not medium.**
|
|
12
|
+
|
|
13
|
+
| The behavior is… | Where it lives |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| One surface's — a panel, an editor, a dialog | `docs/features/{surface}-ux.md`, with `owns:` over that surface's component paths |
|
|
16
|
+
| Cross-cutting — routing, information architecture, the state vocabulary every surface obeys, presentation of streams | `docs/architecture/` — owns no code, like every architecture doc |
|
|
17
|
+
|
|
18
|
+
**Ownership: take the component globs only where they are unclaimed.** A surface's components are frequently already owned — by the page's LLD, by the feature behind one panel — and claiming them again is an ownership conflict, not protection. So: unclaimed globs go in `owns:`; otherwise the doc declares `owns: []` and is named in each owning LLD's **coordinated edits** row, phrased as *different axes, not a conflict* — the LLD owns the code, this document owns what a person observes.
|
|
19
|
+
|
|
20
|
+
That matters because a doc nothing implicates is a doc that rots, and a surface rewritten under an unimplicated document is the failure this genre exists to prevent. The coordinated-edit row is the weaker of the two bindings; prefer real ownership wherever the globs are free.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Required sections
|
|
25
|
+
|
|
26
|
+
### Purpose
|
|
27
|
+
|
|
28
|
+
One sentence: what a person comes to this surface to do. Then the sharper half — **what this surface is not for**, naming the neighbouring surface that is. A purpose that admits everything cannot refuse anything, and a surface that cannot refuse accretes.
|
|
29
|
+
|
|
30
|
+
### Anatomy
|
|
31
|
+
|
|
32
|
+
The regions, and what each is for. An ASCII sketch beats a paragraph. Name each region the way the interface names it, not the way the component tree does — a reader holds the screen, not the file list.
|
|
33
|
+
|
|
34
|
+
### States
|
|
35
|
+
|
|
36
|
+
**The complete set, exhaustively.** Every surface has more states than its happy path, and an unenumerated state is one the interface improvised — which is exactly how a surface starts lying. One row per state: what causes it, what a person sees, and what they can do from it.
|
|
37
|
+
|
|
38
|
+
| State | Entered when | The person sees | Can do |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
|
|
41
|
+
Never omit a state because it is rare or ugly. The failed, empty, and stale states are the ones a person meets on their worst day, and they are the ones no one designs.
|
|
42
|
+
|
|
43
|
+
### Affordances
|
|
44
|
+
|
|
45
|
+
What a person can do, and what each action does. A disabled control states why it is disabled — a control that is simply inert teaches nothing and gets clicked again.
|
|
46
|
+
|
|
47
|
+
### Promises
|
|
48
|
+
|
|
49
|
+
**What this surface never does**, stated as absolutes. This is the section the rest of the system is measured against: a backend change that would break one of these is a breaking change, whoever ships it. Write the ones that are easy to violate accidentally — never silently discard typed input, never show a completed state over incomplete work, never move a control under a cursor mid-interaction.
|
|
50
|
+
|
|
51
|
+
### Transitions
|
|
52
|
+
|
|
53
|
+
What moves the surface between states, and who causes each move — the person, the server, or elapsed time. Server-caused transitions are the ones worth naming precisely, because they are the ones a person did not ask for.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Optional sections
|
|
58
|
+
|
|
59
|
+
**Copy** — the exact words, where the wording is load-bearing (a refusal, an irreversible confirmation). **Density and rhythm** — where a surface deliberately differs from the design system's default. **Open questions** — decisions deliberately not yet made, so an implementer knows what to ask rather than guessing.
|
|
60
|
+
|
|
61
|
+
## Rules
|
|
62
|
+
|
|
63
|
+
- **Present tense, no history.** The journey lives in `docs/history/`; this document simply becomes correct.
|
|
64
|
+
- **Describe the observable, not the implementation.** "The rail shows every phase, the current one marked" — never "`railFromView` maps `view.phases`". Naming a component in a UX document is a boundary leak, and the name goes stale before the behavior does.
|
|
65
|
+
- **Every state gets a person-facing sentence.** If you cannot say what a person sees, the state is not designed yet — write it as an open question rather than eliding it.
|
|
66
|
+
- **No screenshots.** They rot invisibly and cannot be diffed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nurix/etna",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.88",
|
|
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": "417d61b8de2d"
|
|
46
46
|
}
|