@nurix/etna 0.18.20 → 0.18.22
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/README.md +1 -1
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/CLAUDE.md +3 -3
- package/data/harnesses/code/agents/brainstorm.md +1 -1
- package/data/harnesses/code/agents/maintenance.md +8 -7
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/rules/database.md +38 -0
- package/data/harnesses/code/rules/express.md +28 -0
- package/data/harnesses/code/rules/frontend.md +14 -0
- package/data/harnesses/code/rules/general.md +2 -40
- package/data/harnesses/code/rules/nomenclature.md +1 -8
- package/data/harnesses/code/rules/nustack.md +150 -0
- package/data/harnesses/code/skills/brainstorm/README.md +4 -4
- package/data/harnesses/code/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/code/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/code/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/code/skills/design/SKILL.md +14 -11
- package/data/harnesses/code/skills/design/data/catalog/rules.csv +4 -4
- package/data/harnesses/code/skills/design/data/combinations/Readme.md +29 -0
- package/data/harnesses/code/skills/design/data/combinations/charts.csv +33 -0
- package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +437 -0
- package/data/harnesses/code/skills/design/data/combinations/icons.csv +157 -0
- package/data/harnesses/code/skills/design/data/combinations/landing.csv +38 -0
- package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +2001 -0
- package/data/harnesses/code/skills/design/data/combinations/manifest.json +283 -0
- package/data/harnesses/code/skills/design/data/combinations/palettes.csv +49 -0
- package/data/harnesses/code/skills/design/data/combinations/product-router.csv +80 -0
- package/data/harnesses/code/skills/design/data/combinations/styles.csv +54 -0
- package/data/harnesses/code/skills/design/data/combinations/typography.csv +61 -0
- package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +27 -238
- package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +1 -82
- package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/apple.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/binance.md +4 -87
- package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +7 -86
- package/data/harnesses/code/skills/design/data/design-md/library/cal.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/clay.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +3 -84
- package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +10 -91
- package/data/harnesses/code/skills/design/data/design-md/library/composio.md +2 -84
- package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +3 -85
- package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +7 -90
- package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -80
- package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -80
- package/data/harnesses/code/skills/design/data/design-md/library/framer.md +5 -85
- package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +9 -91
- package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -115
- package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +5 -85
- package/data/harnesses/code/skills/design/data/design-md/library/meta.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +3 -84
- package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/miro.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/notion.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +6 -87
- package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +9 -91
- package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +5 -88
- package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/library/resend.md +4 -119
- package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -82
- package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +3 -86
- package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +13 -94
- package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/slack.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +13 -94
- package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +4 -86
- package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +6 -86
- package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +12 -93
- package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +11 -91
- package/data/harnesses/code/skills/design/data/design-md/library/uber.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +11 -126
- package/data/harnesses/code/skills/design/data/design-md/library/warp.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +3 -83
- package/data/harnesses/code/skills/design/data/design-md/library/wired.md +10 -91
- package/data/harnesses/code/skills/design/data/design-md/library/wise.md +7 -90
- package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/nurix.md +4 -87
- package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +580 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +954 -0
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +949 -0
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +962 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +973 -0
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +954 -0
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +963 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +981 -0
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +962 -0
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +959 -0
- package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +251 -0
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +978 -0
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +982 -0
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +589 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +977 -0
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +950 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +976 -0
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +904 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +957 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +945 -0
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +613 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +956 -0
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +980 -0
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +957 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +974 -0
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +973 -0
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +966 -0
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +961 -0
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +977 -0
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +991 -0
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +966 -0
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +988 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +602 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +974 -0
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +988 -0
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +978 -0
- package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +1 -1
- package/data/harnesses/code/skills/design/references/create.md +14 -9
- package/data/harnesses/code/skills/design/references/diagnosis.md +1 -1
- package/data/harnesses/code/skills/design/references/hard-rules.md +4 -4
- package/data/harnesses/code/skills/design/references/improve.md +11 -9
- package/data/harnesses/code/skills/design/references/introspect.md +1 -1
- package/data/harnesses/code/skills/design/references/personality.md +337 -413
- package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +1032 -0
- package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +596 -296
- package/data/harnesses/code/skills/design/scripts/{detector.mjs → lib/checks.mjs} +145 -140
- package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +26 -0
- package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +105 -37
- package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +60 -73
- package/data/harnesses/code/skills/design/scripts/render-rung.mjs +1 -1
- package/data/harnesses/code/skills/design/scripts/scaffold.mjs +1 -1
- package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +205 -37
- package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +68 -0
- package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +314 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/code/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/code/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/code/skills/documentation/references/templates.md +306 -52
- package/data/harnesses/etna/CLAUDE.md +3 -3
- package/data/harnesses/etna/agents/brainstorm.md +1 -1
- package/data/harnesses/etna/agents/maintenance.md +8 -7
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/rules/general.md +2 -40
- package/data/harnesses/etna/rules/nomenclature.md +1 -8
- package/data/harnesses/etna/skills/brainstorm/README.md +4 -4
- package/data/harnesses/etna/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/etna/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/etna/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/etna/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/etna/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/etna/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/etna/skills/documentation/references/templates.md +306 -52
- package/data/harnesses/mobile/CLAUDE.md +3 -3
- package/data/harnesses/mobile/agents/brainstorm.md +1 -1
- package/data/harnesses/mobile/agents/maintenance.md +8 -7
- package/data/harnesses/mobile/harness.json +2 -2
- package/data/harnesses/mobile/rules/database.md +38 -0
- package/data/harnesses/mobile/rules/general.md +2 -40
- package/data/harnesses/mobile/rules/nomenclature.md +1 -8
- package/data/harnesses/mobile/rules/nustack.md +150 -0
- package/data/harnesses/mobile/skills/brainstorm/README.md +4 -4
- package/data/harnesses/mobile/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/mobile/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/mobile/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/mobile/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/mobile/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/mobile/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/mobile/skills/documentation/references/templates.md +306 -52
- package/package.json +1 -1
- package/data/harnesses/code/skills/design/scripts/hook-config.json +0 -11
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Database
|
|
2
|
+
|
|
3
|
+
Fixed conventions for relational schemas — table/column/index **names**, the **key vocabulary** (`id` / `slug` / `label`), column types, and Drizzle mirrors — so the same concept carries the same name in **every** Nurix project. This is a cross-project consistency rule: **one concept, one name, everywhere** — never `slug` in one repo and `handle` / `key` / `code` in another. 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
|
+
## Keys & the shared vocabulary
|
|
8
|
+
|
|
9
|
+
Three column roles are fixed across every table and every project:
|
|
10
|
+
|
|
11
|
+
- **`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` are ❌). 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.
|
|
12
|
+
- **`slug`** — the **stable key other rows reference**: `UNIQUE`, lowercase `snake_case`. **Foreign keys point at `slug`, not `id`.** One concept = one slug name across every table and repo. ❌ Never rename this role `handle`, `key`, `code`, or `name` in a different project — it is always `slug`.
|
|
13
|
+
- **`label`** — the **human display name**. Always `label` — ❌ never `name`, `title`, or `display_name`.
|
|
14
|
+
|
|
15
|
+
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`).
|
|
16
|
+
|
|
17
|
+
- **Enforced** (the referenced row must exist) → a real `FOREIGN KEY (<x>_slug) REFERENCES <table>(slug)`.
|
|
18
|
+
- **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.
|
|
19
|
+
|
|
20
|
+
## Naming
|
|
21
|
+
|
|
22
|
+
- **Tables** — `snake_case`, plural noun for what they hold (`users`, `apps`, `devices`).
|
|
23
|
+
- **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.
|
|
24
|
+
- **Columns** — `snake_case`; booleans `is_*` / `has_*`; timestamps `created_at` / `updated_at`; foreign keys `<entity>_id`.
|
|
25
|
+
- **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`).
|
|
26
|
+
- **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.
|
|
27
|
+
|
|
28
|
+
## Column types (SQLite / D1)
|
|
29
|
+
|
|
30
|
+
- **Timestamps** — `created_at` + `updated_at`, both `TEXT NOT NULL DEFAULT (datetime('now'))`, on **every** table — except append-only logs, which carry only `created_at`.
|
|
31
|
+
- **Booleans** — `INTEGER`, named `is_*` / `has_*` (Drizzle `integer(…, { mode: "boolean" })`).
|
|
32
|
+
- **JSON** — `TEXT` (Drizzle `text(…, { mode: "json" })`).
|
|
33
|
+
|
|
34
|
+
## Vocabulary / lookup tables
|
|
35
|
+
|
|
36
|
+
A controlled-vocabulary table (statuses, kinds, categories) follows a fixed shape: `id` (UUID) · `slug` (UNIQUE) · `label` · optional `description` · `status` · timestamps.
|
|
37
|
+
|
|
38
|
+
- **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 is ❌ — regenerate it.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# General Standards
|
|
2
2
|
|
|
3
|
+
Runtime versions and the canonical package list — the workspace baseline every Nurix code harness loads. Web-frontend/styling conventions are [`frontend.md`](frontend.md); the Express server and the API response envelope are [`express.md`](express.md).
|
|
4
|
+
|
|
3
5
|
## Runtime Versions
|
|
4
6
|
|
|
5
7
|
- **Node.js:** 22 LTS (latest)
|
|
@@ -45,43 +47,3 @@ No alternatives. Just use these.
|
|
|
45
47
|
| fast-deep-equal | ^3.1.3 | Deep equality checks | lodash.isEqual |
|
|
46
48
|
| @ngneat/falso | latest | Fake data generation | @faker-js/faker, chance |
|
|
47
49
|
| pino | ^10.1.0 | Logging | winston |
|
|
48
|
-
|
|
49
|
-
## Frontend
|
|
50
|
-
|
|
51
|
-
Tailwind v4 + shadcn-based UI; conventions below.
|
|
52
|
-
|
|
53
|
-
- **Build every UI through the `design` skill** — route the brief through it instead of hand-rolling layouts; it owns the archetype, personality tokens, and `@nurix/components` wiring.
|
|
54
|
-
- **Light mode is the default** — design for the light theme as the default; dark mode is opt-in, never the default.
|
|
55
|
-
- **@nurix/\* are restricted-scope npm packages** — installed from the npm registry, auto-authed by a read token in `~/.npmrc`. Just attempt the install; the token authenticates you automatically. Don't pre-empt or second-guess it. If the install actually fails, flag it to the user — never reach for alternatives, a substitute package, or `npm login`.
|
|
56
|
-
- **@nurix/components** — the UI component library (restricted-scope npm package, pre-built); import by subpath, e.g. `@nurix/components/button`.
|
|
57
|
-
- No components.json / shadcn CLI scaffold (.tsx, not .jsx) — consume the prebuilt library; never `npx shadcn add`.
|
|
58
|
-
- 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 — keep one hook dispatcher).
|
|
59
|
-
- Tailwind v4, CSS-only (no tailwind.config.js, no PostCSS): styling runs through the `@tailwindcss/vite` plugin.
|
|
60
|
-
- CSS entry `globals.css`, imports in order — `@import "./personality.css"` (token source) → `@import "tailwindcss"` → the library's `styles.css` — then `@theme inline {…}` mapping vars to tokens.
|
|
61
|
-
- Tokens: CSS vars in `:root, :root[data-theme="light"]` + the archetype selector `[data-style="…"]` (personality.css), consumed as semantic Tailwind tokens (bg-card, text-foreground). Honor the archetype's radius/theme decisions (e.g. re-assert `--radius-*` to 0 for a flat archetype; add `@custom-variant dark` only if the project opts into dark mode, and keep light as the default). The library bundles class-variance-authority, clsx, tailwind-merge.
|
|
62
|
-
- Plus general styling rules (spacing in 2/4/6/8, object-cover, truncate, motion, color tokens — never hardcoded hex in components).
|
|
63
|
-
|
|
64
|
-
## Express 5.x
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
app.use(cors({ origin: process.env.FRONTEND_URL }));
|
|
68
|
-
app.use(compression());
|
|
69
|
-
app.use(express.json({ limit: '10mb' }));
|
|
70
|
-
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
- Middleware order: body parsers → custom middleware → routes → error handlers (centralized, last). Auth via middleware. Use Express Router for modular routes.
|
|
74
|
-
|
|
75
|
-
## API Response Format
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"status": 1,
|
|
80
|
-
"message": "Message sent successfully",
|
|
81
|
-
"data": { "delivered": [{ "user@example.com": 2 }] }
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Error: `{ "status": 0, "message": "Error description", "data": null }`
|
|
86
|
-
|
|
87
|
-
HTTP codes: `200`, `201` (created), `400`, `401` (not authenticated), `403` (not authorized), `404`, `500`
|
|
@@ -31,11 +31,4 @@
|
|
|
31
31
|
|
|
32
32
|
## Database
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **Tables** : snake_case. Entity / hub tables use the plural noun for the thing they hold. Examples: `users`, `apps`, `devices`, `services`.
|
|
37
|
-
- **Junction (M:N) tables** : name a many-to-many join `<entityA>_<entityB>_map` — **always**, even when the join carries its own columns (a `role`, a secret, a status). The `_map` suffix is the signal that a row is a relationship, not an entity; extra attributes on the join do **not** earn it a standalone noun. Use the **singular** stem of each side, owning/anchor entity first (mirror the existing tables — `app_*`). Examples: `app_user_map` (apps ⨯ users), `app_device_map` (apps ⨯ devices), `app_service_map` (apps ⨯ services).
|
|
38
|
-
- ❌ Don't invent a "nice" noun for a junction — no `members`, `installs`, `memberships`, `enrolments`. A reviewer should read the table name and know both sides and that it's a join.
|
|
39
|
-
- **Columns** : snake_case. Foreign keys are `<entity>_id` (`user_id`, `app_id`, `device_id`, `service_id`). Booleans follow the boolean rule (`is_*`/`has_*`); timestamps are `created_at` / `updated_at`.
|
|
40
|
-
- **Indexes** : `<table>_<col(s)>_idx`; unique indexes `<table>_<col(s)>_unique`. The composite unique on a junction reads `<table>_<colA>_<colB>_unique` — e.g. `app_user_map_app_user_unique`, `app_device_map_device_app_unique`.
|
|
41
|
-
- **Drizzle mirror** : the exported table object is the camelCase of the snake_case table name (`app_user_map` → `appUserMap`); column TS properties are the camelCase of the column (`created_at` → `createdAt`, `service_key` → `serviceKey`). The snake_case string passed to `sqliteTable("…")` and every index name must match `seed/init.sql` exactly (the G1 schema-parity boundary).
|
|
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), the cross-project database conventions rule. Kept there, not here, so there is one canonical home and the same concept carries the same name in every project.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Nustack — `@nurix/*` Packages: naming, monorepo layout, and publishing
|
|
2
|
+
|
|
3
|
+
How a `@nurix/*` multi-package repo is **named**, **structured**, and **shipped**. For consuming an already-published `@nurix/*` package (auth, install, imports), see the Consuming section of [`typescript.md`](typescript.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Package naming
|
|
8
|
+
|
|
9
|
+
Every workspace package is scoped to **`@nurix/`**. The segment after the scope encodes **intent** — the dot vs. hyphen is semantic, not cosmetic:
|
|
10
|
+
|
|
11
|
+
| Form | Meaning | Examples |
|
|
12
|
+
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
13
|
+
| `@nurix/workflows-sdk` (hyphen, single segment) | The **published, externally-destined** surface. A clean `@nurix/*` name is a published _contract_ — changing an export or peer dep is a breaking change for consumers outside this repo. | `@nurix/workflows-sdk` |
|
|
14
|
+
| `@nurix/workflows.<name>` (dot separator) | **Internal** to the workflows product — `private: true`, refactor freely, no external consumers. | `@nurix/workflows.agent-core`, `.worker`, `.gateway`, `.secrets`, `.connector`, `.playground`, `.playground-tests` |
|
|
15
|
+
| `@nurix/<name>` (plain, no `workflows` prefix) | Cross-repo **shared libs** owned _elsewhere_ and merely consumed here — never renamed. | `@nurix/contracts`, `@nurix/components` |
|
|
16
|
+
|
|
17
|
+
- The `<name>` segment is always **kebab-case** (`agent-core`, `playground-tests`).
|
|
18
|
+
- The dot is **not** a path separator, so subpath exports still resolve: `@nurix/workflows.agent-core/nodes`.
|
|
19
|
+
- The dot tracks "internal product package," not the `private` flag exactly — `@nurix/workflows.secrets` is `private: false` because it's extraction-bound (slated to move to a sibling repo/namespace), yet still wears the dotted internal name. Today `-sdk` is the only clean published form.
|
|
20
|
+
|
|
21
|
+
**Naming a new package:** internal to this repo? → `@nurix/workflows.<thing>`, `private: true`, kebab-case `<thing>` (the default). Externally consumed contract? → clean `@nurix/<thing>` (rare). Shared lib from another repo? → keep its existing `@nurix/<name>`.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. Monorepo & package boundaries
|
|
26
|
+
|
|
27
|
+
One `tsconfig.base.json` at the repo root is the **single owner of TS policy** — the strict set (see [`typescript.md`](typescript.md)), `target`, and any option uniform across packages (here, `module`/`moduleResolution`). Each package's `tsconfig.json` is thin: it `extends` the base, then adds only its own *coordinates* (`rootDir`/`outDir`/`include`) and genuine *environment* overrides (`lib`/`types`/`jsx`, plus `module`/`moduleResolution` when a package's module system genuinely differs — a Worker, browser, or NodeNext package). That is environment, not policy. Never re-declare or weaken a *policy* option locally (no per-package `strict: false`, no widening `noUncheckedIndexedAccess`). A framework that owns its own base (e.g. an Astro app on `astro/tsconfigs/strict`) is the one allowed exception.
|
|
28
|
+
|
|
29
|
+
- **Internal packages are source-first.** A `private: true` workspace package exposes its API through the `exports` field pointing at TypeScript source (`"types"`/`"default"` → `./src/index.ts`) — consumed across the workspace with **no build step**. Prefer the `exports` field; don't add a bare `main`/`module` to new packages. Add one typed subpath per public surface (`"./nodes": { "types": "./src/nodes/index.ts", "default": "./src/nodes/index.ts" }`); consumers import the subpath, **never** a deep relative path into another package's `src/`.
|
|
30
|
+
- **Published packages build to `dist` — never ship raw `src`.** The moment a package crosses a publish boundary (`private: false`), it compiles with `tsc` (`declaration: true`, `declarationMap: true` from the base), ships `files: ["dist"]`, and points `exports`/`types` at `./dist/*` (use `publishConfig.exports` to swap source→dist on publish if the dev entry stays on source). `prepublishOnly` runs the build.
|
|
31
|
+
- **Declare host singletons as `peerDependencies`** on published libraries (`react`, `react-dom`, the framework client) so consumers keep one copy; never bundle them. Apps depend on them directly.
|
|
32
|
+
- **Single-source shared dep versions with pnpm `catalog:`** — `typescript`, `zod`, `vitest`, `react`, type packages. One version per dependency across the workspace so every package's types resolve identically; no per-manifest version drift.
|
|
33
|
+
- **Reach for TS project references only when it hurts** — adopt `references` once the typecheck/build graph is slow enough to feel. Until then, `pnpm -r typecheck` over independent `extends` configs is the correct default.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. Publishing & the release pipeline
|
|
38
|
+
|
|
39
|
+
`@nurix/*` packages publish to **npmjs.org with `restricted` access** — only npm users with read rights to the `nurix` org can install them. Reference implementations: `~/dev/components` (`@nurix/components`, library) and `~/dev/etna/packages/cli` (`@nurix/etna`, CLI).
|
|
40
|
+
|
|
41
|
+
### 3.1 Prerequisites (one-time, org-wide)
|
|
42
|
+
|
|
43
|
+
1. **npm org `nurix`** exists and you're a member with publish rights — <https://www.npmjs.com/settings/nurix/packages>.
|
|
44
|
+
2. **An npm automation token** with `Read and write` for the `nurix` scope — npm → Generate New Token → Automation.
|
|
45
|
+
3. **The token added as a GitHub Actions secret** named `NPM_PUBLISH_TOKEN` on every publishing repo. `NPM_PUBLISH_TOKEN` is the convention; pick another name only with a strong reason.
|
|
46
|
+
|
|
47
|
+
### 3.2 `package.json` — required fields
|
|
48
|
+
|
|
49
|
+
```jsonc
|
|
50
|
+
{
|
|
51
|
+
"name": "@nurix/<package-name>", // The scope makes it discoverable to org members.
|
|
52
|
+
"version": "0.1.0", // Start at 0.1.0; the workflow bumps from here.
|
|
53
|
+
"private": false, // MUST be false (or omitted). `npm publish` refuses if true.
|
|
54
|
+
"publishConfig": { "access": "restricted" }, // Scoped + private: only org members can install.
|
|
55
|
+
"files": ["dist"] // Whitelist of what ships. Anything outside is excluded.
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- **`publishConfig.access`** — `"restricted"` (recommended): visible only to `nurix`-org readers. `"public"`: world-readable (free, but only if you mean it). Omitting it on a scoped package defaults to `restricted`; be explicit anyway.
|
|
60
|
+
- **`files`** — without it, npm publishes everything not in `.gitignore`, **including source**. Library → `["dist"]`; CLI (etna) → `["bin/", "data/", "README.md"]`. Don't list `package.json`/`README.md` — npm always includes them.
|
|
61
|
+
- **Build hooks** — `prepack` for build steps that must produce files in `files` (also runs on install-as-git-dep); `prepublishOnly` for publish-only steps. Either alone is fine; `@nurix/components` runs both.
|
|
62
|
+
- **Other useful fields** — `type: "module"`, `engines.node`, `bin` (CLIs), `main`/`module`/`types`/`exports` (libraries), `sideEffects: ["**/*.css"]`, `repository` (with `directory` for monorepos), `license: "UNLICENSED"`.
|
|
63
|
+
|
|
64
|
+
### 3.3 The publish workflow (generic template)
|
|
65
|
+
|
|
66
|
+
The dual-trigger pattern: a push to the default branch auto-ships a patch; a manual dispatch picks minor/major.
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
name: Publish to npm
|
|
70
|
+
on:
|
|
71
|
+
push:
|
|
72
|
+
branches: [dev] # your default branch
|
|
73
|
+
paths: # ONLY paths that change what ships — else every README edit publishes
|
|
74
|
+
- 'src/**'
|
|
75
|
+
- 'scripts/**'
|
|
76
|
+
- 'package.json'
|
|
77
|
+
- 'package-lock.json'
|
|
78
|
+
- '.github/workflows/publish.yml'
|
|
79
|
+
workflow_dispatch:
|
|
80
|
+
inputs:
|
|
81
|
+
bump: { description: 'Version bump', type: choice, options: [patch, minor, major], default: patch }
|
|
82
|
+
permissions: { contents: write } # push the version-bump commit + tag
|
|
83
|
+
concurrency: { group: publish, cancel-in-progress: false } # monorepo: group: publish-<pkg>
|
|
84
|
+
jobs:
|
|
85
|
+
publish:
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@v5
|
|
89
|
+
with: { fetch-depth: 0, token: '${{ secrets.GITHUB_TOKEN }}' }
|
|
90
|
+
- uses: actions/setup-node@v5
|
|
91
|
+
with: { node-version: 22, registry-url: 'https://registry.npmjs.org' } # writes .npmrc using $NODE_AUTH_TOKEN
|
|
92
|
+
- run: npm ci # skip ONLY if the build is pure-Node with no deps (e.g. @nurix/etna)
|
|
93
|
+
- run: |
|
|
94
|
+
git config user.name "github-actions[bot]"
|
|
95
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
96
|
+
- run: npm version ${{ inputs.bump || 'patch' }} -m "chore: release v%s [skip ci]"
|
|
97
|
+
- run: npm publish # prepublishOnly / prepack runs the build
|
|
98
|
+
env: { NODE_AUTH_TOKEN: '${{ secrets.NPM_PUBLISH_TOKEN }}' }
|
|
99
|
+
- run: git push --follow-tags # pushes the bump commit AND the v<version> tag npm created
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Why dual-trigger is safe** — three safeguards prevent an infinite publish loop: (1) `paths:` scopes the push trigger to artifact-affecting files; (2) `[skip ci]` in the bump commit makes GitHub skip the workflow that bump would otherwise re-trigger; (3) `concurrency: cancel-in-progress: false` queues near-simultaneous merges instead of racing for a version number.
|
|
103
|
+
|
|
104
|
+
**`registry-url` is load-bearing** — without `registry-url: https://registry.npmjs.org` on `setup-node`, it never writes the `.npmrc` line that uses `$NODE_AUTH_TOKEN`, and the publish falls back to anonymous auth and fails.
|
|
105
|
+
|
|
106
|
+
### 3.4 The three ways to ship
|
|
107
|
+
|
|
108
|
+
- **A. Auto on merge (common).** Land on the default branch; if a `paths:`-filtered file changed, the workflow fires and ships a patch.
|
|
109
|
+
- **B. Manual dispatch (minor/major).** **Actions → Publish to npm → Run workflow**, pick `bump = minor|major`.
|
|
110
|
+
- **C. Local (CI down / one-off):** `npm version <patch|minor|major>` → `npm publish` → `git push --follow-tags`.
|
|
111
|
+
|
|
112
|
+
Local auth uses two tokens, two homes: a **read** token in `~/.npmrc` (`//registry.npmjs.org/:_authToken=…`) for `npm install`, and `NPM_PUBLISH_TOKEN` as an env var (sourced from `~/.zsh_secrets` or equivalent, **not** in `.npmrc` or the repo) for `npm publish`.
|
|
113
|
+
|
|
114
|
+
> **Agent guard — if `NPM_PUBLISH_TOKEN` isn't in the environment, do not work around it.** No `npm login` to swap the user's auth, no rewriting `~/.npmrc`, no substituting the read token (it lacks publish rights → `403`), no `--registry` overrides, no temp-file token. Instead **stop and report**: "This repo can't publish locally — `NPM_PUBLISH_TOKEN` isn't set. Source `~/.zsh_secrets` (or wherever you keep it) and re-run, or trigger the CI workflow." Some users publish exclusively from CI — that's the default path for a reason.
|
|
115
|
+
|
|
116
|
+
Verify after any flow: `https://www.npmjs.com/package/@nurix/<name>` and a clean-dir `npx @nurix/<name>@latest`.
|
|
117
|
+
|
|
118
|
+
### 3.5 Monorepo deviations
|
|
119
|
+
|
|
120
|
+
When the package lives in `packages/<pkg>/` of a multi-package repo:
|
|
121
|
+
|
|
122
|
+
- **`working-directory: packages/<pkg>`** on the bump and publish steps so they operate on the right `package.json`.
|
|
123
|
+
- **Scoped concurrency** — `group: publish-<pkg>` lets sibling packages publish in parallel.
|
|
124
|
+
- **Tag prefix — only with multiple tagging packages.** `npm version --tag-version-prefix="<pkg>-v"` (→ `<pkg>-v0.2.0`) is worth it only when more than one package cuts release tags, so they don't collide. A single publishable package (etna's case, even though it's laid out as a monorepo) uses plain `v0.2.0`.
|
|
125
|
+
|
|
126
|
+
A repo with one publishable package only needs `working-directory`; skip the prefix, and concurrency scoping is optional.
|
|
127
|
+
|
|
128
|
+
### 3.6 Common pitfalls
|
|
129
|
+
|
|
130
|
+
- **402 Payment Required** — `access: "public"` on an org without a plan for free public scoped packages. Use `"restricted"` (or upgrade the plan).
|
|
131
|
+
- **403 Forbidden** — `NPM_PUBLISH_TOKEN` missing/wrong, or its user lacks `nurix` write access, or it's a read-only (not Automation) token.
|
|
132
|
+
- **"Cannot publish over previously published version x.y.z"** — a bump ran but publish failed and was re-run without rebasing. `git reset` the bump and let CI re-bump, or `npm version patch && git push --follow-tags && npm publish`.
|
|
133
|
+
- **Publish succeeds but `npx @nurix/foo` is "command not found"** — no `bin` field, or `bin` points outside `files`, or the script is missing its `#!/usr/bin/env node` shebang.
|
|
134
|
+
- **"Git working directory not clean" on `npm version`** — the checkout has untracked/modified files; build only into `.gitignore`d paths (the components repo builds into `dist/`).
|
|
135
|
+
- **Published tarball contains source** — missing `files` in `package.json`. Add `["dist"]` and republish.
|
|
136
|
+
- **Auto-publish fires too often** — no `paths:` filter or one that's too broad. Tighten it to artifact-affecting files, or drop the push trigger for `workflow_dispatch`-only.
|
|
137
|
+
- **Workflow loops forever** — the bump commit lacks `[skip ci]`. Invoke `npm version` with `-m "chore: release v%s [skip ci]"`.
|
|
138
|
+
- **A normal commit silently skips its own push** — the inverse trap. GitHub scans the head commit's **whole message** (subject _and_ body) for skip directives (`[skip ci]`, `[ci skip]`, `[no ci]`, `[skip actions]`, `***NO_CI***`). If any hand-written commit merely _mentions_ the literal token in prose, the entire push is skipped and the publish never fires (symptom: branch moved, paths matched, Actions on — yet zero runs for the SHA). Never write the literal token in a commit message or PR body unless you mean it; to ship a push that carried it by accident, re-trigger via **Run workflow** / `gh workflow run … --ref dev`.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 4. Quick checklist for a new `@nurix/*` package
|
|
143
|
+
|
|
144
|
+
- [ ] `package.json`: `name: "@nurix/X"`, `version: "0.1.0"`, `private: false`, `publishConfig.access: "restricted"`, `files: [...]`
|
|
145
|
+
- [ ] Build step wired into `prepack` (or `prepublishOnly`)
|
|
146
|
+
- [ ] Name follows §1; if it's a workspace member, boundaries follow §2
|
|
147
|
+
- [ ] `.github/workflows/publish.yml` from §3.3
|
|
148
|
+
- [ ] `NPM_PUBLISH_TOKEN` secret added to the repo
|
|
149
|
+
- [ ] First publish from local (`npm publish`) to verify the pipeline, then a no-op commit to verify CI
|
|
150
|
+
- [ ] README notes the `@nurix` scope so consumers know they need org access
|
|
@@ -128,13 +128,13 @@ The writing posture is a **mode** chosen at intake, folded into `build.md`:
|
|
|
128
128
|
|
|
129
129
|
## Exit artifacts
|
|
130
130
|
|
|
131
|
-
The session writes a
|
|
131
|
+
The session writes a design record at `docs/research/{topic}-brainstorming/` (one folder per topic), moved to `docs/history/brainstorms/{topic}/` on harvest. At `stop`, after the final five-source sync (self-containment included — the record is verified standalone-readable exactly when it's about to become the only survivor of the session), the skill _offers_ what to **publish** from it (`AskUserQuestion`, multi-select — a session can emit more than one):
|
|
132
132
|
|
|
133
133
|
- **Source of truth** — one consolidated, README-style canonical doc for the thing designed (`templates/source-of-truth.md`); lands in the repo's feature/architecture doc home, else a topic `Readme.md`.
|
|
134
134
|
- **Plans** — one or more executable plan docs → `docs/history/plans/` (Status: Draft).
|
|
135
|
-
- **Harvest into the living docs** — conclusions dispersed by scope into
|
|
135
|
+
- **Harvest into the living docs** — conclusions dispersed by scope into ADs (architecture decisions), the domain model, and the backlog.
|
|
136
136
|
|
|
137
|
-
The
|
|
137
|
+
The session record is **kept** whichever you pick — never deleted; on harvest it moves to `docs/history/brainstorms/{topic}/` as the provenance every artifact traces back to. See `exit-artifacts.md`.
|
|
138
138
|
|
|
139
139
|
---
|
|
140
140
|
|
|
@@ -159,4 +159,4 @@ brainstorm/ # the skill (in .claude/skills/)
|
|
|
159
159
|
└── templates/ # pillar templates + evidence.md + source-of-truth.md, used in the record and at stop
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
The session itself is written to `docs/
|
|
162
|
+
The session itself is written to `docs/research/{topic}-brainstorming/` (committed; moved to `docs/history/brainstorms/{topic}/` on harvest) — not here.
|
|
@@ -42,6 +42,8 @@ Write as if the transcript is already deleted — it will be. The folder must le
|
|
|
42
42
|
|
|
43
43
|
## `start`
|
|
44
44
|
|
|
45
|
+
First, consult the two indexes — never scan folders. `docs/research/Readme.md` lists **active** sessions; `docs/history/brainstorms/Readme.md` lists **harvested** ones. Match the topic against both: an active match → resume it (§3, reusing its folder); a harvested match → surface that prior exploration and ask whether to reopen it (move the folder back to `docs/research/{topic}-brainstorming/`) or branch a fresh topic; no match → a new session. Then:
|
|
46
|
+
|
|
45
47
|
### 1. The entry gate
|
|
46
48
|
|
|
47
49
|
A session needs substance before it opens. Ask for a **basis**: a reference document (path or URL), or a one-shot brain dump of the whole idea, right now, in prose.
|
|
@@ -62,7 +64,7 @@ Then propose the **aspect map**: the thinking dimensions for _this specific idea
|
|
|
62
64
|
|
|
63
65
|
### 3. Bootstrap
|
|
64
66
|
|
|
65
|
-
Session folder: `docs/
|
|
67
|
+
Session folder: `docs/research/{topic}-brainstorming/` — a **committed** design record, one folder per design topic (slug the topic; confirm it in one line). Add a row to the `docs/research/Readme.md` index. Resume an existing topic by reusing its folder if it already holds a `state.md`. The record lives here while the session is active; on close **and** harvest it moves to `docs/history/brainstorms/{topic}/` as the provenance the exit artifacts distil from (see `stop` and `exit-artifacts.md`). Create only the pillars the complexity calls for, from `templates/` (never overwrite existing files; if a template is missing, create the file from the field lists in **Pillars**). `basis/` holds the frozen inputs; `evidence/` materializes on the first session-produced analysis (memory contract, rule 3). Write top-level `state.md`:
|
|
66
68
|
|
|
67
69
|
```
|
|
68
70
|
STATE: open
|
|
@@ -136,8 +138,8 @@ Zero means _"audited against the five sources and clean"_ — never _"nothing ca
|
|
|
136
138
|
|
|
137
139
|
1. Run a final sync (wait for any in-flight sync first). It audits all five sources — self-containment included, so the record is verified standalone-readable exactly when it is about to become the only survivor of the session.
|
|
138
140
|
2. **Coherent** → say so and proceed. **Questions open** → list them plainly (English first, codes in parentheses) and offer per question: resolve now (mini-converge) / park explicitly (backlog or non-goals, with reason) / leave open and stop anyway — the folder keeps full state and resumes exactly where it left off. Flag parked **self-containment** gaps distinctly: parking one means the record ships not fully standalone.
|
|
139
|
-
3. **Publish exit artifacts** — see `exit-artifacts.md`. Offer the choice (`AskUserQuestion`, multi-select): a **source of truth** (one consolidated README-style doc — the standing reference for the thing designed), **plans** (executable work → `docs/history/plans/`), and/or **harvest into the living docs** (conclusions dispersed by scope into
|
|
140
|
-
4. Write `STATE: closed` + one-line reason. Print: _"Run `/brainstorm start` to resume."_
|
|
141
|
+
3. **Publish exit artifacts** — see `exit-artifacts.md`. Offer the choice (`AskUserQuestion`, multi-select): a **source of truth** (one consolidated README-style doc — the standing reference for the thing designed), **plans** (executable work → `docs/history/plans/`), and/or **harvest into the living docs** (conclusions dispersed by scope into ADs — architecture decisions — the domain model, the backlog). The session record is **kept** (committed) whichever you pick — it is the provenance every artifact traces back to and the seed the next session resumes from.
|
|
142
|
+
4. Write `STATE: closed` + one-line reason. If the harvest is complete (conclusions dispersed into the living docs), **move** the folder from `docs/research/{topic}-brainstorming/` to `docs/history/brainstorms/{topic}/` and update both indexes — drop its row from `docs/research/Readme.md`, add it to `docs/history/brainstorms/Readme.md`. If the session is only paused (questions parked, more to come), leave it in `docs/research/` and update its index row's status. Print: _"Run `/brainstorm start` to resume."_
|
|
141
143
|
|
|
142
144
|
## Conduct — holds for the whole session
|
|
143
145
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Exit artifacts
|
|
2
2
|
|
|
3
|
-
What `/brainstorm stop` publishes from a closed session. The
|
|
3
|
+
What `/brainstorm stop` publishes from a closed session. The session record is **kept
|
|
4
4
|
either way** — committed provenance, never a scratchpad. Exit artifacts copy the session's _conclusions_
|
|
5
|
-
outward into the form the work needs; the record stays as the source they trace back to
|
|
5
|
+
outward into the form the work needs; the record stays as the source they trace back to — and, once
|
|
6
|
+
harvested, moves from `docs/research/{topic}-brainstorming/` to `docs/history/brainstorms/{topic}/`.
|
|
6
7
|
|
|
7
8
|
At `stop`, after the final sync, **offer the artifact choice** (`AskUserQuestion`, multi-select — a session
|
|
8
9
|
can publish more than one):
|
|
@@ -21,7 +22,7 @@ does; pick it too if you want both the one-doc reference and the integrated head
|
|
|
21
22
|
|
|
22
23
|
One consolidated, README-style document — the canonical reference for the thing designed. Distil every
|
|
23
24
|
pillar into it: `thesis.md` → what it is; `domain-model.md` → how it works + parts; `decisions.md` →
|
|
24
|
-
present-tense rationale (no `D-N` codes, no options-considered — those stay in the record and
|
|
25
|
+
present-tense rationale (no `D-N` codes, no options-considered — those stay in the record and ADs);
|
|
25
26
|
`non-goals.md` + accepted tradeoffs → constraints; still-open questions → a one-line pointer back to the
|
|
26
27
|
record. Template: `templates/source-of-truth.md`.
|
|
27
28
|
|
|
@@ -44,19 +45,22 @@ not folders — a finding scoped to one module still lands in `docs/architecture
|
|
|
44
45
|
|
|
45
46
|
| Session source | Destination |
|
|
46
47
|
| --- | --- |
|
|
47
|
-
| Decisions (any scope) | one
|
|
48
|
+
| Decisions (any scope) | one AD per decision subject → `docs/architecture/decisions/AD-NNN-{slug}.md` (`documentation` skill AD template; `status:` frontmatter is the lifecycle source of truth; rejected alternatives → the AD's Options Considered table). A decision that revises an already-recorded subject does **not** mint a new AD — update that AD's body in place and append the revision to its Decision Changelog |
|
|
48
49
|
| `domain-model.md` | `docs/architecture/domain-model.md`; note any IA / cross-cutting contract change there — the `boundary` skill reads it from source at the next plan check |
|
|
49
|
-
| Doctrine / glossary / rejected | `docs/architecture/{domain-model,glossary}.md`, or the relevant
|
|
50
|
-
| `tech.md` deviations | `docs/architecture/references.md` or the relevant
|
|
50
|
+
| Doctrine / glossary / rejected | `docs/architecture/{domain-model,glossary}.md`, or the relevant AD |
|
|
51
|
+
| `tech.md` deviations | `docs/architecture/references.md` or the relevant AD |
|
|
51
52
|
| `non-goals.md` / `references.md` | `docs/architecture/{non-goals,references}.md` |
|
|
52
53
|
| `backlog.md` | `docs/history/backlog.md` (P0–P3) |
|
|
53
54
|
| Still-open questions | `docs/architecture/open-questions.md`, each with a _Resolution lands in_ pointer |
|
|
54
55
|
|
|
55
56
|
Append a changelog entry at `docs/history/changelog/YYYY-MM-DD-brainstorm-{slug}.md` listing what was published where.
|
|
56
57
|
|
|
57
|
-
## After publishing —
|
|
58
|
+
## After publishing — move the record to history
|
|
58
59
|
|
|
59
|
-
**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
**Move `docs/research/{topic}-brainstorming/` → `docs/history/brainstorms/{topic}/`, and update both
|
|
61
|
+
`Readme.md` indexes** (drop the row from `docs/research/Readme.md`, add it to
|
|
62
|
+
`docs/history/brainstorms/Readme.md`). The exit artifacts now carry the distilled conclusions; the record
|
|
63
|
+
itself is **kept** — never deleted — but as harvested provenance it belongs under `docs/history/brainstorms/`:
|
|
64
|
+
a traceable source for every published headline, and the seed the next `/brainstorm start` on this topic
|
|
65
|
+
resumes from. A session that is only **paused** (not harvested) stays in `docs/research/`. Retire a topic's
|
|
66
|
+
folder by hand only when the design line is truly dead.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> This is a **source-of-truth doc**: the standing, canonical reference for [thing]. Write it like a
|
|
4
4
|
> README — present tense, reader-first, the thing described as it _is_. It is **not a plan** (no steps,
|
|
5
5
|
> status, or sequencing — those go to `docs/history/plans/`) and **not the brainstorm record** (no
|
|
6
|
-
> `Q-N`/`D-N` codes, no "Why / How to apply" ledger, no rejected alternatives — those stay in
|
|
7
|
-
> `docs/
|
|
6
|
+
> `Q-N`/`D-N` codes, no "Why / How to apply" ledger, no rejected alternatives — those stay in the harvested
|
|
7
|
+
> record at `docs/history/brainstorms/{topic}/` and any ADs). One document; if a section outgrows it, link out, don't sprawl.
|
|
8
8
|
>
|
|
9
9
|
> **Placement.** In a repo with a feature-doc system this lands as `docs/features/{slug}.md` and carries
|
|
10
10
|
> that system's frontmatter (`owns:` / `module:` / `keywords:` / `status:`). Cross-cutting → `docs/architecture/{slug}.md`.
|
|
@@ -31,7 +31,7 @@ reader-first description. Prose and tables; a diagram only if it earns its token
|
|
|
31
31
|
|
|
32
32
|
[The load-bearing decisions, folded into present-tense rationale — "the index is single-writer because
|
|
33
33
|
concurrent writes corrupted it," not "we decided X over Y." No decision codes, no options-considered
|
|
34
|
-
table. The full rationale and the roads not taken live in the brainstorm record and
|
|
34
|
+
table. The full rationale and the roads not taken live in the brainstorm record and ADs — cite them,
|
|
35
35
|
don't reproduce them.]
|
|
36
36
|
|
|
37
37
|
## Constraints & non-goals
|
|
@@ -41,9 +41,9 @@ and what is explicitly out of scope.]
|
|
|
41
41
|
|
|
42
42
|
## Open questions
|
|
43
43
|
|
|
44
|
-
[One line pointing at `docs/
|
|
44
|
+
[One line pointing at `docs/history/brainstorms/{topic}/questions.md` if any remain open. Omit if none.]
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
_Distilled from `docs/
|
|
48
|
+
_Distilled from `docs/history/brainstorms/{topic}/`. That record holds the rationale, the rejected alternatives,
|
|
49
49
|
and the provenance for everything above._
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: documentation
|
|
3
|
-
description: Template & generator library for technical docs — the skill agents call to produce a doc from a template. Use to (1) document a feature or module (the feature doc is the feature's LLD — low-level design — written in LLD Mode), (2) create or update a changelog entry, (3) document data flows or Redux state, (4) add to protected files, (5) record an architecture decision (
|
|
3
|
+
description: Template & generator library for technical docs — the skill agents call to produce a doc from a template. Use to (1) document a feature or module (the feature doc is the feature's LLD — low-level design — written in LLD Mode), (2) create or update a changelog entry, (3) document data flows or Redux state, (4) add to protected files, (5) record or revise an architecture decision (an AD), (6) create or update the project root README, (7) create or update a plan, (8) derive a feature doc's `owns:` frontmatter (the code-path globs it owns) from code, (9) scaffold a standard doc (README, structure.md, CHANGELOG, backlog, memory) from its template, (10) document an operations procedure (setup, deployment, maintenance) or a one-shot migration runbook, (11) write a steering doc (system overview, domain model, glossary, non-goals, security overview, testing strategy), (12) catalog the API surface or the environment/config registry, or (13) co-author any technical doc. Baselining / reconciling a repo's docs to the installed harness version is the **`maintenance` agent (baseline mode)** (which calls this skill for each template) — this skill does not orchestrate baseline. Triggers on "document this", "create docs", "update changelog", "add to protected files", "AD", "ADR", "architecture decision", "root README", "plan", "feature doc", "LLD", "glossary", "domain model", "runbook", "API reference".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Technical Documentation Skill
|
|
@@ -9,12 +9,31 @@ description: Template & generator library for technical docs — the skill agent
|
|
|
9
9
|
|
|
10
10
|
Document contracts and architecture, not implementation details. Show function signatures and API shapes — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments. Breaking changes belong in changelogs only, not module docs.
|
|
11
11
|
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Two Natures
|
|
15
|
+
|
|
16
|
+
Every document is exactly one of two things. Decide which before writing a word — every rule in this skill derives from the split.
|
|
17
|
+
|
|
18
|
+
| | **Truth document** | **Record** |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| States | Absolutes — how the system is, **now** | What happened — a dated account of activity |
|
|
21
|
+
| Named by | Topic: `auth.md`, `AD-003-persistence.md` | Date: `YYYY-MM-DD-slug.md` (or append position) |
|
|
22
|
+
| On change | Body rewritten in place the moment reality changes | Never edited — frozen at completion or append-only |
|
|
23
|
+
| Read to | Act correctly today | Trace provenance, diagnose, audit |
|
|
24
|
+
| Lives in | `docs/features/`, `docs/architecture/`, `docs/operations/`, `docs/tests/`, READMEs | `docs/history/` (plans, changelog, brainstorms, research, migrations), `docs/research/`, `docs/memory/` |
|
|
25
|
+
|
|
26
|
+
The two guarantees are complementary and both break on mixing: a reader holding a **truth document** must never need history to interpret it; a reader holding a **record** must be able to trust it was never rewritten. So the natures never share a document body.
|
|
27
|
+
|
|
28
|
+
- **Truth documents never narrate history.** No migration/fold stories, no dated "shipped/verified on YYYY-MM-DD" markers, no "was X → now Y" journeys, no provenance asides ("ex-`@nurix/X`, folded 2026-06-12"). When the system changes, the change-story goes to `docs/history/` (a changelog entry) and the truth document simply becomes correct in present tense. When you find historical narration in a truth document, rewrite it to the present-tense fact and let the record carry the story.
|
|
29
|
+
- **Records are never edited to match the present.** A completed plan stays wrong-in-hindsight; a changelog entry describes close-time state; a scope change gets a *new* dated record that links back, never an edit to a frozen one.
|
|
30
|
+
- **The one bridge — head is truth, tail is provenance.** An **Architecture Decision (AD)** ends with a **Decision Changelog**: the single sanctioned dated-history section inside a truth document, because for a decision the journey (what each revision reversed, and what triggered it) is part of the reasoning. The AD body stays current-truth-only; the tail carries the dates and links to the plans that implemented each revision. No other truth document carries dated history.
|
|
31
|
+
- **Truth documents cite records for the _why_, never the _when_.** `Provenance: AD-002` is good; "decided in AD-002 and shipped 2026-06-13" is not. Routing/index docs point only to truth documents — never to a plan or changelog entry as the "read first" source.
|
|
32
|
+
|
|
12
33
|
**No empty stubs.** Never leave a template section as an empty placeholder — omit any section with nothing real to say (each template declares its required core; everything else is optional). Write an explicit "None" only where the absence itself is information (e.g., a plan's Cross-Module Contracts Affected, an LLD's Ownership Conflicts). An empty table stub reads as "not yet researched"; an omitted section reads as "doesn't apply" — keep those meanings distinct.
|
|
13
34
|
|
|
14
35
|
**No redirect docs.** When moving a doc to a new location, delete the old file entirely. Update all references (cross-doc links, memory files) to point to the new path. Never leave a stub file that says "Moved to X" — redirect docs rot, clutter the repo, and create false search hits.
|
|
15
36
|
|
|
16
|
-
**Present tense, current state only.** Active docs (everything outside `docs/history/`) describe the system _as it is now_ — what exists and how it works today. They never narrate how it got there: no migration/fold history, no dated "shipped/verified/built on YYYY-MM-DD" markers, no "ex-`@nurix/X`, folded 2026-06-12" provenance, no "was X → now Y" change journeys, no "removed/deleted in the <date> fold". The historical record — when and how things changed — lives **only** in `docs/history/` (changelog, plans); `docs/memory/` is the agent's dated log and is likewise exempt, and an ADR's **Decision Changelog** section is the one sanctioned dated-history section inside an active doc (the ADR body itself stays current-truth-only). A doc may cite an ADR for the _why_ (the decision rationale), but must not narrate the _when/how it changed_. Routing/index docs point only to current authority docs — never to a historical plan or changelog as the "read first" source. When you find historical narration in an active doc, rewrite it to the present-tense fact and let `docs/history/` carry the story.
|
|
17
|
-
|
|
18
37
|
---
|
|
19
38
|
|
|
20
39
|
## Decision Tree
|
|
@@ -24,23 +43,39 @@ User request
|
|
|
24
43
|
│
|
|
25
44
|
├─ "Baseline/reconcile docs" ──────▶ maintenance agent (baseline mode) (it calls this skill per template)
|
|
26
45
|
│
|
|
27
|
-
├─ "Document feature/module (LLD)" ▶
|
|
46
|
+
├─ "Document feature/module (LLD)" ▶ Feature (LLD) Template
|
|
28
47
|
│
|
|
29
|
-
├─ "Create/update changelog" ──────▶ Changelog Template
|
|
48
|
+
├─ "Create/update changelog" ──────▶ Changelog Template (record)
|
|
30
49
|
│
|
|
31
|
-
├─ "Document data flow" ───────────▶
|
|
50
|
+
├─ "Document data flow" ───────────▶ Feature Template (Architecture section)
|
|
32
51
|
│
|
|
33
|
-
├─ "Document Redux/state" ─────────▶
|
|
52
|
+
├─ "Document Redux/state" ─────────▶ Feature Template (State section)
|
|
34
53
|
│
|
|
35
54
|
├─ "Add to protected files" ───────▶ Protected Files Template
|
|
36
55
|
│
|
|
37
|
-
├─ "Record architecture
|
|
56
|
+
├─ "Record/revise architecture
|
|
57
|
+
│ decision" ────────────────────▶ AD Template (one per subject; revisions update it in place)
|
|
58
|
+
│
|
|
59
|
+
├─ "System at a glance" ───────────▶ System Overview Template
|
|
60
|
+
│
|
|
61
|
+
├─ "Domain model / glossary /
|
|
62
|
+
│ non-goals" ───────────────────▶ Steering Templates
|
|
63
|
+
│
|
|
64
|
+
├─ "Catalog the API surface" ──────▶ API Reference Template
|
|
65
|
+
│
|
|
66
|
+
├─ "Document env vars / config" ───▶ Environment Registry Template
|
|
67
|
+
│
|
|
68
|
+
├─ "Security / threat model" ──────▶ Security Overview Template
|
|
69
|
+
│
|
|
70
|
+
├─ "Testing strategy" ─────────────▶ Testing Strategy Template
|
|
71
|
+
│
|
|
72
|
+
├─ "Recurring procedure/setup" ────▶ Operations Procedure Template
|
|
38
73
|
│
|
|
39
|
-
├─ "
|
|
74
|
+
├─ "One-shot migration/upgrade" ───▶ Migration Runbook Template (record)
|
|
40
75
|
│
|
|
41
76
|
├─ "Create/update root README" ────▶ Project Root README Template
|
|
42
77
|
│
|
|
43
|
-
├─ "Create/update plan" ───────────▶ Plan Template
|
|
78
|
+
├─ "Create/update plan" ───────────▶ Plan Template (record)
|
|
44
79
|
│
|
|
45
80
|
├─ "Update existing doc" ──────────▶ Preserve existing structure
|
|
46
81
|
│
|
|
@@ -51,10 +86,19 @@ User request
|
|
|
51
86
|
|
|
52
87
|
## Naming & Lifecycle
|
|
53
88
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
89
|
+
| Document | Nature | Name | Lifecycle |
|
|
90
|
+
| --- | --- | --- | --- |
|
|
91
|
+
| Feature (LLD) | Truth | `kebab-case.md` | Living; `status:` `draft` → `active` → `deprecated` |
|
|
92
|
+
| Architecture Decision | Truth | `AD-NNN-kebab-case.md` | Living; `Proposed` → `Accepted` → `Deprecated`; revisions rewrite the body + append to its Decision Changelog |
|
|
93
|
+
| Steering docs (overview, domain model, glossary, non-goals, security, testing strategy) | Truth | fixed names | Living |
|
|
94
|
+
| API reference / environment registry | Truth | fixed names | Living |
|
|
95
|
+
| Operations procedure | Truth | `kebab-case.md` | Living |
|
|
96
|
+
| Protected files | Truth | `protected-files.md` | Living |
|
|
97
|
+
| Plan | Record | `YYYY-MM-DD-kebab-case.md` | Freezes at `Complete` / `Abandoned` |
|
|
98
|
+
| Changelog entry | Record | `YYYY-MM-DD-kebab-case.md` | Frozen; master index append-only |
|
|
99
|
+
| Migration runbook | Record | `YYYY-MM-DD-kebab-case.md` | Freezes once executed, outcome stamped |
|
|
100
|
+
| Research | Record | `history/research/{topic}/` | Frozen snapshot |
|
|
101
|
+
| Memory | Record | `{agent-name}.md` | Append-only dated ledger |
|
|
58
102
|
|
|
59
103
|
---
|
|
60
104
|
|
|
@@ -65,7 +109,7 @@ When creating or updating a feature doc, derive its **`owns:` frontmatter** —
|
|
|
65
109
|
### When to run
|
|
66
110
|
|
|
67
111
|
- **Baseline / reconcile** — for every feature doc whose code paths aren't yet declared in its `owns:` frontmatter (the `maintenance` agent (baseline mode) calls this)
|
|
68
|
-
- **New feature doc** — when creating a doc via the Feature
|
|
112
|
+
- **New feature doc** — when creating a doc via the Feature template, project its `owns:` globs
|
|
69
113
|
- **Doc update** — when the documented scope changes, update the doc's `owns:` globs
|
|
70
114
|
|
|
71
115
|
### How to derive the frontmatter
|
|
@@ -123,6 +167,6 @@ For docs that don't match templates:
|
|
|
123
167
|
|
|
124
168
|
| File | Use For |
|
|
125
169
|
| --- | --- |
|
|
126
|
-
| `references/templates.md` | docs/README.md, structure.md, the feature-frontmatter contract, scaffolds (CHANGELOG, backlog, memory), feature, changelog, plan, operations procedure, protected files,
|
|
127
|
-
| `references/style-guide.md` | Writing rules, formatting conventions |
|
|
170
|
+
| `references/templates.md` | docs/README.md, structure.md, the feature-frontmatter contract, scaffolds (CHANGELOG, backlog, memory), feature, changelog, plan, operations procedure, migration runbook, protected files, AD, steering docs (system overview, domain model, glossary, non-goals, security, testing strategy), API reference, environment registry, project root README templates |
|
|
171
|
+
| `references/style-guide.md` | Writing rules, formatting conventions, the two-natures tense rules |
|
|
128
172
|
| `references/examples.md` | Good vs bad documentation examples |
|
|
@@ -151,6 +151,46 @@ When the page loads, the useAppInit hook calls the syncData function. This funct
|
|
|
151
151
|
|
|
152
152
|
---
|
|
153
153
|
|
|
154
|
+
## Example 5: Architecture Decision revision
|
|
155
|
+
|
|
156
|
+
### ❌ Bad: Supersession chain
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
docs/architecture/decisions/
|
|
160
|
+
├── AD-002-auth-keycloak.md (status: Superseded)
|
|
161
|
+
├── AD-006-auth-better-auth.md (status: Superseded, "supersedes AD-002")
|
|
162
|
+
└── AD-011-auth-better-auth-v2.md (status: Accepted, "supersedes AD-006")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Problems:** Three files hold one subject; the reader must diff a chain to learn the current truth; two of the three are wrong-but-present (the same pathology as keeping `report_v1.sql` beside the live `report_v2.sql`); the reasoning that killed Keycloak is stranded in a dead file nobody opens.
|
|
166
|
+
|
|
167
|
+
### ✅ Good: One subject, updated in place
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
docs/architecture/decisions/
|
|
171
|
+
└── AD-002-auth.md (status: Accepted, last-updated bumped)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```markdown
|
|
175
|
+
## Decision
|
|
176
|
+
|
|
177
|
+
We use Better Auth with one-shot credential issuance… ← current truth, no journey
|
|
178
|
+
|
|
179
|
+
…
|
|
180
|
+
|
|
181
|
+
## Decision Changelog
|
|
182
|
+
|
|
183
|
+
- 2026-05-02 — Moved issuance to one-shot tokens because refresh-token theft
|
|
184
|
+
surfaced in review. Implemented by [plan](…). (Previously: long-lived refresh tokens.)
|
|
185
|
+
- 2026-03-18 — Replaced Keycloak with Better Auth because self-hosting cost
|
|
186
|
+
outweighed SSO needs. Implemented by [plan](…). (Previously: Keycloak.)
|
|
187
|
+
- 2026-01-10 — Initial decision accepted. Implemented by [plan](…).
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Why it works:** The body answers "how does auth work and why" without archaeology; the tail preserves every reversal with its trigger; the rejected alternatives stay findable in the one file a reader actually opens.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
154
194
|
## Quick Comparison
|
|
155
195
|
|
|
156
196
|
| Aspect | Bad | Good |
|
|
@@ -159,4 +199,5 @@ When the page loads, the useAppInit hook calls the syncData function. This funct
|
|
|
159
199
|
| State | Every occurrence | Persistence points only |
|
|
160
200
|
| Flows | Prose paragraphs | ASCII diagrams |
|
|
161
201
|
| Changelogs | "Updated X" | Function names + migrations |
|
|
202
|
+
| Decisions | New doc per revision | One AD per subject, updated in place |
|
|
162
203
|
| Length | 100+ lines | 20-40 lines |
|