# Site Starter Component Kit # # Contract for using spwashi.com as a source for new static sites and # component design without confusing portable composition primitives with the # full personal site shell. #>site_starter_component_kit #:convention #!starter #!components #!portable #:layer #!pragmatics @plan: ~"../../.agents/plans/site-starter-component-kit/PLAN.md" @compose_css: ~"../../public/css/compose.css" @compose_js: ~"../../public/js/compose.js" @css_readme: ~"../../public/css/README.md" @js_readme: ~"../../public/js/README.md" @starter_inventory: ~"../../scripts/starter-inventory.mjs" @component_contracts: ~"../../scripts/component-contracts.mjs" @component_fixtures: ~"../../public/ts/component-fixtures.ts" @component_fixture_facade: ~"../../public/js/kernel/component-fixtures.js" @component_snippets: ~"../../design/components/snippets/" @component_screenshots: ~"../../scripts/component-snapshots.mjs" @component_capture_pipeline: ~"./component-capture-pipeline.spw" @design_composition: ~"../../design/composition/index.html" @design_components: ~"../../design/components/index.html" @design_hub: ~"../../design/index.html" @site_source_layout: ~"../../.agents/plans/site-source-layout/PLAN.md" @model_guided_refinement: ~"./model-guided-refinement.spw" @composition_box_model: ~"./composition-box-model.spw" @component_taxonomy: ~"./component-taxonomy.spw" @component_packing: ~"./component-packing.spw" @harmony_audit: ~"../audits/component-philosophy-harmony-2026-07.spw" ^"thesis"{ operation = "contract" fixity = "stable" focus_dimension = "component" audience = "engineer-toolmaker" primary_element = "metal" secondary_element = "wood" claim = "The repo becomes useful for spawning new sites when portable composition entrypoints, component specimens, and site-specific boundaries are inventoryable before any scaffold exists." risk = "Without a boundary, a new site may copy the full Spwashi shell, route copy, ornament, or runtime modules when it only needed the portable composition layer." validation = "npm run starter:inventory -- --check" } ^"portable_entrypoints"{ css = @compose_css js = @compose_js rule = "Start new-site experiments with compose.css and compose.js. Use style.css and site.js only when intentionally running the full spwashi.com shell." css_scope = "tokens, typography, grammar, components, handles, and light effects" js_scope = "DOM contracts, runtime helpers, page hooks, query disposition, palette/SVG tunability, component box model, and console instrumentation" docs = #[@css_readme, @js_readme, @design_composition][reg=set] } ^"site_specific_boundary"{ keep_local = #[ "public/css/style.css", "public/js/site.js", "public/css/routes/", "public/css/shell/", "public/css/ornament/", "public/js/modules/", "personal route copy", "Spwashi creator identity", "analytics and deployment identity", "route-specific images and local content" ][reg=set] rule = "A starter should carry structure, tokens, component grammar, and portable helpers before it carries identity, route behavior, or ornamental site lore." } ^"component_lab"{ surfaces = #[@design_components, @design_composition, @design_hub][reg=set] promotion_rule = "A component becomes starter material only after it has slot anatomy, semantic state, CSS ownership, optional progressive JS, a specimen or documentation route, and validation." anatomy = "header -> meta -> body -> figure -> actions -> footer" inspectability = "Use data-spw-* families, composition-box-model snapshots, and design catalog output so component value can be read before copying code." anti_pattern = "Copying a route-local card because it looks useful while leaving behind its state attributes, slot contract, accessibility affordances, or CSS owner." } ^"inventory_contract"{ script = @starter_inventory command = "npm run starter:inventory -- --check" output = "portable CSS imports, JS exports, component CSS files, component/design docs, site-specific boundaries, and missing referenced files" rule = "The inventory is an orientation and validation surface, not a generator. Add scaffolding only after repeated use proves what should be generated." } ^"component_fixture_contract"{ operation = "contract" fixity = "stable" registry = @component_fixtures facade = @component_fixture_facade validator = @component_contracts commands = #["npm run component:check", "npm run test:modules"][reg=set] role = "A typed fixture registry names real hand-authored component specimens, their CSS owner, slot expectations, and test states without introducing a component framework." promotion = "Move a closed data abstraction from public/js into public/ts, compile to public/js/typed, retain a small JS facade, then add Node and fixture-contract tests before runtime consumers depend on it." non_goal = "Do not convert DOM-narrative modules wholesale or add Storybook until visual regression history justifies the cost." } ^"component_layout_evidence"{ operation = "audit" fixity = "tending" snippets = @component_snippets capture = @component_screenshots pipeline = @component_capture_pipeline command = "npm run component:screenshots" viewports = #["phone", "desktop"][reg=set] flows = #["page", "component", "template"][reg=set] rule = "Capture packs prove page context, component clip, and compose.css isolation; screenshots are review evidence before they become pixel-diff baselines." non_goal = "Do not commit noisy golden images or claim visual regression coverage until a specific component has a stable baseline and owner." output = "design/components/captures/{manifest,pipeline,index.html,captures/*.png} — gitignored by default" } ^"spawn_sequence"{ step_1 = "Run the inventory and read /design/composition/." step_2 = "Choose compose.css plus only the portable JS helpers the host site needs." step_3 = "Select one component specimen from /design/components/ and preserve its slot/state contract." step_4 = "Replace identity, copy, routes, assets, and shell behavior with the host site's own material." step_5 = "Validate with inventory, local browser inspection, and any host-site checks." } ^"active_claims"{ claim #starter-component-kit-001 { layer = "agent-editor" hypothesis = "A future contributor can identify starter-kit material in under a minute by running the inventory and following the compose.css/compose.js boundary." spec_ref = ".spw/conventions/site-starter-component-kit.spw#portable_entrypoints" impl_ref = "scripts/starter-inventory.mjs + package.json#starter:inventory + public/css/README.md + public/js/README.md" probe_ref = "npm run starter:inventory -- --check" falsification = "A portable entrypoint is moved, deleted, or gains missing imports while the inventory still passes, or a contributor must inspect route CSS/site shell before finding the portable layer." status = "active" } claim #starter-component-kit-002 { layer = "component" hypothesis = "New components become reusable more reliably when promotion requires slot anatomy, state attributes, CSS ownership, specimen docs, and validation before extraction." spec_ref = ".spw/conventions/site-starter-component-kit.spw#component_lab" impl_ref = "design/components/index.html + design/composition/index.html + public/css/components/" probe_ref = "Review a proposed reusable component and confirm it satisfies the promotion_rule fields." falsification = "A new copied component works only because of route-local shell assumptions or undocumented Spwashi-specific runtime state." status = "active" } } ^"promotion_prime_2026_07"{ operation = "prime" fixity = "tending" source = @harmony_audit claim = `Starter extraction quality tracks the component passport and packing-axis honesty, not visual polish alone.` promotion_checklist = #[ `slot anatomy header→footer`, `kind + role + feature when reusable`, `CSS owner in components/ (not route-only)`, `declare pack axis: shell | box | content | input`, `specimen on /design/components/ or composition lab`, `optional progressive JS through compose.js only when needed`, `no Spwashi shell/ornament/route identity required for the portable unit` ][reg=set] tone = `Portable kits carry structure and grammar; they do not carry creator identity or wonder lore by default.` lab = #[@design_components, @design_composition][reg=set] packing = @component_packing passport = @component_taxonomy safe_first_patch = `When extracting a specimen, run starter:inventory --check and fill passport fields in the design note before copying files out of tree.` }[reg=facet] ^"dispatch"{ @plan: @plan @compose_css: @compose_css @compose_js: @compose_js @starter_inventory: @starter_inventory @component_contracts: @component_contracts @component_fixtures: @component_fixtures @component_fixture_facade: @component_fixture_facade @component_snippets: @component_snippets @component_screenshots: @component_screenshots @component_capture_pipeline: @component_capture_pipeline @design_composition: @design_composition @design_components: @design_components @site_source_layout: @site_source_layout @model_guided_refinement: @model_guided_refinement @composition_box_model: @composition_box_model @component_taxonomy: @component_taxonomy @component_packing: @component_packing @harmony_audit: @harmony_audit }