8-step path distilled from how RotateAlign/Clock were actually built (morfo ->
langs -> soma provider vs the ChallengeHost -> telemetry block -> sema pack ->
eidos skin -> anti-bot tests -> demo+gates) + the non-negotiable invariants
(challenge never owns the verdict, no network inside, random per instance).
Also refreshed the stale bits: the orchestrator README now names both shipped
challenge engines and documents the rotation telemetry block alongside
pathAdherence; eidos README points to the recipe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- soma: targetSnapDeg knob quantizes the random target bearing (the clock
needs hour-aligned targets: a free bearing misses the marked hour by up to
15deg vs the 8deg tolerance ~47% of the time); default off, unit-tested.
- eidos: clock.svelte + clock.css - face (11 ticks, numbers at 3/6/9,
accent target-hour badge), cuckoo house at 12 (roof, doorway, swinging
doors, sill), FRONT-facing messenger pigeon with the letter, hour hand.
Verified-state dispatch (doors swing -> peek -> hold -> fly) as bespoke
content choreography, every @keyframes annotated functional: per R-4.5;
sill occlusion via clipPath; outer/inner SVG transform split; fulfill
recolor on verdict; reduced-motion = static doors open + peek.
- exported ProofOfHuman.Clock + ClockProps; eidos README challenge list.
- demo: Clock chip reusing the rotate knobs; clock idle instruction; the
success card waits 3.3s for the cuckoo; corner stage-pigeon suppressed in
verifying AND verified for the clock (the cuckoo IS the pigeon). Includes
prettier normalization of the demo page.
- handoff doc rewritten: clock shipped; filming/throttling gotchas recorded.
Verified: 81/81 tests (poh scopes), component:audit 144/144 PASS, svelte-check
clean on touched files, end-to-end solves in real Chrome (light + dark).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full self-contained handoff for a fresh session: architecture, both shipped
challenges (PathTrace + RotateAlign), the clock-skin spec (cuckoo + front-facing
pigeon, from the iterated mockup), the SVG transform-override gotcha, the
concurrency warning (another session on the same branch), verification-env
gotchas, and the commit list.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Split the anti-bot component into a purpose- and interaction-agnostic
orchestrator that owns the lifecycle stages + verdict, and a pluggable
challenge that runs the interaction and reports up via
ProofOfHumanChallengeHost. The primary challenge, PathTrace, has the user
follow a random curved path by pointer OR arrow keys.
This fixes the drag version's two real defects:
- keyboard bypass: the accessible path now yields genuine, non-replayable
behavioural signal (pathAdherence over a per-instance random curve); a
two-key script can't solve it.
- over-coupled abstraction: interaction + animation are decoupled from the
component identity (per-stage consumer slots; challenge is pluggable).
Layers:
- morfo: proof-of-human slimmed to orchestrator (Provider + 3 commits); new
path-trace morfo (Provider + Track + Token; handle-*).
- soma: orchestrator + ProofOfHumanChallengeHost; new path-trace (seeded
Catmull-Rom curve, corridor-gated monotonic progress, adherence telemetry,
pointer + arrow-key input). Old drag Token/Target wrappers retired.
- sema: verdict commits (proof-of-human) + trace handle earcons (path-trace).
- eidos: orchestrator + PathTrace that paints the curve/corridor/trail.
- demo rebuilt: carrier-pigeon skin over the per-stage slots.
Auto-focuses the token when the challenge is armed so the arrow keys start the
trace immediately (gated on the disabled->enabled transition).
Verified: 32/32 tests (incl. arrow trace completes with real signal + two-key
script can't solve, in real chromium) + visual in real Chrome (curve, failed,
verified; scorer rejects instant traces).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Record the last two F4-D optionals as resolved: (1) anti-CLS metric fallbacks
shipped (efc3f4c3); (2) the container-query dogfood is DECLINED — the framework
sizes via explicit `data-size` (79 components), zero are container-aware, so
routing a shipped recipe through `@container` would introduce a paradigm the
framework does not use (speculative, against CLAUDE.md §2). The seam stays a
documented reserved axis, already exercised by the test's synthetic recipe;
dogfood it when a real container-relative layout need arises. F4-D queue empty.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Workflow analysis (state map + 4 dispositions + adversarial stress) resolved the
direction dispute: the stagger/coordinated preset winning the (0,3,0) tie over
the generic commit-affirm firma is the DOCTRINE-CORRECT outcome (RFC B.2 — the
coordinated owns the visual axis, the generic firma is silenced). The earlier
"flip to firma" reading was backwards; that flip contradicts B.2 and its
channels:[] safety net is dormant; @layer sinks as a front-line fix (a semantic
ownership question answered with a global cascade tool + a reduced-motion
!important-inversion a11y risk).
No shipped component shows a defect (dropdown select feedback is sound+haptic
only; the item is fading out at select). The only real issue: the correct
outcome rides on an ACCIDENTAL source-order tiebreak (the explicit neutralization
was retired), undocumented + untested. Execute the proportionate fix:
- Regression test (motion.test.ts) pinning the (0,3,0)==(0,3,0) tie + the
signatures-before-presets emission order + the absence of a (0,4,0)
[data-event^='commit-select'] signature — a HAZARD MONITOR, so a generator
reorder or a widened signature fails loudly, not silently.
- Load-bearing comment at the render-css emission order.
- Doctrine note in motion.md: a known-fragile accident, not a contract; the
structural endpoint ("una firma por evento") + @layer are deferred/tracked.
Zero behavior change; base.css unchanged. Tests 28/28; npm run check src/ = 9
baseline, 0 new.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`--depth-{plane}-scrim` was declared (DepthPlane field, DEPTH_CUES, validation,
applyDepth) but never seeded, emitted or read — a write-surface with no reader
(applyDepth({p:{scrim}}) silently no-op'd; never present in generated base.css).
Analyzed via workflow (state map + 4 dispositions + adversarial stress). The
four collapse to prune vs promote-to-z-parity: wire-and-unify SINKS (contradicts
the test-locked z open-cage precedent + the MD3/Radix/Vaul consensus that the
veil is component-owned, not an elevation cue), relocate flips its verb to
retain, and complete-to-z-parity would mint a third alias of the --color-overlay
backdrop role. Unlike z (kept as an exposed open cage — it varies per plane and
is unpaintable-forever), scrim has no per-plane variance and no value to seed.
Prune: remove scrim from DepthPlane / DEPTH_CUES / validation / emitter +
applyDepth doc. Amend rfc-depth.md (token contract + Phase-4 note + atmosphere
rows), reference.md cue list, changelog, pendiente. The modal veil stays where
MD3/Radix/Vaul + the standing decision put it: --{component}-overlay-* tinted by
--color-overlay.
Zero observable change (never emitted). Tests 71/71; npm run check src/ = 9
baseline, 0 new; base.css unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Close the no-decision F4-D GAP items after the professional (reference-grounded
+ adversarial) analysis. Constant finding: near-zero real debt — most items are
deliberate reserved axes or stale audit premises.
- layer-4 / depth-z / container-queries -> KEEP (documented reserved axes; MD3/
Primer/Radix/Tailwind/DTCG precedent). The audit's "layer 4 sin consumidores"
is stale — it's consumed by banner/toast/avatar/editable/words + the THM-2
fallback. Fix the one real defect: the false comment at render-css.ts depth
block claiming the floating-wrapper consumes --depth-{plane}-z (it reads the
computed z from --{component}-content-z / --z-index-*; depth-z is an unwired
reserved read-surface).
- Register the 4 deliberate limits (LIM-SND/ICON/TOUCH/RECIPES) in the gap-log.
- assets-variables shipped in 7d4f9500; scrim + motion-direction remain design
decisions (documented, not executed to avoid pinning the wrong call).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ship the base theme's default families (Instrument Sans / Lora / Azeret Mono --
identity unchanged) as self-hosted VARIABLE woff2 (SIL OFL, latin subset, wght
range, preload on primary), so the engine's variable path is exercised by the
default theme, not merely capable. The hand-written themes/fonts.css is retired
(@font-face is config-driven from typography.families[].faces); the static TTF
set under static/fonts/air is removed.
Also close the theming-API gaps so it supports ANY variable font, not just
wght+opsz:
- FontAxes is now a 4-letter-tag map. renderFontFace emits a descriptor per
registered axis: wdth -> font-stretch: min% max%, slnt -> font-style: oblique
(OpenType slnt negated to the CSS oblique sign), alongside wght/opsz.
- TypographyStyle.variationSettings -> --style-{name}-font-variation-settings,
applied by the Text recipe (fallback normal), engaging non-standard axes
(GRAD/MONO/custom) and fixed axis defaults.
Verified: variable faces load with weight ranges + mid-axis rendering; new axis
+ variation-settings emission covered by active-eidos-config.test.ts (99 pass);
npm run check src/ = 9-error baseline (0 new); no default-font regression.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a "Foundation globals" section to eidos/archetypes.css (document-wide,
not archetype-keyed) closing the two zero-coverage systemic gaps + the
scrollbar item from the F4-D GAP menu:
- ::selection — translucent accent wash (background only, text keeps its
colour so it stays legible in light and dark)
- caret-color — accent identity on input/textarea/contenteditable, in
:where() so a field recipe can override (invalid -> threat)
- native scrollbars — themed + thin via the STANDARD properties on :root
(Firefox + Chromium >= 121). Heavy ::-webkit-scrollbar deliberately
skipped: ScrollArea draws overlay bars and hides the native one inline
(scrollbar-width: none on its viewport, which wins). Thumb colour matches
ScrollArea's thumb.
Cursors were already archetype-wired (trigger/close/action/item/option =
pointer, thumb = grab/grabbing, disabled = not-allowed, text zones = native
input + explicit cursor:text in date-field/editable) — no change needed.
All values read role tokens (--color-primary-solid, --color-content-muted),
lowest specificity so any component recipe still wins.
Verified live (tags-input demo, base-dark): input caret = --color-primary-solid
exactly; scrollbar-width thin applied; ::selection rule present + token
resolves; docs-harness :root override wins (app > foundation). npm run check
src/ = 9-error baseline, 0 new.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a close-of-session state block at the top: what shipped this session
(media-player Batch-4, THM-2 full rollout + avatar + closure, THM-4
5-hotspot adjudication) with commit refs, the real-component verification
method, and the remaining §9 / side queue (F4-D GAP scoping, motion
cascade-vs-signatures).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adjudicate color-picker (29), avatar (28), time-range-picker (26): all
0 debt — composition (de-dialoged pickers compose Popover; avatar's
per-role color now lives in the shared layer after the THM-2 migration;
sliders/toggle composed), behavioral (sema last-action, format, endpoint,
loading status), and per-file-lint blind spots (recipe-token variant
rules). Across the 5 biggest hotspots (156 unused) the only real debt was
stepper's dual-representation API, now consolidated. Confirms the doctrine:
the unused column stays informational, no machine rule warranted. THM-4
closed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every step part (item/trigger/indicator/separator) declared BOTH
`data-state` (enum) AND `data-current`/`data-complete`/`data-incomplete`
(booleans) — the same state twice, used inconsistently (enum on
trigger/indicator, boolean on separator). Consolidate on the canonical
`data-state`:
- morfo: prune the 12 boolean declarations.
- provider: drop the current/complete/incomplete sources
(item/indicator/separator) + the trigger's explicit boolean writes +
the now-unused isComplete/isIncomplete getters (isCurrent stays — it
drives aria-current/tabindex).
- separator.css: [data-complete] -> [data-state='complete'].
- README + provider test updated to the single form.
Verified with the real component (Next advances → complete/current/
incomplete via data-state, boolean attrs gone, complete separator still
paints). stepper unused 30->18; provider test + contracts green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Burn the two biggest THM-4 hotspots. media-player (47 unused): 0 real
debt — all composition artifacts (composed Buttons/Sliders), behavioral
state mirrors of the media element, default-state enum values, or
documented-v2 roadmap surfaces (settings-button, custom captions).
stepper (30 unused): mostly legit + one API redundancy — every step
part declares both data-state (enum) and data-current/complete/incomplete
(booleans), used inconsistently (enum on trigger/indicator, boolean on
separator). Consolidating is a public-API design decision, not a prune.
Emerging read (2 batches): hotspots are mostly legitimate; genuine
declared-for-nothing debt is rare, confirming the doctrine — the debt
rate does not justify a machine rule. THM-4 is mostly documented
adjudication.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Record the rollout as shipped (05f0031c + cc7e9a16) and re-label the
Avatar.Badge as a deliberate design boundary, not debt: a status badge
takes a role/intent or a direct CSS color (MUI/Spectrum/Bootstrap =
semantic; Chakra/Mantine/Ant = direct), and no framework routes an
avatar's status badge through a brand-scale palette. THM-2 closed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The avatar body's per-instance palette now resolves through the shared
per-instance layer (size collapse, behavior-preserving for roles, adds
the 33 scales):
- avatar.svelte: isCanonicalColor recognizes palette scales, so a scale
name routes to data-color instead of the custom CSS-color path ('teal'
is also a CSS color name, so it used to fall to --avatar-color-custom).
- recipes/base.ts: _palette-{solid,surface,contrast,text,border} (host
fallback only - the avatar always emits a canonical data-color, so the
presence-guarded forward routes roles + scales) + _bg/_fg/_border move
from a variant x color matrix to variant-only readers of
--_avatar-palette-*. The matrix helper + intermediates stay (the badge
still uses them; 0 orphans). avatar.css unchanged.
- demo: scale picker.
Verified end-to-end with the REAL component (drive the demo color control
-> the avatar emits data-color -> the shared layer resolves the exact
scale): affirm+soft behavior-preserving, teal+soft = scale-teal-a2
(translucent surface), teal+solid = scale-teal-9.
The Avatar.Badge sub-part (aria-hidden decorative chip with its own color
+ default) stays on its role palette + custom-CSS: migrating it needs a
per-part forward + pruning ~36 orphaned intermediates, disproportionate
for a decoration whose arbitrary-color case already works. Documented for
a decision.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
media-player Batch-4 (closes SOM-4): the 10 sub-parts migrate to
renderProps() (35 attr-dup hits -> 0). Register the sources the morfo
reads (label propRef, on stateRef, direction/type) so renderProps emits
type/role/aria-*/data-state; keep only contract-only soma-owned attrs.
Pin the soma-attr-audit ceiling to 0.
THM-2 rollout - collapse each per-component palette cascade into the
shared per-instance layer (size win, behavior-preserving for roles,
adds the 33 scales):
- Rename palette tokens to canonical _palette-{slot} + route via the
presence-guarded forward: tags-input, stepper, badge, card, select
(parts-aware trigger+content), file-upload, editable, tag-group.
- Extend the shared vocabulary with alpha surface(a2)/surface-hover(a3)
slots (soft variant of variant-aware recipes) and hover(4) - the
latter also fixes Toggle's latent scale-hover.
- tag-group: variant-aware migration (solid/outline -> canonical,
soft -> alpha surface; merge outline-fg into text, prune orphans).
- toggle-group: replace the 4-role cross-recipe composition with a
hand-authored presence-scoped route to the shared layer (the
composition DSL can't presence-scope); covers roles + 33 scales.
- Widen color to ComponentColor (roles + 33 scales) where arbitrary
color is meaningful: badge, tag-group, tags-input, toggle-group, and
add the scale picker to their demos. Semantic controls stay restricted.
Verified end-to-end with the REAL components (drive the demo color
control -> the component emits data-color -> the shared layer resolves
the exact scale). Gates: recipe-css-contract/config/contracts/
soma-attr-audit/media-player suites green; 0 orphan tokens.
avatar remains for a focused pass: its variant-resolved matrix and badge
sub-part don't fit a mechanical migration.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per request: one `colors` prop that discriminates by shape instead of two
rival props. A `string[]` is an explicit stop list (unchanged); a bare
`string` names a canonical gradient from the theming's named set, resolved as
`var(--gradient-{name})` — exactly what the removed `preset` prop did. The set
is an open cage (`EidosConfig.gradients` / `applyGradients`), so the type stays
`string | readonly string[]`, not a closed union. Removed `preset` outright (no
back-compat shim, per project rule); the canonical S9 vocabulary and raw stops
are now the SAME input.
Docs shell: register a small canonical named set on `uix/+layout@` via
`applyGradients` (`brand`, `spectrum`) — role-derived, so they re-tint with the
seed and flip light/dark. Demo gains a live stops|named toggle so both branches
are a real testbed.
Finding worth recording (types + README): a named gradient painted through
`background-clip: text` must be a single `<image>` (linear/radial/conic). A
role-derived MESH serializes to radials + a base COLOR, and a bare color is not
a valid `background-image` (only the `background` shorthand accepts it) — so a
mesh name computes to `none` and never paints. The docs set is linear-only for
this reason.
Verified in real Chrome: stops branch paints the token gradient; `colors="spectrum"`
paints `var(--gradient-spectrum)` through the text. svelte-check 0 own errors,
component:audit 141/0/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Estado: F0·F1·F2·F3·F4-C·SEM-4·THM-2 ✅ commiteadas/pusheadas. El bloque
ARRANQUE reescrito: media-player Batch-4 (cierra SOM-4) con el diagnóstico
completo (10 sub-partes hardcodean attrs que el morfo declara; migración
renderProps parte-a-parte; plantilla carousel/table; cierre con ceiling +
navegador) para ejecutar en frío sin re-scopear. Cola posterior: rollout
THM-2 (12) · hotspots THM-4 · F4-D GAP (scoping) · cascada-vs-firmas.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
El mecanismo genérico ya existía (universalPaletteDecls auto-completaba las 33
escalas para recetas con tokens palette-*), pero con PREFIJO de componente
(--button-palette-*) — cada superficie pagaba ~21 KB, por eso solo button/toggle
lo tenían (rollout a las 17 = ~+315 KB). Colapso al modelo compartido:
- renderSharedPaletteLayer: UNA cascada component-agnóstica
[data-color='{role|scale}'] { --palette-{slot}: … } — 8 roles + 33 escalas,
emitida una vez (~19 KB). Roles 1:1 a --color-{role}-*; escalas con el step
map + on-solid contrast, valor idéntico a la cascada per-component retirada.
- renderRecipePaletteForward: toda receta con palette-* (público) o _palette-*
(privado) recibe [data-{c}][data-color] { --{c}-palette-{slot}:
var(--palette-{slot}, host-default) }. La guarda de PRESENCIA es la seguridad
de anidamiento — un hijo sin color dentro de un ancestro coloreado matchea
solo [data-{c}] (su default) y nunca lee el --palette-* heredado.
- Generalización a la paleta PRIVADA: checkbox/radio-group/switch ganan las 33
escalas con CERO cambio de CSS (ya consumen --_{c}-palette-*).
- universalPaletteDecls eliminado; 2 guards migrados al modelo compartido
(recipe-css-contract "shared layer + forward"; active-eidos-config contrast
en la capa compartida).
DONE (per-instance): button, toggle, checkbox, radio-group, switch (5/17).
Rollout de las 12 restantes en docs/process/continue-cleanroom-fixes §THM-2.
Doctrina en theming/reference §25 ("The per-instance palette layer").
Verificado en vivo (button + checkbox): color="teal" → escala teal exacta ·
affirm → rol exacto · primary → primary · nested-nocolor en ancestro teal →
primary (sin contaminación). Peso 345K → 329K. Gates: matriz 141/141 ·
eidos 314 · recipe-css-contract + active-eidos-config 98/98 · contracts 38/38.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two streams, split by what the animation touches:
STREAM A — decorative backgrounds → the pack tier
- arts/scene: a consolidated scene runtime ($scene) that owns, once, the
citizenship every ad-hoc background reinvented or skipped (frame loop,
off-view pause, DPR cap, mandatory reduced-motion, WebGL context
loss/restore, scene budget, teardown). SceneDom port (adom satisfies it),
webgl/webgl2/canvas2d drivers + a custom-pipeline extension (vertexShader +
draw + glContext.depth/dprCap) for real geometry (beam, particles, dither,
grid, eter, pixel-blast, hyperspeed). 32 effects as shared resources.
- src/packs/ambient: the first pack — <Ambient effect="…"> mounts a registered
effect; the P contract (P-1..P-6) guarded by scripts/packs-check.ts; colors
are token-aware (P-4). One-way dependency, removable-by-construction.
- resolveToken extended to semantic color slots (--color-{role}-{slot}) so
consumers resolve theme tokens to concrete colors (the P-4 half).
STREAM B — animations over real text → canon
- Six components (count-up + text-{gradient,circular,blur,focus,scramble}):
each a morfo + eidos recipe (where there's styling) + demo. CountUp is a
service component (counts through uix.format.numbers). The five Text* are
passive decoratives. Upgrades over the seeds: SR hardening (real text
visually-hidden + aria-hidden decoration), a11y fix (no fake role=button),
measurement discipline (cached rects via dom.measure, no reflow storm),
reduced-motion, ecosystem citizenship (eidos.dom/timers, no raw platform).
- MorfoElement gains 'p'.
DOCS
- docs/architecture/packs.md (pack tier, admission rule, P contract, Aura
promotion path); docs/decisions/design-text-effects.md (the family design
record) + indexed in decisions.md / README.md; glossary entries
(scene/Ambient/Aura/text effects); scene README custom-pipeline + authoring
bridge; motion-guide content-effects note; strata tables acknowledge packs.
Gates: component:audit 141/0/0 · docs:check 0/0 · scene tests 9/9 · packs:check
0/36 · check 0 own errors. Verified in browser (32 effects mount+compile;
6 text components SSR+hydrate, CountUp re-formats by locale live, TextGradient
resolves token stops to OKLCH via var()).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- book-deviations: los caveats de D.6 (emisión dormida + branch-vs-item) marcados
RESUELTOS con verificación en vivo 2026-07-12 (los 6 providers emiten; packs con
onBranch/onRow casan con los targets reales) — el párrafo stale fue citado por la
clean-room como evidencia de dormancia: lección anotada (el registro se actualiza
en el mismo pase que el cableado). D.11: párrafo de pickers actualizado al cierre
real (delegado closeWith→dismissWith, b55ca6ee).
- continue-cleanroom: SEM-4 sesión 2 cerrada por verificación (stamps
open·emerge / commit-select·commit·affirm en vivo); D.2 (flag emission)
DESCARTADO — el gap que auditaba ya no existe y el check estático sería frágil
(Simplicity First). Arranque siguiente = cola F4 restante (THM-2 diseño universal ·
media-player Batch-4 · hotspots THM-4 · F4-D).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
F2 — lote mecánico (13 ítems):
- DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString
propio + suite de contrato (props.test.ts; soma.md §12 cerrado).
- THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector
(los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la
deriva que el builder previene, demostrada en el propio doc).
- MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9
tests (selectors.test.ts, matches() real con comillas/corchetes) ·
MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad ·
MOR-3 _resetCompileCache borrado (0 usos).
- SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo ·
SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin.
- SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled
rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de
applyDominance → skip defensivo + timer tope de awaitExpression cancelado ·
SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11)
+ pin del path de VALOR.
- accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) —
verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33.
F3 — censos con guard:
- SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred
(consumidores cableados: date/time-field vía soma.uix.timers; avatar/image
vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de
soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige
.schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo).
- THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo
comment-blanked) + las 15 declaraciones anotadas con su razón + canon
recipe-contract §3/§4.
- SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/
timeline pinneados (overrides documentados en call-site); media-player
Batch-4 (35 hits, cero renderProps) = único batch restante, registrado.
- THM-4 doctrinado en eidos.md §unused (comportamiento/composición =
legítimo; deuda = eje visual sin consumidor; hotspots por lotes).
F4-C — corpus documental (decisiones de usuario aplicadas):
- DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL
trackeada / des-link históricos) · docs:check I6-links WARN→ERROR.
- DOC-1: tabla «Build contract» MIGRADA a component-guide con estados
modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas
de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil.
- DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures ·
gradient añadido a los DOS capstones (sextet real) · nota de paleta de
demo-authoring corregida (universalPaletteDecls + decisión THM-2 =
mecanismo universal como sucesor del tracker borrado).
- DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps
historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en
eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado ·
EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado.
SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11):
- Reconciliación: los morfos ya no declaran close (delegated al Popover,
de-dialoged 06-27); el agujero real era el cierre programático bypaseando
dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS.
- Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5
providers (14 sitios; select/commit → 'save' = commit.save+fulfill,
cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en
el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito
(ya suena commit-set/cancel por diseño S9).
- Verificado en vivo (date-picker): Done → close·commit·fulfill·active ·
Cancel → close·emerge · cierre real.
Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela
también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 ·
docs:check 0/0 con I6 en error · baseline propio 57.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- continue-cleanroom: bloque de ARRANQUE para la próxima sesión (F2 en 6
pasos ordenados, barato→delicado, no-cascada) + registro de ejecución de
F1 (EID-1 anillo fundación→outline con :where() — el reset global que lo
justificaba NO existía y el anillo viejo pintaba en paralelo con los de
receta; EID-2 opacidades→tokens; F1.3 3 guards de fundación; SEM-1
prioridad=intent pinneada con liveRegionFixtureMorfo) + cola lateral
nueva: accordion outline:none+box-shadow = cero anillo en HCM (a F2).
- sema.md §Announce: doctrina AUX-1 "who owns what" — 1 sink
(uix.announce), 2 emisores (runtime a11y + AnnounceChannel), <Announce>
= región de app; UNA política de prioridad (SEM-1) pinneada en ambos lados.
Gates al cierre: matriz 135/0/0 · contracts 38/38 · eidos 309/309 ·
sema 178 · baseline 57.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Clean-room fixes (2026-07-11, sobre los P1 de la auditoría):
- EID-1: el anillo de foco de la fundación migra a `outline` (§32) — el último
box-shadow del catálogo; :where()-wrapped para que las recetas siempre ganen;
doctrina actualizada en theming/reference + changelog.
- EID-2: opacidades literales de archetypes.css → var(--opacity-disabled/hover).
- SEM-1: política de live-region unificada — la urgencia va SOLO por intent
(threat/loss → assertive), runtime y AnnounceChannel ya coinciden.
- MOR-4: card-group con morfo propio (scope eidos) + guard de enumeración.
- THM-1: component-audit + recipe-css-contract escanean los *.css hermanos
(calendar-select, color-picker-spectrum, date-range-picker-time…); R-2.1
caza también hsl()/oklch(); violaciones de los secundarios corregidas.
- THM-3: canario de censo de toggle volteado (lint.test); commit-block promovido
a firma global block-shake; regen de generated/base.css.
Docs nuevos:
- docs/audit-new-10-july/audit-active-uix.md — auditoría clean-room 2026-07-10
del ecosistema (hallazgos P1–P3 con evidencia ruta:línea, matriz y gap analysis).
- docs/process/PLAN-scene-ambient-pack.md — plan por fases: motor arts/scene +
pack Ambient (45 animaciones de demos) + vía de promoción agéntica (Aura);
gate de decisiones D1–D9.
- docs/Disenando_lo_que_ocurre_FINAL.{docx,pdf} — edición FINAL del libro.
- README.md raíz (esqueleto de paquete).
Excluidos deliberadamente de este commit: words/palabras/chronos (pista
separada), web/routes/alpha (terminado, sin commitear por decisión), rt.css
(volcado de referencia Radix Themes).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- docs/audit/components/_cierre.md — the programme closure: final gates
(matrix 134/0/0, contracts 37/37, vocab 0, baseline 57), the full package
journey with hashes, the canonized method (dossier template, evidence-only
exceptions, no-cascada, machine valves), the findings that outlive the
programme, and what moved to new owners (demo frame, active tracks,
follow-ups).
- docs/process/continue-cleanroom-fixes-2026-07.md — the LIVE turnkey for
the next sessions: the clean-room severity table as the queue, the state
reconciliation (SOM-5 P1 already closed post-snapshot; SOM-3 partial), the
proposed P1 order (machine-extending THM-1/MOR-4 first), the WIDENED
verification protocol (134/0/0 and 37/37 must HOLD), exclusions and the
side queue.
- The old audit-fixes handoff is sealed as historical with a redirect header.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Option (a) with riders: the ::before slop stands for bare markers (the
Material mdc-touch-target / Android touch-delegate / iOS hit-inset lineage).
Rider 1: dense coarse stacks must keep pitch >= --touch-target (WCAG excludes
overlapped area; bare boxes still hold AA via 2.5.8 Spacing worst-case).
Rider 2: the Field labeled-row task stays open as the ADDITIVE improvement —
the row becomes the real AAA target (2.5.5 Equivalent) and the slop remains a
harmless net. Chronicle updated in changelog §37; standing in reference §37;
handoff block resolved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both were type-only: the assertions read morfo-declared keys (data-editing,
role) that DO reach the provider props at runtime through the renderProps()
spread, but the static type of runtimePart.assert erases them. Read them
through an explicit indexed cast instead; suites stay green (6/6). Baseline
drops 59 -> 57 — protocol number updated in the handoff, with the remaining
out-of-mandate errors inventoried (9 src/: file-upload x4, navigation-menu,
arts/connection x4; ~48 web/ demos).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mark S6 done (16 fields compose field.css + 199 orphaned recipe tokens pruned +
date/time pickers de-aliased onto the Field public tokens, commits 5eb92132..
d1670caa). Rewrite "lo que queda" to start at S8 calendar-surface; record the
two non-blocking follow-ups (TimeRangePicker endpoint data-size threading
task_d66356de, PickerProvider deferValue migration) and the S6 method lessons
(run the recipe-css-contract vitest scope after CSS refactors; --field-segment-
height only exists under [data-field][data-size]).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mark the workstream done in the continuation handoff: orca translated (A2),
active-app promoted to an architecture chapter (B1), historical DESIGN docs
moved to decisions/ (B2), runtime-artifact shortcut rerouted (B3). Guards green
at close (arts:check 0/0/22, docs:check 0 err).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "I want to… use a runtime artifact" row in docs/README.md now routes
through the composition root (architecture/active-app.md) → the arts map
(arts/README.md) → the per-artifact README. Map/aliases were already complete
(9e48b80b). docs:check 0 errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the three superseded arts design-phase records into the E3 corpus
(already indexed in docs/decisions.md), verbatim-as-historical:
- docs/decisions/design-connection.md (from src/arts/connection/DESIGN_CONN.md)
- docs/decisions/design-session.md (from src/arts/session/DESIGN.md)
- docs/decisions/design-timer.md (from src/arts/timer/DESIGN_TIMR.md, kept Spanish)
Each gets a `status: historical` frontmatter block; the current reference for
each subsystem is its README.md. A stub at every old src/arts/* path keeps the
~30 source provenance citations (`DESIGN_TIMR §12.8`, `DESIGN.md §7.Q1`, …)
resolving. Bodies kept verbatim (no reformat). docs/decisions.md index + naming
note updated to the new paths. docs:check 0 errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the active-app reference into the book tree as the arts composition root,
the App-side analogue of active-uix.md:
- new docs/architecture/active-app.md (frontmatter + fixed relative paths); the
dated Spanish "Handoff 2026-05-13" heading becomes a timeless "Quick start".
- extract that Handoff block verbatim (ES) to docs/process/handoffs-2026-05.md,
alongside the other extracted arts/uix handoffs.
- stub src/arts/active-app/README.md pointing at the chapter (active-uix pattern).
- wire the chapter into the docs/README.md E1 map.
docs:check 0 errors (11 pre-existing warnings unrelated).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>