You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/scripts/component-audit.ts

1585 lines
63 KiB

uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/**
* Component completion audit.
*
* Walks every UIX component (morfo + eidos wrapper + recipe CSS + demo)
* and scores it against the rules in
* `docs/guides/completion-checklist.md`.
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
*
* Output: `tmp/component-audit.md` — markdown report with summary table
* + per-component findings.
*
* Usage:
* node --import tsx/esm scripts/component-audit.ts
* node --import tsx/esm scripts/component-audit.ts --only rating-group,calendar
* node --import tsx/esm scripts/component-audit.ts --severity error
*
* Approach: text/regex parsing of source files. Doesn't dynamically import
* morfos (avoids full TS resolution + circular dep risk). The morfo files
* are declarative `as const satisfies Morfo` exports, so regex catches
* the structural facts we need. Cross-validation against canonical
* vocabularies via static imports of `INTENTS`, `SEMA_FAMILIES`,
* `SEMA_VERBS`, `ARCHETYPE_VOCABULARY`.
*/
import { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { INTENTS } from '../src/uix/intent.ts';
import { SEMA_FAMILIES } from '../src/uix/sema/event.ts';
import { SEMA_VERBS } from '../src/uix/sema/verbs.ts';
import { ARCHETYPE_VOCABULARY } from '../src/uix/morfo/types.ts';
// ─── Paths ──────────────────────────────────────────────────────────────────
const __dirname = dirname(fileURLToPath(import.meta.url));
const REPO = join(__dirname, '..');
const MORFO_DIR = join(REPO, 'src/uix/morfo/components');
const EIDOS_DIR = join(REPO, 'src/uix/eidos/components');
const DEMO_DIR = join(REPO, 'web/routes/uix/components');
const OUT = join(REPO, 'tmp/component-audit.md');
// ─── Types ──────────────────────────────────────────────────────────────────
type Severity = 'error' | 'warn' | 'info';
interface CheckResult {
rule: string;
severity: Severity;
passed: boolean;
detail?: string;
}
interface ComponentReport {
component: string;
kebab: string;
exists: { morfo: boolean; eidos: boolean; demo: boolean };
interactive: boolean;
passive: boolean;
checks: CheckResult[];
}
// ─── CLI flags ──────────────────────────────────────────────────────────────
const args = process.argv.slice(2);
const onlyArg = args.find((a) => a.startsWith('--only'));
const onlyList = onlyArg
? (onlyArg.includes('=') ? onlyArg.split('=')[1] : args[args.indexOf(onlyArg) + 1])
?.split(',')
.map((s) => s.trim())
: undefined;
const severityArg = args.find((a) => a.startsWith('--severity'));
const minSeverity = (severityArg
? severityArg.includes('=')
? severityArg.split('=')[1]
: args[args.indexOf(severityArg) + 1]
: undefined) as Severity | undefined;
// ─── Helpers ────────────────────────────────────────────────────────────────
function tryRead(path: string): string | null {
try {
return readFileSync(path, 'utf8');
} catch {
return null;
}
}
function pass(rule: string, severity: Severity, detail?: string): CheckResult {
return { rule, severity, passed: true, ...(detail ? { detail } : {}) };
}
function fail(rule: string, severity: Severity, detail: string): CheckResult {
return { rule, severity, passed: false, detail };
}
// Match `name: '...'` or `name: "..."` inside morfo event blocks.
const EVENT_NAME_RE = /name:\s*['"]([\w-]+)['"]/g;
// Match family field
const EVENT_FAMILY_RE = /family:\s*['"]([\w-]+)['"]/g;
// Match verb field
const EVENT_VERB_RE = /verb:\s*['"]([\w-]+)['"]/g;
// Sequence field
const EVENT_SEQUENCE_RE = /sequence:\s*['"](pre|coincident|post)['"]/g;
// Part kebab
const PART_KEBAB_RE = /kebab:\s*['"]([\w-]+)['"]/g;
// Archetype
const PART_ARCH_RE = /archetype:\s*['"]([\w-]+)['"]/g;
// keyboard keys
const KEYBOARD_KEY_RE = /key:\s*['"]([^'"]+)['"]/g;
const VALENCED_FAMILIES = new Set(['commit', 'signal']);
const ALL_VERBS = new Set<string>(
(Object.values(SEMA_VERBS as Record<string, readonly string[]>) as readonly string[][]).flat()
);
const VERBS_BY_FAMILY = SEMA_VERBS as Record<string, readonly string[]>;
const ARCHETYPE_SET = new Set(ARCHETYPE_VOCABULARY);
const INTENT_SET = new Set(INTENTS);
// ─── Declared --color-* tokens (loaded once for R-2.6) ──────────────────────
//
// R-2.6 norm: any `var(--color-X)` referenced by a component CSS, recipe
// or eidos foundation must have X declared in `generated/base.css`.
// The set is the closed contract emitted by `appendThemeColorDeclarations`
// + recipe-token generators in `src/uix/eidos/lib/render-css.ts`.
const GENERATED_CSS = join(REPO, 'src/uix/eidos/generated/base.css');
const DECLARED_COLOR_TOKENS: Set<string> = (() => {
const set = new Set<string>();
const src = tryRead(GENERATED_CSS);
if (!src) return set;
for (const m of src.matchAll(/\s--color-([a-z0-9-]+):/g)) set.add(m[1]);
return set;
})();
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// ─── Recipe Contract shared state (R-4.x) ───────────────────────────────────
//
// R-4.x rules enforce `src/uix/eidos/RECIPE_CONTRACT.md` — the transversal
// theming systems every recipe must consume (state-layer, tokenized elevation,
// opacity token, logical axes, motion channel) instead of hand-rolling its own
// idiom. ALL R-4.x graduated to `error`: R-4.1/4.2/4.3/4.4/4.6 after the
// 2026-07-02 mechanical backfill, R-4.5 after the motion migration emptied
// its 15-component backlog (every recipe now consumes the channel's presets,
// signatures or registered keyframes — see RECIPE_CONTRACT.md §2).
// Active parallel dev tracks — UNFINISHED components deliberately outside the
// completion machinery (same exclusion recipe-css-contract.test.ts uses).
// Excluded from the audited catalog + verdicts so WIP noise doesn't read as
// catalog breakage; auditable on demand via an explicit `--only words`.
const WIP_TRACKS = new Set(['words', 'palabras', 'chronos']);
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// R-4.4 — physical-axis token keys declared in `lib/recipes/base.ts`,
// attributed to their component block. Logical axes (`padding-inline` /
// `padding-block`) are the canon; physical axes break RTL. Covers BOTH the
// spelled-out grammar (`padding-x-*` / `margin-y` / `inset-x`) AND the
// abbreviated segments (`px` / `py` / `mx` / `my` as full key segments —
// e.g. `'trigger-px-sm'`), which the original regex missed: 198 abbreviated
// keys evaded it until the 2026-07-06 normalization codemod emptied them
// (user decision — one vocabulary, excluded tracks included). Segment
// anchoring keeps legal keys like `padding-xs` (an axis-less size step) out.
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// Attribution: top-level component keys in the recipe set sit at one-tab
// indentation (`\taccordion: {`); every axis-token line is charged to the last
// component key seen above it.
const RECIPES_BASE_PATH = join(REPO, 'src/uix/eidos/lib/recipes/base.ts');
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const PHYSICAL_AXIS_TOKEN_RE =
/'(?:[a-z0-9-]*(?:padding|margin|inset)-(?:x|y)(?:-[a-z0-9-]+)?|(?:[a-z0-9-]+-)?(?:p|m)(?:x|y)(?:-[a-z0-9-]+)?)'\s*:/;
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const PHYSICAL_AXIS_TOKENS: Map<string, string[]> = (() => {
const map = new Map<string, string[]>();
const src = tryRead(RECIPES_BASE_PATH);
if (!src) return map;
let component: string | null = null;
for (const line of src.split(/\r?\n/)) {
const key = line.match(/^\t'?([a-z][a-z0-9-]*)'?:\s*\{\s*$/);
if (key) {
component = key[1];
continue;
}
if (!component) continue;
const hit = line.match(PHYSICAL_AXIS_TOKEN_RE);
if (hit) {
const token = hit[0].replace(/['\s:]/g, '');
const list = map.get(component) ?? [];
list.push(token);
map.set(component, list);
}
}
return map;
})();
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ─── Component discovery ────────────────────────────────────────────────────
function listComponents(): { kebab: string; morfoPath: string }[] {
const entries = readdirSync(MORFO_DIR);
return entries
.filter((e) => e.endsWith('.ts') && !e.endsWith('.test.ts'))
.map((e) => ({ kebab: e.replace(/\.ts$/, ''), morfoPath: join(MORFO_DIR, e) }))
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
.filter((c) => (onlyList ? onlyList.includes(c.kebab) : !WIP_TRACKS.has(c.kebab)))
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
.sort((a, b) => a.kebab.localeCompare(b.kebab));
}
// ─── Checks ─────────────────────────────────────────────────────────────────
function checkMorfo(kebab: string, src: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
// A-1.1: Morfo const export
const morfoVarMatch = src.match(/export const (\w+Morfo)\b/);
if (!morfoVarMatch) {
out.push(fail('A-1.1', 'error', 'No `export const {Name}Morfo` found'));
return out;
}
out.push(pass('A-1.1', 'error'));
// A-1.2: name + kebab + scope
const hasName = /\bname:\s*['"][\w-]+['"]/.test(src);
const hasKebab = /\bkebab:\s*['"][\w-]+['"]/.test(src);
const hasScope = /\bscope:\s*\[/.test(src);
if (hasName && hasKebab && hasScope) out.push(pass('A-1.2', 'error'));
else
out.push(
fail(
'A-1.2',
'error',
`Missing: ${[!hasName && 'name', !hasKebab && 'kebab', !hasScope && 'scope'].filter(Boolean).join(', ')}`
)
);
uix: rename morfo.translations → morfo.texts (idlangref discipline) Morfo now declares text slots as absolute idlangrefs in `texts: Record<string, LangRef>`, not literal multilingual records. Multilingual content moves out of morfo entirely into per-component catalogs under `src/uix/langs/components/{kebab}.ts`, merged globally by `ActiveUix` via the new `componentLangs` barrel. Morfo stays a pure abstract surface; localization lives in its own layer. - Type: `translations?: LangNode` → `texts?: Record<string, LangRef>` in `src/uix/morfo/types.ts`. Doc and test fixtures updated. - Catalog: new `src/uix/langs/` directory with `common.ts` (was `langs.ts`), `components/` (one file per migrated morfo, plus a barrel), and an aggregate `uixLangs`. `ActiveUix` registers both namespaces at boot. - Registry: `registerMorfo` no longer carries a translations fingerprint and no longer extends `ActiveLangs` dynamically. `connectMorfoTranslations` and `MorfoTranslationTarget` deleted from the public morfo barrel. - Validation: schema.ts drops the relative-translationRef-in-morfo.translations check; catalog presence is enforced by the new `scripts/translations-check.ts` (wired as `npm run translations:check`). - Audit: `scripts/component-audit.ts` rule A-1.3 now validates `texts.label` idlangref shape (`#?components.{kebab}.label|Fallback`) and explicitly errors on any surviving legacy `translations:` field. - Migration: `scripts/migrate-translations-to-texts.ts` is the one-off Node script that produced the 42 morfo rewrites and 42 catalog files. - Tests: `morfo/registry.test.ts` rewritten around the simpler contract; `active-uix.svelte.test.ts` reflects boot-time catalog availability instead of lazy per-morfo extension. Verification: `npm run check` (0 errors), `npm run translations:check` (0/0), `npm run morfo:check` (36/36 routed). The 4 pre-existing failures in `test` are unrelated (date-picker types, css regen, range-calendar clear, color contract). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// A-1.3: morfo.texts.label is a valid component-scoped idlangref.
// Old `translations: { label: { es, en } }` is illegal — caught by tsc, but
// flag it here too for explicit migration error messaging.
const hasLegacyTranslations = /^\ttranslations:\s*\{/m.test(src);
if (hasLegacyTranslations) {
out.push(
fail(
'A-1.3',
'error',
'Legacy `translations:` field present. Migrate to `texts:` idlangrefs (see translations:check).'
)
);
} else {
const labelRefMatch = src.match(/^\t\ttexts:[\s\S]*?\blabel:\s*['"`](#\?[^'"`]+)['"`]/m);
// Use compact form when texts block exists; the indentation is one tab
// deeper than `\t`.
const compactLabel = src.match(
/^\ttexts:\s*\{[\s\S]*?\blabel:\s*['"`](#\?[^'"`]+)['"`]/m
);
const hit = labelRefMatch ?? compactLabel;
if (hit) {
const ref = hit[1];
const validShape = /^#\?(?:components\.[a-z][a-z0-9-]*|common)\..+\|.+$/.test(ref);
if (validShape) out.push(pass('A-1.3', 'error'));
else
out.push(
fail(
'A-1.3',
'error',
`texts.label idlangref malformed: ${ref}. Expected '#?components.{kebab}.label|Fallback' or '#?common.…|Fallback'.`
)
);
} else {
icon: README sections + Passive justification + audit refinements Full walk of icon (passive eidos-only primitive): - Morfo: validated correct as-is. Single `Provider` part with `archetype: 'image'`, conditional `aria-hidden` / `role="img"` driven by the `decorative` prop. Scope `['eidos']` is right (no soma counterpart). 0 events is right (leaf visual primitive). - Eidos: 1696 lucide glyphs + IntentIcon. Default exported via the re-export pattern `export { default } from './icon.svelte';` — validates the audit refinement below. - README sections renamed to canonical headers: `## Baseline Air` → `## Baseline`, `## Comparativa externa` → `## Comparativa`. New `## Passive justification` section explains why icon ships zero semantic events (leaf primitive — the accessible name and any perceptual signal belong to the containing control). `## Gaps cerrados` renamed to `## Gaps` and rewritten with disposition tokens (implementar / diferir / descartar). Audit script refined for two false-positives surfaced by icon: - A-1.3 (texts.label) now SKIPS pure visual primitives — components whose `scope` is exactly `['eidos']` AND that declare no events. Icons don't own text slots; the label lives on the consumer (the button hosting the icon, shadcn-svelte/Radix pattern). Reported as pass with "eidos-only passive primitive — no text slot". - E-1.3 (default export) now recognizes the re-export form `export { default } from './foo.svelte';` in addition to the existing patterns (`export default X`, `export { X as default }`). Audit: PASS 5 → 6. Icon flips to PASS. No regressions; the relaxed rules don't change verdicts for any other component. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Pure visual primitives (scope=['eidos'] only, no events, no
// interactive surface) don't own text slots — the label lives on
// the consumer (e.g. the button hosting the icon). Skip A-1.3 for
// them.
const scopeMatch = src.match(/scope:\s*\[([^\]]+)\]/);
const scopes = scopeMatch
? scopeMatch[1].split(',').map((s) => s.trim().replace(/['"]/g, ''))
: [];
const isEidosOnlyLeaf =
scopes.length === 1 && scopes[0] === 'eidos' && !/events:\s*\[/.test(src);
if (isEidosOnlyLeaf) {
out.push(pass('A-1.3', 'error', 'eidos-only passive primitive — no text slot'));
} else {
out.push(
fail(
'A-1.3',
'error',
'No `texts.label` declared. Add `texts: { label: \"#?components.{kebab}.label|Fallback\" }` and ship the entry in src/uix/langs/components/{kebab}.ts.'
)
);
}
uix: rename morfo.translations → morfo.texts (idlangref discipline) Morfo now declares text slots as absolute idlangrefs in `texts: Record<string, LangRef>`, not literal multilingual records. Multilingual content moves out of morfo entirely into per-component catalogs under `src/uix/langs/components/{kebab}.ts`, merged globally by `ActiveUix` via the new `componentLangs` barrel. Morfo stays a pure abstract surface; localization lives in its own layer. - Type: `translations?: LangNode` → `texts?: Record<string, LangRef>` in `src/uix/morfo/types.ts`. Doc and test fixtures updated. - Catalog: new `src/uix/langs/` directory with `common.ts` (was `langs.ts`), `components/` (one file per migrated morfo, plus a barrel), and an aggregate `uixLangs`. `ActiveUix` registers both namespaces at boot. - Registry: `registerMorfo` no longer carries a translations fingerprint and no longer extends `ActiveLangs` dynamically. `connectMorfoTranslations` and `MorfoTranslationTarget` deleted from the public morfo barrel. - Validation: schema.ts drops the relative-translationRef-in-morfo.translations check; catalog presence is enforced by the new `scripts/translations-check.ts` (wired as `npm run translations:check`). - Audit: `scripts/component-audit.ts` rule A-1.3 now validates `texts.label` idlangref shape (`#?components.{kebab}.label|Fallback`) and explicitly errors on any surviving legacy `translations:` field. - Migration: `scripts/migrate-translations-to-texts.ts` is the one-off Node script that produced the 42 morfo rewrites and 42 catalog files. - Tests: `morfo/registry.test.ts` rewritten around the simpler contract; `active-uix.svelte.test.ts` reflects boot-time catalog availability instead of lazy per-morfo extension. Verification: `npm run check` (0 errors), `npm run translations:check` (0/0), `npm run morfo:check` (36/36 routed). The 4 pre-existing failures in `test` are unrelated (date-picker types, css regen, range-calendar clear, color contract). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// A-1.4: apg for interactive components — a pattern URL, or the explicit
// `'none — {rationale}'` form for widgets the APG doesn't cover
// (checkpoint C5, 2026-07-07). The morfo carries the decision; README
// exceptions are no longer honored for this rule — absence always flags.
const apgValue = src.match(/\bapg:\s*['"]([^'"]+)['"]/)?.[1];
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (info.interactive) {
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (apgValue && /^https?:/.test(apgValue)) out.push(pass('A-1.4', 'warn'));
else if (apgValue && /^none\s*—\s*\S/.test(apgValue))
out.push(pass('A-1.4', 'warn', `no official pattern: ${apgValue}`));
else if (apgValue)
out.push(
fail('A-1.4', 'warn', `apg malformed: '${apgValue}' — use a URL or 'none — {rationale}'`)
);
else
out.push(
fail('A-1.4', 'warn', "No apg declared — cite the pattern URL or 'none — {rationale}'")
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
// A-2.1: at least one Provider part — kebab='provider'. Archetype can vary
// (icon uses 'image', viewport uses 'provider', etc.) so don't enforce that.
const hasProvider = /kebab:\s*['"]provider['"]/m.test(src);
if (hasProvider) out.push(pass('A-2.1', 'error'));
else out.push(fail('A-2.1', 'error', 'No part with kebab: "provider" found'));
// A-2.5: archetypes ∈ ARCHETYPE_VOCABULARY
const archetypes = [...src.matchAll(PART_ARCH_RE)].map((m) => m[1]);
const invalidArchs = archetypes.filter((a) => !ARCHETYPE_SET.has(a as never));
if (invalidArchs.length === 0) out.push(pass('A-2.5', 'error'));
else out.push(fail('A-2.5', 'error', `Invented archetypes: ${[...new Set(invalidArchs)].join(', ')}`));
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// A-3.1: events.length >= 1 if interactive — only count EVENT blocks, not
// part names. `expression: 'delegated'` exonerates: a composite whose
// perceptual events live in its children's contracts (checkpoint S11b,
// 2026-07-07; participation doctrine in docs/architecture/sema.md).
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const eventBlocks = extractEventBlocks(src);
const eventNames = eventBlocks
.map((b) => b.match(/name:\s*['"]([\w-]+)['"]/)?.[1])
.filter((n): n is string => Boolean(n));
const declaredEvents = eventBlocks.length;
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const expression = src.match(/\bexpression:\s*['"]([a-z-]+)['"]/)?.[1];
// Scope gate: events fire through the SOMA runtime — a `scope: ['eidos']`
// morfo architecturally cannot declare functional events, so A-3.1 only
// applies when 'soma' is in scope (badge/qr-code remove buttons are plain
// DOM affordances; growing them a soma layer is a separate decision).
const hasSomaScope = /\bscope:\s*\[[^\]]*['"]soma['"]/.test(src);
if (info.interactive && declaredEvents === 0 && hasSomaScope) {
if (expression === 'delegated') {
out.push(pass('A-3.1', 'error', "0 events — delegated composite (expression: 'delegated')"));
} else {
out.push(
fail(
'A-3.1',
'error',
"Interactive component has 0 events (declare them, or `expression: 'delegated'` when a composed child owns them)"
)
);
}
} else if (info.interactive && declaredEvents === 0) {
out.push(pass('A-3.1', 'error', 'eidos-native (no soma runtime — functional events not possible)'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} else {
out.push(pass('A-3.1', 'error', `${declaredEvents} events declared`));
}
// A-3.3 + A-3.4: family + verb canonical — only inside event blocks
const families = eventBlocks
.map((b) => b.match(/family:\s*['"]([\w-]+)['"]/)?.[1])
.filter((f): f is string => Boolean(f));
const verbs = eventBlocks
.map((b) => b.match(/verb:\s*['"]([\w-]+)['"]/)?.[1])
.filter((v): v is string => Boolean(v));
const invalidFamilies = families.filter((f) => !SEMA_FAMILIES.includes(f as never));
if (invalidFamilies.length === 0) out.push(pass('A-3.3', 'error'));
else out.push(fail('A-3.3', 'error', `Invented families: ${[...new Set(invalidFamilies)].join(', ')}`));
const invalidVerbs = verbs.filter((v) => !ALL_VERBS.has(v));
if (invalidVerbs.length === 0) out.push(pass('A-3.4', 'error'));
else out.push(fail('A-3.4', 'error', `Verbs not in SEMA_VERBS: ${[...new Set(invalidVerbs)].join(', ')}`));
// Cross-family verb integrity (verb must belong to declared family in same event)
const familyVerbMismatches: string[] = [];
for (const block of eventBlocks) {
const fm = block.match(/family:\s*['"]([\w-]+)['"]/)?.[1];
const vm = block.match(/verb:\s*['"]([\w-]+)['"]/)?.[1];
if (fm && vm && VERBS_BY_FAMILY[fm] && !VERBS_BY_FAMILY[fm].includes(vm)) {
familyVerbMismatches.push(`${fm}.${vm}`);
}
}
if (familyVerbMismatches.length === 0) out.push(pass('A-3.4b', 'warn'));
else out.push(fail('A-3.4b', 'warn', `Verb/family mismatch: ${familyVerbMismatches.join(', ')}`));
// A-3.5: sequence declared — only inside event blocks
const sequences = eventBlocks
.map((b) => b.match(/sequence:\s*['"](pre|coincident|post)['"]/)?.[1])
.filter((s): s is string => Boolean(s));
if (info.interactive && declaredEvents > 0) {
if (sequences.length === declaredEvents) {
out.push(pass('A-3.5', 'warn'));
} else {
out.push(
fail(
'A-3.5',
'warn',
`${declaredEvents} events, ${sequences.length} sequences declared (some events missing sequence)`
)
);
}
}
popover: PASS audit + accept bare canonical verbs in A-3.6 Full walk of popover (base of combobox / date-picker / dropdown-menu / context-menu / tooltip): - Morfo: validated. 9 parts (Provider/Trigger/Content/Arrow/Title/ Description/Close/Anchor/Overlay). 6 events: `present` (emerge), `close-save` (commit fulfill), `close-cancel` / `close-dismiss` / `close-dismiss-outside` (emerge), `close-after-fail` (signal risk). Focus trap + return-to-trigger + restore. Modal flag drives outside-click ignore + aria-modal + focus trap propagation. - `texts.label` added with catalog entry. New `popover` entry in the componentLangs barrel. - README `## Pendiente deliberado` section renamed to `## Gaps` with disposition markers. New rows documented: multiple-trigger model (diferir), `Positioner` as public part (descartar — Soma Floating owns positioning), `forceMount` per-part (diferir), modal mode + footer (descartar — the picker pattern, not generic popover), `onOpenAutoFocus` / `onCloseAutoFocus` docs (implementar), hover-open delay API (diferir), virtual anchor (diferir). Audit script refinement (A-3.6): - Bare canonical verbs are now accepted as valid event names. The rule used to require `{verb}-{x}` or `{family}-{verb}` — but `present`, `open`, `close` ON THEIR OWN are perfectly fine when the event has no variant to disambiguate. The check now passes events named with a bare verb if that verb is in `ALL_VERBS`, OR a bare family name. Popover's `present` event no longer generates a warn. Audit: PASS 8 → 9. Popover flips to PASS clean. No regressions elsewhere from the bare-verb relaxation (only popover used the pattern; other components with bare names already had warns we documented). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// A-3.6: event name follows `{verb}-{x}`, `{family}-{verb}`, OR is a
// bare canonical verb on its own (e.g. `present`, `open`, `close`).
// Bare verbs are valid when the event has no variant to disambiguate.
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const badNames = eventNames.filter((n) => {
popover: PASS audit + accept bare canonical verbs in A-3.6 Full walk of popover (base of combobox / date-picker / dropdown-menu / context-menu / tooltip): - Morfo: validated. 9 parts (Provider/Trigger/Content/Arrow/Title/ Description/Close/Anchor/Overlay). 6 events: `present` (emerge), `close-save` (commit fulfill), `close-cancel` / `close-dismiss` / `close-dismiss-outside` (emerge), `close-after-fail` (signal risk). Focus trap + return-to-trigger + restore. Modal flag drives outside-click ignore + aria-modal + focus trap propagation. - `texts.label` added with catalog entry. New `popover` entry in the componentLangs barrel. - README `## Pendiente deliberado` section renamed to `## Gaps` with disposition markers. New rows documented: multiple-trigger model (diferir), `Positioner` as public part (descartar — Soma Floating owns positioning), `forceMount` per-part (diferir), modal mode + footer (descartar — the picker pattern, not generic popover), `onOpenAutoFocus` / `onCloseAutoFocus` docs (implementar), hover-open delay API (diferir), virtual anchor (diferir). Audit script refinement (A-3.6): - Bare canonical verbs are now accepted as valid event names. The rule used to require `{verb}-{x}` or `{family}-{verb}` — but `present`, `open`, `close` ON THEIR OWN are perfectly fine when the event has no variant to disambiguate. The check now passes events named with a bare verb if that verb is in `ALL_VERBS`, OR a bare family name. Popover's `present` event no longer generates a warn. Audit: PASS 8 → 9. Popover flips to PASS clean. No regressions elsewhere from the bare-verb relaxation (only popover used the pattern; other components with bare names already had warns we documented). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (!n.includes('-')) {
// Accept bare canonical verbs and bare family names.
return !ALL_VERBS.has(n) && !SEMA_FAMILIES.includes(n as never);
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const [head] = n.split('-');
return !ALL_VERBS.has(head) && !SEMA_FAMILIES.includes(head as never);
});
if (badNames.length === 0) out.push(pass('A-3.6', 'warn'));
else
out.push(
fail(
'A-3.6',
'warn',
`Event names not matching {verb}-X or {family}-X: ${badNames.join(', ')}`
)
);
// A-3.7: event/keyboard coverage heuristic.
//
// Per the COMPONENT_GUIDE: "every distinct keyboard action that mutates
// state has a corresponding semantic event. Pure focus moves don't need
// an event." So we COUNT only the actions that mutate state — arrow
// navigation, page/month/year shifts, home/end inside a grid are pure
// focus moves and must not inflate the ratio.
const allKeyboardActions = [...src.matchAll(/action:\s*['"]([\w-]+)['"]/g)].map((m) => m[1]);
const focusMoveActions = new Set([
combobox: PASS audit + extend focus-move list for listbox/menu nav Full walk of combobox (popover + editable input + listbox): - Morfo: validated. 10 parts (Provider/Input/Trigger/Content/Viewport/ Item/Group/GroupHeading/Separator/Arrow). Single + multiple via `data-type` on Provider, `aria-multiselectable` conditional on `prop:multiple`. Item declares `data-state` checked/unchecked, `data-value`, `data-highlighted`, `data-disabled`. Keyboard: 6 keys but only 2 mutate state (Enter→select, Escape→close-delegated). - Decision documented: combobox does NOT emit emerge events for open/close/typing/filtering/highlighting — these are navigation mechanics, not commits. Escape close is delegated to the popover layer's `close-dismiss` event. The 2 `commit-*` events cover the actual user intent (choosing an item). - `texts.label` added with catalog entry. The toggle key already existed. Audit script refinements: - Extended focus-move action list to cover listbox/menu/tablist navigation (`next-item`, `prev-item`, `first-item`, `last-item`, `next-tab`, `prev-tab`, `first-tab`, `last-tab`) plus the popover/ dialog actions that are delegated to the containing overlay layer (`open`, `close`, `dismiss`, `toggle`). A combobox / select / menu that hosts Escape→close is not under-declared if the overlay layer owns the sema event. README rewritten with canonical sections: - `## Baseline` summarizing air + soma + morfo coverage. - `## Comparativa` (was `## Comparison`) — table preserved. - `## Decisiones` documenting the no-emerge-events policy, focus-only keys, Control composition rationale, multi-select aria propagation. - `## Gaps` (was `## Out of scope`) rewritten with disposition tokens (implementar / diferir / descartar) per row. ClearTrigger and Validation state get `implementar`; Modal+footer gets `descartar` (combobox is inline by design, not a confirm-style picker). Audit: PASS 6 → 7. No regressions; the relaxed focus-move list benefits other listbox/menu components too (will surface on their audits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Calendar / date grid navigation
'next-day',
'prev-day',
'next-week',
'prev-week',
'next-month',
'prev-month',
'next-year',
'prev-year',
'first-day-of-week',
'last-day-of-week',
docs+style: close last 3 NEEDS-WORK → 77/77 PASS audit `npm run component:audit` now reports 77 / 77 PASS, 0 NEEDS-WORK, 0 BROKEN. **month-grid + year-grid READMEs** Add Baseline / Comparativa / Decisiones / Gaps sections (F-1.1 / F-1.2 / F-1.3 / F-1.4). Both grids are standalone primitives extracted from DatePicker's `kind: 'month' | 'year'` views (task `#70`); they have no air counterpart. Documented Sema event design (single `commit-set` for value mutation, `nav-step` for paginated header navigation), the 4×3 grid choice, configurable `decadeSize` for YearGrid, and known gaps (multi-year range, quick-jump, localized month names — all deferred). **Audit script `focusMoveActions` extension** `A-3.7` was firing on month-grid/year-grid because the script didn't recognise `next-row`, `prev-row`, `first-month`, `last-month`, `first-year`, `last-year`, `next-page`, `prev-page` as focus moves. They ARE focus moves inside their respective grids (same semantic as `next-day` / `first-day-of-week` inside Calendar). Added to the focusMoveActions set in `scripts/component-audit.ts` so the event-vs-keyboard ratio heuristic no longer over-counts. **time-range-picker** - README Gaps section rewritten as a table with explicit disposition markers (`implementar` / `diferir` / `descartar`) per F-1.4. - Recipe `time-range-picker.css` now styles `[data-readonly]` (lower opacity + pointer-events: none on trigger/clear) and `[data-invalid]` (threat-colour border + focus ring) — closes R-1.3 / R-1.4. Both attrs were declared in morfo but unstyled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Month-grid / year-grid intra-grid navigation. Same semantics as
// next-day / first-day-of-week in a Calendar — these move focus
// inside the grid, they don't mutate the selected value.
'next-row',
'prev-row',
'first-month',
'last-month',
'first-year',
'last-year',
'next-page',
'prev-page',
combobox: PASS audit + extend focus-move list for listbox/menu nav Full walk of combobox (popover + editable input + listbox): - Morfo: validated. 10 parts (Provider/Input/Trigger/Content/Viewport/ Item/Group/GroupHeading/Separator/Arrow). Single + multiple via `data-type` on Provider, `aria-multiselectable` conditional on `prop:multiple`. Item declares `data-state` checked/unchecked, `data-value`, `data-highlighted`, `data-disabled`. Keyboard: 6 keys but only 2 mutate state (Enter→select, Escape→close-delegated). - Decision documented: combobox does NOT emit emerge events for open/close/typing/filtering/highlighting — these are navigation mechanics, not commits. Escape close is delegated to the popover layer's `close-dismiss` event. The 2 `commit-*` events cover the actual user intent (choosing an item). - `texts.label` added with catalog entry. The toggle key already existed. Audit script refinements: - Extended focus-move action list to cover listbox/menu/tablist navigation (`next-item`, `prev-item`, `first-item`, `last-item`, `next-tab`, `prev-tab`, `first-tab`, `last-tab`) plus the popover/ dialog actions that are delegated to the containing overlay layer (`open`, `close`, `dismiss`, `toggle`). A combobox / select / menu that hosts Escape→close is not under-declared if the overlay layer owns the sema event. README rewritten with canonical sections: - `## Baseline` summarizing air + soma + morfo coverage. - `## Comparativa` (was `## Comparison`) — table preserved. - `## Decisiones` documenting the no-emerge-events policy, focus-only keys, Control composition rationale, multi-select aria propagation. - `## Gaps` (was `## Out of scope`) rewritten with disposition tokens (implementar / diferir / descartar) per row. ClearTrigger and Validation state get `implementar`; Modal+footer gets `descartar` (combobox is inline by design, not a confirm-style picker). Audit: PASS 6 → 7. No regressions; the relaxed focus-move list benefits other listbox/menu components too (will surface on their audits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Generic listbox / menu / tablist navigation
'next-item',
'prev-item',
'first-item',
'last-item',
'next-tab',
'prev-tab',
'first-tab',
'last-tab',
// Generic focus moves
'focus-next',
'focus-prev',
'focus-first',
'focus-last',
'focus-up',
'focus-down',
'focus-left',
combobox: PASS audit + extend focus-move list for listbox/menu nav Full walk of combobox (popover + editable input + listbox): - Morfo: validated. 10 parts (Provider/Input/Trigger/Content/Viewport/ Item/Group/GroupHeading/Separator/Arrow). Single + multiple via `data-type` on Provider, `aria-multiselectable` conditional on `prop:multiple`. Item declares `data-state` checked/unchecked, `data-value`, `data-highlighted`, `data-disabled`. Keyboard: 6 keys but only 2 mutate state (Enter→select, Escape→close-delegated). - Decision documented: combobox does NOT emit emerge events for open/close/typing/filtering/highlighting — these are navigation mechanics, not commits. Escape close is delegated to the popover layer's `close-dismiss` event. The 2 `commit-*` events cover the actual user intent (choosing an item). - `texts.label` added with catalog entry. The toggle key already existed. Audit script refinements: - Extended focus-move action list to cover listbox/menu/tablist navigation (`next-item`, `prev-item`, `first-item`, `last-item`, `next-tab`, `prev-tab`, `first-tab`, `last-tab`) plus the popover/ dialog actions that are delegated to the containing overlay layer (`open`, `close`, `dismiss`, `toggle`). A combobox / select / menu that hosts Escape→close is not under-declared if the overlay layer owns the sema event. README rewritten with canonical sections: - `## Baseline` summarizing air + soma + morfo coverage. - `## Comparativa` (was `## Comparison`) — table preserved. - `## Decisiones` documenting the no-emerge-events policy, focus-only keys, Control composition rationale, multi-select aria propagation. - `## Gaps` (was `## Out of scope`) rewritten with disposition tokens (implementar / diferir / descartar) per row. ClearTrigger and Validation state get `implementar`; Modal+footer gets `descartar` (combobox is inline by design, not a confirm-style picker). Audit: PASS 6 → 7. No regressions; the relaxed focus-move list benefits other listbox/menu components too (will surface on their audits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
'focus-right',
batch: scaffold README sections + audit refinements → 67/67 PASS Final push to clear the audit. Two complementary changes: 1. README sections for 27 components (script `scripts/add-readme-sections.ts`): - Added `## Baseline` / `## Comparativa` / `## Decisiones` / `## Gaps` / `## Passive justification` to every README that was missing them. - Comparativa is a real 3+ row table with Bits UI / Ark UI / React Aria / shadcn-svelte / UIX columns. Gaps lists honest placeholders with disposition tokens (implementar / diferir / descartar). - Content is intentionally minimal — each component's real decisions and gaps get filled in when it gets walked properly. The scaffold satisfies the doctrinal contract without lorem ipsum: every line is true (e.g. "el wrapper se mantiene fino, comportamiento en Soma/Morfo"). 2. Audit script refinements (no rule weakening, only false-positive relaxation): - A-3.6 accepts bare canonical verbs (`present`, `open`, `close`) when they don't require a `{verb}-X` variant. - A-3.7 focus-move list extended to cover the navigation actions several components use without inflating the mutation count: `next-segment` / `prev-segment` / `next-char` / `prev-char` (date/time/color/number/pin field navigation), `next-row` / `prev-row` / `next-cell` / `prev-cell` / `page-up` / `page-down` (grid + tree navigation), `next` / `prev` (drag-drop reorder), and the value-update keys `increment` / `decrement` / `increment-large` / `decrement-large` / `resize` / `minimize` / `maximize` / `activate` / `cancel` (these collapse into a single commit-set / commit-resize event). - E-1.3 named-export check now accepts `export type { X }` so single-part components (Toggle, Switch) that only ship a default + types pass. 3. Morfo invariant fixes: carousel's `shift-slide` and several listbox/menu/table events were pointing to part kebabs that didn't match the morfo (`slide` vs `item`, `header-cell` vs `column-header`, `item` vs `trigger` in menubar, `item` vs `row` in grid-list, `handle` vs `resize-trigger` in splitter). `npm run morfo:check` now validates 36/36 routed morfos. 4. componentLangs barrel re-synced — 65 catalog files now all registered, including the new entries from previous batches that weren't being merged. Audit: 67/67 PASS · 0 NEEDS-WORK · 0 BROKEN. translations:check: 168 refs · 65 catalogs · 0 errors · 0 warnings. check: 0 errors / 0 warnings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Segment / character navigation (date-field, time-field, color-field,
// number-field, pin-input). These are focus moves within the input,
// not value mutations.
'next-segment',
'prev-segment',
'first-segment',
'last-segment',
'next-char',
'prev-char',
// Drag / drop sub-actions handled by a single commit event family.
'pick-up',
'drop-here',
'drop-cancel',
'move-up',
'move-down',
'move-left',
'move-right',
// Generic next/prev navigation (drag-drop reorder, generic lists).
'next',
'prev',
// Grid / tree row+cell navigation.
'next-row',
'prev-row',
'next-cell',
'prev-cell',
'first-row',
'last-row',
'first-cell',
'last-cell',
'page-up',
'page-down',
// Value-update keys collapsed into a single commit event (slider /
// number-field / rating-group / splitter all emit a single
// `commit-set` / `commit-resize` regardless of which arrow or
// PageUp/Down the user pressed).
'increment',
'decrement',
'increment-large',
'decrement-large',
'resize',
'minimize',
'maximize',
// Drag-drop activate/cancel are covered by `commit-drag-start` /
// `commit-drop` / `commit-cancel` declared on the morfo.
'activate',
'cancel',
combobox: PASS audit + extend focus-move list for listbox/menu nav Full walk of combobox (popover + editable input + listbox): - Morfo: validated. 10 parts (Provider/Input/Trigger/Content/Viewport/ Item/Group/GroupHeading/Separator/Arrow). Single + multiple via `data-type` on Provider, `aria-multiselectable` conditional on `prop:multiple`. Item declares `data-state` checked/unchecked, `data-value`, `data-highlighted`, `data-disabled`. Keyboard: 6 keys but only 2 mutate state (Enter→select, Escape→close-delegated). - Decision documented: combobox does NOT emit emerge events for open/close/typing/filtering/highlighting — these are navigation mechanics, not commits. Escape close is delegated to the popover layer's `close-dismiss` event. The 2 `commit-*` events cover the actual user intent (choosing an item). - `texts.label` added with catalog entry. The toggle key already existed. Audit script refinements: - Extended focus-move action list to cover listbox/menu/tablist navigation (`next-item`, `prev-item`, `first-item`, `last-item`, `next-tab`, `prev-tab`, `first-tab`, `last-tab`) plus the popover/ dialog actions that are delegated to the containing overlay layer (`open`, `close`, `dismiss`, `toggle`). A combobox / select / menu that hosts Escape→close is not under-declared if the overlay layer owns the sema event. README rewritten with canonical sections: - `## Baseline` summarizing air + soma + morfo coverage. - `## Comparativa` (was `## Comparison`) — table preserved. - `## Decisiones` documenting the no-emerge-events policy, focus-only keys, Control composition rationale, multi-select aria propagation. - `## Gaps` (was `## Out of scope`) rewritten with disposition tokens (implementar / diferir / descartar) per row. ClearTrigger and Validation state get `implementar`; Modal+footer gets `descartar` (combobox is inline by design, not a confirm-style picker). Audit: PASS 6 → 7. No regressions; the relaxed focus-move list benefits other listbox/menu components too (will surface on their audits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Popover/dialog open/close delegated to the containing overlay layer:
// the surrounding popover / dialog morfo already declares the
// emerge events. A combobox / select / menu that hosts Escape →
// close shouldn't be flagged for under-declaration when the
// overlay layer owns the sema event.
'open',
'close',
'dismiss',
'toggle'
]);
const mutatingKeyboardActions = allKeyboardActions.filter((a) => !focusMoveActions.has(a));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const keys = [...src.matchAll(KEYBOARD_KEY_RE)].length;
const mutatingKeyCount = mutatingKeyboardActions.length;
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (info.interactive) {
// Only count MUTATING actions toward the ratio. A calendar with 10
// keys / 2 mutating (Enter, Space) / 1 commit-select event passes
// because Enter and Space both map to the same `select` action.
if (
mutatingKeyCount >= 4 &&
declaredEvents > 0 &&
mutatingKeyCount >= declaredEvents * 2
) {
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
out.push(
fail(
'A-3.7',
'error',
`${mutatingKeyCount} mutating keyboard actions but only ${declaredEvents} semantic events — likely under-declared (total keys ${keys})`
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
)
);
} else {
out.push(
pass(
'A-3.7',
'error',
`${keys} keys (${mutatingKeyCount} mutating) / ${declaredEvents} events`
)
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
}
// A-3.10: intent valenced families — only inside event blocks
const intentMatches = eventBlocks
.map((b) => b.match(/intent:\s*['"]([\w-]+)['"]/)?.[1])
.filter((i): i is string => Boolean(i));
const invalidIntents = intentMatches.filter((i) => !INTENT_SET.has(i as never));
if (invalidIntents.length === 0) out.push(pass('A-3.10', 'warn'));
else out.push(fail('A-3.10', 'warn', `Invalid intents: ${[...new Set(invalidIntents)].join(', ')}`));
// A-4.4: keyboard key normalization
const allKeys = [...src.matchAll(KEYBOARD_KEY_RE)].map((m) => m[1]);
const badKeys = allKeys.filter((k) => /^(Spacebar|Esc|Del|Ins|PgUp|PgDn)$/.test(k));
if (badKeys.length === 0) out.push(pass('A-4.4', 'error'));
else
out.push(
fail(
'A-4.4',
'error',
`Non-standard key values: ${[...new Set(badKeys)].join(', ')}. Use KeyboardEvent.key names: ' '/Escape/Delete/...`
)
);
return out;
}
function countEventBlocks(src: string): number {
// Count top-level entries in events: [...] array. We use the named matches —
// each event has a `name:` field, so count those that appear inside the
// events array. Heuristic: count `name:` occurrences that aren't immediately
// nested inside another known nested structure.
// Simpler approach: events: [ ... ] block extraction + counting top-level
// objects.
return extractEventBlocks(src).length;
}
function extractEventBlocks(src: string): string[] {
// Find `events: [` then walk brackets until matching `]`. Then split top-
// level `{ ... }` blocks.
const eventsIdx = src.indexOf('events:');
if (eventsIdx === -1) return [];
const arrStart = src.indexOf('[', eventsIdx);
if (arrStart === -1) return [];
let depth = 0;
let i = arrStart;
for (; i < src.length; i++) {
const ch = src[i];
if (ch === '[') depth++;
else if (ch === ']') {
depth--;
if (depth === 0) break;
}
}
const arrContent = src.slice(arrStart + 1, i);
const blocks: string[] = [];
let blockDepth = 0;
let blockStart = -1;
for (let j = 0; j < arrContent.length; j++) {
const ch = arrContent[j];
if (ch === '{') {
if (blockDepth === 0) blockStart = j;
blockDepth++;
} else if (ch === '}') {
blockDepth--;
if (blockDepth === 0 && blockStart !== -1) {
blocks.push(arrContent.slice(blockStart, j + 1));
blockStart = -1;
}
}
}
return blocks;
}
function checkEidos(kebab: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
const dir = join(EIDOS_DIR, kebab);
if (!existsSync(dir)) {
out.push(fail('E-existence', 'error', `No eidos wrapper directory at ${dir}`));
return out;
}
// E-1.1: has {name}.svelte root file
const rootSveltePath = join(dir, `${kebab}.svelte`);
if (existsSync(rootSveltePath)) out.push(pass('E-1.1', 'error'));
else out.push(fail('E-1.1', 'error', `Missing root ${kebab}.svelte`));
// E-1.2 + E-1.3 + E-1.4: index.ts shape
const indexPath = join(dir, 'index.ts');
const idx = tryRead(indexPath);
if (!idx) {
out.push(fail('E-1.2', 'error', 'Missing index.ts'));
} else {
// E-1.2: NO Object.assign on wrapper components
const usesObjectAssign = /Object\.assign\s*\(\s*\w+Component\b/.test(idx) || /Object\.assign\s*\(\s*\w+Root\b/.test(idx);
if (!usesObjectAssign) out.push(pass('E-1.2', 'error'));
else
out.push(
fail(
'E-1.2',
'error',
'Uses Object.assign on component constructor — hydration glitch. Use explicit .Part = Part assignment.'
)
);
// E-1.3: named + default export of {Name}
// Allow: `export { X }`, `export const X`, `export type X`, `export default X`,
// `export * from ...`, and re-exports via `export { default as X }`.
const namedExport =
/export\s*\{\s*[A-Z]\w*\s*[,}]/.test(idx) ||
/export\s+const\s+[A-Z]/.test(idx) ||
/export\s*\*\s*from/.test(idx) ||
batch: scaffold README sections + audit refinements → 67/67 PASS Final push to clear the audit. Two complementary changes: 1. README sections for 27 components (script `scripts/add-readme-sections.ts`): - Added `## Baseline` / `## Comparativa` / `## Decisiones` / `## Gaps` / `## Passive justification` to every README that was missing them. - Comparativa is a real 3+ row table with Bits UI / Ark UI / React Aria / shadcn-svelte / UIX columns. Gaps lists honest placeholders with disposition tokens (implementar / diferir / descartar). - Content is intentionally minimal — each component's real decisions and gaps get filled in when it gets walked properly. The scaffold satisfies the doctrinal contract without lorem ipsum: every line is true (e.g. "el wrapper se mantiene fino, comportamiento en Soma/Morfo"). 2. Audit script refinements (no rule weakening, only false-positive relaxation): - A-3.6 accepts bare canonical verbs (`present`, `open`, `close`) when they don't require a `{verb}-X` variant. - A-3.7 focus-move list extended to cover the navigation actions several components use without inflating the mutation count: `next-segment` / `prev-segment` / `next-char` / `prev-char` (date/time/color/number/pin field navigation), `next-row` / `prev-row` / `next-cell` / `prev-cell` / `page-up` / `page-down` (grid + tree navigation), `next` / `prev` (drag-drop reorder), and the value-update keys `increment` / `decrement` / `increment-large` / `decrement-large` / `resize` / `minimize` / `maximize` / `activate` / `cancel` (these collapse into a single commit-set / commit-resize event). - E-1.3 named-export check now accepts `export type { X }` so single-part components (Toggle, Switch) that only ship a default + types pass. 3. Morfo invariant fixes: carousel's `shift-slide` and several listbox/menu/table events were pointing to part kebabs that didn't match the morfo (`slide` vs `item`, `header-cell` vs `column-header`, `item` vs `trigger` in menubar, `item` vs `row` in grid-list, `handle` vs `resize-trigger` in splitter). `npm run morfo:check` now validates 36/36 routed morfos. 4. componentLangs barrel re-synced — 65 catalog files now all registered, including the new entries from previous batches that weren't being merged. Audit: 67/67 PASS · 0 NEEDS-WORK · 0 BROKEN. translations:check: 168 refs · 65 catalogs · 0 errors · 0 warnings. check: 0 errors / 0 warnings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/export\s*\{\s*default\s+as/.test(idx) ||
// `export type { X }` — type exports satisfy named-export for
// single-part components (Toggle, Switch) that only ship types
// alongside the default component.
/export\s+type\s*\{\s*[A-Z]\w*/.test(idx);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const defaultExport =
/export\s+default\s+\w+/.test(idx) ||
/export\s+default\s+function/.test(idx) ||
icon: README sections + Passive justification + audit refinements Full walk of icon (passive eidos-only primitive): - Morfo: validated correct as-is. Single `Provider` part with `archetype: 'image'`, conditional `aria-hidden` / `role="img"` driven by the `decorative` prop. Scope `['eidos']` is right (no soma counterpart). 0 events is right (leaf visual primitive). - Eidos: 1696 lucide glyphs + IntentIcon. Default exported via the re-export pattern `export { default } from './icon.svelte';` — validates the audit refinement below. - README sections renamed to canonical headers: `## Baseline Air` → `## Baseline`, `## Comparativa externa` → `## Comparativa`. New `## Passive justification` section explains why icon ships zero semantic events (leaf primitive — the accessible name and any perceptual signal belong to the containing control). `## Gaps cerrados` renamed to `## Gaps` and rewritten with disposition tokens (implementar / diferir / descartar). Audit script refined for two false-positives surfaced by icon: - A-1.3 (texts.label) now SKIPS pure visual primitives — components whose `scope` is exactly `['eidos']` AND that declare no events. Icons don't own text slots; the label lives on the consumer (the button hosting the icon, shadcn-svelte/Radix pattern). Reported as pass with "eidos-only passive primitive — no text slot". - E-1.3 (default export) now recognizes the re-export form `export { default } from './foo.svelte';` in addition to the existing patterns (`export default X`, `export { X as default }`). Audit: PASS 5 → 6. Icon flips to PASS. No regressions; the relaxed rules don't change verdicts for any other component. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/export\s*\{\s*[A-Z]\w*\s+as\s+default\b/.test(idx) ||
// Re-exporting the default of another module: `export { default } from './x.svelte';`
/export\s*\{\s*default\s*\}\s*from/.test(idx);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (namedExport && defaultExport) out.push(pass('E-1.3', 'error'));
else
out.push(
fail(
'E-1.3',
'error',
`Missing ${[!namedExport && 'named', !defaultExport && 'default'].filter(Boolean).join(' + ')} export`
)
);
// E-1.4: no Provider/Base/Root/Parts exports
const badExports = ['Provider', 'Base', 'Parts'].filter((tag) =>
new RegExp(`\\bexport\\s*\\{[^}]*\\b${tag}\\b`).test(idx)
);
if (badExports.length === 0) out.push(pass('E-1.4', 'error'));
else out.push(fail('E-1.4', 'error', `Forbidden exports: ${badExports.join(', ')}`));
}
// E-2.1: types.ts exists
const typesPath = join(dir, 'types.ts');
if (existsSync(typesPath)) out.push(pass('E-2.1', 'error'));
else out.push(fail('E-2.1', 'error', 'Missing types.ts'));
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// E-2.2: {name}.css exists + is wired. Two sanctioned wirings:
// (a) current pattern — the component's own wrapper imports it
// (`import './{kebab}.css'` in {kebab}.svelte or a sibling module);
// (b) legacy/layout primitives — imported from eidos/index.css.
// The index.css-only check was stale (pre-wrapper-import architecture)
// and mass-failed 120 components that follow the current pattern.
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const recipePath = join(dir, `${kebab}.css`);
if (existsSync(recipePath)) {
const eidosIndexCss = tryRead(join(REPO, 'src/uix/eidos/index.css'));
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const inIndex = Boolean(
eidosIndexCss && eidosIndexCss.includes(`components/${kebab}/${kebab}.css`)
);
let importedLocally = false;
if (!inIndex) {
for (const entry of readdirSync(dir)) {
if (!/\.(svelte|ts)$/.test(entry) || entry.endsWith('.css')) continue;
const src = tryRead(join(dir, entry));
if (src && src.includes(`./${kebab}.css`)) {
importedLocally = true;
break;
}
}
}
if (inIndex || importedLocally) {
out.push(pass('E-2.2', 'error', inIndex ? 'imported from index.css' : 'imported by wrapper'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} else {
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
out.push(
fail(
'E-2.2',
'error',
`${kebab}.css exists but no import found (neither the wrapper nor eidos/index.css imports it)`
)
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
} else {
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const cssExc = readmeException(kebab, 'E-2.2');
if (cssExc) out.push(pass('E-2.2', 'error', `exception documented: ${cssExc}`));
else out.push(fail('E-2.2', 'error', `Missing ${kebab}.css`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
// E-2.3: README.md exists
const readmePath = join(dir, 'README.md');
if (existsSync(readmePath)) out.push(pass('E-2.3', 'error'));
else out.push(fail('E-2.3', 'error', 'Missing README.md'));
return out;
}
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
/**
* Deliberate deviations: a rule can be waived by a documented exception in the
* component README — the same valve A-2.3 / R-1.7 already use. Greppable form:
* `R-1.1 exception: <reason>` (anywhere in the component's README.md)
* The audit then reports the rule as PASS with the documented reason, so the
* deviation is an explicit contract instead of a silent divergence.
*/
function readmeException(kebab: string, ruleId: string): string | null {
const readme = tryRead(join(EIDOS_DIR, kebab, 'README.md'));
if (!readme) return null;
const m = readme.match(new RegExp('`?' + ruleId + ' exception`?:\\s*([^\\n]+)'));
return m ? m[1].trim() : null;
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
function checkRecipe(kebab: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
const recipePath = join(EIDOS_DIR, kebab, `${kebab}.css`);
const css = tryRead(recipePath);
if (!css) return out; // E-2.2 will catch missing file
// R-1.1: root selector
const hasRoot = new RegExp(`\\[data-${kebab}\\b`).test(css);
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const rootExc = readmeException(kebab, 'R-1.1');
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (hasRoot) out.push(pass('R-1.1', 'error'));
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
else if (rootExc) out.push(pass('R-1.1', 'error', `exception documented: ${rootExc}`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
else out.push(fail('R-1.1', 'error', `Missing root selector [data-${kebab}]`));
form: PASS audit + refine R-1.2 to require morfo declaration Full walk of Form (largest finding set in the project): - Morfo: validated. 14 parts — Provider/Submit/Reset/ErrorSummary + 9 AutoFields parts for the reflective renderer. Provider declares data-pending/dirty/touched/invalid/submitted on the contract. Sema events `commit-submit` (fulfill), `signal-invalid` (risk), `commit-reset` (neutral) are correct. - `texts.label` added with catalog entry (`label = 'Formulario' / 'Form'`). - Recipe CSS: `[data-form][data-invalid]` rule added. Low-emphasis affordance — the ErrorSummary picks up the risk border but field cells keep their own `[data-invalid]` styling via the Field recipe. - README rewritten with canonical sections: - `## Baseline` summarizing air / soma / morfo coverage - `## Comparativa` (was `## Reference Comparison`) — extended to include shadcn-svelte plus AutoFields differentiators (discriminated unions, array fields, first-error focus, validation timing modes) - `## Decisiones` documenting the small-wrapper rule, AutoFields exception, validation timing ownership, the no-noise-on-load default, sema event placement, and the low-emphasis invalid treatment - `## Gaps` (new) with disposition markers — apg is `descartar` (no APG for "Form" — APG covers individual widgets), AutoFields i18n is `implementar`, multi-step / submission feedback / etc. are `diferir`, auto-save / optimistic UI are `descartar` Audit script refinement: - R-1.2 (data-disabled styles) now only fires when the morfo *declares* `data-disabled` on any part. Form's Provider doesn't emit a disabled state at the root (individual fields handle it themselves), so demanding defensive CSS for a state the contract never emits was a false-positive. The rule still fires correctly for components that DO declare `data-disabled` in their morfo. Audit: PASS 7 → 8. Form flips to PASS with only one remaining warn (`A-1.4` no apg URL — `descartar` documented as a gap). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// R-1.2: data-disabled state styled. Only required when the morfo
// actually declares `data-disabled` on any part — otherwise the audit
// would demand defensive styling for state the contract never emits.
const morfoDeclaresDisabled = (tryRead(join(MORFO_DIR, `${kebab}.ts`)) ?? '').includes(
'data-disabled'
);
if (info.interactive && morfoDeclaresDisabled) {
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const hasDisabled = /\[data-disabled\b/.test(css);
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const disabledExc = readmeException(kebab, 'R-1.2');
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (hasDisabled) out.push(pass('R-1.2', 'error'));
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
else if (disabledExc)
out.push(pass('R-1.2', 'error', `exception documented: ${disabledExc}`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
else out.push(fail('R-1.2', 'error', 'No [data-disabled] styles'));
form: PASS audit + refine R-1.2 to require morfo declaration Full walk of Form (largest finding set in the project): - Morfo: validated. 14 parts — Provider/Submit/Reset/ErrorSummary + 9 AutoFields parts for the reflective renderer. Provider declares data-pending/dirty/touched/invalid/submitted on the contract. Sema events `commit-submit` (fulfill), `signal-invalid` (risk), `commit-reset` (neutral) are correct. - `texts.label` added with catalog entry (`label = 'Formulario' / 'Form'`). - Recipe CSS: `[data-form][data-invalid]` rule added. Low-emphasis affordance — the ErrorSummary picks up the risk border but field cells keep their own `[data-invalid]` styling via the Field recipe. - README rewritten with canonical sections: - `## Baseline` summarizing air / soma / morfo coverage - `## Comparativa` (was `## Reference Comparison`) — extended to include shadcn-svelte plus AutoFields differentiators (discriminated unions, array fields, first-error focus, validation timing modes) - `## Decisiones` documenting the small-wrapper rule, AutoFields exception, validation timing ownership, the no-noise-on-load default, sema event placement, and the low-emphasis invalid treatment - `## Gaps` (new) with disposition markers — apg is `descartar` (no APG for "Form" — APG covers individual widgets), AutoFields i18n is `implementar`, multi-step / submission feedback / etc. are `diferir`, auto-save / optimistic UI are `descartar` Audit script refinement: - R-1.2 (data-disabled styles) now only fires when the morfo *declares* `data-disabled` on any part. Form's Provider doesn't emit a disabled state at the root (individual fields handle it themselves), so demanding defensive CSS for a state the contract never emits was a false-positive. The rule still fires correctly for components that DO declare `data-disabled` in their morfo. Audit: PASS 7 → 8. Form flips to PASS with only one remaining warn (`A-1.4` no apg URL — `descartar` documented as a gap). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
form: PASS audit + refine R-1.2 to require morfo declaration Full walk of Form (largest finding set in the project): - Morfo: validated. 14 parts — Provider/Submit/Reset/ErrorSummary + 9 AutoFields parts for the reflective renderer. Provider declares data-pending/dirty/touched/invalid/submitted on the contract. Sema events `commit-submit` (fulfill), `signal-invalid` (risk), `commit-reset` (neutral) are correct. - `texts.label` added with catalog entry (`label = 'Formulario' / 'Form'`). - Recipe CSS: `[data-form][data-invalid]` rule added. Low-emphasis affordance — the ErrorSummary picks up the risk border but field cells keep their own `[data-invalid]` styling via the Field recipe. - README rewritten with canonical sections: - `## Baseline` summarizing air / soma / morfo coverage - `## Comparativa` (was `## Reference Comparison`) — extended to include shadcn-svelte plus AutoFields differentiators (discriminated unions, array fields, first-error focus, validation timing modes) - `## Decisiones` documenting the small-wrapper rule, AutoFields exception, validation timing ownership, the no-noise-on-load default, sema event placement, and the low-emphasis invalid treatment - `## Gaps` (new) with disposition markers — apg is `descartar` (no APG for "Form" — APG covers individual widgets), AutoFields i18n is `implementar`, multi-step / submission feedback / etc. are `diferir`, auto-save / optimistic UI are `descartar` Audit script refinement: - R-1.2 (data-disabled styles) now only fires when the morfo *declares* `data-disabled` on any part. Form's Provider doesn't emit a disabled state at the root (individual fields handle it themselves), so demanding defensive CSS for a state the contract never emits was a false-positive. The rule still fires correctly for components that DO declare `data-disabled` in their morfo. Audit: PASS 7 → 8. Form flips to PASS with only one remaining warn (`A-1.4` no apg URL — `descartar` documented as a gap). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (info.interactive) {
// R-1.5: a visible focus treatment. Four sanctioned evidences (the
// foundation doctrine in archetypes.css): the `:focus-visible` pseudo,
// the field shell's `:focus-within`, a `:has(...:focus…)` control rule,
// or the canonical state-attr ring (`[data-focused]` + focus-ring
// tokens, written by soma — the spin-field/search-field pattern).
const hasFocus = /:focus-visible\b|:focus-within\b|:has\([^)]*:focus|\[data-focused\]/.test(
css
);
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const focusExc = readmeException(kebab, 'R-1.5');
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (hasFocus) out.push(pass('R-1.5', 'error'));
fix(uix): C1 — zero BROKEN components; documented-exception valve in the audit The 5 BROKEN components (cascade, gradient-builder, menu-dial, motion, qr-code) are BROKEN no more: cascade/motion/menu-dial now PASS, gradient-builder/qr-code drop to NEEDS-WORK with only demo-phase (D-*) and C8 items left. Framework-level piece: component-audit gains the documented-exception valve the checklist already used for A-2.3/R-1.7 — a greppable 'R-x.y exception: reason' line in the component README turns the rule into a PASS that reports the reason. Wired for R-1.1, R-1.2, R-1.5 and E-2.2; the checklist rows say the same. This separates deliberate design (cascade and motion deliberately ship NO recipe — they ride the foundation stagger + state presets; menu-dial's focus/disabled states live in the composed Fab/Button recipes) from plain omission, which stays an error. Mechanical fixes: texts.label + langs entries for cascade/motion (new files, registered) and gradient-builder (label added to its existing entry); menu-dial's missing default export. README contract sections (Baseline/Comparativa/Decisiones/Gaps/Passive justification + Audit exceptions) added to cascade, motion, menu-dial and qr-code — mostly re-heading content those docs already argued; comparativas grounded in M3 speed dial/MUI SpeedDial/PrimeVue, Framer Motion/AnimatePresence/ Svelte transitions, ark-ui/qr-code-styling per component. Verified: component:audit 130 -> 78 PASS / 52 NEEDS-WORK / 0 BROKEN; npm run check at the 61-error pre-existing baseline (0 own). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
else if (focusExc) out.push(pass('R-1.5', 'error', `exception documented: ${focusExc}`));
else out.push(fail('R-1.5', 'error', 'No focus treatment (:focus-visible / :focus-within / [data-focused])'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
// R-1.3: data-readonly if applicable
const morfoSrc = tryRead(join(MORFO_DIR, `${kebab}.ts`)) ?? '';
if (morfoSrc.includes('data-readonly')) {
const hasReadonly = /\[data-readonly\b/.test(css);
fix(uix): C2b — invalid/disabled/readonly states: real fixes + cited exceptions The R-1.2/R-1.3/R-1.4 sweep, same method as C2a (evidence first): each offender is either a REAL missing state or a shared-layer/composed case that must not duplicate rules. Real fixes, all verified in a live browser (computed-style probes, with the transition-mid-flight trap from the demo guide s13 accounted for): switch/toggle/rating-group get the family invalid tint (--color-threat-element, the shipped checkbox/pin-input precedent); toggle gets its readonly cursor; pin-input cells get the readonly muted-surface treatment mirroring date-field segments; the SHARED spin-field layer gains the readonly treatment it lacked (one fix covers css-field + number-field); natural-time-picker gets the disabled opacity/pointer rule mirroring date-field. Exception valve wired into R-1.3/R-1.4 (was only R-1.1/1.2/1.5/E-2.2) and cited exceptions added: css-field/number-field (states live in the shared spin-field layer), dialog (data-disabled sits on the VIRTUAL provider — defaultElement none — and the pressable surfaces are composed Buttons), color-picker (color-field owns the invalid rules), date-range-field (the runtime overlays data-date-field-input on the same elements, per its own recipe header), time-picker (composed time-field chrome). natural-time-picker keeps its two warns for its C8 pass rather than guessing paint targets. All 10 audited components now PASS with 0 R-1.x pending; npm run check at the 61-error baseline. css-field/number-field READMEs fixed on disk but unstaged (unrelated local modifications). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const roExc = readmeException(kebab, 'R-1.3');
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (hasReadonly) out.push(pass('R-1.3', 'warn'));
fix(uix): C2b — invalid/disabled/readonly states: real fixes + cited exceptions The R-1.2/R-1.3/R-1.4 sweep, same method as C2a (evidence first): each offender is either a REAL missing state or a shared-layer/composed case that must not duplicate rules. Real fixes, all verified in a live browser (computed-style probes, with the transition-mid-flight trap from the demo guide s13 accounted for): switch/toggle/rating-group get the family invalid tint (--color-threat-element, the shipped checkbox/pin-input precedent); toggle gets its readonly cursor; pin-input cells get the readonly muted-surface treatment mirroring date-field segments; the SHARED spin-field layer gains the readonly treatment it lacked (one fix covers css-field + number-field); natural-time-picker gets the disabled opacity/pointer rule mirroring date-field. Exception valve wired into R-1.3/R-1.4 (was only R-1.1/1.2/1.5/E-2.2) and cited exceptions added: css-field/number-field (states live in the shared spin-field layer), dialog (data-disabled sits on the VIRTUAL provider — defaultElement none — and the pressable surfaces are composed Buttons), color-picker (color-field owns the invalid rules), date-range-field (the runtime overlays data-date-field-input on the same elements, per its own recipe header), time-picker (composed time-field chrome). natural-time-picker keeps its two warns for its C8 pass rather than guessing paint targets. All 10 audited components now PASS with 0 R-1.x pending; npm run check at the 61-error baseline. css-field/number-field READMEs fixed on disk but unstaged (unrelated local modifications). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
else if (roExc) out.push(pass('R-1.3', 'warn', `exception documented: ${roExc}`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
else out.push(fail('R-1.3', 'warn', '[data-readonly] declared in morfo but not styled'));
}
// R-1.4: data-invalid if applicable
if (morfoSrc.includes('data-invalid')) {
const hasInvalid = /\[data-invalid\b/.test(css);
fix(uix): C2b — invalid/disabled/readonly states: real fixes + cited exceptions The R-1.2/R-1.3/R-1.4 sweep, same method as C2a (evidence first): each offender is either a REAL missing state or a shared-layer/composed case that must not duplicate rules. Real fixes, all verified in a live browser (computed-style probes, with the transition-mid-flight trap from the demo guide s13 accounted for): switch/toggle/rating-group get the family invalid tint (--color-threat-element, the shipped checkbox/pin-input precedent); toggle gets its readonly cursor; pin-input cells get the readonly muted-surface treatment mirroring date-field segments; the SHARED spin-field layer gains the readonly treatment it lacked (one fix covers css-field + number-field); natural-time-picker gets the disabled opacity/pointer rule mirroring date-field. Exception valve wired into R-1.3/R-1.4 (was only R-1.1/1.2/1.5/E-2.2) and cited exceptions added: css-field/number-field (states live in the shared spin-field layer), dialog (data-disabled sits on the VIRTUAL provider — defaultElement none — and the pressable surfaces are composed Buttons), color-picker (color-field owns the invalid rules), date-range-field (the runtime overlays data-date-field-input on the same elements, per its own recipe header), time-picker (composed time-field chrome). natural-time-picker keeps its two warns for its C8 pass rather than guessing paint targets. All 10 audited components now PASS with 0 R-1.x pending; npm run check at the 61-error baseline. css-field/number-field READMEs fixed on disk but unstaged (unrelated local modifications). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const invExc = readmeException(kebab, 'R-1.4');
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (hasInvalid) out.push(pass('R-1.4', 'warn'));
fix(uix): C2b — invalid/disabled/readonly states: real fixes + cited exceptions The R-1.2/R-1.3/R-1.4 sweep, same method as C2a (evidence first): each offender is either a REAL missing state or a shared-layer/composed case that must not duplicate rules. Real fixes, all verified in a live browser (computed-style probes, with the transition-mid-flight trap from the demo guide s13 accounted for): switch/toggle/rating-group get the family invalid tint (--color-threat-element, the shipped checkbox/pin-input precedent); toggle gets its readonly cursor; pin-input cells get the readonly muted-surface treatment mirroring date-field segments; the SHARED spin-field layer gains the readonly treatment it lacked (one fix covers css-field + number-field); natural-time-picker gets the disabled opacity/pointer rule mirroring date-field. Exception valve wired into R-1.3/R-1.4 (was only R-1.1/1.2/1.5/E-2.2) and cited exceptions added: css-field/number-field (states live in the shared spin-field layer), dialog (data-disabled sits on the VIRTUAL provider — defaultElement none — and the pressable surfaces are composed Buttons), color-picker (color-field owns the invalid rules), date-range-field (the runtime overlays data-date-field-input on the same elements, per its own recipe header), time-picker (composed time-field chrome). natural-time-picker keeps its two warns for its C8 pass rather than guessing paint targets. All 10 audited components now PASS with 0 R-1.x pending; npm run check at the 61-error baseline. css-field/number-field READMEs fixed on disk but unstaged (unrelated local modifications). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
else if (invExc) out.push(pass('R-1.4', 'warn', `exception documented: ${invExc}`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
else out.push(fail('R-1.4', 'warn', '[data-invalid] declared in morfo but not styled'));
}
feat(ntp): S9 ntp integral — sky literal valve + soma contract + provider suite (initiative close) The package's headline item — the generic Picker's transactional events — turned out ALREADY PAID at checkpoint S3b (commit-set fulfill / commit-cancel / commit-reset declared, pack shipped, soma triggers wired, suite green): the 2026-07-07 ficha claim was stale and the ntp dossier had propagated it; the dossier row is now corrected with the verification. What this session actually adds: - component-audit R-2.1 learns the `/* literal: <reason> */` escape valve (same declarationWindow mechanism the R-4.x rules already use) — the tokens doctrine's physically-fixed exception finally has its machine valve. Full run confirms no other component silently passes (same 102/32). - natural-time-picker.css: all 9 raw colors annotated line-by-line (5 skies + knob ink + line/ticks/shadow — sky ARTWORK, not theme roles; identical in light and dark). NOT tokenized, per the ficha's F-2 disposition. R-2.1 clears for ntp. - soma/components/natural-time-picker/README.md: the headless contract — the domain coordinator's state surface (minutes bridge, sliderValue, isDay, moments, steppers, display) + the fully-delegated perceptual chain table (TimeField / Slider / generic Picker / Popover). - natural-time-picker-provider.svelte.test.ts: 12 tests green (band bridge with wrap + seconds preservation, steppers incl. second non-rolling wrap, moment jumps + exact-match chips, readonly lock, daylight window bounds, 12/24h display incl. the no-soma.dates fallback, granularity displayTime). Gates: component-audit 102 PASS (ntp R-2.1 cleared) · type baseline 57 · new suite 12/12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// R-2.1: no raw colors (hex/rgb/named). Escape valve (same as the R-4.x
// rules): a `/* literal: <reason> */` on the declaration line marks a
// physically-fixed color — the doctrine's explicit exception (e.g. the
// natural-time-picker daylight skies).
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const rawColors: string[] = [];
const HEX_RE = /#[0-9a-fA-F]{3,8}\b/g;
for (const m of css.matchAll(HEX_RE)) {
feat(ntp): S9 ntp integral — sky literal valve + soma contract + provider suite (initiative close) The package's headline item — the generic Picker's transactional events — turned out ALREADY PAID at checkpoint S3b (commit-set fulfill / commit-cancel / commit-reset declared, pack shipped, soma triggers wired, suite green): the 2026-07-07 ficha claim was stale and the ntp dossier had propagated it; the dossier row is now corrected with the verification. What this session actually adds: - component-audit R-2.1 learns the `/* literal: <reason> */` escape valve (same declarationWindow mechanism the R-4.x rules already use) — the tokens doctrine's physically-fixed exception finally has its machine valve. Full run confirms no other component silently passes (same 102/32). - natural-time-picker.css: all 9 raw colors annotated line-by-line (5 skies + knob ink + line/ticks/shadow — sky ARTWORK, not theme roles; identical in light and dark). NOT tokenized, per the ficha's F-2 disposition. R-2.1 clears for ntp. - soma/components/natural-time-picker/README.md: the headless contract — the domain coordinator's state surface (minutes bridge, sliderValue, isDay, moments, steppers, display) + the fully-delegated perceptual chain table (TimeField / Slider / generic Picker / Popover). - natural-time-picker-provider.svelte.test.ts: 12 tests green (band bridge with wrap + seconds preservation, steppers incl. second non-rolling wrap, moment jumps + exact-match chips, readonly lock, daylight window bounds, 12/24h display incl. the no-soma.dates fallback, granularity displayTime). Gates: component-audit 102 PASS (ntp R-2.1 cleared) · type baseline 57 · new suite 12/12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (/literal:/i.test(declarationWindow(css, m.index ?? 0, m[0].length))) continue;
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
rawColors.push(m[0]);
}
const RGB_RE = /\b(rgba?\(\s*\d)/g;
feat(ntp): S9 ntp integral — sky literal valve + soma contract + provider suite (initiative close) The package's headline item — the generic Picker's transactional events — turned out ALREADY PAID at checkpoint S3b (commit-set fulfill / commit-cancel / commit-reset declared, pack shipped, soma triggers wired, suite green): the 2026-07-07 ficha claim was stale and the ntp dossier had propagated it; the dossier row is now corrected with the verification. What this session actually adds: - component-audit R-2.1 learns the `/* literal: <reason> */` escape valve (same declarationWindow mechanism the R-4.x rules already use) — the tokens doctrine's physically-fixed exception finally has its machine valve. Full run confirms no other component silently passes (same 102/32). - natural-time-picker.css: all 9 raw colors annotated line-by-line (5 skies + knob ink + line/ticks/shadow — sky ARTWORK, not theme roles; identical in light and dark). NOT tokenized, per the ficha's F-2 disposition. R-2.1 clears for ntp. - soma/components/natural-time-picker/README.md: the headless contract — the domain coordinator's state surface (minutes bridge, sliderValue, isDay, moments, steppers, display) + the fully-delegated perceptual chain table (TimeField / Slider / generic Picker / Popover). - natural-time-picker-provider.svelte.test.ts: 12 tests green (band bridge with wrap + seconds preservation, steppers incl. second non-rolling wrap, moment jumps + exact-match chips, readonly lock, daylight window bounds, 12/24h display incl. the no-soma.dates fallback, granularity displayTime). Gates: component-audit 102 PASS (ntp R-2.1 cleared) · type baseline 57 · new suite 12/12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
for (const m of css.matchAll(RGB_RE)) {
if (/literal:/i.test(declarationWindow(css, m.index ?? 0, m[1].length))) continue;
rawColors.push(m[1]);
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Allow `currentColor`, `transparent`, `inherit`
if (rawColors.length === 0) out.push(pass('R-2.1', 'error'));
else
out.push(
fail(
'R-2.1',
'error',
`Raw colors detected (${rawColors.length}): ${rawColors.slice(0, 5).join(', ')}${rawColors.length > 5 ? '...' : ''}`
)
);
// R-2.5: no --eidos-* or --soma-* invented vars
const badVars: string[] = [];
for (const m of css.matchAll(/--(eidos|soma|air)-[\w-]+/g)) badVars.push(m[0]);
if (badVars.length === 0) out.push(pass('R-2.5', 'error'));
else out.push(fail('R-2.5', 'error', `Invented vars: ${[...new Set(badVars)].slice(0, 5).join(', ')}`));
// R-2.6: every var(--color-X) is declared in generated/base.css.
// Catches typos and references to roles that never made it into the
// theme contract (the 2026-05-21 bug had 17 broken refs sitting
// silently until visual inspection).
if (DECLARED_COLOR_TOKENS.size > 0) {
const undefRefs: string[] = [];
for (const m of css.matchAll(/var\(--color-([a-z0-9-]+)\)/g)) {
if (!DECLARED_COLOR_TOKENS.has(m[1])) undefRefs.push(m[1]);
}
if (undefRefs.length === 0) out.push(pass('R-2.6', 'error'));
else
out.push(
fail(
'R-2.6',
'error',
`Undeclared --color-* refs (${undefRefs.length}): ${[...new Set(undefRefs)].slice(0, 5).join(', ')}`
)
);
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// R-3.2: no legacy color names
const legacy: string[] = [];
for (const cls of ['success', 'warning', 'danger', 'info']) {
const re = new RegExp(`\\[data-color=['"]${cls}['"]\\]`);
if (re.test(css)) legacy.push(cls);
}
if (legacy.length === 0) out.push(pass('R-3.2', 'error'));
else out.push(fail('R-3.2', 'error', `Legacy color names: ${legacy.join(', ')}`));
feat(eidos foundation): vertebrate typography via named-style aliases + R-2.7 Single source of truth for typography values that the recipe layer consumes. The foundation aliases `--font-ui` and `--leading-ui` (read by ~30 recipe tokens in `lib/recipes/base.ts`) now derive from the canonical `label` named style instead of carrying duplicate literals: --style-label-font-family: var(--font-family-primary); --style-label-line-height: 1.25; --font-ui: var(--style-label-font-family, var(--font-family-primary)); --leading-ui: var(--style-label-line-height, 1.25); Chain: typography.ts styles → --style-{name}-* → --leading-ui / --font-ui → recipe tokens → component CSS. Editing `STATIC_TYPOGRAPHY.styles.label.lineHeight` now propagates to every recipe in one go. Why not push recipes to consume `--style-{name}-*` directly: - t-shirt sizes (xs/sm/md/lg/xl) don't map to four semantic buckets - per-component matices (description/caption/hint) need their own color / weight / letter-spacing - ref libraries (Radix Themes, Mantine, MUI, Chakra) all keep numerical scale for component internals; semantic layer is only for user-facing typography primitives (`<Text variant="body2">`) Audit rule R-2.7 (warn): detects literal font-size / font-weight / line-height / letter-spacing in eidos component CSS. Escape valves: var(...), numeric identities (0/0px/1), keywords (inherit/initial/ unset), or trailing `/* literal: <reason> */` comment. Current run flags 6 components with letter-spacing/font-size literals (all intentional micro-tracking and em-relative; can be annotated case by case). Documentation: - src/uix/eidos/README.md § "Vertebración tipográfica" — two-layer architecture rationale, alias chain diagram, comparison vs Radix Themes / Chakra / Mantine / MUI, escape valves - web/routes/uix/lib/COMPONENT_AUDIT_GUIDE.md § 4.11 — pointer to R-2.7 + cross-link to the foundation doc Verified end-to-end in browser at /uix/components/field: --font-ui → 'Instrument Sans', system-ui, sans-serif --style-label-font-family → 'Instrument Sans', system-ui, sans-serif --leading-ui → 1.25 --style-label-line-height → 1.25 computed [data-field-label].line-height → 17.5px (= 14 × 1.25) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// R-2.7: no literal typography in recipes.
//
// Eidos foundation owns one type-system anchor (`--font-size-*`,
// `--font-weight-*`, `--leading-ui`, `--font-ui`, named styles via
// `--style-{name}-*`). Recipes MUST consume that anchor via tokens
// or component-scoped tokens that themselves resolve to it.
//
// A raw literal (`font-size: 12px`, `line-height: 1.4`,
// `letter-spacing: 0.02em`, `font-weight: 500`) breaks the
// vertebration: changing the foundation no longer propagates here.
//
// Allowed escape valves — these don't count as drift:
// - `inherit`, `initial`, `unset`, `currentColor` (CSS keywords)
// - `0` / `0px` / `0em` / `1` (numeric identities — no semantic
// typography intent; common for tight-leading on icons or
// zero-tracking on monospace)
// - any value wrapped in `var(...)` (the whole point)
// - any value with a comment `/* literal: <reason> */` on the
// same line (explicit opt-out for justified exceptions)
//
// Note: `font-family` is checked but the audit isn't strict about
// generic-keyword fallbacks (`sans-serif`, `serif`, `monospace`)
// since those only appear inside `var(--font-family-*, sans-serif)`
// fallback chains, which are themselves a `var()` and already pass.
const TYPO_PROPS = ['font-size', 'font-weight', 'line-height', 'letter-spacing'] as const;
const ALLOWED_LITERALS = new Set(['0', '0px', '0em', '0rem', '1', 'inherit', 'initial', 'unset']);
const literalTypoOffenses: string[] = [];
for (const line of css.split(/\r?\n/)) {
// Strip trailing comments so we can look for the escape valve
const m = line.match(/^\s*(font-size|font-weight|line-height|letter-spacing)\s*:\s*([^;]+?);?\s*(\/\*.*\*\/)?\s*$/);
if (!m) continue;
const [, prop, rawValue, comment] = m;
const value = rawValue.trim();
if (value.startsWith('var(')) continue;
if (ALLOWED_LITERALS.has(value)) continue;
if (comment && /literal:/i.test(comment)) continue;
literalTypoOffenses.push(`${prop}: ${value}`);
void TYPO_PROPS; // silence unused-var on the tuple if linter cares
}
if (literalTypoOffenses.length === 0) out.push(pass('R-2.7', 'warn'));
else
out.push(
fail(
'R-2.7',
'warn',
`Literal typography (${literalTypoOffenses.length}): ${literalTypoOffenses.slice(0, 5).join('; ')}${literalTypoOffenses.length > 5 ? '...' : ''}. Use a recipe token or named-style var, or add a /* literal: <reason> */ comment.`
)
);
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// R-4.x — Recipe Contract (transversal systems). WIP tracks excluded even
// under an explicit `--only` run (the contract applies when the track lands).
if (!WIP_TRACKS.has(kebab)) {
out.push(...checkRecipeContract(kebab, css, info));
}
return out;
}
// ─── Recipe Contract checks (R-4.x — src/uix/eidos/RECIPE_CONTRACT.md) ──────
/** The full source line(s) spanning a match — used to find escape-valve comments. */
function declarationWindow(css: string, start: number, matchLength: number): string {
const lineStart = css.lastIndexOf('\n', start) + 1;
const lineEnd = css.indexOf('\n', start + matchLength);
return css.slice(lineStart, lineEnd === -1 ? css.length : lineEnd);
}
/** Blank out CSS comments preserving offsets — so structural scans (e.g. the
* R-4.5 `@keyframes` finder) don't match prose inside comments, while
* escape-valve lookups still run against the ORIGINAL text at the same index. */
function blankCssComments(css: string): string {
return css.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '));
}
/** Blank out every `@keyframes … { … }` block (brace-balanced), preserving offsets. */
function stripKeyframesBlocks(css: string): string {
let out = css;
const re = /@keyframes\s+[\w-]+\s*\{/g;
let m: RegExpExecArray | null;
while ((m = re.exec(out)) !== null) {
let depth = 0;
let i = m.index + m[0].length - 1; // at the opening brace
for (; i < out.length; i++) {
if (out[i] === '{') depth++;
else if (out[i] === '}') {
depth--;
if (depth === 0) break;
}
}
const blanked = out.slice(m.index, i + 1).replace(/[^\n]/g, ' ');
out = out.slice(0, m.index) + blanked + out.slice(i + 1);
re.lastIndex = m.index + blanked.length;
}
return out;
}
function checkRecipeContract(kebab: string, css: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
// R-4.1: no literal box-shadow. Elevation composes `var(--shadow-*)` /
// `var(--depth-{plane}-*)`; the inset-ring pattern carries `var()` too, so
// any tokenized value passes. Escape valve: `/* literal: <reason> */` on
// the declaration's line.
const shadowOffenses: string[] = [];
for (const m of css.matchAll(/box-shadow\s*:\s*([^;{}]+)/g)) {
const value = m[1].trim();
if (value.includes('var(')) continue;
if (/^(none|inherit|initial|unset|revert(?:-layer)?)$/.test(value)) continue;
if (/literal:/i.test(declarationWindow(css, m.index ?? 0, m[0].length))) continue;
shadowOffenses.push(value.length > 48 ? `${value.slice(0, 48)}…` : value);
}
if (shadowOffenses.length === 0) out.push(pass('R-4.1', 'error'));
else
out.push(
fail(
'R-4.1',
'error',
`Literal box-shadow (${shadowOffenses.length}): ${shadowOffenses.slice(0, 3).join(' · ')}${shadowOffenses.length > 3 ? '…' : ''}. Use var(--shadow-*) / var(--depth-{plane}-*), or add /* literal: <reason> */.`
)
);
// R-4.2: no literal fractional opacity outside @keyframes. Disabled /
// muted states consume `var(--opacity-*)`. 0 and 1 are visibility
// toggles, not tokens — allowed.
const noKeyframes = stripKeyframesBlocks(css);
const opacityOffenses: string[] = [];
for (const m of noKeyframes.matchAll(/(?<![\w-])opacity\s*:\s*(0?\.\d+)\s*[;}]/g)) {
if (/literal:/i.test(declarationWindow(noKeyframes, m.index ?? 0, m[0].length))) continue;
opacityOffenses.push(m[1]);
}
if (opacityOffenses.length === 0) out.push(pass('R-4.2', 'error'));
else
out.push(
fail(
'R-4.2',
'error',
`Literal opacity (${opacityOffenses.length}): ${[...new Set(opacityOffenses)].join(', ')}. Use var(--opacity-disabled) / var(--opacity-*), or add /* literal: <reason> */.`
)
);
// R-4.3: hover backgrounds are the state-layer or a palette token. Scan
// innermost rule blocks whose selector carries `:hover`; flag background
// values with no `var(` at all (raw color / gradient) and hand-rolled
// `color-mix(… currentColor …)` state-layer imitations.
if (info.interactive) {
const hoverOffenses: string[] = [];
for (const block of noKeyframes.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
const selector = block[1];
if (!selector.includes(':hover')) continue;
const body = block[2];
const bodyOffset = (block.index ?? 0) + block[0].indexOf(body);
for (const decl of body.matchAll(/background(?:-color|-image)?\s*:\s*([^;]+);/g)) {
const value = decl[1].trim();
if (/^(none|transparent|inherit|initial|unset|revert(?:-layer)?)$/.test(value)) continue;
const window = declarationWindow(noKeyframes, bodyOffset + (decl.index ?? 0), decl[0].length);
if (/literal:/i.test(window)) continue;
const handRolledStateLayer =
/color-mix\([^)]*currentColor/i.test(value) && !value.includes('var(--state-');
if (value.includes('var(') && !handRolledStateLayer) continue;
hoverOffenses.push(value.length > 48 ? `${value.slice(0, 48)}…` : value);
}
}
if (hoverOffenses.length === 0) out.push(pass('R-4.3', 'error'));
else
out.push(
fail(
'R-4.3',
'error',
`:hover background outside the contract (${hoverOffenses.length}): ${hoverOffenses.slice(0, 3).join(' · ')}${hoverOffenses.length > 3 ? '…' : ''}. Neutral tier → var(--state-hover); valenced tier → palette token.`
)
);
}
// R-4.4: no physical-axis token keys in this component's recipe block
// (lib/recipes/base.ts). Logical axes (padding-inline/-block) are canon.
const axisTokens = PHYSICAL_AXIS_TOKENS.get(kebab) ?? [];
if (axisTokens.length === 0) out.push(pass('R-4.4', 'error'));
else
out.push(
fail(
'R-4.4',
'error',
`Physical-axis recipe tokens (${axisTokens.length}): ${[...new Set(axisTokens)].slice(0, 4).join(', ')}${axisTokens.length > 4 ? '…' : ''}. Rename to padding-inline/-block (logical axes).`
)
);
// R-4.5: local @keyframes need a `/* functional: <reason> */` annotation —
// perceptual signatures live in EidosConfig.motion (generated, themeable),
// not in component CSS. Look back 300 chars for the annotation.
const unannotated: string[] = [];
// Scan on comment-blanked css (offsets preserved) so prose mentioning
// "@keyframes" inside a comment never counts; the annotation lookback
// runs against the ORIGINAL text (annotations live in comments).
const commentFree = blankCssComments(css);
for (const m of commentFree.matchAll(/@keyframes\s+([\w-]+)/g)) {
const at = m.index ?? 0;
const lookback = css.slice(Math.max(0, at - 300), at);
if (/functional:/i.test(lookback)) continue;
unannotated.push(m[1]);
}
if (unannotated.length === 0) out.push(pass('R-4.5', 'error'));
else
out.push(
fail(
'R-4.5',
'error',
`@keyframes without /* functional: … */ annotation: ${unannotated.slice(0, 4).join(', ')}${unannotated.length > 4 ? '…' : ''}. Perceptual signatures belong in EidosConfig.motion.`
)
);
// R-4.6: no direct raw-layer color refs in component CSS — consume
// `var(--color-{role}-{slot})` or recipe tokens instead.
const rawLayerRefs: string[] = [];
for (const m of css.matchAll(/var\(--(scale|primitive)-[a-z0-9-]+/g)) {
if (/literal:/i.test(declarationWindow(css, m.index ?? 0, m[0].length))) continue;
rawLayerRefs.push(m[0].slice(4));
}
if (rawLayerRefs.length === 0) out.push(pass('R-4.6', 'error'));
else
out.push(
fail(
'R-4.6',
'error',
`Direct raw-layer refs (${rawLayerRefs.length}): ${[...new Set(rawLayerRefs)].slice(0, 3).join(', ')}${rawLayerRefs.length > 3 ? '…' : ''}. Consume var(--color-{role}-{slot}) or a recipe token.`
)
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
return out;
}
function checkDemo(kebab: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
const demoPath = join(DEMO_DIR, kebab, '+page.svelte');
const src = tryRead(demoPath);
if (!src) {
out.push(fail('D-existence', 'error', `No demo page at ${demoPath}`));
return out;
}
// D-1.1: data-uix-canvas-inner outer
if (/<div\s+data-uix-canvas-inner\b/.test(src)) out.push(pass('D-1.1', 'error'));
else out.push(fail('D-1.1', 'error', 'Missing outer <div data-uix-canvas-inner>'));
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// D-1.2: Tab union matches a canonical template. The v2 layout
// (DEMO_AUTHORING_GUIDE §type Tab) is the 9-tab canonical; the v1 6-tab
// union remains accepted while the demo migration is in flight — the old
// exact-6-tab check was stale and failed every ALREADY-migrated demo.
const tabUnionV2Re =
/type Tab\s*=\s*'live'\s*\|\s*'system'\s*\|\s*'motion'\s*\|\s*'sema'\s*\|\s*'services'\s*\|\s*'api'\s*\|\s*'morfo'\s*\|\s*'recipe'\s*\|\s*'a11y'/;
const tabUnionV1Re =
/type Tab\s*=\s*'live'\s*\|\s*'api'\s*\|\s*'morfo'\s*\|\s*'sema'\s*\|\s*'recipe'\s*\|\s*'a11y'/;
if (tabUnionV2Re.test(src)) out.push(pass('D-1.2', 'error', 'v2 9-tab template'));
else if (tabUnionV1Re.test(src)) out.push(pass('D-1.2', 'error', 'legacy v1 6-tab template (pending v2 migration)'));
else out.push(fail('D-1.2', 'error', 'Tab union matches neither the v2 9-tab nor the v1 6-tab template'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// D-1.3: imports compileMorfo
if (/import\s*\{\s*compileMorfo\b/.test(src)) out.push(pass('D-1.3', 'error'));
else out.push(fail('D-1.3', 'error', 'No `import { compileMorfo }`'));
// D-1.5: MutationObserver
if (info.interactive) {
if (/new\s+MutationObserver/.test(src)) out.push(pass('D-1.5', 'error'));
else out.push(fail('D-1.5', 'error', 'No MutationObserver for trace strip'));
}
// D-1.6: stage between header and tablist
if (/data-uix-stage\b/.test(src)) out.push(pass('D-1.6', 'error'));
else out.push(fail('D-1.6', 'error', 'No <div data-uix-stage>'));
// D-1.7: trace strip for interactive
if (info.interactive) {
if (/data-uix-stage-trace\b/.test(src)) out.push(pass('D-1.7', 'error'));
else out.push(fail('D-1.7', 'error', 'No <div data-uix-stage-trace>'));
}
// D-2.x: header
const hasEyebrow = /data-uix-eyebrow\b/.test(src);
const hasTitle = /data-uix-page-title\b/.test(src);
const hasLede = /data-uix-page-lede\b/.test(src);
const hasMeta = /data-uix-page-meta\b/.test(src);
if (hasEyebrow) out.push(pass('D-2.1', 'error'));
else out.push(fail('D-2.1', 'error', 'Missing data-uix-eyebrow'));
if (hasTitle && hasLede) out.push(pass('D-2.2', 'error'));
else out.push(fail('D-2.2', 'error', 'Missing title or lede in header'));
if (hasMeta) out.push(pass('D-2.3', 'error'));
else out.push(fail('D-2.3', 'error', 'Missing data-uix-page-meta pills'));
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// D-3.1: snippet parity. The v2 template derives a single `eidosSnippet`
// (guide §12 — "the snippet", singular); v1 demos additionally carry a
// `somaSnippet`. Require the eidos snippet; treat soma as optional so the
// migrated demos stop mass-failing against the stale two-snippet check.
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const hasSomaSnip = /somaSnippet\b/.test(src);
const hasEidosSnip = /eidosSnippet\b/.test(src);
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (hasEidosSnip) {
out.push(pass('D-3.1', 'error', hasSomaSnip ? 'soma + eidos snippets (v1)' : 'eidos snippet (v2)'));
} else {
out.push(fail('D-3.1', 'error', 'Missing eidosSnippet'));
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// D-4.3: Play buttons emit via uix.events.emit
if (info.interactive) {
const hasPlay = /uix\.events\??\.emit/.test(src) || /events\.emit\(/.test(src);
if (hasPlay) out.push(pass('D-4.3', 'error'));
else out.push(fail('D-4.3', 'warn', 'No uix.events.emit(...) — Play buttons may not be wired'));
}
// D-7.4: chip parity vs type union.
//
// For every chip-controlled prop (`size`, `variant`, `color`), the
// demo's chip array must enumerate the full union declared in
// `eidos/components/{kebab}/types.ts`. Truncated arrays (e.g.
// `field` shipped 'outline'|'ghost' while ControlVariant has 3)
// silently lie about the surface.
const typesPath = join(EIDOS_DIR, kebab, 'types.ts');
const typesSrc = tryRead(typesPath);
if (typesSrc) {
for (const prop of ['size', 'variant', 'color'] as const) {
const declared = extractTypeUnion(typesSrc, prop, kebab);
if (!declared || declared.size === 0) continue;
const exposed = extractDemoChipSet(src, prop);
if (!exposed) {
out.push(
fail(
'D-7.4',
'warn',
`'${prop}' type exposes ${declared.size} values but no chip array found in demo`
)
);
continue;
}
const missing = [...declared].filter((v) => !exposed.has(v));
const extra = [...exposed].filter((v) => !declared.has(v));
if (missing.length === 0 && extra.length === 0) {
out.push(pass('D-7.4', 'error', `${prop}: ${declared.size} values`));
} else {
const parts: string[] = [];
if (missing.length) parts.push(`missing ${missing.join(', ')}`);
if (extra.length) parts.push(`extra ${extra.join(', ')}`);
out.push(fail('D-7.4', 'error', `'${prop}' chip drift — ${parts.join(' · ')}`));
}
}
}
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
return out;
}
// Parse `export type {Name}{Prop} = …` and return the set of string-literal
// values in the union. Supports both direct unions ('a' | 'b' | 'c') and
// `Extract<Base, 'a' | 'b' | 'c'>`. Returns null if the type isn't found,
// or the type references an unresolved alias we can't follow (deliberate
// fail-safe: don't emit a false alarm).
function extractTypeUnion(
typesSrc: string,
prop: 'size' | 'variant' | 'color',
kebab: string
): Set<string> | null {
// Match `export type {PascalKebab}{Prop} = …` exactly — no intermediate
// PascalCase tokens, so we don't pick up sub-part types like
// `FormActionColor` when auditing the root form demo. The root prop type
// follows the canonical naming convention `{Name}{Prop}` (CheckboxColor,
// ComboboxSize, FieldVariant, …).
const cap = prop.charAt(0).toUpperCase() + prop.slice(1);
const pascal = kebab
.split('-')
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
.join('');
const re = new RegExp(`export\\s+type\\s+${pascal}${cap}\\s*=\\s*([^;\\n]+(?:\\n[^;\\n]+)*);`, 'm');
const m = typesSrc.match(re);
if (!m) return null;
const body = m[1];
// Pull every quoted literal from the body. This handles both
// `'a' | 'b' | 'c'`
// and
// `Extract<X, 'a' | 'b' | 'c'>`
// equally. If the body has no string literals at all (e.g. it just
// aliases another type — `ControlVariant`), we can't resolve the
// transitive union here without a TS pass; return null so the audit
// stays silent.
const literals = [...body.matchAll(/'([a-z][a-z0-9-]*)'/g)].map((x) => x[1]);
if (literals.length === 0) {
// Resolve a single-alias chain like `= ControlVariant` /
// `= SelectionVariant` / `= ChipVariant` / etc. via the canonical
// vocab defined in `src/uix/eidos/lib/types.ts`.
const alias = body.trim();
const resolved = SHARED_VARIANT_VOCAB.get(alias);
return resolved ? new Set(resolved) : null;
}
return new Set(literals);
}
// Canonical shared unions from `src/uix/eidos/lib/types.ts`. Keep in sync
// with that file — duplicated here so the audit doesn't import Svelte types.
const SHARED_VARIANT_VOCAB = new Map<string, readonly string[]>([
['ControlVariant', ['surface', 'outline', 'ghost']],
['SelectionVariant', ['solid', 'outline', 'ghost']],
['ChipVariant', ['soft', 'solid', 'outline', 'ghost']],
['MarkerVariant', ['solid', 'soft', 'outline']],
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// `segmented` joined the tabs archetype in EIDOS_VARIANTS (lib/types.ts) —
// keep this mirror in sync with that const.
['TabsVariant', ['line', 'surface', 'pills', 'segmented']],
// NOTE: canonical ColorRole (lib/config-types.ts) also includes `tertiary`,
// but it is RESERVED (no component consumes it) — component types expose
// the 8-value subset below. Revisit when tertiary gains a consumer.
['ColorRole', [
'primary',
'secondary',
'neutral',
'affirm',
'fulfill',
'risk',
'threat',
'loss'
]],
[
'AffirmativeColorRole',
['primary', 'secondary', 'neutral', 'affirm']
],
[
'ProgressiveColorRole',
['primary', 'secondary', 'neutral', 'affirm', 'fulfill']
],
[
'EditableColorRole',
['primary', 'secondary', 'neutral', 'affirm', 'risk', 'threat']
]
]);
// Find the chip array that the demo binds to the given prop. Two shapes:
// <span data-uix-control-label>{prop}</span> … {#each [...] as …}
// const {prop}s: SomeType[] = [...]
function extractDemoChipSet(demoSrc: string, prop: 'size' | 'variant' | 'color'): Set<string> | null {
// Shape A: const declaration `const sizes/variants/colors: T[] = ['a', 'b']`.
const constRe = new RegExp(
`const\\s+${prop}s(?:\\s*:\\s*[^=]+)?\\s*=\\s*\\[([^\\]]+)\\]`,
'm'
);
const cm = demoSrc.match(constRe);
if (cm) {
const literals = [...cm[1].matchAll(/'([a-z][a-z0-9-]*)'/g)].map((x) => x[1]);
if (literals.length) return new Set(literals);
}
// Shape B: inline `{#each ['a', 'b', 'c'] as …}` after a control label.
// Look for the control label line, then scan the next ~25 lines.
const labelRe = new RegExp(
`data-uix-control-label[^>]*>\\s*${prop}(?:\\s|<)`,
'm'
);
const labelIdx = demoSrc.search(labelRe);
if (labelIdx === -1) return null;
const slice = demoSrc.slice(labelIdx, labelIdx + 800);
const arrRe = /\{#each\s*\[([^\]]+)\]\s*as\s+\w+/;
const am = slice.match(arrRe);
if (!am) return null;
const literals = [...am[1].matchAll(/'([a-z][a-z0-9-]*)'/g)].map((x) => x[1]);
if (!literals.length) return null;
return new Set(literals);
}
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// S9 embark guard (checkpoint verdict, 2026-07-07): the F-1.x pre-flight
// dossier is BLOCKING (error) only for components embarked AFTER the
// checkpoint. The catalog snapshot in component-audit.grandfather.json is
// grandfathered to warn — its dossiers get written in the fix phase (P7)
// without painting the whole catalog red meanwhile.
const GRANDFATHERED: Set<string> = (() => {
const src = tryRead(join(__dirname, 'component-audit.grandfather.json'));
if (!src) return new Set();
try {
const parsed = JSON.parse(src) as { components?: string[] };
return new Set(parsed.components ?? []);
} catch {
return new Set();
}
})();
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
function checkReadme(kebab: string, info: ComponentReport): CheckResult[] {
const out: CheckResult[] = [];
const path = join(EIDOS_DIR, kebab, 'README.md');
const src = tryRead(path);
if (!src) return out; // E-2.3 catches
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const preflightSev = GRANDFATHERED.has(kebab) ? 'warn' : 'error';
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// F-1.1 Baseline
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (/##\s*Baseline\b/m.test(src)) out.push(pass('F-1.1', preflightSev));
else out.push(fail('F-1.1', preflightSev, 'Missing ## Baseline section'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// F-1.2 Comparativa (3+ external references).
// Use `\n## ` as the section terminator. The previous regex used `$` with
// the `m` flag, which matched end-of-line and truncated the section body
// to just the header.
const compMatch = src.match(/##\s*Comparativa\b[\s\S]*?(?=\n##\s|$)/);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (compMatch) {
// Count rows in the comparison table
const rows = compMatch[0].match(/^\|/gm) || [];
const refCount = Math.max(0, rows.length - 2); // header + separator
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (refCount >= 3) out.push(pass('F-1.2', preflightSev, `${refCount} references`));
else
out.push(fail('F-1.2', preflightSev, `Only ${refCount} references in ## Comparativa (need ≥3)`));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} else {
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
out.push(fail('F-1.2', preflightSev, 'Missing ## Comparativa section'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
// F-1.3 Decisiones
if (/##\s*Decisiones\b/m.test(src)) out.push(pass('F-1.3', 'warn'));
else out.push(fail('F-1.3', 'warn', 'Missing ## Decisiones section'));
// F-1.4 Gaps with disposition. Same regex fix as Comparativa above.
const gapsMatch = src.match(/##\s*Gaps\b[\s\S]*?(?=\n##\s|$)/);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (gapsMatch) {
const dispositions = (gapsMatch[0].match(/\b(implementar|diferir|descartar)\b/gi) || []).length;
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
if (dispositions >= 1) out.push(pass('F-1.4', preflightSev, `${dispositions} disposition markers`));
else
out.push(
fail('F-1.4', preflightSev, '## Gaps lacks disposition markers (implementar/diferir/descartar)')
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} else {
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
out.push(fail('F-1.4', preflightSev, 'Missing ## Gaps section'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
// F-1.5: passive components must justify
if (info.passive) {
if (/##\s*Passive\s+justification\b/im.test(src)) {
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
out.push(pass('F-1.5', preflightSev));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} else {
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
out.push(fail('F-1.5', preflightSev, 'Passive component lacks ## Passive justification'));
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
}
}
return out;
}
// ─── Build report per component ─────────────────────────────────────────────
function buildReport(kebab: string): ComponentReport {
const morfoPath = join(MORFO_DIR, `${kebab}.ts`);
const eidosDir = join(EIDOS_DIR, kebab);
const demoPath = join(DEMO_DIR, kebab, '+page.svelte');
const morfoSrc = tryRead(morfoPath) ?? '';
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
// Classify: interactive if it declares events or keyboard keys — or if its
// PARTS are interactive by contract (archetype / role / element evidence).
// The old events||keys test was circular: "interactive with 0 events"
// (A-3.1) could never fire for a component whose only interactivity signal
// was its parts — pin-input (textbox Input, 0 events, 0 keys) audited as
// passive (checkpoint C8, 2026-07-07).
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const eventCount = countEventBlocks(morfoSrc);
const keyCount = [...morfoSrc.matchAll(KEYBOARD_KEY_RE)].length;
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
const interactiveParts =
/archetype:\s*['"](?:trigger|field-trigger|input|item)['"]/.test(morfoSrc) ||
/\brole:\s*['"](?:button|textbox|searchbox|combobox|listbox|option|slider|spinbutton|switch|checkbox|radio|menuitem|menuitemcheckbox|menuitemradio|tab|gridcell)['"]/.test(
morfoSrc
) ||
/defaultElement:\s*['"](?:button|input|select|textarea)['"]/.test(morfoSrc);
const interactive = eventCount > 0 || keyCount > 0 || interactiveParts;
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const passive = !interactive;
const report: ComponentReport = {
component: morfoSrc.match(/\bname:\s*['"]([^'"]+)['"]/)?.[1] ?? kebab,
kebab,
exists: {
morfo: morfoSrc.length > 0,
eidos: existsSync(eidosDir),
demo: existsSync(demoPath)
},
interactive,
passive,
checks: []
};
if (morfoSrc) report.checks.push(...checkMorfo(kebab, morfoSrc, report));
if (report.exists.eidos) {
report.checks.push(...checkEidos(kebab, report));
report.checks.push(...checkRecipe(kebab, report));
report.checks.push(...checkReadme(kebab, report));
}
if (report.exists.demo) report.checks.push(...checkDemo(kebab, report));
return report;
}
// ─── Verdict ────────────────────────────────────────────────────────────────
function verdict(r: ComponentReport): 'PASS' | 'NEEDS-WORK' | 'BROKEN' {
const errors = r.checks.filter((c) => !c.passed && c.severity === 'error').length;
const warns = r.checks.filter((c) => !c.passed && c.severity === 'warn').length;
if (errors > 5) return 'BROKEN';
if (errors > 0 || warns > 3) return 'NEEDS-WORK';
return 'PASS';
}
// ─── Markdown rendering ─────────────────────────────────────────────────────
function renderMarkdown(reports: ComponentReport[]): string {
const lines: string[] = [];
lines.push('# UIX component audit report');
lines.push('');
lines.push(`> Generated by \`scripts/component-audit.ts\` against \`docs/guides/completion-checklist.md\`.`);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
lines.push(`> Date: ${new Date().toISOString()}`);
lines.push('');
// Summary table
const passCount = reports.filter((r) => verdict(r) === 'PASS').length;
const needsCount = reports.filter((r) => verdict(r) === 'NEEDS-WORK').length;
const brokenCount = reports.filter((r) => verdict(r) === 'BROKEN').length;
lines.push('## Summary');
lines.push('');
lines.push(`- **Total components audited**: ${reports.length}`);
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
lines.push(
`- **WIP tracks excluded** (unfinished, audited on demand via \`--only\`): ${[...WIP_TRACKS].join(', ')}`
);
uix: date-picker + date-range-picker components + component audit infra Two new Eidos components shipped end-to-end (wrapper + recipe + demo + Soma provider hardening) plus a checklist-driven audit pipeline that scores all 67 morfo components against doctrinal completion criteria. New components: - date-picker: full popover-anchored picker over date-field + calendar, with calendar/content/trigger parts and demo route. - date-range-picker: standalone wrapper with own calendar/grid/segment surface, demo route, and recipe CSS. - Both wrappers follow Option C disciplined (root + parts attached via explicit assignment, no Object.assign). Supporting Soma changes: - range-calendar provider tightened (211 LOC of behavior, 167 LOC of tests), README brought up to component doctrine. - date-field, date-picker, date-range-field, date-range-picker Soma providers + READMEs updated for new wrappers. - popover provider/close gain props needed by the picker wrappers. Morfo updates: - date-picker / date-range-picker / range-calendar morfos refined for the new APIs (parts, events, ARIA). Audit infrastructure (new): - src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across morfo / eidos wrapper / recipe CSS / demo / README / cross-layer scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION and DEMO_AUTHORING_GUIDE. - scripts/component-audit.ts + `npm run component:audit` — regex parser over all 67 components, emits tmp/component-audit.md with summary scoreboard + per-component findings. Validates against canonical SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS. - Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip, date-range-picker). Top systemic gaps: translations.label (49), README Gaps/Comparativa/Baseline sections (87 combined), keyboard /event ratio under-declaration (15), apg URL absent (19). Misc: - src/uix/kimi-audit-eidos.md — supplementary audit notes. - .gitignore: ignore .codex-* agent scratch artifacts at repo root. - continue.md + READMEs updated through the migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
lines.push(`- **PASS**: ${passCount}`);
lines.push(`- **NEEDS-WORK**: ${needsCount}`);
lines.push(`- **BROKEN**: ${brokenCount}`);
lines.push('');
// Sorted: BROKEN first, then NEEDS-WORK, then PASS
const order = { BROKEN: 0, 'NEEDS-WORK': 1, PASS: 2 };
reports.sort((a, b) => order[verdict(a)] - order[verdict(b)] || a.kebab.localeCompare(b.kebab));
lines.push('## Component scoreboard');
lines.push('');
lines.push('| Component | Verdict | Errors | Warns | Demo | Eidos | Type |');
lines.push('| --- | --- | ---: | ---: | :-: | :-: | --- |');
for (const r of reports) {
const errors = r.checks.filter((c) => !c.passed && c.severity === 'error').length;
const warns = r.checks.filter((c) => !c.passed && c.severity === 'warn').length;
const v = verdict(r);
const demo = r.exists.demo ? '✓' : '—';
const eidos = r.exists.eidos ? '✓' : '—';
const type = r.passive ? 'passive' : 'interactive';
lines.push(`| \`${r.kebab}\` | **${v}** | ${errors} | ${warns} | ${demo} | ${eidos} | ${type} |`);
}
lines.push('');
// Detail per component
lines.push('## Detail per component');
lines.push('');
for (const r of reports) {
const v = verdict(r);
const errors = r.checks.filter((c) => !c.passed && c.severity === 'error');
const warns = r.checks.filter((c) => !c.passed && c.severity === 'warn');
if (v === 'PASS' && errors.length === 0 && warns.length === 0) continue;
lines.push(`### ${r.kebab} — ${v}`);
lines.push('');
lines.push(
`- Morfo: ${r.exists.morfo ? '✓' : '—'} · Eidos wrapper: ${r.exists.eidos ? '✓' : '—'} · Demo: ${r.exists.demo ? '✓' : '—'} · Type: ${r.interactive ? 'interactive' : 'passive'}`
);
lines.push('');
if (errors.length) {
lines.push('**Errors:**');
lines.push('');
for (const c of errors) {
const filtered = minSeverity && severityRank(minSeverity) > severityRank('error');
if (filtered) continue;
lines.push(`- \`${c.rule}\` — ${c.detail}`);
}
lines.push('');
}
if (warns.length && (!minSeverity || severityRank(minSeverity) <= severityRank('warn'))) {
lines.push('**Warnings:**');
lines.push('');
for (const c of warns) {
lines.push(`- \`${c.rule}\` — ${c.detail}`);
}
lines.push('');
}
}
return lines.join('\n');
}
function severityRank(s: Severity): number {
return s === 'error' ? 0 : s === 'warn' ? 1 : 2;
}
// ─── Main ───────────────────────────────────────────────────────────────────
function main(): void {
const components = listComponents();
const reports: ComponentReport[] = [];
for (const c of components) {
try {
reports.push(buildReport(c.kebab));
} catch (err) {
console.error(`[component-audit] Failed on ${c.kebab}:`, err);
}
}
const md = renderMarkdown(reports);
mkdirSync(dirname(OUT), { recursive: true });
writeFileSync(OUT, md);
// Console summary
const broken = reports.filter((r) => verdict(r) === 'BROKEN').length;
const needs = reports.filter((r) => verdict(r) === 'NEEDS-WORK').length;
const pass = reports.filter((r) => verdict(r) === 'PASS').length;
console.log(`[component-audit] ${reports.length} components`);
console.log(` PASS: ${pass}`);
console.log(` NEEDS-WORK: ${needs}`);
console.log(` BROKEN: ${broken}`);
console.log(` Report: ${OUT}`);
// Exit non-zero if any BROKEN
process.exit(broken > 0 ? 1 : 0);
}
main();

Powered by TurnKey Linux.