@3xhaust/oh-my-design 0.16.1

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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +282 -0
  3. package/README.md +282 -0
  4. package/adapters/build.ts +184 -0
  5. package/adapters/claude.ts +111 -0
  6. package/adapters/codex.ts +68 -0
  7. package/adapters/tokens.ts +21 -0
  8. package/adapters/tool-map.json +7 -0
  9. package/bin/omd-install.ts +76 -0
  10. package/bin/omd.ts +1774 -0
  11. package/core/asset-sourcing/index.ts +187 -0
  12. package/core/coach/index.ts +98 -0
  13. package/core/composition/app-shell-workbench.md +168 -0
  14. package/core/composition/asymmetric-diagonal-grid.md +178 -0
  15. package/core/composition/bento-grid.md +223 -0
  16. package/core/composition/editorial-index-labels.md +173 -0
  17. package/core/composition/form-wizard-stepper.md +132 -0
  18. package/core/composition/master-detail-flow.md +129 -0
  19. package/core/composition/section-inversion.md +182 -0
  20. package/core/composition/sidebar-margin-annotation.md +184 -0
  21. package/core/composition/split-screen-hero.md +224 -0
  22. package/core/composition/sticky-sidebar-scroll.md +219 -0
  23. package/core/composition/typographic-hero.md +100 -0
  24. package/core/composition-contract/index.ts +233 -0
  25. package/core/composition-contract/visual-richness.ts +101 -0
  26. package/core/config/index.ts +27 -0
  27. package/core/copy/index.ts +296 -0
  28. package/core/craft/finish-pass.md +356 -0
  29. package/core/craft/index.ts +33 -0
  30. package/core/design/index.ts +581 -0
  31. package/core/design/interaction-states.ts +189 -0
  32. package/core/eval-harness/index.ts +225 -0
  33. package/core/evidence/final.ts +444 -0
  34. package/core/evidence/task.ts +459 -0
  35. package/core/figma/client.ts +312 -0
  36. package/core/figma/diff.ts +261 -0
  37. package/core/figma/responsive.ts +310 -0
  38. package/core/figma/system.ts +466 -0
  39. package/core/figma/types.ts +185 -0
  40. package/core/frame/check-ux.ts +180 -0
  41. package/core/frame/index.ts +39 -0
  42. package/core/frame/write.ts +168 -0
  43. package/core/graphics/css-illustration-primitives.md +189 -0
  44. package/core/graphics/duotone-image-presets.md +173 -0
  45. package/core/graphics/gradient-mesh.md +178 -0
  46. package/core/graphics/noise-grain-texture.md +150 -0
  47. package/core/graphics/placeholder-policy.md +185 -0
  48. package/core/graphics/svg-geometric-patterns.md +145 -0
  49. package/core/history/index.ts +39 -0
  50. package/core/install/detect.ts +32 -0
  51. package/core/install/install.ts +321 -0
  52. package/core/install/patch-claude.ts +109 -0
  53. package/core/install/patch-codex.ts +82 -0
  54. package/core/interaction/index.ts +101 -0
  55. package/core/interaction/recipes/signature-lighting.md +203 -0
  56. package/core/ir/dom.ts +352 -0
  57. package/core/ir/normalize.ts +177 -0
  58. package/core/motion/easing.md +151 -0
  59. package/core/motion/energy.ts +188 -0
  60. package/core/motion/recipes/image-hover-distortion.md +198 -0
  61. package/core/motion/recipes/magnetic-hover.md +229 -0
  62. package/core/motion/recipes/marquee.md +202 -0
  63. package/core/motion/recipes/number-counter.md +242 -0
  64. package/core/motion/recipes/page-loader.md +240 -0
  65. package/core/motion/recipes/parallax.md +233 -0
  66. package/core/motion/recipes/scroll-reveal.md +210 -0
  67. package/core/motion/recipes/section-color-inversion.md +217 -0
  68. package/core/motion/recipes/split-text-entrance.md +222 -0
  69. package/core/motion/recipes/stagger-orchestrator.md +227 -0
  70. package/core/motion/recipes/sticky-scene-transition.md +246 -0
  71. package/core/motion/recipes/view-transitions.md +239 -0
  72. package/core/probe/index.ts +186 -0
  73. package/core/probe/schema.json +46 -0
  74. package/core/protocol/composition-contract.md +192 -0
  75. package/core/protocol/copy-deck.md +96 -0
  76. package/core/protocol/human-design-loop.md +447 -0
  77. package/core/protocol/slop-review.md +71 -0
  78. package/core/ref/batch.ts +94 -0
  79. package/core/ref/blueprint.ts +199 -0
  80. package/core/ref/distance.ts +225 -0
  81. package/core/ref/invariants.ts +162 -0
  82. package/core/ref/signal.ts +37 -0
  83. package/core/ref/store.ts +122 -0
  84. package/core/render/index.ts +607 -0
  85. package/core/rules/attribution.ts +159 -0
  86. package/core/rules/builtin/contrast.yaml +8 -0
  87. package/core/rules/builtin/focus.yaml +8 -0
  88. package/core/rules/builtin/hit-area.yaml +8 -0
  89. package/core/rules/builtin/ko.yaml +6 -0
  90. package/core/rules/builtin/motion.yaml +80 -0
  91. package/core/rules/builtin/slop.yaml +365 -0
  92. package/core/rules/builtin/spacing.yaml +9 -0
  93. package/core/rules/builtin/system.yaml +42 -0
  94. package/core/rules/builtin/token.yaml +8 -0
  95. package/core/rules/builtin/ux.yaml +125 -0
  96. package/core/rules/engine.ts +88 -0
  97. package/core/rules/leakage.ts +72 -0
  98. package/core/rules/motion-spec.ts +204 -0
  99. package/core/site/index.ts +100 -0
  100. package/core/slop/index.ts +427 -0
  101. package/core/slop/text-slop.ts +220 -0
  102. package/core/source-seal/index.ts +174 -0
  103. package/core/stack/index.ts +53 -0
  104. package/core/target/index.ts +183 -0
  105. package/core/theory/color.md +285 -0
  106. package/core/theory/components.md +272 -0
  107. package/core/theory/craft.md +270 -0
  108. package/core/theory/expressive.md +213 -0
  109. package/core/theory/imagegen.md +105 -0
  110. package/core/theory/layout.md +159 -0
  111. package/core/theory/motion.md +283 -0
  112. package/core/theory/typography.md +134 -0
  113. package/core/theory/ux.md +580 -0
  114. package/core/theory/voice.md +595 -0
  115. package/core/types.ts +684 -0
  116. package/package.json +40 -0
  117. package/src/agents/composer.agent.yaml +174 -0
  118. package/src/agents/eye.agent.yaml +208 -0
  119. package/src/agents/framer.agent.yaml +52 -0
  120. package/src/agents/glance.agent.yaml +19 -0
  121. package/src/agents/hand.agent.yaml +200 -0
  122. package/src/agents/scout.agent.yaml +71 -0
  123. package/src/agents/sketch.agent.yaml +64 -0
  124. package/src/agents/typesetter.agent.yaml +52 -0
  125. package/src/agents/writer.agent.yaml +63 -0
  126. package/src/skills/omd-coach/SKILL.md +40 -0
  127. package/src/skills/omd-critique/SKILL.md +77 -0
  128. package/src/skills/omd-figma/SKILL.md +256 -0
  129. package/src/skills/omd-humanize/SKILL.md +160 -0
  130. package/src/skills/omd-scout/SKILL.md +77 -0
  131. package/src/skills/omd-ultradesign/SKILL.md +521 -0
