@nurix/etna 0.18.19 → 0.18.20

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 (94) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/code/harness.json +2 -2
  3. package/data/harnesses/code/skills/design/SKILL.md +65 -0
  4. package/data/harnesses/code/skills/design/data/catalog/rules.csv +132 -0
  5. package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +317 -0
  6. package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +235 -0
  7. package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +232 -0
  8. package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +220 -0
  9. package/data/harnesses/code/skills/design/data/design-md/library/apple.md +220 -0
  10. package/data/harnesses/code/skills/design/data/design-md/library/binance.md +223 -0
  11. package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +219 -0
  12. package/data/harnesses/code/skills/design/data/design-md/library/cal.md +220 -0
  13. package/data/harnesses/code/skills/design/data/design-md/library/clay.md +220 -0
  14. package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +220 -0
  15. package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +227 -0
  16. package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +237 -0
  17. package/data/harnesses/code/skills/design/data/design-md/library/composio.md +220 -0
  18. package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +220 -0
  19. package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +220 -0
  20. package/data/harnesses/code/skills/design/data/design-md/library/expo.md +228 -0
  21. package/data/harnesses/code/skills/design/data/design-md/library/figma.md +221 -0
  22. package/data/harnesses/code/skills/design/data/design-md/library/framer.md +236 -0
  23. package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +220 -0
  24. package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +234 -0
  25. package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +240 -0
  26. package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +236 -0
  27. package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +237 -0
  28. package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +220 -0
  29. package/data/harnesses/code/skills/design/data/design-md/library/meta.md +220 -0
  30. package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +220 -0
  31. package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +220 -0
  32. package/data/harnesses/code/skills/design/data/design-md/library/miro.md +233 -0
  33. package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +220 -0
  34. package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +236 -0
  35. package/data/harnesses/code/skills/design/data/design-md/library/notion.md +220 -0
  36. package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +222 -0
  37. package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +226 -0
  38. package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +223 -0
  39. package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +234 -0
  40. package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +220 -0
  41. package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +220 -0
  42. package/data/harnesses/code/skills/design/data/design-md/library/resend.md +285 -0
  43. package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +225 -0
  44. package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +219 -0
  45. package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +251 -0
  46. package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +244 -0
  47. package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +227 -0
  48. package/data/harnesses/code/skills/design/data/design-md/library/slack.md +240 -0
  49. package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +252 -0
  50. package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +248 -0
  51. package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +241 -0
  52. package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +255 -0
  53. package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +226 -0
  54. package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +233 -0
  55. package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +248 -0
  56. package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +220 -0
  57. package/data/harnesses/code/skills/design/data/design-md/library/uber.md +220 -0
  58. package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +220 -0
  59. package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +245 -0
  60. package/data/harnesses/code/skills/design/data/design-md/library/warp.md +220 -0
  61. package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +220 -0
  62. package/data/harnesses/code/skills/design/data/design-md/library/wired.md +220 -0
  63. package/data/harnesses/code/skills/design/data/design-md/library/wise.md +220 -0
  64. package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +220 -0
  65. package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +238 -0
  66. package/data/harnesses/code/skills/design/data/design-md/nurix.md +217 -0
  67. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +249 -0
  68. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +249 -0
  69. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +248 -0
  70. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +245 -0
  71. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +223 -0
  72. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +249 -0
  73. package/data/harnesses/code/skills/design/data/operator-pack/fixtures.md +88 -0
  74. package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +132 -0
  75. package/data/harnesses/code/skills/design/data/operator-pack/trust-rubric.md +76 -0
  76. package/data/harnesses/code/skills/design/references/create.md +126 -0
  77. package/data/harnesses/code/skills/design/references/diagnosis.md +108 -0
  78. package/data/harnesses/code/skills/design/references/hard-rules.md +155 -0
  79. package/data/harnesses/code/skills/design/references/improve.md +85 -0
  80. package/data/harnesses/code/skills/design/references/interaction.md +77 -0
  81. package/data/harnesses/code/skills/design/references/introspect.md +100 -0
  82. package/data/harnesses/code/skills/design/references/lifecycle.md +73 -0
  83. package/data/harnesses/code/skills/design/references/personality.md +504 -0
  84. package/data/harnesses/code/skills/design/references/structure.md +138 -0
  85. package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +706 -0
  86. package/data/harnesses/code/skills/design/scripts/detector.mjs +898 -0
  87. package/data/harnesses/code/skills/design/scripts/generate-fixtures.mjs +551 -0
  88. package/data/harnesses/code/skills/design/scripts/hook-config.json +11 -0
  89. package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +386 -0
  90. package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +280 -0
  91. package/data/harnesses/code/skills/design/scripts/render-rung.mjs +690 -0
  92. package/data/harnesses/code/skills/design/scripts/scaffold.mjs +552 -0
  93. package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +432 -0
  94. package/package.json +1 -1
