@nurix/etna 0.19.42 → 0.19.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/etna.js +47 -6
- package/data/harness-index.json +5 -1
- package/data/harnesses/apollo/.prettierignore +29 -0
- package/data/harnesses/apollo/.prettierrc.json +3 -0
- package/data/harnesses/apollo/.vscode/settings.json +19 -0
- package/data/harnesses/apollo/CLAUDE.md +162 -0
- package/data/harnesses/apollo/agents/brainstorm.md +144 -0
- package/data/harnesses/apollo/agents/change-review.md +251 -0
- package/data/harnesses/apollo/agents/lld-mode.md +56 -0
- package/data/harnesses/apollo/agents/maintenance.md +231 -0
- package/data/harnesses/apollo/agents/performance-review.md +223 -0
- package/data/harnesses/apollo/agents/retro.md +46 -0
- package/data/harnesses/apollo/codex/agents/brainstorm.toml +142 -0
- package/data/harnesses/apollo/codex/agents/change-review.toml +249 -0
- package/data/harnesses/apollo/codex/agents/lld-mode.toml +52 -0
- package/data/harnesses/apollo/codex/agents/maintenance.toml +228 -0
- package/data/harnesses/apollo/codex/agents/performance-review.toml +222 -0
- package/data/harnesses/apollo/codex/agents/retro.toml +45 -0
- package/data/harnesses/apollo/docs/README.md +28 -0
- package/data/harnesses/apollo/docs/history/CHANGELOG.md +26 -0
- package/data/harnesses/apollo/docs/history/backlog.md +19 -0
- package/data/harnesses/apollo/docs/memory/main.md +15 -0
- package/data/harnesses/apollo/docs/structure.md +54 -0
- package/data/harnesses/apollo/harness.json +18 -0
- package/data/harnesses/{code → apollo}/hooks/generate-ownership-index.mjs +1 -1
- package/data/harnesses/apollo/hooks/hooks.json +16 -0
- package/data/harnesses/apollo/rules/changelog.md +19 -0
- package/data/harnesses/apollo/rules/database.md +123 -0
- package/data/harnesses/apollo/rules/express.md +33 -0
- package/data/harnesses/apollo/rules/frontend.md +32 -0
- package/data/harnesses/apollo/rules/general.md +62 -0
- package/data/harnesses/apollo/rules/nomenclature.md +34 -0
- package/data/harnesses/apollo/rules/pnpm.md +57 -0
- package/data/harnesses/apollo/rules/testing.md +23 -0
- package/data/harnesses/apollo/rules/verification.md +67 -0
- package/data/harnesses/apollo/skills/boundary/SKILL.md +71 -0
- package/data/harnesses/apollo/skills/boundary/references/index.md +16 -0
- package/data/harnesses/apollo/skills/boundary/references/mechanisms.md +99 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/async-messaging.md +81 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/auth.md +93 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/build-config-runtime.md +93 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/cloudflare.md +93 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/frontend.md +93 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/generic-tail.md +55 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/persistence.md +93 -0
- package/data/harnesses/apollo/skills/boundary/references/packs/wire-api.md +87 -0
- package/data/harnesses/apollo/skills/brainstorm/README.md +56 -0
- package/data/harnesses/apollo/skills/brainstorm/SKILL.md +173 -0
- package/data/harnesses/apollo/skills/brainstorm/references/doctrine.md +98 -0
- package/data/harnesses/apollo/skills/brainstorm/references/harvest.md +86 -0
- package/data/harnesses/apollo/skills/brainstorm/references/session-schema.md +186 -0
- package/data/harnesses/apollo/skills/brainstorm/scripts/detector.mjs +460 -0
- package/data/harnesses/apollo/skills/design/SKILL.md +100 -0
- package/data/harnesses/apollo/skills/design/components/charts.md +76 -0
- package/data/harnesses/apollo/skills/design/components/collections.md +132 -0
- package/data/harnesses/apollo/skills/design/components/feedback.md +47 -0
- package/data/harnesses/apollo/skills/design/components/hooks.md +35 -0
- package/data/harnesses/apollo/skills/design/components/index.md +143 -0
- package/data/harnesses/apollo/skills/design/components/inputs.md +327 -0
- package/data/harnesses/apollo/skills/design/components/layout.md +52 -0
- package/data/harnesses/apollo/skills/design/components/media.md +66 -0
- package/data/harnesses/apollo/skills/design/components/motion.md +82 -0
- package/data/harnesses/apollo/skills/design/components/navigation.md +29 -0
- package/data/harnesses/apollo/skills/design/components/overlays.md +72 -0
- package/data/harnesses/apollo/skills/design/components/setup.md +40 -0
- package/data/harnesses/apollo/skills/design/components/typography.md +46 -0
- package/data/harnesses/apollo/skills/design/components/utils.md +37 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/browse.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/creation-flow.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/dashboard.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/grid.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/queue.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/record-detail.md +38 -0
- package/data/harnesses/apollo/skills/design/data/blueprints/settings.md +38 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/Readme.md +33 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/carbon-accessible-alert-semantic.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/carbon-monochrome-sequential-trend.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/datadog-classic-six-aligned.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/datawrapper-tiered-gray-hierarchy.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/econ-red-rule-horizontal.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/financial-diverging-threshold-overlay.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/ft-vocabulary-ranked-muted.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/grafana-dark-threshold-bands.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/material-rounded-explicit-label.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/nyt-ghost-grid-direct-label.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/plot-currentcolor-inherit.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/saas-gradient-glow-area.md +19 -0
- package/data/harnesses/apollo/skills/design/data/chart-styling/shadcn-composable-css-vars.md +19 -0
- package/data/harnesses/apollo/skills/design/data/charts/census.csv +58 -0
- package/data/harnesses/apollo/skills/design/data/checklists/browse.md +21 -0
- package/data/harnesses/apollo/skills/design/data/checklists/creation-flow.md +20 -0
- package/data/harnesses/apollo/skills/design/data/checklists/dashboard.md +21 -0
- package/data/harnesses/apollo/skills/design/data/checklists/grid.md +21 -0
- package/data/harnesses/apollo/skills/design/data/checklists/queue.md +21 -0
- package/data/harnesses/apollo/skills/design/data/checklists/record-detail.md +21 -0
- package/data/harnesses/apollo/skills/design/data/checklists/settings.md +21 -0
- package/data/harnesses/apollo/skills/design/data/chrome/board-column.md +68 -0
- package/data/harnesses/apollo/skills/design/data/chrome/data-table.md +63 -0
- package/data/harnesses/apollo/skills/design/data/chrome/side-panel.md +60 -0
- package/data/harnesses/apollo/skills/design/data/chrome/sidebar.md +78 -0
- package/data/harnesses/apollo/skills/design/data/chrome/stat-cards.md +62 -0
- package/data/harnesses/apollo/skills/design/data/chrome/topbar.md +65 -0
- package/data/harnesses/apollo/skills/design/data/color/accent-presets.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/aesop-earth-mute.md +91 -0
- package/data/harnesses/apollo/skills/design/data/color/arc-peach-play.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/attio-hunter-teal.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/carbon-cyan-signal.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/clay-parchment.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/duolingo-feather.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/geist-mono-signal.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/linear-graphite-violet.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/mercury-onyx-cobalt.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/notion-paper-ink.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/radix-slate-iris.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/raycast-void-spectrum.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/spectrum-celery-fuchsia.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/stripe-blurple-ruby.md +90 -0
- package/data/harnesses/apollo/skills/design/data/color/superhuman-cod-picton.md +89 -0
- package/data/harnesses/apollo/skills/design/data/corpora/operations-review/companies.csv +15 -0
- package/data/harnesses/apollo/skills/design/data/corpora/operations-review/corpus.md +87 -0
- package/data/harnesses/apollo/skills/design/data/corpora/operations-review/people.csv +25 -0
- package/data/harnesses/apollo/skills/design/data/corpora/procurement-approvals/companies.csv +15 -0
- package/data/harnesses/apollo/skills/design/data/corpora/procurement-approvals/corpus.md +83 -0
- package/data/harnesses/apollo/skills/design/data/corpora/procurement-approvals/people.csv +25 -0
- package/data/harnesses/apollo/skills/design/data/corpora/revenue-analytics/companies.csv +15 -0
- package/data/harnesses/apollo/skills/design/data/corpora/revenue-analytics/corpus.md +89 -0
- package/data/harnesses/apollo/skills/design/data/corpora/revenue-analytics/people.csv +25 -0
- package/data/harnesses/apollo/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
- package/data/harnesses/apollo/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
- package/data/harnesses/apollo/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
- package/data/harnesses/apollo/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
- package/data/harnesses/apollo/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
- package/data/harnesses/apollo/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
- package/data/harnesses/apollo/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
- package/data/harnesses/apollo/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
- package/data/harnesses/apollo/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
- package/data/harnesses/apollo/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
- package/data/harnesses/apollo/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
- package/data/harnesses/apollo/skills/design/data/gradients/amber-attention-fill.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/cloud-shadow-wash.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/confident-lavender-wash.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/ember-ship-flare.md +18 -0
- package/data/harnesses/apollo/skills/design/data/gradients/full-metal-wash.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/indigo-ruby-cta-band.md +18 -0
- package/data/harnesses/apollo/skills/design/data/gradients/linear-graphite-wash.md +18 -0
- package/data/harnesses/apollo/skills/design/data/gradients/marble-quartz-wash.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/midnight-aurora-panel.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/neutral-volume-fill.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/revenue-uptrend-fill.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/risk-decline-fill.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/signal-blue-develop.md +18 -0
- package/data/harnesses/apollo/skills/design/data/gradients/slate-mist-wash.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/stripe-atmosphere-mesh.md +18 -0
- package/data/harnesses/apollo/skills/design/data/gradients/teal-signal-accent.md +16 -0
- package/data/harnesses/apollo/skills/design/data/gradients/violet-magenta-promo.md +16 -0
- package/data/harnesses/apollo/skills/design/data/iconography.md +199 -0
- package/data/harnesses/apollo/skills/design/data/motion/accordion-expand.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/destructive-hold-confirm.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/empty-state-arrive.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/hover-lift.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/modal-center-arrive.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/number-ticker-roll.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/onboarding-bounce.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/panel-slide.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/press-feedback.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/progress-linear-loop.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/route-crossfade.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/rubber-band-overscroll.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/skeleton-shimmer.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/stagger-arrive.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/toast-enter-stack.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/tooltip-chain-instant.md +18 -0
- package/data/harnesses/apollo/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
- package/data/harnesses/apollo/skills/design/data/tells.csv +34 -0
- package/data/harnesses/apollo/skills/design/data/typography/anton-work-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/archivo-black-archivo.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/bitter-karla.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/dm-serif-dm-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/fraunces-inter.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/geist-geist-mono.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/hubot-sans-mona-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/ibm-plex-sans-operator-single-family.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/instrument-serif-instrument-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/inter-operator-single-family.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/libre-baskerville-libre-franklin.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/newsreader-inter.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/playfair-display-source-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/public-sans-operator-single-family.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/sohne-inter-fintech.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/source-serif-source-sans.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/space-grotesk-work-sans-space-mono.md +17 -0
- package/data/harnesses/apollo/skills/design/data/typography/spectral-manrope.md +17 -0
- package/data/harnesses/apollo/skills/design/data/voices/bright-collaborator.md +29 -0
- package/data/harnesses/apollo/skills/design/data/voices/direct-operator.md +29 -0
- package/data/harnesses/apollo/skills/design/data/voices/earnest-helper.md +29 -0
- package/data/harnesses/apollo/skills/design/data/voices/editorial-composed.md +29 -0
- package/data/harnesses/apollo/skills/design/data/voices/quiet-concierge.md +29 -0
- package/data/harnesses/apollo/skills/design/data/voices/warm-guide.md +29 -0
- package/data/harnesses/apollo/skills/design/design-md/SCHEMA.md +179 -0
- package/data/harnesses/apollo/skills/design/design-md/index.csv +67 -0
- package/data/harnesses/apollo/skills/design/design-md/library/airbnb.md +207 -0
- package/data/harnesses/apollo/skills/design/design-md/library/airtable.md +205 -0
- package/data/harnesses/apollo/skills/design/design-md/library/anthropic-claude.md +203 -0
- package/data/harnesses/apollo/skills/design/design-md/library/apple.md +206 -0
- package/data/harnesses/apollo/skills/design/design-md/library/binance.md +210 -0
- package/data/harnesses/apollo/skills/design/design-md/library/bmw.md +210 -0
- package/data/harnesses/apollo/skills/design/design-md/library/cal.md +209 -0
- package/data/harnesses/apollo/skills/design/design-md/library/clay.md +204 -0
- package/data/harnesses/apollo/skills/design/design-md/library/clickhouse.md +205 -0
- package/data/harnesses/apollo/skills/design/design-md/library/cohere.md +205 -0
- package/data/harnesses/apollo/skills/design/design-md/library/coinbase.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/library/composio.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/library/cursor.md +197 -0
- package/data/harnesses/apollo/skills/design/design-md/library/elevenlabs.md +199 -0
- package/data/harnesses/apollo/skills/design/design-md/library/expo.md +200 -0
- package/data/harnesses/apollo/skills/design/design-md/library/figma.md +199 -0
- package/data/harnesses/apollo/skills/design/design-md/library/framer.md +202 -0
- package/data/harnesses/apollo/skills/design/design-md/library/hashicorp.md +205 -0
- package/data/harnesses/apollo/skills/design/design-md/library/ibm.md +205 -0
- package/data/harnesses/apollo/skills/design/design-md/library/intercom.md +204 -0
- package/data/harnesses/apollo/skills/design/design-md/library/kraken.md +200 -0
- package/data/harnesses/apollo/skills/design/design-md/library/linear-app.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/library/lovable.md +199 -0
- package/data/harnesses/apollo/skills/design/design-md/library/meta.md +204 -0
- package/data/harnesses/apollo/skills/design/design-md/library/minimax.md +204 -0
- package/data/harnesses/apollo/skills/design/design-md/library/mintlify.md +210 -0
- package/data/harnesses/apollo/skills/design/design-md/library/miro.md +209 -0
- package/data/harnesses/apollo/skills/design/design-md/library/mistral-ai.md +201 -0
- package/data/harnesses/apollo/skills/design/design-md/library/mongodb.md +201 -0
- package/data/harnesses/apollo/skills/design/design-md/library/notion.md +204 -0
- package/data/harnesses/apollo/skills/design/design-md/library/nvidia.md +215 -0
- package/data/harnesses/apollo/skills/design/design-md/library/ollama.md +213 -0
- package/data/harnesses/apollo/skills/design/design-md/library/opencode-ai.md +216 -0
- package/data/harnesses/apollo/skills/design/design-md/library/posthog.md +218 -0
- package/data/harnesses/apollo/skills/design/design-md/library/raycast.md +214 -0
- package/data/harnesses/apollo/skills/design/design-md/library/replicate.md +202 -0
- package/data/harnesses/apollo/skills/design/design-md/library/resend.md +203 -0
- package/data/harnesses/apollo/skills/design/design-md/library/revolut.md +203 -0
- package/data/harnesses/apollo/skills/design/design-md/library/runwayml.md +203 -0
- package/data/harnesses/apollo/skills/design/design-md/library/sanity.md +200 -0
- package/data/harnesses/apollo/skills/design/design-md/library/sentry.md +201 -0
- package/data/harnesses/apollo/skills/design/design-md/library/shopify.md +202 -0
- package/data/harnesses/apollo/skills/design/design-md/library/slack.md +202 -0
- package/data/harnesses/apollo/skills/design/design-md/library/spacex.md +206 -0
- package/data/harnesses/apollo/skills/design/design-md/library/spotify.md +206 -0
- package/data/harnesses/apollo/skills/design/design-md/library/stripe.md +196 -0
- package/data/harnesses/apollo/skills/design/design-md/library/supabase.md +196 -0
- package/data/harnesses/apollo/skills/design/design-md/library/superhuman.md +194 -0
- package/data/harnesses/apollo/skills/design/design-md/library/tesla.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/library/theverge.md +199 -0
- package/data/harnesses/apollo/skills/design/design-md/library/together-ai.md +193 -0
- package/data/harnesses/apollo/skills/design/design-md/library/uber.md +195 -0
- package/data/harnesses/apollo/skills/design/design-md/library/vercel.md +195 -0
- package/data/harnesses/apollo/skills/design/design-md/library/voltagent.md +197 -0
- package/data/harnesses/apollo/skills/design/design-md/library/warp.md +196 -0
- package/data/harnesses/apollo/skills/design/design-md/library/webflow.md +197 -0
- package/data/harnesses/apollo/skills/design/design-md/library/wired.md +197 -0
- package/data/harnesses/apollo/skills/design/design-md/library/wise.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/library/x-ai.md +199 -0
- package/data/harnesses/apollo/skills/design/design-md/library/zapier.md +198 -0
- package/data/harnesses/apollo/skills/design/design-md/nurix.md +214 -0
- package/data/harnesses/apollo/skills/design/design-md/variants/editorial-luxury.md +184 -0
- package/data/harnesses/apollo/skills/design/design-md/variants/expressive-saas.md +216 -0
- package/data/harnesses/apollo/skills/design/design-md/variants/quiet-premium.md +211 -0
- package/data/harnesses/apollo/skills/design/design-md/variants/terse-dense-operator.md +212 -0
- package/data/harnesses/apollo/skills/design/design-md/variants/warm-approachable.md +216 -0
- package/data/harnesses/apollo/skills/design/references/compose.md +23 -0
- package/data/harnesses/apollo/skills/design/references/content.md +28 -0
- package/data/harnesses/apollo/skills/design/references/emission.md +21 -0
- package/data/harnesses/apollo/skills/design/references/existing-apps.md +27 -0
- package/data/harnesses/apollo/skills/design/references/intake.md +36 -0
- package/data/harnesses/apollo/skills/design/references/object-pass.md +24 -0
- package/data/harnesses/apollo/skills/design/references/ship-gate.md +29 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/Readme.md +195 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/ai-layer.md +49 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/attributes-lifecycle.md +43 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/container-choice.md +44 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/creation-paths.md +46 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/dashboards.md +42 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/modes.md +42 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/object-model.md +46 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/page-archetype.md +48 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/promotion-demotion.md +37 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/settings.md +42 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/standard-pages.md +46 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/state-matrix.md +41 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/table-mechanics.md +48 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/verbs.md +45 -0
- package/data/harnesses/apollo/skills/design/references/ux-patterns/viewer-context.md +40 -0
- package/data/harnesses/apollo/skills/design/scripts/README-validator.md +27 -0
- package/data/harnesses/apollo/skills/design/scripts/select-chart.mjs +596 -0
- package/data/harnesses/apollo/skills/design/scripts/validate-design-md.mjs +1198 -0
- package/data/harnesses/apollo/skills/documentation/SKILL.md +134 -0
- package/data/harnesses/apollo/skills/documentation/references/examples.md +279 -0
- package/data/harnesses/apollo/skills/documentation/references/frontmatter.md +44 -0
- package/data/harnesses/apollo/skills/documentation/references/instruction-style.md +49 -0
- package/data/harnesses/apollo/skills/documentation/references/style-guide.md +351 -0
- package/data/harnesses/apollo/skills/documentation/references/untemplated.md +38 -0
- package/data/harnesses/apollo/skills/documentation/scripts/doc-lint.mjs +140 -0
- package/data/harnesses/apollo/skills/documentation/templates/Readme.md +34 -0
- package/data/harnesses/apollo/skills/documentation/templates/api-reference.md +20 -0
- package/data/harnesses/apollo/skills/documentation/templates/architecture-decision.md +121 -0
- package/data/harnesses/apollo/skills/documentation/templates/backlog.md +33 -0
- package/data/harnesses/apollo/skills/documentation/templates/behavioral-checklist.md +79 -0
- package/data/harnesses/apollo/skills/documentation/templates/bookkeeping.md +18 -0
- package/data/harnesses/apollo/skills/documentation/templates/changelog-entry.md +57 -0
- package/data/harnesses/apollo/skills/documentation/templates/changelog-index.md +41 -0
- package/data/harnesses/apollo/skills/documentation/templates/docs-readme.md +72 -0
- package/data/harnesses/apollo/skills/documentation/templates/domain-model.md +30 -0
- package/data/harnesses/apollo/skills/documentation/templates/environment-registry.md +15 -0
- package/data/harnesses/apollo/skills/documentation/templates/feature.md +149 -0
- package/data/harnesses/apollo/skills/documentation/templates/glossary.md +11 -0
- package/data/harnesses/apollo/skills/documentation/templates/journal.md +13 -0
- package/data/harnesses/apollo/skills/documentation/templates/memory-main.md +25 -0
- package/data/harnesses/apollo/skills/documentation/templates/migration-runbook.md +34 -0
- package/data/harnesses/apollo/skills/documentation/templates/non-goals.md +11 -0
- package/data/harnesses/apollo/skills/documentation/templates/operations-procedure.md +36 -0
- package/data/harnesses/apollo/skills/documentation/templates/plan.md +74 -0
- package/data/harnesses/apollo/skills/documentation/templates/protected-files.md +37 -0
- package/data/harnesses/apollo/skills/documentation/templates/root-readme.md +104 -0
- package/data/harnesses/apollo/skills/documentation/templates/security-overview.md +27 -0
- package/data/harnesses/apollo/skills/documentation/templates/structure.md +65 -0
- package/data/harnesses/apollo/skills/documentation/templates/system-overview.md +32 -0
- package/data/harnesses/apollo/skills/documentation/templates/testing-strategy.md +29 -0
- package/data/harnesses/apollo/skills/test-plan/SKILL.md +85 -0
- package/data/harnesses/apollo/skills/workflow-mapper/SKILL.md +451 -0
- package/data/harnesses/apollo/skills/workflow-mapper/references/patterns.md +214 -0
- package/data/harnesses/code/agents/bookkeeper.md +27 -0
- package/data/harnesses/code/agents/maintenance.md +5 -3
- package/data/harnesses/code/codex/agents/maintenance.toml +2 -2
- package/data/harnesses/code/harness.json +3 -2
- package/data/harnesses/code/hooks/awareness.mjs +370 -0
- package/data/harnesses/code/hooks/check-bookkeeping-clean.mjs +19 -0
- package/data/harnesses/code/hooks/check-changelog-presence.mjs +48 -0
- package/data/harnesses/code/hooks/check-completion-integrity.mjs +68 -0
- package/data/harnesses/code/hooks/check-ownership.mjs +22 -0
- package/data/harnesses/code/hooks/compliance.mjs +332 -0
- package/data/harnesses/code/hooks/hooks.json +16 -10
- package/data/harnesses/code/hooks/lib/frozen.mjs +58 -0
- package/data/harnesses/code/hooks/lib/ownership.mjs +223 -0
- package/data/harnesses/code/hooks/lib/state.mjs +156 -0
- package/data/harnesses/code/skills/boundary/SKILL.md +3 -1
- package/data/harnesses/code/skills/documentation/SKILL.md +2 -0
- package/data/harnesses/code/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/code/skills/documentation/templates/bookkeeping.md +18 -0
- package/data/harnesses/code/skills/documentation/templates/journal.md +13 -0
- package/data/harnesses/code/skills/documentation/templates/plan.md +3 -0
- package/data/harnesses/code/skills/test-plan/SKILL.md +2 -0
- package/data/harnesses/delivery/agents/maintenance.md +5 -3
- package/data/harnesses/delivery/codex/agents/maintenance.toml +2 -2
- package/data/harnesses/delivery/harness.json +3 -2
- package/data/harnesses/delivery/skills/documentation/SKILL.md +2 -0
- package/data/harnesses/delivery/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/delivery/skills/documentation/templates/bookkeeping.md +18 -0
- package/data/harnesses/delivery/skills/documentation/templates/journal.md +13 -0
- package/data/harnesses/delivery/skills/documentation/templates/plan.md +3 -0
- package/data/harnesses/discover/harness.json +2 -1
- package/data/harnesses/discussion/harness.json +1 -0
- package/data/harnesses/etna/agents/maintenance.md +5 -3
- package/data/harnesses/etna/codex/agents/maintenance.toml +2 -2
- package/data/harnesses/etna/harness.json +3 -2
- package/data/harnesses/etna/skills/boundary/SKILL.md +3 -1
- package/data/harnesses/etna/skills/documentation/SKILL.md +2 -0
- package/data/harnesses/etna/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/etna/skills/documentation/templates/bookkeeping.md +18 -0
- package/data/harnesses/etna/skills/documentation/templates/journal.md +13 -0
- package/data/harnesses/etna/skills/documentation/templates/plan.md +3 -0
- package/data/harnesses/hr/harness.json +1 -0
- package/data/harnesses/kb-agi/harness.json +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: project-memory
|
|
3
|
+
owner: main-agent
|
|
4
|
+
description: Project-wide patterns and conventions confirmed in this codebase. Project facts only — user-centric facts go in ~/.claude/.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Main Agent — Project Memory
|
|
8
|
+
|
|
9
|
+
Append entries below, oldest at bottom. Format:
|
|
10
|
+
|
|
11
|
+
## YYYY-MM-DD — {topic}
|
|
12
|
+
|
|
13
|
+
{1-3 line fact, with file paths or references where relevant}
|
|
14
|
+
|
|
15
|
+
---
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Documentation Structure
|
|
2
|
+
|
|
3
|
+
> This file is the entry point for understanding the docs folder.
|
|
4
|
+
> The `harness-version` frontmatter field is the repo's single baseline/version sentinel — the `maintenance` agent (baseline mode) owns it and stamps the installed harness version (semver) on every reconcile. This seeded copy ships without the field: its absence is what tells the first session the repo has not been baselined yet.
|
|
5
|
+
|
|
6
|
+
## Authority Map
|
|
7
|
+
|
|
8
|
+
Each topic has one canonical location. Read from here, not from plans or changelogs.
|
|
9
|
+
|
|
10
|
+
| Topic | Authority | Key Files |
|
|
11
|
+
| ----- | --------- | --------- |
|
|
12
|
+
| Code-path ownership (path → doc + module) | feature `owns:` frontmatter | the generated ownership index |
|
|
13
|
+
| System overview | `docs/architecture/` | system-design.md |
|
|
14
|
+
| Steering (domain model, glossary, non-goals) | `docs/architecture/` | domain-model.md, glossary.md, non-goals.md |
|
|
15
|
+
| Architecture decisions (ADs) | `docs/architecture/decisions/` | AD-NNN-*.md |
|
|
16
|
+
| API surface | `docs/architecture/` | api.md |
|
|
17
|
+
| Security | `docs/architecture/` | security.md |
|
|
18
|
+
| Feature behavior | `docs/features/` | one `kebab-case.md` doc per feature |
|
|
19
|
+
| Setup & development | `docs/operations/` | setup.md |
|
|
20
|
+
| Environment / config surface | `docs/operations/` | environment.md |
|
|
21
|
+
| Testing strategy | `docs/tests/` | strategy.md |
|
|
22
|
+
| Historical plans | `docs/history/plans/` | YYYY-MM-DD-name.md |
|
|
23
|
+
| Change records | `docs/history/changelog/` | `YYYY-MM-DD-{three-words}.md` — one per unit of work, written at commit time |
|
|
24
|
+
| Migration runbooks | `docs/history/migrations/` | YYYY-MM-DD-name.md |
|
|
25
|
+
| Deep-research artifacts | `docs/history/research/{topic}/` | README.md + findings.md + sources.md |
|
|
26
|
+
| Brainstorm design records | `docs/research/{topic}-brainstorm/` (active; legacy `-brainstorming/`) → `docs/history/brainstorms/{topic}/` (harvested; user deletes or commits) | thesis.md + forks.md + ledger.md + state.md |
|
|
27
|
+
| Backlog | `docs/history/` | backlog.md |
|
|
28
|
+
|
|
29
|
+
## The Two Natures
|
|
30
|
+
|
|
31
|
+
Every doc is a **truth document** (states current absolutes, topic-named, updated in place) or a **record** (dated account of activity, frozen or append-only). `architecture/`, `features/`, `operations/`, `tests/` hold truth; `history/`, `research/`, `memory/` hold records.
|
|
32
|
+
|
|
33
|
+
- Truth documents are rewritten in place when reality changes — the change-story goes to a changelog entry, never into the truth doc's body.
|
|
34
|
+
- Records freeze: plans at `Complete`/`Abandoned`, changelog entries and migration runbooks once written/executed. A scope change is a new dated record that links back.
|
|
35
|
+
- Feature docs are the living reference for implemented features; an AD is the living truth for one decision subject, with its dated journey confined to its Decision Changelog tail.
|
|
36
|
+
|
|
37
|
+
## Folder Rules
|
|
38
|
+
|
|
39
|
+
- `docs/features/`: Living reference for implemented features. Each feature doc **carries** the `owns:` / `module:` / `keywords:` / `status:` frontmatter — `owns:` declares the code-path globs it owns (the only ownership key), `module:` is an optional bounded-context label, `keywords:` are discovery terms, `status:` is `active`/`draft`/`deprecated`. The SessionStart hook unions every feature's `owns:` globs into the injected ownership index.
|
|
40
|
+
- `docs/architecture/`: The truth layer for system-wide shape: overview, domain model, glossary, non-goals, API surface, security, and `decisions/` (ADs — one per subject, updated in place, journey in each AD's Decision Changelog). Update when cross-cutting reality changes.
|
|
41
|
+
- `docs/operations/`: How-to procedures for setup, development, and deployment, plus the environment registry. Update when workflows change. One-shot migrations do NOT live here — they are records (`docs/history/migrations/`).
|
|
42
|
+
- `docs/tests/`: Testing strategy and test docs. Present when the repo has a test posture worth documenting.
|
|
43
|
+
- `docs/history/plans/`: Records. Must have `Status:` field. Never modify after completion.
|
|
44
|
+
- `docs/history/changelog/`: Records. One entry per unit of work (`YYYY-MM-DD-{three-words}.md`), written by whoever does the work and frozen inside the commit it describes. Entries carry the refinement context a diff cannot show — the ask in the user's words, iterations and rejections, skill survived/overridden verdicts, discoveries, pins. Format is the `documentation` skill's `templates/changelog-entry.md`; trigger and lifecycle are the `changelog` rule; distillation is the `retro` agent. Immutability begins at commit — a draft in the working tree is mutable until then, never after. Every entry appends a row to `docs/history/CHANGELOG.md`.
|
|
45
|
+
- `docs/history/migrations/`: Records. One-shot migration/upgrade runbooks — authored before execution, outcome-stamped and frozen after.
|
|
46
|
+
- `docs/history/research/{topic}/`: Deep-research artifacts — the dumped output of a research pass, one folder per topic (conventionally `README.md` synthesis + `findings.md` verified claims & citations + `sources.md`). A point-in-time, cited record — **not** a living authority doc: it owns no code (no `owns:` frontmatter) and is never edited to "stay current." A spec/plan links to it for grounding; a new question gets a new topic folder.
|
|
47
|
+
- `docs/research/{topic}-brainstorm/` → `docs/history/brainstorms/{topic}/`: Brainstorm design records — the Brainstorming-Mode session for a topic (working surface `thesis.md` + `forks.md` + `ledger.md` + `state.md` + `basis/` + `fragments/`, plus an untracked `ops/` capture layer deleted at stop), written by the `brainstorm` skill and its twin agent. An active session lives under `docs/research/` (legacy folders carry the older `-brainstorming/` suffix); on a **passed harvest** it **moves** to `docs/history/brainstorms/` — the completion marker — and the **user decides whether the moved folder is deleted or committed** as provenance. Each of the two folders carries a `Readme.md` index (the skill reads it at start instead of scanning). Author-created (never scaffolded empty), one folder per design conversation. Owns no code (no `owns:` frontmatter); the harvest routes its conclusions into `architecture/`/`features/`/`history/`. (Distinct from `docs/history/research/{topic}/` above — that is a frozen deep-research record, not a brainstorm session.)
|
|
48
|
+
- `docs/history/backlog.md`: Tracked work items. Append new items under appropriate priority.
|
|
49
|
+
|
|
50
|
+
## Health Log
|
|
51
|
+
|
|
52
|
+
<!-- Updated by maintenance agent — the sanctioned dated tail in this truth doc (SKILL.md § The Two Natures names the two bridges) -->
|
|
53
|
+
| Date | Review Summary |
|
|
54
|
+
| ---- | -------------- |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"harness": "apollo",
|
|
3
|
+
"name": "apollo",
|
|
4
|
+
"version": "1.0.2",
|
|
5
|
+
"files": [
|
|
6
|
+
".prettierignore",
|
|
7
|
+
".prettierrc.json",
|
|
8
|
+
".vscode/settings.json"
|
|
9
|
+
],
|
|
10
|
+
"seeds": [
|
|
11
|
+
"docs/README.md",
|
|
12
|
+
"docs/structure.md",
|
|
13
|
+
"docs/history/CHANGELOG.md",
|
|
14
|
+
"docs/history/backlog.md",
|
|
15
|
+
"docs/memory/main.md"
|
|
16
|
+
],
|
|
17
|
+
"digest": "3c2fc6ad2e82"
|
|
18
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// harness/
|
|
1
|
+
// harness/apollo/hooks/generate-ownership-index.mjs — SessionStart hook: scan docs/features/**/*.md,
|
|
2
2
|
// extract the focal frontmatter (owns / module / keywords / status), and inject a compact
|
|
3
3
|
// code-path → owning-doc index via additionalContext. Fires on startup/resume/clear/compact so the
|
|
4
4
|
// map survives /clear and /compact and is regenerated fresh every time. Writes no file.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Every unit of work leaves one record — `docs/history/changelog/YYYY-MM-DD-{three-words}.md` (the three words name the work, not the commit) — plus its row in `docs/history/CHANGELOG.md`, appended in the same pass so the index never trails the folder. Entry format, field rules, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`; this rule owns when an entry is owed and how it lives. An entry is never a commit summary — it carries the refinement context only the working session holds, which no diff reconstructs.
|
|
4
|
+
|
|
5
|
+
## When an entry is owed
|
|
6
|
+
|
|
7
|
+
| Trigger | What to write |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| A plan reaches `Status: Complete` | A draft entry for that plan, linked to it — written now, while the session still holds the context |
|
|
10
|
+
| The user asks for a changelog | The entry for the work in hand. No commit required |
|
|
11
|
+
| A commit is made | Every non-exempt commit is covered by an entry — the `commit` skill writes or completes it |
|
|
12
|
+
|
|
13
|
+
## Lifecycle
|
|
14
|
+
|
|
15
|
+
Draft (created before its commit exists) → complete (missing fields filled from the diff and the session) → frozen the moment it rides in a commit. **Immutability begins at commit, not at creation** — a draft is meant to be edited, which is what lets a completed plan record its context before anything is committed; a committed entry is history, and a correction is a new entry linking back, **never** an edit.
|
|
16
|
+
|
|
17
|
+
## Granularity
|
|
18
|
+
|
|
19
|
+
A commit is the smallest unit an entry may describe; above that the mapping is judgment — four commits may be four entries or one, whichever reads better as history. An entry spanning several commits rides in the **last** of them, naming the predecessors in `Commits:`. When work exceeds what a draft describes, write a second entry rather than stretching the draft — the first stays an honest account of the plan.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Database
|
|
2
|
+
|
|
3
|
+
Fixed conventions for relational schemas in **every** Nurix project — what earns a table, the key vocabulary, foreign-key doctrine, naming, and column types. A cross-project consistency rule: **one concept, one name, everywhere**. General code naming (variables, files, casing) is [`nomenclature.md`](nomenclature.md); this rule owns the database.
|
|
4
|
+
|
|
5
|
+
Written for SQLite / Cloudflare D1 + Drizzle (the concrete types below). The names and key vocabulary are engine-agnostic — a Postgres project keeps the same column names and semantics with native types (`uuid`, `timestamptz`, `boolean`).
|
|
6
|
+
|
|
7
|
+
## What earns a table
|
|
8
|
+
|
|
9
|
+
A table is the most expensive home for data — a migration to change its shape, a join to read, a mirror to keep in sync. Default to **not** a table — a concept earns one only with at least one property in the left column.
|
|
10
|
+
|
|
11
|
+
| A table is earned by… | Lacking all of these, the data belongs in… |
|
|
12
|
+
| -------------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
13
|
+
| identity minted at **runtime** | — |
|
|
14
|
+
| variation **per tenant / user** | — |
|
|
15
|
+
| **independent addressing** — queried, indexed, or FK'd in isolation | a **JSON column** on its parent row |
|
|
16
|
+
| **concurrency-safe** writes — racing writers must not clobber a shared blob | — |
|
|
17
|
+
| a **DB-enforced invariant** — immutability trigger, unique, atomic boundary | — |
|
|
18
|
+
| dev-authored, published on deploy, identical for every tenant | **config / a constants file**, validated at build |
|
|
19
|
+
| exactly recomputable from other rows | a **cache** (KV / edge), recomputed on demand |
|
|
20
|
+
| process state that is dead once the request completes | a **log or workflow engine**, never the domain DB |
|
|
21
|
+
| owned by another system-of-record | a **reference column** — store the id, not the data |
|
|
22
|
+
|
|
23
|
+
Each right-column route is one test: process state — would a product feature break if this vanished the instant the request finished?; derived output — exactly recomputable from other rows + code?; un-addressed detail — is the row ever `SELECT`ed / `JOIN`ed / FK'd alone?; another system's record — does a specialized service (chat, telemetry, object store) already own it?
|
|
24
|
+
|
|
25
|
+
- **Static vocabulary or a fixed graph → config, not a table.** Surface it in code as a constant/type; reifying it into tables plus a seed makes the file and the tables a two-copy sync problem. The refined boundary is § Vocabulary / lookup tables.
|
|
26
|
+
- **History → one immutable log + a mutable head.** Never shatter versioning into per-entity `*_revisions` / `*_revision_sections` tables — snapshot the coherent set into one append-only versions table; current state is a projection of the newest entry. A table that is just "old rows of another table" collapses into the snapshot.
|
|
27
|
+
- **A surviving table names the invariant it buys** — content-addressed immutable rows buy reproducibility, a monotonic sequence buys ordering/sync, an atomic write boundary buys multi-row atomicity. Drop the requirement and the table drops with it.
|
|
28
|
+
|
|
29
|
+
Table count tracks **requirements, not domain richness** — a rich domain is not entitled to a table per noun.
|
|
30
|
+
|
|
31
|
+
## Scope, not parallel tables
|
|
32
|
+
|
|
33
|
+
One entity that exists at several scopes is **one table with a nullable scope column** — never one table per scope, and never one table shared across entity families.
|
|
34
|
+
|
|
35
|
+
- **A table shared by several families carries the union of their columns** — almost nothing can be `NOT NULL`, the payload lands in JSON beyond every constraint, index, and FK, and a new family widens a table other features already depend on. One table per family.
|
|
36
|
+
- **Two tables declared to have "the same columns" are two schemas maintained by hand** — the drift is silent, surfacing as an incomplete copy, never as an error. Collapse them and discriminate by column.
|
|
37
|
+
- **The scope column is the discriminator** (`app_id IS NULL` = parent scope, set = child scope). Copying a scope is then `INSERT … SELECT` over one table with one column rewritten, so source and target cannot disagree about shape.
|
|
38
|
+
- **A nullable owner column is how a row exists before its owner does** — a pending enrolment or unclaimed record is creatable before the owner is known, which is what lets a `pending_*` / `*_requests` table collapse into the real one.
|
|
39
|
+
- **A reserved row can own the shipped defaults.** A fixed-id "system" parent makes the defaults and a tenant's copy the same kind of row, through the same code. It must then be excluded from every tenant-scoped query — state that invariant where the id is defined.
|
|
40
|
+
|
|
41
|
+
## Copying rows between scopes
|
|
42
|
+
|
|
43
|
+
- **A copied junction row is already correct with no remapping** — its endpoints are `slug` references (§ Keys & the shared vocabulary), and a slug means the same thing in every scope. Rewriting ids through a source→copy map is the most error-prone step in a multi-level copy, and a partial failure leaves wiring pointed into another scope rather than raising.
|
|
44
|
+
- **Provenance is a soft reference — no FK.** `source_id` must outlive its referent; an FK would either block the source's deletion or erase the lineage.
|
|
45
|
+
- **Store the source's version at copy time** — `version` + `source_version` make "is an upgrade available" a comparison of two stored values, not a content diff.
|
|
46
|
+
- **A copy is a row, never a live read.** Nothing at the child scope reads the parent's row at runtime; propagation happens only through an explicit re-copy, so a local edit is never silently overwritten.
|
|
47
|
+
|
|
48
|
+
## Keys & the shared vocabulary
|
|
49
|
+
|
|
50
|
+
Three column roles are fixed across every table and every project:
|
|
51
|
+
|
|
52
|
+
- **`id`** — the primary key, **always a UUID** (`TEXT PRIMARY KEY` on D1, `uuid` on Postgres), never a synthetic or natural key (❌ `type_page_button`, `human:default`). Runtime rows mint a UUIDv7; seed rows derive a deterministic UUIDv5 of the natural key so re-seeds stay stable. **Never** mix synthetic and UUID ids in one table.
|
|
53
|
+
- **`slug`** — the **stable key rows in another scope reference**: `UNIQUE`, lowercase `snake_case`. A slug means the same thing in every scope, so a slug reference survives a copy with no remapping (§ Copying rows between scopes). ❌ Never rename this role `handle`, `key`, `code`, or `name` in another project.
|
|
54
|
+
- **`label`** — the **human display name** — ❌ never `name`, `title`, or `display_name`.
|
|
55
|
+
|
|
56
|
+
Reference columns name what they point at: `<entity>_id` for a UUID-PK reference (`user_id`, `app_id`), `<entity>_slug` for a slug reference (`source_slug`).
|
|
57
|
+
|
|
58
|
+
- **Enforced, same scope** (the referenced row must exist) → a real `FOREIGN KEY (<x>_id) REFERENCES <table>(id)`.
|
|
59
|
+
- **Cross-scope** (the reference must survive being copied) → `<x>_slug` as a plain column, **no** FK — an FK would bind the row to one scope's copy of the target, which is the remapping the slug exists to avoid.
|
|
60
|
+
- **Drift-tolerant** (a controlled-vocabulary value that may fall off-list) → a plain value column, **no** FK, paired with an `is_*` boolean recording whether the value is in the canonical set.
|
|
61
|
+
|
|
62
|
+
**Every inbound FK to a hub table declares a deliberate `ON DELETE`.** A hub (`users`, `devices`, anything several modules point at) collects edges from teams that never meet, and a single `NO ACTION` among them turns deleting the parent into a constraint error naming neither table. Decide per edge: the child dies with the row (`CASCADE`) or survives it (`SET NULL`, which needs a nullable column) — `NO ACTION` on a hub is a deferred outage, not a default.
|
|
63
|
+
|
|
64
|
+
## A junction spells many-to-many — nothing else
|
|
65
|
+
|
|
66
|
+
**A `_map` table is the schema's notation for M:N. Using it for 1:M is a category error** — the junction's own uniqueness admits many parents per child, so the "one parent" rule stops being enforced the moment it is written this way. Cardinality decides between the only two shapes:
|
|
67
|
+
|
|
68
|
+
| Relationship | Shape |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| **1:M** — the child has exactly one parent | a **reference column on the child** (`agents.routing_slug`), plus an index |
|
|
71
|
+
| **M:N** — both sides have many | a **`<a>_<b>_map` junction** with a composite unique |
|
|
72
|
+
|
|
73
|
+
- **The test is one question about the child**: can this row ever belong to two parents at once? No ⇒ column. A junction "in case it becomes M:N later" ships the unenforced model today to buy a migration you may never run.
|
|
74
|
+
- **A junction for a 1:M also** makes the association a row that can go missing independently of the child — a child can exist correctly while its wiring does not — and forces a join onto the most common read in the system.
|
|
75
|
+
- **A junction carrying only its two endpoints and timestamps is the tell** — a real M:N junction usually earns its own columns (a role, an order, a status); one that never does is a 1:M waiting to be collapsed into a column.
|
|
76
|
+
- **Collapsing deletes a copy step** — the association travels inside the row it belongs to: no second pass to remap, no copy landing with its wiring half-applied.
|
|
77
|
+
- **A pair already recorded elsewhere needs no table at all.** If an append-only log stores `(parent, child)` on every write, the association table is `SELECT DISTINCT` over that log — a cache free to disagree with the log it derives from (§ What earns a table).
|
|
78
|
+
|
|
79
|
+
## Foreign keys into and out of append-only tables
|
|
80
|
+
|
|
81
|
+
**An append-only table can afford no `ON DELETE` action at all, so its references to mutable tables are soft — no FK.** Every option is closed to it:
|
|
82
|
+
|
|
83
|
+
| Action | Why it fails on an append-only table |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `SET NULL` | It is an **UPDATE**. An append-only trigger aborts it, so the parent's deletion fails — with an error naming the trigger, not the constraint. |
|
|
86
|
+
| `CASCADE` | Deletes history to delete a person. The log exists precisely to outlive its subjects. |
|
|
87
|
+
| `NO ACTION` | Makes anyone who ever appeared in the log undeletable — the hub defect above. |
|
|
88
|
+
|
|
89
|
+
- **`SET NULL` is the trap** — it reads like a safe relaxation of `NO ACTION` and passes review as one.
|
|
90
|
+
- **Record the actor as a plain column** — the same soft-reference treatment provenance gets (`source_id`, `thread_id`). The log keeps naming who acted after the account is gone, which is what an audit trail is for.
|
|
91
|
+
- **`CASCADE` from the append-only side's own parent is still fine** — a cascade is a DELETE, so a `BEFORE UPDATE` trigger never sees it: an App's log dying with the App is legitimate, distinct from erasing a log to delete a person.
|
|
92
|
+
- **State the exemption where it exists.** A catalog whose rows must not disappear under a referencing row (a service definition, a vocabulary) keeps `NO ACTION` deliberately — that guarantee is worth one line saying so.
|
|
93
|
+
|
|
94
|
+
## Naming
|
|
95
|
+
|
|
96
|
+
- **Tables** — `snake_case`, plural noun for what they hold (`users`, `apps`, `devices`).
|
|
97
|
+
- **Junction (M:N) tables** — `<entityA>_<entityB>_map`, **always**, even when the join carries its own columns; singular stems, owning/anchor entity first (`app_user_map`, `app_device_map`). ❌ Never a "nice" noun (`members`, `installs`, `memberships`, `enrolments`) — the name must read as a join, and a reviewer should know both sides from it. The `_map` suffix is reserved for genuine M:N (§ A junction spells many-to-many).
|
|
98
|
+
- **Columns** — `snake_case`; booleans `is_*` / `has_*`; timestamps `created_at` / `updated_at`; foreign keys `<entity>_id`.
|
|
99
|
+
- **Indexes** — `<table>_<col(s)>_idx`; unique `<table>_<col(s)>_unique`; a junction's composite unique reads `<table>_<colA>_<colB>_unique` (`app_user_map_app_user_unique`).
|
|
100
|
+
- **Drizzle mirror** — the exported object is the camelCase table name (`app_user_map` → `appUserMap`); column props are the camelCase of the column (`created_at` → `createdAt`). The `sqliteTable("…")` string and every index name must match the DDL (`init.sql`) exactly — the schema-parity boundary.
|
|
101
|
+
|
|
102
|
+
## Uniqueness with a nullable column
|
|
103
|
+
|
|
104
|
+
**`UNIQUE (a, b)` does not constrain rows where `b` is `NULL`** — SQL treats every `NULL` as distinct, so a composite unique over a nullable discriminator silently permits exactly the duplicates it was introduced to keep apart. Write one partial index per scope instead:
|
|
105
|
+
|
|
106
|
+
```sql
|
|
107
|
+
CREATE UNIQUE INDEX <t>_parent_slug_unique ON <t> (parent_id, slug) WHERE child_id IS NULL;
|
|
108
|
+
CREATE UNIQUE INDEX <t>_child_slug_unique ON <t> (child_id, slug) WHERE child_id IS NOT NULL;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Prove a uniqueness claim by inserting the duplicate it forbids** — a schema review cannot tell a firing index from a silent one by reading.
|
|
112
|
+
|
|
113
|
+
## Column types (SQLite / D1)
|
|
114
|
+
|
|
115
|
+
- **Timestamps** — `created_at` + `updated_at`, both `TEXT NOT NULL DEFAULT (datetime('now'))`, on **every** table — except append-only logs, which carry only `created_at`.
|
|
116
|
+
- **Booleans** — `INTEGER` (Drizzle `integer(…, { mode: "boolean" })`); the `is_*` / `has_*` names are § Naming.
|
|
117
|
+
- **JSON** — `TEXT` (Drizzle `text(…, { mode: "json" })`).
|
|
118
|
+
|
|
119
|
+
## Vocabulary / lookup tables
|
|
120
|
+
|
|
121
|
+
A controlled vocabulary earns a **table** only when a user row FKs into it and reads its `label` / `description` at runtime; static dev-authored config nobody references by FK stays **config** (§ What earns a table) — enumerable is not tabular, and a `type`-style column validated against the constants file beats an FK to a seeded mirror. An earned table has a fixed shape: `id` (UUID) · `slug` (UNIQUE) · `label` · optional `description` · `status` · timestamps.
|
|
122
|
+
|
|
123
|
+
- **Seeds are generated, never hand-written** — the source of truth is a CSV or a shared package; a generator emits the `*.seed.sql` with UUIDv5 ids and an idempotent `ON CONFLICT(slug)` upsert that preserves live counts / admin-tuned columns. ❌ Hand-editing seed SQL — regenerate it.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Express & API Format
|
|
2
|
+
|
|
3
|
+
Express 5.x server setup and the JSON response envelope every Nurix HTTP service returns — backend only. Package versions live in [`general.md`](general.md); web-frontend conventions in [`frontend.md`](frontend.md).
|
|
4
|
+
|
|
5
|
+
## Express 5.x
|
|
6
|
+
|
|
7
|
+
Canonical middleware stack:
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
app.use(cors({ origin: process.env.FRONTEND_URL }));
|
|
11
|
+
app.use(compression());
|
|
12
|
+
app.use(express.json({ limit: '10mb' }));
|
|
13
|
+
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- **Middleware order is fixed**: body parsers → custom middleware → routes → error handlers (centralized, **always** last) — no ad-hoc per-route error responses.
|
|
17
|
+
- Auth is middleware, not inline route checks. Routes are modular via Express Router.
|
|
18
|
+
|
|
19
|
+
## API Response Format
|
|
20
|
+
|
|
21
|
+
Success and error share **one** envelope — a cross-service contract clients branch on, so a per-service "improvement" (`success: true`, a boolean `status`, a bare payload) breaks every consumer:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"status": 1,
|
|
26
|
+
"message": "Message sent successfully",
|
|
27
|
+
"data": { "delivered": [{ "user@example.com": 2 }] }
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Error: `{ "status": 0, "message": "Error description", "data": null }`
|
|
32
|
+
|
|
33
|
+
HTTP codes, **closed list**: `200`, `201` (created), `400`, `401` (not authenticated), `403` (not authorized), `404`, `500`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Frontend
|
|
2
|
+
|
|
3
|
+
Tailwind v4 + shadcn-based UI conventions for **web** apps — styling, the `@nurix/components` library, the `design.md` token artifact, and design-skill routing — plus the TypeScript conventions every package compiles under. Package versions live in [`general.md`](general.md); the Express server and API envelope in [`express.md`](express.md); workspace layout and consuming `@nurix/*` packages in [`pnpm.md`](pnpm.md); React Native styling is [`react-native.md`](react-native.md).
|
|
4
|
+
|
|
5
|
+
- **Build every UI through the `design` skill** — never hand-roll layouts; the page archetypes, the `design.md` identity system with its token artifact (`design.tokens.css`), and chrome wiring live in the skill.
|
|
6
|
+
- **The brief's stated theme binds** — dark boots dark when the brief says so (recorded in the project's `design.md`); light is the default only when the brief is silent.
|
|
7
|
+
- **`@nurix/components`** is the UI library — import by subpath (`@nurix/components/button`); install, auth, and the no-substitutes guard are [`pnpm.md`](pnpm.md) §3. **Never** `npx shadcn add`, no `components.json` scaffold — consume the prebuilt library (`.tsx`, not `.jsx`).
|
|
8
|
+
- Vite: `@tailwindcss/vite` + `@vitejs/plugin-react-swc`. Pin `react` / `react-dom` / `react/jsx-runtime` / `react/jsx-dev-runtime` to the app's single copy via `resolve.alias` — `@nurix/*` ship nested react, and two copies means two hook dispatchers.
|
|
9
|
+
- Tailwind v4 is CSS-only — no `tailwind.config.js`, no PostCSS.
|
|
10
|
+
- CSS entry `globals.css`, imports in order: `@import "./fonts.css"` (`@fontsource` registrations) → the project's `design.tokens.css` (derived from the repo-base `design.md` by the design skill's validator — **never** hand-edited) → `@import "tailwindcss"` → the library's `styles.css` — then `@theme inline {…}` mapping vars to tokens.
|
|
11
|
+
- Tokens: CSS vars in `:root, :root[data-theme="light"]` and `:root[data-theme="dark"]` (both specificity 0,2,0 — armor a later bare `:root` can't defeat), consumed as semantic Tailwind tokens (`bg-card`, `text-foreground`). `globals.css` carries the active `@custom-variant dark` line; the theme attribute is `data-theme`. The library bundles `class-variance-authority`, `clsx`, `tailwind-merge` — don't re-add them.
|
|
12
|
+
- Spacing in 2/4/6/8; `object-cover`; `truncate`; color through tokens — **never** hardcoded hex in components.
|
|
13
|
+
|
|
14
|
+
## TypeScript
|
|
15
|
+
|
|
16
|
+
Every package compiles under `strict: true` and `noUncheckedIndexedAccess: true`.
|
|
17
|
+
|
|
18
|
+
### Type Safety
|
|
19
|
+
|
|
20
|
+
- **Never** `any` to silence the checker. Unknown value → type `unknown`, then narrow (type guard / `zod` parse).
|
|
21
|
+
- **Never** weaken strictness: no `// @ts-nocheck`; `// @ts-expect-error` only with a same-line reason.
|
|
22
|
+
- Infer locals and return types; annotate at boundaries (exports, props, contracts).
|
|
23
|
+
|
|
24
|
+
### Generics
|
|
25
|
+
|
|
26
|
+
Shared libraries (`@nurix/components`, etc.) are generic on purpose — that's what types `cell(row)`, checks `slug` against `keyof TData`, and ties `data`/`columns` together; **never** widen to `any` to dodge it. State the row type **once per file** and let inference carry it — repeating `fn<Type>(…)` / `<Comp<Type>>` per call site is cosmetic (same safety, same emitted JS):
|
|
27
|
+
|
|
28
|
+
- **Bind a repeated factory once** (preferred): `const col = defineColumn<BriefRow>;` → `col({...})`. Canonical: `modules/briefs/BriefsListPage.tsx`.
|
|
29
|
+
- **Infer JSX type args from props:** `<Table data={rows} columns={columns} />`, not `<Table<BriefRow> …>`.
|
|
30
|
+
- **Anchor with a collection annotation** when nothing else can: `const columns: ColumnDefinition<BriefRow>[] = [...]`.
|
|
31
|
+
|
|
32
|
+
> Monorepo TS policy (`tsconfig.base.json` + thin per-package `extends`, source-first internal packages, `peerDependencies`, pnpm `catalog:`) lives in [`pnpm.md`](pnpm.md) §2 — it travels with package boundaries.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# General Standards
|
|
2
|
+
|
|
3
|
+
Runtime versions, the canonical package list, and GitHub Actions pins — the workspace baseline. Web-frontend/styling conventions are [`frontend.md`](frontend.md); the Express server and the API response envelope are [`express.md`](express.md).
|
|
4
|
+
|
|
5
|
+
## Runtime Versions
|
|
6
|
+
|
|
7
|
+
- **Node.js:** 24 LTS
|
|
8
|
+
- **Package manager:** detect from the lockfile — **never** hardcode one.
|
|
9
|
+
- **PostgreSQL:** 17 · **Redis:** 7.x (latest)
|
|
10
|
+
|
|
11
|
+
## Packages
|
|
12
|
+
|
|
13
|
+
**Only** these — no alternatives.
|
|
14
|
+
|
|
15
|
+
| Package | Version | Use | Don't use |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| `react` | ^19.2.3 | UI components | — |
|
|
18
|
+
| `vite` | ^8.0.0 | Build tool, dev server | `webpack`, CRA |
|
|
19
|
+
| `tailwindcss` | ^4.1.18 | Styling | `styled-components` |
|
|
20
|
+
| `@vitejs/plugin-react-swc` | ^4.2.2 | JSX compilation | `@vitejs/plugin-react` |
|
|
21
|
+
| `react-router-dom` | ^7.11.0 | Routing | — |
|
|
22
|
+
| `@reduxjs/toolkit` | ^2.11.2 | State management | `zustand`, `jotai` |
|
|
23
|
+
| `react-redux` | ^9.2.0 | Redux React bindings | — |
|
|
24
|
+
| `axios` | ^1.13.2 | HTTP requests | `fetch` |
|
|
25
|
+
| `@microsoft/fetch-event-source` | ^2.0.1 | SSE over POST — streaming agent output | hand-rolled `getReader()` loops, `EventSource` |
|
|
26
|
+
| `date-fns` | ^4.1.0 | Date formatting | `moment`, `dayjs` |
|
|
27
|
+
| `@dnd-kit/core` | ^6.3.1 | Drag and drop | `react-beautiful-dnd` |
|
|
28
|
+
| `@xyflow/react` | ^12.11.0 | Node-based flow charts | `reactflow`, `react-flow-renderer` |
|
|
29
|
+
| `motion` | ^12.23.26 | Animations | `react-spring` |
|
|
30
|
+
| `sonner` | ^2.0.7 | Toast notifications | `react-toastify` |
|
|
31
|
+
| `react-window` | ^2.2.3 | List virtualization | `react-virtualized` |
|
|
32
|
+
| `nanoid` | ^6.0.0 | ID generation | `uuid` |
|
|
33
|
+
| `express` | ^5.2.1 | HTTP server | `fastify`, `koa` |
|
|
34
|
+
| `drizzle-orm` | ^0.45.2 | Database ORM | `prisma`, `sequelize`, `typeorm` |
|
|
35
|
+
| `drizzle-kit` | ^0.31.10 | Schema tooling | — |
|
|
36
|
+
| `zod` | ^4.2.1 | Schema validation | `yup`, `joi` |
|
|
37
|
+
| `jose` | ^6.1.3 | JWT handling | `jsonwebtoken` |
|
|
38
|
+
| `microdiff` | ^1.5.0 | JSON object diffing | `deep-diff`, `just-diff` |
|
|
39
|
+
| `react18-json-view` | ^0.2.9 | JSON tree view | `react-json-view` |
|
|
40
|
+
| `@tiptap/react` | ^3.11.1 | Rich text editor | `slate`, `quill`, `draft-js` |
|
|
41
|
+
| `shiki` | ^4.3.1 | Syntax highlighting | `prism`, `highlight.js` |
|
|
42
|
+
| `lucide-react` | ^1.26.0 | Icons | `react-icons`, `heroicons` |
|
|
43
|
+
| `@pdfme/generator` | ^6.1.12 | PDF generation | `jspdf`, `pdfkit` |
|
|
44
|
+
| `cmdk` | ^1.1.1 | Command palette | `kbar`, `ninja-keys` |
|
|
45
|
+
| `@monaco-editor/react` | ^4.7.0 | Code editor | `codemirror`, `ace` |
|
|
46
|
+
| `localforage` | ^1.10.0 | Client-side storage | `idb`, `dexie` |
|
|
47
|
+
| `react-markdown` | ^10.1.0 | Markdown rendering | `marked`, `markdown-it` |
|
|
48
|
+
| `remark-gfm` | ^4.0.1 | GFM (tables, tasklists) | `remark-github`, custom |
|
|
49
|
+
| `fast-deep-equal` | ^3.1.3 | Deep equality checks | `lodash.isEqual` |
|
|
50
|
+
| `@ngneat/falso` | latest | Fake data generation | `@faker-js/faker`, `chance` |
|
|
51
|
+
| `pino` | ^10.1.0 | Logging | `winston` |
|
|
52
|
+
|
|
53
|
+
## GitHub Actions
|
|
54
|
+
|
|
55
|
+
Pin the major, and check it against the action's releases — a major behind still runs, so a stale pin never fails, it only warns.
|
|
56
|
+
|
|
57
|
+
| Action | Version | Use |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `actions/checkout` | v7 | Repo checkout |
|
|
60
|
+
| `actions/setup-node` | v7 | Node toolchain + npm cache |
|
|
61
|
+
|
|
62
|
+
Set `node-version` from the Runtime Versions block above, **never** from the runner's default.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Nomenclature
|
|
2
|
+
|
|
3
|
+
Naming and casing for code — identifiers, files, folders. The rationale throughout is consistency: one concept, one name, one casing shape, in every repo that loads this rule. Database naming is not here — see § Database.
|
|
4
|
+
|
|
5
|
+
Names state intent in full words — clarity over brevity; no abbreviations unless universally understood (`id`, `url` ✅ · `cfg`, `btn`, `idx` ❌).
|
|
6
|
+
|
|
7
|
+
## Casing
|
|
8
|
+
|
|
9
|
+
| Casing | Used for | Example |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `camelCase` | variables, functions, methods, properties; a module file exporting no component | `calculateTotal`, `sessionClient.ts` |
|
|
12
|
+
| `PascalCase` | classes, type definitions, components; the file exporting one | `PaymentProcessor`, `AppsListPage.tsx` |
|
|
13
|
+
| `UPPER_SNAKE_CASE` | constants, environment variables | `MAX_RETRY_COUNT` |
|
|
14
|
+
| `kebab-case` | URLs, CSS class names, HTML IDs, multi-word folders | `user-profile`, `workspace-provisioning/` |
|
|
15
|
+
| `snake_case` | database tables, columns, indexes — § Database | `created_at` |
|
|
16
|
+
|
|
17
|
+
**A file exporting one component carries that component's name exactly**, so an import names the file it came from; a single-word folder is plain lowercase (`lib`, `surfaces`). ❌ Never `snake_case` a file or folder — that casing belongs to the database.
|
|
18
|
+
|
|
19
|
+
## Identifier shape
|
|
20
|
+
|
|
21
|
+
| Identifier | Shape | Example |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| Variable | noun phrase | `paymentStatus` |
|
|
24
|
+
| Function / method | verb phrase naming the action | `validateInput` |
|
|
25
|
+
| Boolean | `is` / `has` / `can` / `should` prefix — **never** a bare adjective | `hasPermission` |
|
|
26
|
+
| Array / collection | plural noun | `errorMessages` |
|
|
27
|
+
| Class / component | singular noun phrase | `RequestHandler` |
|
|
28
|
+
| Event handler | `handle` or `on` prefix | `handleSubmit`, `onPageLoad` |
|
|
29
|
+
| Interface | `I` prefix acceptable; type aliases stay plain | `IConfigOptions`, `AuthResponse` |
|
|
30
|
+
| Async function | verb phrase; `Async` suffix acceptable | `loadConfigAsync` |
|
|
31
|
+
|
|
32
|
+
## Database
|
|
33
|
+
|
|
34
|
+
Table, column, index, and key naming for relational schemas — the `id` / `slug` / `label` vocabulary, junction `_map` tables, and Drizzle mirrors — lives in [`database.md`](database.md), which routes general code naming back here.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# pnpm — `@nurix/*` Workspaces: naming, boundaries, and consuming
|
|
2
|
+
|
|
3
|
+
How a `@nurix/*` repo is **named**, **structured**, and how its packages are **consumed** — every repo takes the workspace shape, single-package frontends included. Publishing and CLI design live in the `nustack` skill, not here. TypeScript language conventions are [`frontend.md`](frontend.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Package naming
|
|
8
|
+
|
|
9
|
+
Every workspace package is scoped **`@nurix/`**; the dot vs. hyphen after the scope is semantic, not cosmetic:
|
|
10
|
+
|
|
11
|
+
| Form | Meaning | Examples |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `@nurix/workflows-sdk` (hyphen) | **Published, externally-destined** contract | `@nurix/workflows-sdk` |
|
|
14
|
+
| `@nurix/workflows.<name>` (dot) | **Internal** to the product — `private: true`, refactor freely. The default for a new package | `@nurix/workflows.agent-core`, `.worker`, `.playground` |
|
|
15
|
+
| `@nurix/<name>` (plain) | Cross-repo shared lib owned **elsewhere** — never renamed | `@nurix/contracts`, `@nurix/components` |
|
|
16
|
+
|
|
17
|
+
- `<name>` is always **kebab-case**.
|
|
18
|
+
- The dot is **not** a path separator — subpath exports resolve normally (`@nurix/workflows.agent-core/nodes`).
|
|
19
|
+
- The dot tracks "internal product package," not the `private` flag: `@nurix/workflows.secrets` is `private: false` (extraction-bound) yet dotted. `-sdk` is the only clean published form.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Monorepo & package boundaries
|
|
24
|
+
|
|
25
|
+
- **One `tsconfig.base.json` at the repo root owns TS policy** — the strict set ([`frontend.md`](frontend.md)), `target`, and everything uniform across packages (here, `module`/`moduleResolution`). Each package's `tsconfig.json` `extends` the base and adds only its coordinates (`rootDir`/`outDir`/`include`) and genuine environment overrides (`lib`/`types`/`jsx`; `module`/`moduleResolution` only when the package's module system truly differs). **Never** re-declare or weaken a policy option locally. One exception: a framework that owns its own base (an Astro app on `astro/tsconfigs/strict`).
|
|
26
|
+
- **Internal packages are source-first.** A `private: true` package exposes its API via `exports` pointing at source (`"types"`/`"default"` → `./src/index.ts`) — no build step, and no bare `main`/`module` on new packages. One typed subpath per public surface; consumers import the subpath, **never** a deep relative path into another package's `src/`. `types` comes **first** in every subpath block — resolvers take the first matching condition, so a `types` listed after `default` is never reached.
|
|
27
|
+
- **Crossing the publish boundary is the `nustack` skill** — `private: false`, the published manifest, the pipeline.
|
|
28
|
+
- **Single-source shared dep versions with pnpm `catalog:`** — `typescript`, `zod`, `vitest`, `react`, type packages — so every package resolves the same copy and its types stay mutually assignable.
|
|
29
|
+
- **TS project references only when it hurts** — adopt `references` once the typecheck/build graph is slow enough to feel; until then, `pnpm -r typecheck`.
|
|
30
|
+
|
|
31
|
+
### The catalog has no garbage collector
|
|
32
|
+
|
|
33
|
+
- **Removing the last consumer of a cataloged package removes its catalog entry in the same change** — `pnpm remove` rewrites the manifest and lockfile but **never** `pnpm-workspace.yaml`, and nothing downstream flags the orphan: no install fails, no lint fires.
|
|
34
|
+
- The check is mechanical: an entry no workspace manifest names under any dependency field is orphaned; one absent from `pnpm-lock.yaml` is an orphan with certainty.
|
|
35
|
+
- **A cataloged package is `catalog:` in every manifest** — a literal range (`"zod": "^4.2.1"`) resolves identically today and silently stops tracking the catalog the moment it moves.
|
|
36
|
+
|
|
37
|
+
### The workspace root is a hard boundary
|
|
38
|
+
|
|
39
|
+
- **A dependency spec never points outside the folder holding `pnpm-workspace.yaml`** — `devDependencies` included. Inside the root, `workspace:*` between `packages/*` is the normal, correct thing; outside it, nothing — no `file:../…`, no `link:`, no absolute `file:`. A sibling checkout is another repo, and the registry is the only supported way to consume one — a cross-root spec bakes machine-local paths into the lockfile and the published tarball, so `install --frozen-lockfile` fails on any other machine.
|
|
40
|
+
- **A package unreachable from the registry is an auth or publishing bug — fix it there, never with a local path.** Diagnosis order: the scope's registry (§3) → the token → whether it was actually published.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3. Consuming `@nurix/*` packages
|
|
45
|
+
|
|
46
|
+
`@nurix/*` packages publish to npm with **`restricted`** access — installing needs read rights to the `nurix` org.
|
|
47
|
+
|
|
48
|
+
- **Registry** — point the scope at npmjs, where the packages are published. A restricted read answers `404`, not `401`, so a mispaired registry is indistinguishable from "never published" — on an `@nurix/*` 404, check the registry pairing **first**, before auth and before assuming the package is missing.
|
|
49
|
+
- **Auth** — `npm login` once (the npm user must be a `nurix` member), or a read token in `.npmrc` (the only CI option):
|
|
50
|
+
```ini
|
|
51
|
+
@nurix:registry=https://registry.npmjs.org/
|
|
52
|
+
//registry.npmjs.org/:_authToken=${NPM_READ_TOKEN}
|
|
53
|
+
```
|
|
54
|
+
The token needs only `Read` on the `nurix` scope. A `403` on install means auth failed — check `npm whoami` (local) or the `NPM_READ_TOKEN` secret (CI). Attempt the install directly — the token authenticates ambiently; don't pre-empt or second-guess it. If it fails, flag it to the user — **never** reach for alternatives, a substitute package, or `npm login` swaps.
|
|
55
|
+
- **Import by subpath, never the barrel** — subpaths tree-shake reliably; the available subpaths are the package's `exports` keys. `import { Button } from "@nurix/components/button";`
|
|
56
|
+
- **Styles** — import a CSS-shipping package's stylesheet **once** at the app entry: `import "@nurix/components/styles.css";`. Unstyled components are almost always a missing styles import. The shipped stylesheet is precompiled — no Tailwind `@source` directive unless consuming source via a workspace link.
|
|
57
|
+
- **CLIs** ship a `bin` — run directly: `npx @nurix/etna@latest` (or `npm install -g`).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Test technology and placement — framework per stack, suite layout, mocking policy; **when** a test is written and how work is proven is [`verification.md`](verification.md), not here. Framework choice is **never** ad hoc and never the user's problem mid-task: detect the stack, use its row; if the repo already has a runner, that runner wins — **never** introduce a second framework beside it.
|
|
4
|
+
|
|
5
|
+
## Frameworks by stack
|
|
6
|
+
|
|
7
|
+
| Stack | Unit / integration | Component | E2E | HTTP mocking | Don't use |
|
|
8
|
+
| --- | --- | --- | --- | --- | --- |
|
|
9
|
+
| Node + Vite / React (web) | `vitest` | `@testing-library/react` (+ `@testing-library/user-event`, `happy-dom`) | `@playwright/test` | `msw` | `jest`, `mocha`, `jasmine`, `cypress`, `enzyme` |
|
|
10
|
+
| Express APIs | `vitest` | — | `supertest` against the app instance | `msw` (outbound calls) | `jest`, `chai-http` |
|
|
11
|
+
| React Native / Expo | `jest` via the `jest-expo` preset | `@testing-library/react-native` | `maestro` | `msw` | `detox`, `enzyme` |
|
|
12
|
+
| Cloudflare Workers | `vitest` + `@cloudflare/vitest-pool-workers` | — | `@playwright/test` against `wrangler dev` | `msw` | `jest` |
|
|
13
|
+
| Rust | `cargo test` (built-in) | — | — | — | — |
|
|
14
|
+
|
|
15
|
+
Test packages install at `latest` — they sit outside [`general.md`](general.md)'s pinned table. Fake data comes from `@ngneat/falso` — **never** `@faker-js/faker` / `chance` (its row there).
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- **Suite, not scripts.** Tests live in the canonical test tree — `tests/` mirroring `src/`, or the convention the repo already uses — named `<subject>.test.ts`; shared fixtures, factories, and helpers in `tests/helpers/` (or the suite's existing shared home).
|
|
20
|
+
- **Wire the canonical command.** `"test"` in `package.json` runs the whole unit suite (`vitest run`); e2e under `"test:e2e"`. A repo where `pnpm test` / `npm test` doesn't run the suite is misconfigured — fix the wiring, **never** route around it.
|
|
21
|
+
- **Unit and E2E trees stay separate.** Vitest/Jest suites in `tests/`; Playwright/Maestro suites in `e2e/` with their own config — **never** mixed into the unit runner's glob.
|
|
22
|
+
- **No test doubles for what you own.** Prefer real instances — in-memory SQLite for drizzle, the actual Express app via `supertest` — over mocks; mock **only** true externals (network via `msw`, time via the runner's fake timers).
|
|
23
|
+
- **Determinism.** No real network, no real time, no shared mutable state between tests; every test **must** pass alone and in any order.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Verification
|
|
2
|
+
|
|
3
|
+
**When** work is proven and **by what mechanism** — the gate, the two regimes, and the ladder of ways to drive a change. Framework choice, suite layout, and mocking policy are [`testing.md`](testing.md); the plan-gate obligation manifest is the `test-plan` skill. This rule owns the moment, not the technology.
|
|
4
|
+
|
|
5
|
+
## Two regimes
|
|
6
|
+
|
|
7
|
+
**Deferral is a property of plans, not of code.** A plan carries a Test Obligations ledger and a gate that discharges it; nothing else does, so nothing else may defer.
|
|
8
|
+
|
|
9
|
+
| Regime | During the work | Proven |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| **Plan-driven build** | No new test files. Code only — the loop stays fast | At the verification gate, before `Status: Complete` |
|
|
12
|
+
| **Bug fix** — a defect in shipped behavior | The regression test ships with the fix | Immediately — it fails before the change, passes after |
|
|
13
|
+
| **Ad-hoc / non-plan change** | The test ships with the change | Immediately, same discipline as a bug fix |
|
|
14
|
+
|
|
15
|
+
- **A bug fix cannot defer, because "fails before, passes after" is provable afterward only by reverting to the pre-fix ref** — a cost nobody pays, so the property is captured at fix time or lost.
|
|
16
|
+
- **Ad-hoc work cannot defer, because there is no ledger to defer into.** An obligation recorded nowhere is an obligation forgotten. A non-plan change that alters no promised behavior — a pure refactor, a rename — owes no test: the implementer applies § What earns a durable test directly.
|
|
17
|
+
|
|
18
|
+
## During the loop
|
|
19
|
+
|
|
20
|
+
Rules for the plan regime between the plan gate and the verification gate:
|
|
21
|
+
|
|
22
|
+
- **No new test files** — obligations wait in the ledger.
|
|
23
|
+
- **Existing tests broken by the plan's intended behavior change are updated to the new contract before any mid-plan commit** — the shared branch never carries a red suite, and an update is never a weakening (§ What earns a durable test).
|
|
24
|
+
- **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row; the behavior it belongs to is already in the ledger. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it with its regression test now — deferring it to the gate loses "fails before", the property the regime exists to capture — or, when not fixing it now, send it to the backlog via Out-of-Scope Discovery. Never fix silently.
|
|
25
|
+
- **The ledger is amendable while the plan is open** — a boundary finding or a newly promised behavior appends a row; the gate discharges whatever the ledger holds at gate time.
|
|
26
|
+
- **A mid-plan commit is a checkpoint, not a verification claim.** It may ship deliberately unverified code; the gate, not the commit, is the verification event for plan work.
|
|
27
|
+
|
|
28
|
+
## The gate
|
|
29
|
+
|
|
30
|
+
**The gate is a discrete, user-triggered step.** When implementation is complete, report it and offer the gate — never run it unbidden, and never flip `Status: Complete` without it. A plan with outstanding obligations stays open, whatever the code does.
|
|
31
|
+
|
|
32
|
+
- **Precondition: the ledger exists.** A plan with no Test Obligations section is blocked at the gate — run the `test-plan` skill on it first. Without this check an empty ledger passes vacuously and the gap surfaces only after the file is frozen.
|
|
33
|
+
- **Every row is discharged into exactly one outcome**: **satisfied** (the test exists and is green, or the driven check passed), **owes nothing** (with the reason — compiler-guarded, covered elsewhere), or **blocked** (the missing infrastructure named, the row converted to a backlog item so the debt outlives the frozen plan). A row left unexamined blocks the gate.
|
|
34
|
+
- **The gate's verdict is never delegated.** A sub-agent's summary is not verifiable ground truth, and where browser work is main-session-only (the root `CLAUDE.md` § Runtime Notes), the driving is too. Fan-out may prepare fixtures or draft test bodies; the driving and the verdict stay inline.
|
|
35
|
+
- **Abandonment does not erase debt.** Before `Status: Abandoned` freezes a plan whose code was committed, convert its undischarged rows into backlog items; uncommitted code owes nothing.
|
|
36
|
+
- **Report what happened, including failures.** A gate that reports green while a suite is red is worse than no gate; state the failing test and its output.
|
|
37
|
+
|
|
38
|
+
## The mechanism ladder
|
|
39
|
+
|
|
40
|
+
**Drive the real thing first, then pin what must not regress.** Ordering matters: driving finds the defects that matter to a user, and shows which behaviors are worth the permanent cost of a test.
|
|
41
|
+
|
|
42
|
+
| Rung | Mechanism | Proves |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| 0 | **Write the checklist** — `docs/tests/{feature}.md`, from the ledger and the LLD's promises | There is a stated behavior to drive against, and to trace a test back to |
|
|
45
|
+
| 1 | **Drive the real surface** — browser automation for web UI, the actual CLI binary, HTTP against the running worker | The change works in the product, against real wiring |
|
|
46
|
+
| 2 | **Pin the durable behaviors** as suite tests per [`testing.md`](testing.md) | The behavior survives the next change |
|
|
47
|
+
| 3 | **Run the affected suite**, plus the project's e2e smoke gate where one is wired | Nothing else broke |
|
|
48
|
+
|
|
49
|
+
- **Rung 0 is what makes 1 and 2 repeatable.** The checklist is the script rung 1 executes and the menu rung 2 selects from — one `**Assert**` per observable, and the section records which test now guards it (or that none does, and why). Derived after the driving it is a report; derived before, it is the only artifact that survives the session and still says what the feature promises. Its shape is the `documentation` skill's `templates/behavioral-checklist.md`.
|
|
50
|
+
- **A failing checklist assertion is never softened to make a run green.** The checklist states the contract; a run that fails records the defect and sends it to the backlog.
|
|
51
|
+
- **Browser automation is the default for a web surface, and needs no permission to use** — a rendered page driven through real interaction is the only oracle that catches wiring, styling, and state defects together.
|
|
52
|
+
- **Where the runtime offers no browser automation**, rung 1's verdict belongs to the user: emit a browser-verification checklist (URLs, actions, expected outcomes), the user runs it and reports, the result lands in the changelog entry — and `Status: Complete` waits for it.
|
|
53
|
+
- **A driven check is evidence, not an artifact.** It proves the change works today; it leaves nothing behind. That is why rung 2 exists.
|
|
54
|
+
|
|
55
|
+
## What earns a durable test
|
|
56
|
+
|
|
57
|
+
**A test is a permanent maintenance cost, so it is bought deliberately** — the ledger names behaviors, and the gate decides which of them are worth pinning.
|
|
58
|
+
|
|
59
|
+
| Earns a suite test | Verified by driving alone |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| A promise an LLD makes about the feature's contract | Layout, spacing, copy — restated by a test, not protected by one |
|
|
62
|
+
| A bug that occurred once — its regression test | A one-off migration or backfill's output |
|
|
63
|
+
| An error path, race, or idempotency guarantee | Behavior a type or the compiler already makes unshippable |
|
|
64
|
+
|
|
65
|
+
- **A behavior that is compiler-guarded owes no test** — if it cannot ship green-but-broken, a test adds cost and no safety.
|
|
66
|
+
- **Never weaken, skip, or delete a test to mask an unexplained failure.** When a plan or LLD intentionally changes behavior, updating the affected tests to the new contract is part of that change.
|
|
67
|
+
- **Throwaway checks are not tests.** Temporary scripts written to drive a change live in scratch space and are deleted — never committed into the test tree.
|