@@ -0,0 +1,96 @@
1
+ # Copy deck protocol
2
+
3
+ `.omd/copy-deck.md` is the sole durable source for copy that ships. Analytical metadata
4
+ and headings are English. Actual surface copy and verbatim audience/source quotations stay
5
+ in the target language. The writer owns this file; layout and implementation agents consume
6
+ it without silently rewriting it.
7
+
8
+ Use these H2 sections exactly and keep every section non-empty.
9
+
10
+ ## Sources and fact ledger
11
+
12
+ Use an explicit ledger. Every factual claim that ships references a `verified` ID. `fixture`
13
+ rows exist only to test layout density and must never ship as achievements, customers,
14
+ prices, certifications, or testimonials. `open` rows are unresolved and cannot support
15
+ shipped claims. If evidence is unavailable, write action, label, or recovery copy that needs
16
+ no factual claim instead of inventing one.
17
+
18
+ | ID | Status | Source | Fact |
19
+ | --- | --- | --- | --- |
20
+ | F-001 | verified | User brief or cited URL | Exact supported fact |
21
+ | F-002 | fixture | Density fixture | Clearly fictional layout-only value |
22
+ | F-003 | open | Evidence needed from owner | Unresolved fact, not for shipping |
23
+
24
+ ## Audience language
25
+
26
+ Record cited or verbatim audience language, its source, and the implication for wording.
27
+ Keep quotations in the audience's language; never translate them into analytical English.
28
+
29
+ ## Voice contract
30
+
31
+ Declare exactly one of each required field, then record vocabulary, sentence breath,
32
+ terminology, and words to avoid:
33
+
34
+ - **Audience**: the specific reader and situation
35
+ - **Language**: target language code, such as `ko`
36
+ - **Register**: the chosen register, such as `해요체`
37
+
38
+ For Korean, choose one register, read every line aloud, and keep one breath per sentence.
39
+
40
+ ## Surface copy
41
+
42
+ Give every page or surface its own H3 block with exactly one `Main message`, `Supporting fact`,
43
+ `Next action`, and `Claim refs` field. Include real title, body, label, CTA, and representative
44
+ data. Do not repeat the same proposition across title/body/CTA. A CTA predicts what happens
45
+ immediately after activation. `Claim refs` is exactly `none` or a comma-separated explicit ID
46
+ list such as `F-001, F-004`; commentary or garbage suffixes are invalid.
47
+
48
+ Portfolio and landing heroes state audience value or proven work; they do not narrate the
49
+ document or design process with lines such as “과정을 남깁니다” or “순서대로 씁니다.”
50
+
51
+ ## Navigation and actions
52
+
53
+ List destination, visible label, immediate result, and return/next action for every primary
54
+ navigation or case-study path. Labels describe the destination rather than generic intent.
55
+
56
+ ## States and recovery
57
+
58
+ Declare one field exactly:
59
+
60
+ - **Interaction scope**: `stateful` | `navigation-only` | `static`
61
+ - **Primary copy**: shipped primary-path text
62
+ - **Recovery copy**: shipped recovery text, or `N/A — explicit reason`
63
+ - **Primary probe**: `.omd/probes/primary.json`, or `N/A — explicit reason`
64
+ - **Recovery probe**: `.omd/probes/recovery.json`, or `N/A — explicit reason`
65
+
66
+ Each of these five fields appears exactly once; duplicates are ambiguous and fail the gate.
67
+
68
+ `stateful` requires primary and recovery copy plus both probes. `navigation-only` requires
69
+ primary copy and a primary probe; recovery copy/probe are N/A with reasons. `static` requires
70
+ primary copy; recovery copy and both probes are N/A with reasons. Write error, empty,
71
+ disabled, offline, and recovery strings only where the product can actually reach those
72
+ states. Never fabricate error or empty UI to satisfy a checklist.
73
+
74
+ ## Humanize audit
75
+
76
+ Record these fields for the reviewed surface:
77
+
78
+ - **Input contract**: speaker; listener; situation; intended change/next move; genre/register;
79
+ verified facts and verbatim quotes
80
+ - **Mode**: `local repair` | `reconstruct from facts`
81
+ - **Fidelity**: factual-ledger diff, uncertainty retained, quote status, and claim refs
82
+ - **Root cause**: the discourse problem repaired, or `none` with a reason
83
+ - **Next action**: the concrete action/state the final text makes available
84
+ - **Owner handoff**: writer changed deck -> copy check -> hand synchronizes source, or N/A
85
+
86
+ Also record proposition repetition, CTA prediction, terminology, read-aloud/register,
87
+ emotion, and applicable error/empty/recovery/accessibility checks. This is a review record,
88
+ not a style score or detector report. Missing input-contract context is a gap for the writer,
89
+ not permission for another agent to invent it.
90
+
91
+ The deterministic gate rejects only missing structure, invalid scope/state applicability,
92
+ unresolved exact sentinels, and broken explicit fact references. It never judges AI-ness,
93
+ sentence variance, common words, perplexity, or whether a claim is semantically true.
94
+ An unresolved sentinel is a whole value or marker such as `TODO`, `Label: TBD`, `[TODO]`,
95
+ `[PLACEHOLDER]`, or a placeholder comment. Normal copy such as `TODO 목록 보기` or
96
+ `TBD라는 약어를 설명합니다` is not a sentinel.
@@ -0,0 +1,447 @@
1
+ # Human design loop protocol
2
+
3
+ This is the durable contract for an OMD run. Host prompts may explain it, but may not
4
+ reorder it:
5
+
6
+ `preflight -> frame -> concept -> research -> writer copy deck -> copy check -> blind copy
7
+ edit -> preserve copy-eye report -> copy review-check -> writer revision -> copy check -> typesetter proof -> blind type review -> type
8
+ revision/proof pass -> composition contract/check -> structural sketches -> blind selection -> production build ->
9
+ semantic checkpoint -> selected-container type reproof -> visual checkpoint -> squint
10
+ glance -> source candidate scan/triage -> sharp critique/probe -> repair/rescan -> reframe ->
11
+ ship`.
12
+
13
+ ## Stack routing
14
+
15
+ Apply one precedence everywhere: explicit user request > existing repository stack/toolchain
16
+ (including existing vanilla HTML) > React + Vite + TypeScript only for a truly blank
17
+ greenfield. Plain HTML greenfield requires an explicit user request. There is no autonomous
18
+ single-static-surface exception. Before the hand's first write it reads the brief,
19
+ package.json when present, and one representative existing surface/component when present,
20
+ then records the stack choice and evidence. Preserve and investigate an unrecognised package
21
+ or toolchain; never cover it with a React scaffold. Greenfield scaffold dependencies are
22
+ allowed. Existing projects receive no unnecessary dependencies.
23
+ An "existing repository stack" is a real project the user brought — a package manifest, a build
24
+ config, or files the user points at. A bare `index.html`/`.css`/`.js` with no manifest, next to an
25
+ `.omd/` from a prior OMD run, is OMD's own leftover output, not a user stack: a fresh brief there is
26
+ a greenfield (React + Vite + TypeScript by default), and a prior run's output never pins the stack.
27
+ Immediately after scaffold/dependency resolution, resolve every newly introduced import/export
28
+ against the exact installed versions, parse generated configuration with its owning tool, and run
29
+ focused typecheck, build, and test-discovery. Repeat this smoke verification after every
30
+ dependency, dependency-API, or configuration change; retain the full final verification.
31
+
32
+ ## State boundary
33
+
34
+ Durable, reviewable state lives under `.omd/`: `frame.md`, `scout.md`, `copy-deck.md`,
35
+ `type-proof.md`, `composition.md`, `decisions.md`, `design.md`, `attribution.md`, `motion-spec.md`, `craft.jsonl`,
36
+ `source-seal.json`, `task-evidence.json`, `task-evidence-runs/*.json`, `final-evidence.json`,
37
+ `final-evidence-runs/<runId>.json`, `config.json`, `probes/*.json`, `refs/*.json`, and explicit
38
+ taste records. `task-evidence.json` and `final-evidence.json` are validated current indexes; their
39
+ run records preserve immutable prior publications. Reusable intent and final evidence identity
40
+ belong there, while generated screenshots and raw execution output do not.
41
+
42
+ Ephemeral state lives under `.omd/.cache/`: raw build/check/test/probe/render output, renders,
43
+ filmstrips, typography specimens, structural candidates, raw source-candidate JSON, and scratch
44
+ output. All ordinary evidence artifacts are cache-local; the deliberate published
45
+ `.omd/task-evidence.json` index is the sole artifact-path exception. It can be deleted without
46
+ erasing a design decision or the durable final-evidence index. Accepted and dismissed candidate
47
+ reasoning is durable and belongs in `.omd/decisions.md`.
48
+
49
+ ## Evidence and taste precedence
50
+
51
+ When evidence conflicts, apply this order and record the conflict:
52
+
53
+ 1. the current brief;
54
+ 2. explicit feedback from the current user in this run;
55
+ 3. prior explicit project taste recorded with verbatim evidence;
56
+ 4. agent choices and legacy/unknown records.
57
+
58
+ Never infer user taste from an agent selection, silence, an unchanged screen, or legacy
59
+ choice data. Coach remains taste-blind.
60
+
61
+ ## Surface grammar
62
+
63
+ The frame records a surface classification (`uxSurface`: `marketing` | `product` |
64
+ `editorial` | `mixed`, per `theory/ux.md` §Surface types) alongside the primary task,
65
+ frequent action, and costliest error; `FRAME-UX-INCOMPLETE` flags a frame that skipped any
66
+ of the four. The classification selects the composition grammar downstream: a `product`
67
+ work surface composes as a task loop over screen regions and reachable states with the
68
+ work object as the dominant first-viewport anchor at representative density — never as a
69
+ marketing message ladder with a hero band. A `product` or `mixed` surface always completes
70
+ the `omd design` contract (information architecture and interaction states) before
71
+ production. Selector and critique eyes read their frozen dimensions through the same
72
+ grammar: on a product surface a "section" is a screen region or reachable state and the
73
+ "CTA" is the frequent action.
74
+ ## Feature-level reference research and transfer
75
+
76
+ Reference synthesis starts from function, not mood. Field names, record shape, axis vocabulary, and validation belong exclusively to `protocol/composition-contract.md`. This protocol governs only when synthesis applies and how it flows: select **Branch A — explicit functions** when the user named detailed features, preserving each feature and deriving its interaction primitives directly; add only indispensable connective or recovery primitives, marked as inferred with an assumption. Select **Branch B — product goal only** only for `product` work and product screens of `mixed` work when detailed functions are absent; first record the smallest task-complete feature set and every assumption. Explicit details always win. An inferred addition needs a task-completion dependency and may not add optional analytics, AI, collaboration, personalization, admin, export, or adjacent capability. Pure `marketing`, `editorial`, and static work does not infer CRUD, state machinery, probes, or task evidence; it transfers only explicit applicable content or interaction primitives. User-origin references receive a concrete canonical synthesis record or an explicit decline individually; scout-found sources cannot satisfy an omitted user-reference mention. Source identity stays scout-side: downstream receives only stable source keys/labels, trust, uncertainty, and sanitized rules—not URLs, screenshots, pixels, or source-page descriptions. Synthesis records never issue `T#`, create probes, alter task coverage, or redefine task/final-evidence contracts.
77
+ ## Visual reference gallery and concept exploration
78
+
79
+ Function fixes structure; a production-grade result also needs a deliberate visual system, so visual reference discovery is a first-class research obligation, not optional polish. For every surface the scout treats curated design galleries and inspiration sources — for example Pinterest, Dribbble, Mobbin, Behance, Land-book, Godly, Savee, and equivalent boards — as an admissible visual reference category alongside domain and competitor evidence, and captures enough high-craft main-screen references for the product's domain and register to support a visual decision. It sanitizes each into the canonical multi-axis synthesis (macro layout, density, typography, spacing/rhythm, component anatomy, surface/material, colour role, motion). Gallery evidence obeys the same clean-room boundary as every other source: no raw URL, screenshot, pixel sample, or source-page description travels downstream, and no gallery image is copied — only measured, sanitized principles transfer. Build for coverage, not counts, and report no capture quota.
80
+
81
+ Concept selection is exploratory, not a single guess. Grounded in that gallery and domain evidence, the concept stage enumerates multiple distinct main-screen visual directions — each a named generator/metaphor, colour and typographic register, surface/material stance, density posture, and one memorable moment — then blind-selects the strongest direction and records it durably with its rejected alternatives. The number of directions scales with ambition and uncertainty; an awards-level or explicitly ambitious brief explores more. This visual-direction selection is a direction signal only: it never replaces the structural sketch divergence, the task/accessibility/viewport UX gates, the blind copy/type/critique gates, or the clean-room boundary, and the chosen direction still passes `omd composition --check` and every downstream gate. A result whose visual system is a generic default — unstyled or stock controls, flat undifferentiated fields, weak typographic hierarchy, arbitrary whitespace, or no distinctive surface/material and colour system — fails the visual acceptance gate even when every task succeeds; beautiful production-grade UI and sound UX are co-equal requirements.
82
+ ## Support-chat conditional regression
83
+ A support-ticket conversation is a conditional primitive regression, never a default grammar. When explicitly requested or task-completely inferred, its transfer requires customer-left/agent-right direction, intrinsic content width with a max-width cap, machine-readable timestamps, a declared temporal compatibility window, temporal grouping that merges consecutive same-sender messages within that window and splits an expired-window reply into a new group with fresh sender/time metadata, distinct internal-note treatment and vocabulary, an anchored composer, and deliberate mobile recomposition. Generic full-width message slabs fail. Production probes/tests prove both temporal boundaries: a same-sender reply within the declared window merges without a duplicate sender/time group, and an expired-window same-sender reply splits into a new group with fresh metadata. After commit, the new bubble must be visibly revealed in the desktop and mobile conversation viewport; a toast or offscreen DOM text alone fails. Require immediate repeated-send regression and visible-last-bubble evidence. Do not apply these conversation traits to non-conversation, marketing, editorial, or static surfaces.
84
+
85
+ ## Task coverage matrix
86
+
87
+ For `product` and the product screens of `mixed` surfaces, the frame owns `Task coverage matrix`
88
+ as a durable section. It is the only issuer of stable rows `T1`, `T2`, and so
89
+ on; rows cover every explicit user core task and invariant, not merely the primary
90
+ task, frequent action, or costliest error. Each row records the user-visible goal,
91
+ start state, minimal actions, success observable, applicable error/recovery, and
92
+ required viewport(s). `N/A` is valid only with evidence that the field or task is
93
+ inapplicable. These are production tasks and production-reachable states: a component
94
+ showcase or gallery is never evidence that a task or state is reachable. `marketing`,
95
+ `editorial`, and static-only work does not invent a matrix, tasks, states, or probes;
96
+ `mixed` records rows only for its product screens.
97
+ For a requested or task-completely inferred list→detail workspace with two or more work objects, the frame includes a production `T#` whose actions open a non-default, non-first object and whose success observable asserts that detail's identity and object-local state. Selection is keyed to the work-object identity, never a fixture identifier or list position; the bound production locator/probe exercises that same non-primary selection. This rule is conditional on that workspace shape and does not impose list-detail tasks on non-list-detail product, marketing, editorial, or static surfaces.
98
+
99
+ ## UX task coverage
100
+ This protocol exclusively owns the exact `## UX task coverage` schema, including row syntax,
101
+ cardinality, applicability, and locator semantics. Roles may state their mapping responsibility
102
+ and point here, but must not restate that schema.
103
+
104
+ For every applicable frame-owned `T#`, the composer preserves that id and maps it 1:1
105
+ into a named `## UX task coverage` section. Each nonblank row in that section uses this
106
+ exact syntax: `T# | production: /route | locator: selector |`. There is exactly one row
107
+ per applicable `T#` and no showcase, gallery, demo, fixture, or additional prose row.
108
+ `/route` is the local production-reachable path; `selector` is the unique stable semantic
109
+ action locator for that task at every required viewport. Repeated controls include their
110
+ operated work-object identity in the locator contract, and accessible names remain stable
111
+ across responsive hiding unless the action itself changes. The mapping realizes the frame
112
+ row's goal, actions, success observable, applicable recovery, required viewports, and
113
+ `requirements` field through the bound production path, probes, and renders. The hand
114
+ consumes these existing mappings; it never creates a new `T#` or a row merely because a
115
+ state is reachable. Showcase-only controls and gallery states do not count.
116
+
117
+ A user-requested invalid submit remains attemptable when it is part of a task: its
118
+ production evidence proves an actionable error and preserved entered values. Preventing the
119
+ attempt with a disabled control is acceptable only when that prevention matches the user
120
+ contract and the row explains why; it must not make a requested invalid-submit path
121
+ unreachable. `requirements: invalid-submit` requires an invalid-submit probe; `requirements:
122
+ transient` requires settled or reduced-motion PNG pixels for the transient state; `none`
123
+ requires neither.
124
+
125
+ ## Task evidence index
126
+
127
+ For `product` and `mixed` only, the hand writes
128
+ `.omd/.cache/task-evidence-manifest.json` from actual production probe plans/results and
129
+ desktop/mobile renders, then runs `omd evidence tasks --input
130
+ .omd/.cache/task-evidence-manifest.json` followed by `omd evidence tasks-check --json`.
131
+ The manifest is schema version `1` with exactly `schemaVersion`, `surface`, `frame`,
132
+ `composition`, and `tasks`. `surface` equals the frame's `uxSurface`; `frame` and `composition`
133
+ bind their canonical `.omd` paths and SHA-256 values. Every task has `id`, `context: production`,
134
+ `production` (`route`, `locator`, `workObject`), actual `probes`, and actual `renders`; optional
135
+ `invalidSubmit` and `transient` evidence are present exactly when the frame row's `requirements`
136
+ demands them. Every probe record, including `invalidSubmit`, has `role`, `viewport`, plan/result
137
+ cache paths, and SHA-256 values. For every viewport required by the frame row, a task has exactly
138
+ one `primary` probe; when recovery applies, it has exactly one distinct `recovery` probe for that
139
+ same viewport. A probe result must be a successful local production route run. Its activation
140
+ step uses the task's production locator, and that same step's declared successful expectations
141
+ prove the task outcome. Invalid-submit evidence orders a fill of one field and an enabled
142
+ production-locator activation; that activation step's expectations prove the actionable error and
143
+ preservation of that same field's entered value.
144
+
145
+ Each render is a decoded PNG at exactly `1280x900` for `desktop` or `390x844` for `mobile`; it
146
+ uses the fixed viewport named by its role, never a full-page substitute. A transient record has
147
+ `probeRole`, `viewport`, `stepIndex`, `stateSelector`, `path`, `sha256`, and `captureMode`; it
148
+ binds its probe role and exact viewport to the successful activation step at `stepIndex` and its
149
+ successful state selector, uses `settled` or `reduced-motion`, and is a decoded fixed-viewport PNG
150
+ with a coherent visible state region rather than merely non-uniform pixels. The published
151
+ `.omd/task-evidence.json` is the validated immutable production index, not a hand-written
152
+ substitute. `marketing`, `editorial`, and static-only runs omit this manifest and index entirely.
153
+
154
+ When user-origin references exist, the scout records sanitized multi-axis feature/primitive transfers, and the composer preserves each in the canonical `Reference synthesis` plan at its declared destination or explicitly declines it; `omd composition --check` still fails when a user reference is absent. The hand implements each accepted transfer at that landing or records an evidence-backed deviation. The sharp eye verifies visible structural/behavioral correspondence across every applicable accepted axis at the named landing, not token resemblance; interaction correspondence requires matching probe evidence. The clean-room transfer boundary still governs every trait; a reference landing never creates or replaces a frame `T#` task locator.
155
+
156
+ ## Blindness and isolation
157
+
158
+ The composer owns only `.omd/composition.md`. After typography approval it receives the sanitized frame/concept, clean copy deck, approved type proof, and durable scout summary when present. Reference transfer input is limited to stable source keys/labels, trust, uncertainty, and sanitized multi-axis feature/primitive rules, adaptations, token variation, conflicts, and destination criteria; it receives no raw screenshots, source files, pixel samples, URLs, source-page descriptions, candidate renders, rejected alternatives, or authorship. It turns evidence into a structural contract, records exact SHA-256 fingerprints, and runs `omd composition --check` before divergence.
159
+
160
+ Each sketch receives only a sanitized frame/concept, the copy deck, the approved typography
161
+ contract derived from `.omd/type-proof.md`, the same sanitized `.omd/composition.md`, an
162
+ anonymous candidate id, and one axis from its Candidate axes section. The contracts expose
163
+ approved structural dependencies, roles, family, weight, size/measure, and wrapping
164
+ constraints, not rejected-alternative rationale or authorship. A sketch preserves both
165
+ contracts, varies only its assigned axis, cannot invent a new type scale, cannot read or
166
+ reuse another candidate, and writes only to `.omd/.cache/sketches/<id>/`. It preserves the
167
+ first-viewport anchor, lawful media or alternate mental-model carrier, uninterrupted CTA
168
+ cue/path, and responsive relationships. A visible CTA plus a predictable completion path
169
+ proves reach; the terminal form/control surface need not be above fold and earns no credit
170
+ merely for being there. A photo is never mandatory.
171
+
172
+ The copy editor is a fresh eye context and sees only the sanitized brief, copy deck/fact
173
+ ledger, and cited voice/audience evidence. It sees no renders, layout, code, build rationale,
174
+ frame, decisions, or authorship, and it reports without editing.
175
+ This protocol exclusively owns the exact copy-eye report format, including its fields and
176
+ cardinality. Roles may state their review or preservation responsibility and point here, but
177
+ must not restate that format.
178
+ The coordinator first
179
+ preserves the report verbatim at `.omd/.cache/copy-eye.md` with exact `Mode: copy-editor`,
180
+ `Review time: <ISO 8601 timestamp>`, `Reviewed copy-deck SHA-256: <64 lowercase hex>`,
181
+ `Verdict: <non-empty verdict>`, and a non-empty `Findings:` section. It immediately runs
182
+ `omd copy --review-check`; a failure stops writer revision and divergence until the report
183
+ format is repaired. This gate checks report structure only. It neither proves blindness or
184
+ semantic review quality nor requires the reviewed hash to equal the current deck. Only after
185
+ the gate passes does the writer receive the findings and revise the deck before another
186
+ deterministic check. The writer's revision and final `omd copy --check` are later, separate
187
+ evidence. Never replace the reviewed hash with the final deck hash or imply the eye reviewed
188
+ bytes it never saw.
189
+
190
+ The typesetter owns `.omd/type-proof.md` and `.omd/.cache/type-proof/`. It sees the clean
191
+ copy deck, typography theory, and scout typography evidence, but does not design composition,
192
+ colour, graphics, motion, or rewrite copy. A fresh eye in typography-proof mode sees only
193
+ desktop/mobile specimens plus sanitized copy and typography requirements. It never sees
194
+ authorship, references, rationale, page structure, colour, or code and never edits.
195
+
196
+ The selector gets a fresh context and sees anonymous renders plus the sanitized frame, copy
197
+ deck, typography contract, and the same sanitized composition contract. It scores exactly:
198
+ task/CTA clarity, narrative dependency, composition rhythm, concept-specific form,
199
+ responsive hierarchy, type/copy accommodation, interaction/form usability risk, and
200
+ accessibility/implementation cost. It never sees candidate prose, author identity, reference
201
+ attribution, or the production plan. Each candidate supplies fixed 1280x900 and 390x844
202
+ renders plus full-page desktop/mobile continuity captures. Fixed renders govern acceptance;
203
+ full-page captures inform only narrative dependency and composition rhythm.
204
+
205
+ The selector uses the frozen anchors: 0 absent/broken (missing or task-blocking); 1 weak
206
+ (major contradictions/failures dominate); 2 adequate (functional and understandable with
207
+ generic or consequential weaknesses); 3 strong (deliberate, task-specific, robust, only
208
+ minor weaknesses); 4 exceptional (unusually coherent/specific with no material desktop/
209
+ mobile contradiction). It reports eight integers, eight one-sentence visible-evidence
210
+ rationales, and their arithmetic mean. Contract violation or any dimension below 2 rejects
211
+ the candidate; a mean cannot hide a floor failure. It does not equate form-above-fold with
212
+ CTA reach or award concept-specific credit to a motif without a functional domain/evidence/
213
+ action relationship.
214
+
215
+ These dimension-specific anchors are frozen. Score 1 or 3 only by interpolating between the
216
+ adjacent 0/2/4 anchors; never replace them with a generic taste judgment:
217
+
218
+ - **Task/CTA clarity** — 0: no immediate primary CTA or completion path; entry or next action
219
+ is ambiguous or blocked. 2: the CTA is visible and usable with an understandable next step,
220
+ but feedback or the path is generic or weak. 4: an immediate primary CTA, predictable
221
+ completion path, and state feedback are unmistakable on desktop and mobile; a terminal form
222
+ is not required above the fold.
223
+ - **Narrative dependency** — 0: sections are interchangeable or out of order, or prerequisite
224
+ information is missing or follows the decision that needs it. 2: the sequence is
225
+ understandable, but some sections remain weakly dependent or generic. 4: every section
226
+ answers an entering question and creates a prerequisite for the next; removal or reordering
227
+ visibly weakens the narrative.
228
+ - **Composition rhythm** — 0: alignment, visual mass, negative space, span, and density are
229
+ arbitrary or monotonous and obscure hierarchy or sequence. 2: those five properties form a
230
+ workable hierarchy with generic or uneven transitions. 4: alignment, visual mass, negative
231
+ space, span, and density vary deliberately to stage the sequence and dominant anchor across
232
+ desktop and mobile, without an arbitrary break.
233
+ - **Concept-specific form** — 0: the result is a generic template or its motif/carrier is
234
+ decorative and unrelated to the domain. 2: a domain relationship is recognizable, but some
235
+ anatomy remains generic or ornamental. 4: motif, anchor, and carrier arise from the domain
236
+ mechanism, material, workflow, evidence, or action and govern functional relationships
237
+ rather than decoration.
238
+ - **Responsive hierarchy** — 0: mobile is a shrunken/stacked desktop with lost or cropped
239
+ content, a broken task path, or a broken anchor dependency. 2: usable reflow preserves
240
+ content and task reach, but priority or anchor recomposition is conventional or uneven.
241
+ 4: deliberate mobile recomposition preserves semantic order, dominant-anchor morphology,
242
+ priority, and an uninterrupted CTA/task path with no desktop-only dependency.
243
+ - **Type/copy accommodation** — 0: real copy truncates, overlaps, becomes placeholder content,
244
+ or breaks Korean wrapping, hierarchy, or CTA labels. 2: real copy fits and hierarchy remains
245
+ understandable, with minor awkward wraps, repetition, or density. 4: real Korean copy,
246
+ repeated data, and CTA labels are fully integrated; measure, wrapping, hierarchy, and
247
+ concept-bearing type remain robust on desktop and mobile.
248
+ - **Interaction/form usability risk** — 0: the primary task cannot succeed, or controls,
249
+ focus path, feedback, error/recovery, or a required reachable state is broken. 2: the primary
250
+ task works with adequate controls and states, but feedback, recovery, or an edge state has a
251
+ consequential non-blocking weakness. 4: task success, immediate feedback, focus path,
252
+ duplicate prevention, value preservation, and every applicable recovery/exit are robust in
253
+ supplied probes; inapplicable states are not invented.
254
+ - **Accessibility/implementation cost** — 0: contrast, focus/order, reflow, or target reach
255
+ fails, or the structure is impractical and visibly unfinished. 2: the implementation path is
256
+ credible and basic access works, but costly complexity or incomplete finish remains. 4:
257
+ contrast, keyboard focus/order, reflow, target reach, reduced motion, maintainable structure,
258
+ and applicable finish details form a credible, accessible, finished implementation.
259
+
260
+ If every candidate violates a contract or scores below 2 on any dimension, the selector
261
+ returns **no winner**. It never lowers the floor, averages away the failure, or selects the
262
+ closest candidate. From visible evidence only, it classifies the shared failure:
263
+
264
+ - **contract-level** — a supplied contract requirement creates the shared contradiction or
265
+ makes the acceptance criterion impossible to satisfy faithfully;
266
+ - **execution-level** — the approved contracts permit a passing answer, but the rendered
267
+ candidates fail to execute it.
268
+
269
+ Contract-level recovery starts one bounded replacement round with a fresh composer. The
270
+ composer receives only the sanitized shared visible contract conflict, never candidate
271
+ renders, scores, identities, or rationale; it revises `.omd/composition.md`, runs
272
+ `omd composition --check`, and produces a new composition hash. That new hash invalidates
273
+ every old candidate. Fresh sketch contexts then produce replacements under the revised
274
+ contract and their assigned axes. Execution-level recovery keeps the approved contracts and
275
+ also permits exactly one bounded replacement round in fresh sketch contexts. Each replacement
276
+ receives the same approved contracts and assigned axis plus only its own sanitized visible
277
+ failure and acceptance criteria—never numeric scores, another candidate or render, the prior
278
+ render/source, or candidate/selector rationale.
279
+
280
+ A fresh selector reviews the replacement set. This is the sole recovery round: if no
281
+ replacement passes, do not retry again. Reframe and stop with visible evidence, or pause only
282
+ when the configured structure checkpoint explicitly requires a human decision. Never create
283
+ an automatic retry loop or choose a failing candidate.
284
+
285
+ The glance receives only squint renders. It never sees sharp renders,
286
+ frame, decisions, references, or rationale. The general eye receives only a sanitized
287
+ review brief: primary task, costliest error, generator/register, the composition contract's
288
+ acceptance criteria without its source rationale—including focal hierarchy and lawful media
289
+ or alternate-carrier criteria—renders, and deterministic check/probe
290
+ output. For source-candidate judgment it additionally receives only candidate id,
291
+ controlled signals, and review question — never path, source excerpt, authorship, or rationale.
292
+ It must not read frame, decisions, references, or attribution rationale.
293
+ The sharp eye receives only sanitized multi-axis observed rules, adaptations, and destination landing criteria—never source identity, rationale, URL, screenshot, pixels, or source description. It verifies visible or probe-supported correspondence at the landing rather than destination tokens; interaction correspondence requires matching probe evidence. It fails a feature synthesis reduced to interaction-only or token-only treatment when applicable layout or visual-system axes lack an observed rule, adaptation, or reasoned `N/A`; it does not invent axes irrelevant to the feature.
294
+
295
+ ## Divergence and checkpoints
296
+
297
+ Structural divergence is conditional, not ceremonial: default to two independent sketches;
298
+ use three for showpiece work or high structural uncertainty/impact. Skip only when structure
299
+ is already supplied (for example, a Figma frame or explicit visual target), and record why.
300
+ Every sketch produces four proofs: fixed desktop 1280x900, fixed mobile 390x844, full-page
301
+ desktop continuity, and full-page mobile continuity. Full-page evidence is supplemental and
302
+ never replaces fixed-viewport acceptance.
303
+
304
+ The hand builds once. During that build it must render real content and record two craft
305
+ checkpoints: semantic layout, then the visual system before motion. After semantic structure
306
+ and before the visual checkpoint, it re-proves the approved typography inside the selected
307
+ production container at desktop and mobile. Each checkpoint names a concrete observation
308
+ and the resulting change. Human approval checkpoints are separate:
309
+ `.omd/config.json` defaults to `checkpoint: none`; concept, structure, or both are opt-in.
310
+ The hand receives the selected candidate and the same composition contract, runs
311
+ `omd composition --check` before its first production write and again before ship, and
312
+ records any deliberate deviation with visible evidence. A changed frame, copy deck, type
313
+ proof, or scout summary invalidates the contract and stops dependent work until recomposed.
314
+ The hand treats focal hierarchy and the lawful mechanism carrier or explicit alternate
315
+ mental-model carrier as production acceptance, preserves them responsively, and records
316
+ visible evidence or an evidence-backed deviation before the sharp eye judges them.
317
+ The hand receives only accepted sanitized transfer criteria, never raw URLs, screenshots, pixels, or source descriptions. It implements each criterion at its destination screen/route and unique semantic reference-landing selector, or records an evidence-backed deviation; transfer records do not create tasks or probes.
318
+
319
+ ## Safe probe policy
320
+
321
+ Probe only an explicit plan under `.omd/probes/*.json`. Plans are non-destructive and may
322
+ use only declared click, fill, and keypress steps with declared expectations. Probe only a
323
+ local file or localhost/loopback URL; reject remote, authenticated, credential, destructive,
324
+ or undeclared actions. Never discover controls and auto-click them. A probe warning can
325
+ come only from an expected tab order or a declared post-action expectation.
326
+
327
+ Squint rendering is a hierarchy-isolation aid: conservative blur plus grayscale. It is not
328
+ a colour-vision simulation and does not reproduce a literal timed first impression.
329
+
330
+ ## Source candidate triage
331
+
332
+ Read `protocol/slop-review.md`. After production source exists and before the final sharp
333
+ verdict, run `omd slop scan <root> --json` into `.omd/.cache/`. Candidate presence is not a
334
+ failed gate and is not a linter verdict. The coordinator marks every candidate `confirmed`,
335
+ `dismissed`, or `needs-render`. `needs-render` is transitional and must resolve after the
336
+ relevant sharp render. The final gate is zero untriaged and zero needs-render candidates. A
337
+ fresh eye judges only sanitized candidate metadata against sharp renders. Rendered IR is authoritative when
338
+ source and render overlap, and the two evidence streams are never merged or double-counted.
339
+
340
+ The hand repairs confirmed visual/source findings, then rerenders, runs `omd check`, and
341
+ rescans. Copy diagnosis may use humanize and a copy eye, but only the writer changes
342
+ `.omd/copy-deck.md`; the deck passes `omd copy --check` before the hand synchronizes source.
343
+ Changing copy, a claim, or an action invalidates the relevant blind copy review and type
344
+ proof. Durable evidence for a confirmed repair or dismissal goes to `.omd/decisions.md`.
345
+
346
+ Interaction scope in `.omd/copy-deck.md` owns applicability. `stateful` work requires
347
+ explicit `.omd/probes/primary.json` and `.omd/probes/recovery.json`, and both run through
348
+ `omd probe`. `navigation-only` requires only the primary probe; recovery copy/probe are N/A
349
+ with reasons. `static` records both probes N/A with reasons. Never add fake error, empty, or
350
+ recovery UI to make an inapplicable gate look complete. An eye makes interaction claims only
351
+ from supplied probe evidence.
352
+
353
+ ## UX acceptance contract
354
+
355
+ Every applicable surface names and verifies the primary task, most frequent action,
356
+ costliest-error recovery, an exit from every reachable state, immediate visible feedback,
357
+ and mobile reach. The hand reads the exact `theory/ux.md`, copy deck, and design contract;
358
+ uses native semantics; preserves form values on error; blocks duplicate submits; and honors
359
+ reduced motion. Loading, empty, error, success, disabled, and offline exist only when the
360
+ surface can reach them.
361
+
362
+ ## Production quality gates
363
+
364
+ These gates are part of every applicable production run, not optional polish:
365
+
366
+ - The coordinator never authors production copy. After scout, a fresh `omd-writer` writes
367
+ the deck, `omd copy --check` must pass, a fresh eye performs copy-editor mode, the writer
368
+ revises deck-first, and `omd copy --check` passes again before any sketch. A failed check
369
+ stops divergence and is fixed autonomously without waiting for the user.
370
+ - Preserve the copy-editor report at `.omd/.cache/copy-eye.md` with reviewed deck hash,
371
+ copy-editor mode/time, verdict, and findings. A post-review writer revision and final copy
372
+ check do not rewrite that hash; the report proves only which bytes were blindly reviewed.
373
+ - After the second clean copy check and before sketches, a fresh `omd-typesetter` creates
374
+ actual-copy specimens at 1280x900 and 390x844 plus `.omd/type-proof.md`. A fresh eye reviews
375
+ only sanitized typography requirements and specimens; the typesetter revises and rerenders
376
+ until the proof passes. The proof records roles, source/licence, target glyph coverage,
377
+ requested and computed family/weight evidence, axes, fallback/loading, wraps/clips, rejected
378
+ alternatives, and its invalidation fingerprint.
379
+ - After typography proof passes and before sketches, a fresh `omd-composer` writes
380
+ `.omd/composition.md` from sanitized frame, copy, type, and scout-summary inputs. Run
381
+ `omd composition --check`; a missing section, bad fingerprint, or stale dependency stops
382
+ divergence. When no durable scout summary exists, the contract records `N/A — reason`.
383
+ - Composition specifies one dominant first-viewport anchor with a visual-mass budget,
384
+ value/proof/CTA relation, and rejection condition. When mechanism/material/workflow is
385
+ central, it specifies lawful media or an explicit alternate non-media mental-model carrier
386
+ with its limitation. It never mandates a photo, invents facts/assets, or treats a terminal
387
+ form above fold as proof of task reach.
388
+ - Copy, font family/file, requested weight/axis, or proof container-width changes invalidate
389
+ typography proof and require a rerun. After structure is selected, the hand re-proves the
390
+ type in that real container at desktop/mobile before the visual checkpoint. OMD waits for
391
+ `document.fonts.ready`; computed styles and FontFace status do not identify the physical
392
+ font that painted each glyph.
393
+ - Before any animation code, write `.omd/motion-spec.md`. Production implements only its
394
+ declared scenes; every timing/easing cites measured reference or theory evidence.
395
+ - Write `.omd/attribution.md` for the sources of shipped tokens, motion, composition, and
396
+ graphics. A deliberate theory choice is still a source; an arbitrary choice is not.
397
+ - Walk `craft/finish-pass.md`. Complete applicable items and record a concrete reason for
398
+ every skipped item.
399
+ - When `.omd/design.md` exists, run `omd design --check` and resolve its findings.
400
+ - Always run `omd ref distance <page>`; a similarity above `0.6` does not ship.
401
+ - When `.omd/target/manifest.json` exists, run a bounded `omd target diff` repair loop.
402
+ Stop at the configured threshold or record the remaining measured mismatch and evidence;
403
+ never iterate without a bound.
404
+ - For multi-page output, run `omd check --site <dir>` and resolve cross-page drift.
405
+ - For a confident/showpiece register, and always when the brief signals awards-level ambition, the first shippable build begins a bounded RED/GREEN refinement loop, not the ship. Acceptance criteria written from the frame and `theory/expressive.md` are the GREEN target; any unmet one is RED. Each round leaves evidence (sharp renders under `.omd/.cache/rounds/round-<N>/`, measured gate results, and the blind-choose verdict) — a round with no evidence does not count. Before accepting a round, rerun every applicable declared task probe, accessibility check, and required-viewport task evidence; all must remain passing or the round rolls back. Blind-choose distinguishes visual quality only and cannot overrule those UX invariants. The loop advances only on measured visual improvement (blind-choose after beats before), targets one RED criterion per round, and stops on GREEN, a regression (revert), a plateau, or the round budget (default 3). This is a deliberate convergence loop, never an unbounded automatic retry, and it never overrides the gates above.
406
+ - Once production source exists, run the source-candidate scan and contextual triage before
407
+ the final sharp verdict. Resolve every triage item, repair and rescan confirmed current
408
+ candidates, and retain evidence for dismissals. Candidate presence alone never fails the
409
+ run; final untriaged and needs-render counts must both be zero.
410
+ - Final evidence includes sharp desktop and mobile renders, plus an applicable filmstrip for
411
+ motion, `omd check`, humanize review, declared/applicable probes, and project tests/build.
412
+ Findings must be clean or deliberately overruled with written evidence; silence is not an overrule.
413
+ - After all production source and approved inputs stop changing, run `omd source --seal <root>`
414
+ and then `omd source --check <root>`. Build and collect every final check, test,
415
+ declared/applicable probes, fixed-viewport screenshot/render, and applicable motion filmstrip
416
+ from that sealed source; run `omd source --check <root>` again. The hand then writes the
417
+ strict metadata manifest at `.omd/.cache/final-evidence-manifest.json`, runs
418
+ `omd evidence finalize --input .omd/.cache/final-evidence-manifest.json`, and runs
419
+ `omd evidence check --json`. Never write `.omd/final-evidence.json` directly: only
420
+ `omd evidence finalize` publishes it. Each successful finalize creates the immutable per-run
421
+ record `.omd/final-evidence-runs/<runId>.json` and atomically publishes the full current
422
+ manifest at `.omd/final-evidence.json`.
423
+ This protocol is the canonical final-evidence ABI and owns the manifest schema. The manifest
424
+ has exactly `schemaVersion`, `runId`, `sourceSeal`, `build`, `tools`, `interaction`, and
425
+ `artifacts`; `sourceSeal` is canonical `.omd/source-seal.json` plus its SHA-256, `build`
426
+ records target, fingerprint, and served target, and `tools` records non-empty versions and
427
+ `interaction` is exactly `{scope: stateful|navigation-only|static, motion:boolean,
428
+ surface: marketing|product|editorial|mixed}`; `surface` must equal the frame's `uxSurface`.
429
+ Every ordinary artifact has a globally unique cache-local path under `.omd/.cache/` and a
430
+ SHA-256; the deliberate `task-evidence` artifact alone is `.omd/task-evidence.json`. Check and
431
+ test are required; probes use strict `primary`/`recovery` roles (`stateful`: exactly one of each;
432
+ `navigation-only`: exactly one primary and no recovery; `static`: none); screenshot/render
433
+ records carry desktop/mobile viewport roles and include both; and a filmstrip is present exactly
434
+ when motion is true. Raw artifacts remain in `.omd/.cache/` and are never embedded in the durable
435
+ index. Any source or build mutation invalidates the bundle and forces resealing, rebuilding,
436
+ rerunning, and reindexing.
437
+ To recover a stale bundle, do that sequence again with a new `runId`, write a new manifest, then
438
+ finalize and check it: a different `runId` after reseal, rebuild, or rerun may supersede the
439
+ current manifest while preserving every prior run record. An existing same `runId` is an
440
+ `EEXIST` conflict that fails closed; never retry it by manually deleting either the current
441
+ manifest or a per-run record. The seal proves byte freshness for copy deck, type proof,
442
+ composition, and sorted production source files only; it does not claim semantic copy/source
443
+ fidelity.
444
+
445
+ `omd render` captures the exact requested viewport by default. Use `--full-page` only as
446
+ supplementary continuity evidence; it never replaces the fixed desktop/mobile viewport
447
+ captures used for hierarchy, critique, or acceptance.
@@ -0,0 +1,71 @@
1
+ # Source-candidate review protocol
2
+
3
+ `omd slop scan` is a read-only attention aid for production source. It reports narrow source
4
+ compounds that deserve a person looking at the rendered result. A candidate is not a defect,
5
+ warning, severity, score, authorship judgment, or `omd check` violation. It never enters check
6
+ history or coach data.
7
+
8
+ ## Provenance and use
9
+
10
+ This protocol was informed conceptually by the public
11
+ [`yetone/kill-ai-slop`](https://github.com/yetone/kill-ai-slop) repository, accessed
12
+ 2026-07-13. The upstream repository exposed no explicit licence at the time of access. OMD
13
+ therefore uses it only as research direction: no upstream code, wording, example copy,
14
+ assets, catalogue, identifiers, or catalogue ordering is reproduced here. OMD's scanner,
15
+ candidate families, language, data contract, and review flow are independently authored.
16
+
17
+ ## Fixed source boundary
18
+
19
+ The MVP reads `.html`, `.css`, `.scss`, `.js`, `.jsx`, `.ts`, and `.tsx`. It does not parse
20
+ Markdown, Vue, or Svelte and does not interpret `.gitignore`. It skips symlinks; hidden
21
+ directories; files over 512 KiB; NUL/binary or invalid UTF-8 files; lockfiles and minified
22
+ files; dependencies, build output, coverage, framework output, vendor content, Git and OMD
23
+ state; generated root `agents/` and `skills/`; and test, fixture, and snapshot trees. This is
24
+ a fixed safety and ownership policy, not a claim that skipped files are clean.
25
+
26
+ JSON contains only the schema version, resolved root, number of files read, and sorted
27
+ candidates. Each candidate supplies a controlled id and signal tokens, relative path, line,
28
+ review question, reason, and owner. It never includes the source line or an excerpt. Finding
29
+ candidates exits successfully; unreadable or invalid roots are operational failures.
30
+
31
+ ## Triage loop
32
+
33
+ Once production source exists, the coordinator runs:
34
+
35
+ ```bash
36
+ omd slop scan <root> --json > .omd/.cache/slop-source.json
37
+ ```
38
+
39
+ The raw report is disposable evidence under `.omd/.cache/`. The coordinator assigns each
40
+ candidate exactly one status:
41
+
42
+ - `confirmed`: the rendered result shows a contextual problem;
43
+ - `dismissed`: the treatment is deliberate and evidence explains why it serves this work;
44
+ - `needs-render`: the candidate cannot yet be judged from the available sharp render.
45
+
46
+ `needs-render` is transitional: obtain the relevant sharp render and resolve it to confirmed
47
+ or dismissed before ship. Candidate presence is still non-gating, but the final gate requires
48
+ both `untriaged = 0` and `needs-render = 0`, not `candidates = 0`. Confirmed current
49
+ candidates are repaired and rescanned; dismissals require concise evidence. Durable accepted
50
+ or dismissed reasoning belongs in `.omd/decisions.md`; do not promote raw JSON into durable
51
+ state.
52
+
53
+ The order is: source scan, coordinator triage, blind sharp judgment, owner repair, then
54
+ rerender, `omd check`, and source rescan. The rescan must happen after the repair. Source
55
+ candidates and rendered IR warnings remain separate records and are never added together or
56
+ double-counted. Where the two overlap, rendered IR is authoritative because it describes the
57
+ result a user can actually see.
58
+
59
+ ## Blind review and ownership
60
+
61
+ The general eye receives only a sanitized candidate id, controlled signals, and review
62
+ question beside the relevant sharp render. It does not receive source path, source excerpt,
63
+ authorship, implementation rationale, or prior decision. The eye judges the visible outcome;
64
+ it does not classify who or what wrote it.
65
+
66
+ Visual and source repairs belong to `omd-hand`. Copy diagnosis may use `omd-humanize` and a
67
+ fresh copy eye, but only `omd-writer` may modify `.omd/copy-deck.md`. After a copy finding,
68
+ the writer repairs the deck, `omd copy --check` passes, and the hand synchronizes production
69
+ source before rerender/check/rescan. A changed claim, action, or shipped copy invalidates the
70
+ affected blind copy review and typography proof under the existing copy and type contracts;
71
+ rerun those gates instead of carrying an obsolete approval.