@@ -0,0 +1,100 @@
1
+ # Introspect
2
+
3
+ The workflow that explains **why** a UI isn't working. Loaded when the front gate routes to introspect. Diagnoses with the shared engine (`diagnosis.md`); hands findings to `improve.md` on consent. Reads code — never edits it.
4
+
5
+ ## The deliverable is understanding
6
+
7
+ Introspect produces a causal explanation, not a fix. The badness a user reports is always felt in **Perception** — the table looks noisy, the page feels heavy, nothing tells you where to look. Its cause almost always lives one layer down, in **Structure** (how it's built) or **Behavior** (how it responds). The run's job is to walk that chain and name every link, so the reader finishes understanding not just *what* is wrong but *why the thing they felt is produced by the thing they didn't see*.
8
+
9
+ ## The run
10
+
11
+ 1. **Ask the reader.** One question, before anything else (below).
12
+ 2. **Diagnose** with `diagnosis.md`: passes run causes-first — Structure → Behavior → Perception — producing severity-ranked canonical findings. Introspect invents no diagnosis of its own.
13
+ 3. **Explain** each finding as a causal chain narrated the other way: from where the badness is felt (Perception) down to where its cause lives (Structure or Behavior).
14
+ 4. **Render** every finding in the reader's register.
15
+ 5. **File** the dated report; **offer** the improve handoff.
16
+
17
+ ## The reader question
18
+
19
+ Asked at invocation, every run, verbatim:
20
+
21
+ > Who is reading this — a designer, a developer, or a PM/general reader?
22
+
23
+ Never inferred from the brief. Never a stored default carried from a prior run — ask again every time. Asking costs a beat and is never wrong; a silent guess about the reader is how one diagnosis turns into the wrong three sentences.
24
+
25
+ The register is presentation only. It changes how a finding is *said*, never what the finding *is* — it is not an axis on the UI or on the diagnosis.
26
+
27
+ ## The three registers
28
+
29
+ One diagnosis, three renderings. Same evidence, same fix, same severity — never three different opinions.
30
+
31
+ - **Designer** — the untranslated finding, in design language: dimensions, hierarchy, the causal chain as-is. No translation; the finding is already in their tongue.
32
+ - **Developer** — the finding compiled to code-speak: the token, the file, the line site, the exact edit, and whether it stays within existing levers.
33
+ - **PM / general reader** — the finding translated to outcomes: what the operator loses today, what changes after the fix, and roughly what it costs.
34
+
35
+ ### Worked example — one finding, three ways
36
+
37
+ Canonical finding (fields owned by `diagnosis.md`):
38
+
39
+ - **dimension** · B1 Interactive States **cause layer** · Behavior **tier** · within-levers **severity** · major **provenance** · B1 Interactive States (states-presence)
40
+ - **felt symptom (Perception)** · on first load the queue renders as an empty, misaligned frame, then snaps into place when rows arrive
41
+ - **evidence** · `src/routes/queue/QueueRoute.tsx:28` — `<QueueTable rows={data}>` renders unconditionally while `data` is `[]` during the fetch
42
+ - **before → after** · no loading state → the lifecycle pattern's skeleton, column-geometry-matched, shown while `isLoading`
43
+ - **consequence** · every visit shows a flash of broken-looking UI and a layout shift; the queue reads as *failing* before it reads as *loading*
44
+
45
+ Rendered per register:
46
+
47
+ - **Designer** · "The queue has no loading state: it paints its empty frame before data arrives, so the first thing an operator sees is a broken, misaligned table that then jumps. Give it a skeleton matched to the column geometry, held until rows load. A surface that reads as broken before it reads as loading erodes trust on every visit. (Interactive states; cause in Behavior; major.)"
48
+ - **Developer** · "`src/routes/queue/QueueRoute.tsx:28` — `<QueueTable rows={data}>` renders while `data` is `[]` during the fetch. Branch on `isLoading` and render the lifecycle skeleton (column-width-matched rows) until the query resolves. Within existing levers; no token or manifest change. (B1, Behavior; major.)"
49
+ - **PM** · "The queue looks broken for a moment every time it opens, then jumps into place — it needs a real loading state so it reads as loading, not failing. Low effort; removes a daily 'is this thing working?' flinch for every agent. (Major.)"
50
+
51
+ The designer hears design, the developer gets the branch and the file, the PM gets the cost and the outcome — one diagnosis underneath all three.
52
+
53
+ ## The findings report
54
+
55
+ Every run files a dated report — introspection doubles as documentation, so a run that produced understanding doesn't evaporate with the conversation. The path is shared with review reports:
56
+
57
+ ```
58
+ docs/design/findings/YYYY-MM-DD-<slug>.md
59
+ ```
60
+
61
+ `<slug>` names the target (the surface, or the app). The report carries the canonical findings so a consented improve run consumes it directly, topped with a two-line executive summary in the chosen register. It is a deliverable, not runtime state — never read back as design state (code is the cache, floor P8).
62
+
63
+ ### Template
64
+
65
+ ```
66
+ # Introspection — <target> · <YYYY-MM-DD>
67
+
68
+ Reader: <designer | developer | pm>
69
+ Scope: <surface / dimension / whole app examined>
70
+
71
+ ## Summary
72
+ <two lines, in the chosen register — the shape of what's wrong and what it costs>
73
+
74
+ ## Findings
75
+ <severity-ranked: auto-critical → critical → major → minor; canonical format per diagnosis.md>
76
+
77
+ ### <n>. <one-line title> — <severity>
78
+ - dimension · cause layer · tier · provenance
79
+ - evidence: <file:line / token / value>
80
+ - before → after: <token-cited; numeric where machine-backed>
81
+ - consequence: <what it costs the operator>
82
+ - <the finding rendered in the chosen register>
83
+
84
+ ## Handoff
85
+ Findings share the canonical format. To apply, run improve over this report:
86
+ within-levers findings apply jailed; lever-change findings need lever consent.
87
+ ```
88
+
89
+ Severity is a ranked scale, never a number — no scores, ever.
90
+
91
+ ## The improve handshake
92
+
93
+ Introspect diagnoses; it never touches app code. When the user wants the findings applied, the same canonical findings feed an improve run (D10's escalation, run in reverse): the report *is* the input — improve reads it directly because both share the finding format. Scope covers what the findings name; depth is apply; authority follows each finding's tier — **within-levers** findings apply jailed to the lever manifest, **lever-change** findings are offered and need lever consent, never changed unbidden. The handoff is offered, never automatic.
94
+
95
+ ## Never
96
+
97
+ - Never edit code — introspect reads, diagnoses, explains, and files the report; fixes happen only through a consented improve run.
98
+ - Never infer or store the reader — ask, every run.
99
+ - Never let a register become three opinions — it is presentation of one diagnosis.
100
+ - Never emit a numeric score — severity rank only.
@@ -0,0 +1,73 @@
1
+ # Lifecycle & microcopy
2
+
3
+ The states a surface actually lives in, and the microcopy mechanisms that fill them. The brief describes the happy path; production is mostly everything else — loading at 9am, empty for a new tenant, degraded and half-stale at 3am. A surface designed only for the state the brief names is a broken surface.
4
+
5
+ **Loads** at the create **surfaces** phase (state-shells get filled here) and whenever improve/introspect diagnoses state or copy coverage. Reads the `temporal` facts from `docs/design/structure.md`; the state-presence and copy-shape rules (`sta-*`) are already in boot context via `hard-rules.md` — this file is the design content behind them, not a restatement. Dial defaults come from `personality.md`.
6
+
7
+ ## The seam: mechanisms, not words
8
+
9
+ Everything here is a **mechanism** — a formula, a required shape, a consistency discipline. The actual words are the business's call (floor P12). The skill enforces that an error names what happened / why / how to fix; it never writes the error text. It enforces one term per concept; it never picks the term. Emit shells and shapes; leave the vocabulary to the domain.
10
+
11
+ ## Required states per surface
12
+
13
+ Four states are **always** required on every data surface: **loading**, **empty**, **error**, **partial/degraded**. They are not afterthoughts — they are the surface. Beyond the four, these are required **only where the model says they exist**, and the model is `docs/design/structure.md`'s `temporal` block, not a guess:
14
+
15
+ - **post-action** — an action passes through pending/saving/processing before it resolves.
16
+ - **cancel path** — a long or reversible action can be abandoned mid-flight.
17
+ - **disconnection / timeout** — the surface can lose the backend.
18
+ - **concurrent edit** — two operators can touch one record at once.
19
+
20
+ The temporal probe (run inside the object pass — see `structure.md`) is what decides which conditional states a surface carries; read its facts, don't invent them.
21
+
22
+ **States are built into the shell, never bolted on.** The scaffold phase already stubbed every declared state per surface (the state-shell stubs). The surfaces phase composes real content into those stubs. A shell whose `error` or `empty` slot ships as a placeholder is an unfinished surface and fails the phase gate. You are never adding states to a finished surface — you are filling shells that already exist.
23
+
24
+ ## Empty states
25
+
26
+ An empty state is not one state. Five are distinct, and each earns distinct copy — collapsing them into one generic "No data found" is the defect:
27
+
28
+ | Kind | It means | The copy teaches |
29
+ | --- | --- | --- |
30
+ | first-time | nothing created yet | what this surface is for, how to make the first thing |
31
+ | user-cleared | they emptied it | that the clear worked, how to undo or add again |
32
+ | no-results | filter/search matched nothing | that data exists, that the filter is the cause |
33
+ | no-access | forbidden, not empty | that it exists but is gated, who to ask |
34
+ | error | the fetch failed | routes to the error formula below, never to "empty" |
35
+
36
+ **The empty formula: acknowledge → state the value → at most one action.** Text-first (floor P2) — copy plus at most one action, never an illustration showcase. *At most* one, not exactly one: a read-only surface (an audit log) legitimately offers zero. Never a dead-end on an actionable surface. Copy runs one to two sentences.
37
+
38
+ ## Errors
39
+
40
+ **The error formula: what happened / why / how to fix.** All three parts. "Something went wrong" fails all three — it diagnoses nothing, explains nothing, offers no recovery, and is a named defect.
41
+
42
+ **Dead ends and silent failures are banned.** Every error is visible and every error has an exit. A failure the operator can't see and a failure they can see but can't act on are the same bug.
43
+
44
+ **Errors render inline, next to the offending field** — not in a banner divorced from the cause. The exception is genuinely system-wide failure (the backend is down, not one field is invalid), which legitimately banners; that scope is why the inline rule grades warning-tier, not absolute.
45
+
46
+ ## Temporal honesty
47
+
48
+ Render the read model's lag honestly. When a write isn't yet visible in the read model, show a **pending state** — never paint the optimistic result as settled truth. Pending is not a lie; a premature success is.
49
+
50
+ - **Skeletons mirror the content's shape**, not a centered spinner — the same columns, rows, and blocks the loaded surface will show. **Delay showing ~150–300ms** so a fast response never flashes a skeleton. The full loading-indicator bands (nothing under the short threshold, skeleton in the mid band, progress bar past the long one) are pinned by `mot-*`.
51
+ - **Optimistic updates only for low-stakes actions, always with a visible rollback surface** — the row reverts and says why when the write loses. High-stakes or irreversible actions wait for the server (pessimistic) and preview before commit.
52
+ - **Distinguish "no data" from "can't get data."** Empty means the query succeeded and found nothing; degraded means the query failed or the data is stale. **Mark staleness honestly** — a panel showing a cached value while its source is unreachable says so.
53
+
54
+ ## Toasts
55
+
56
+ Toasts acknowledge transient, low-stakes success — nothing that needs action. **Auto-dismiss 3–5s, `aria-live="polite"`, never steal focus** (pinned in `sta-*`). An actionable error never lives only in a toast that vanishes; it goes inline where the operator can act on it. A toast is never the only signal for something the operator must do.
57
+
58
+ ## Copy disciplines
59
+
60
+ Two disciplines govern every visible string, and they apply to UI copy, help text, and API names alike:
61
+
62
+ - **One term per concept, one concept per term.** If the thing is a "ticket," it is a ticket in the label, the tooltip, the empty state, the toast, and the endpoint. Two words for one concept, or one word for two, is the defect. Divergence is allowed only when deliberate — a legacy-locked internal name may lag a renamed label — never accidental.
63
+ - **Verb+object action labels.** "Create ticket," "Assign agent," "Archive job" — never bare "Submit," "OK," "Done." The label states the object it acts on.
64
+
65
+ Both ride **sentence case** (not Title Case, not ALL CAPS outside tracked micro-labels) and **front-loading** — put the information-bearing word first so a scanning eye catches meaning at the left edge. "Payment failed — card declined," not "There was a problem processing your payment." Front-load labels, headings, menu items, and column headers.
66
+
67
+ ## The copy self-audit
68
+
69
+ A pre-ship mandatory procedure (`proc-*`, fires in the whole-app sweep): **re-read every visible string on every surface and rewrite every flagged one.** This is the pass that kills lorem-slop, fabricated metrics, generic "No data found" empties, and dead-end errors in one sweep — and the pass that verifies one-term-per-concept held across the whole app, not just per file. No surface ships un-audited.
70
+
71
+ ## Dials modulate presentation
72
+
73
+ Lifecycle presentation is dial-controlled, never per-surface improvisation. `data-verbosity` scales how much status copy renders — `full` spells out pending and progress narration, `expert` compresses it. `data-feedback` scales feedback intensity — how often toasts fire, how much motion a state transition carries. The dials compose *with* density, never instead of it. Their levels, defaults, and wiring live in `personality.md`; this file governs the states, not the knobs.