@codepassion/skills 1.2.0 → 1.4.0

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.
Files changed (34) hide show
  1. package/README.md +6 -1
  2. package/SKILLS.md +6 -1
  3. package/bin/c9n-skills.js +28 -3
  4. package/install.sh +25 -2
  5. package/package.json +1 -1
  6. package/skills/c9n/SKILL.md +279 -0
  7. package/skills/c9n-pipeline/SKILL.md +128 -0
  8. package/skills/c9n-pipeline/templates/Dockerfile.api +49 -0
  9. package/skills/c9n-pipeline/templates/Dockerfile.service +45 -0
  10. package/skills/c9n-pipeline/templates/Dockerfile.web +50 -0
  11. package/skills/c9n-pipeline/templates/dockerignore +18 -0
  12. package/skills/c9n-pipeline/templates/workflows/_build-job.partial.yml +13 -0
  13. package/skills/c9n-pipeline/templates/workflows/_deploy-job.partial.yml +17 -0
  14. package/skills/c9n-pipeline/templates/workflows/_migration-check.partial.yml +16 -0
  15. package/skills/c9n-pipeline/templates/workflows/ci.yml +38 -0
  16. package/skills/c9n-pipeline/templates/workflows/deployment.yml +21 -0
  17. package/skills/c9n-sentry/REFERENCE.md +172 -0
  18. package/skills/c9n-sentry/SKILL.md +53 -0
  19. package/skills/c9n-spec/SKILL.md +92 -0
  20. package/skills/c9n-spec/templates/.github/pull_request_template.md +29 -0
  21. package/skills/c9n-spec/templates/AGENTS.md +179 -0
  22. package/skills/c9n-spec/templates/CLAUDE.md +6 -0
  23. package/skills/c9n-spec/templates/CONTEXT.md +53 -0
  24. package/skills/c9n-spec/templates/DESIGN.md +73 -0
  25. package/skills/c9n-spec/templates/docs/SRS.md +37 -0
  26. package/skills/c9n-spec/templates/docs/adr/0001-spec-driven-iso29110-docs.md +44 -0
  27. package/skills/c9n-spec/templates/docs/adr/_TEMPLATE.md +26 -0
  28. package/skills/c9n-spec/templates/docs/agents/domain.md +43 -0
  29. package/skills/c9n-spec/templates/docs/agents/issue-tracker.md +22 -0
  30. package/skills/c9n-spec/templates/docs/agents/triage-labels.md +27 -0
  31. package/skills/c9n-spec/templates/docs/architecture.md +50 -0
  32. package/skills/c9n-spec/templates/docs/features/_TEMPLATE.md +34 -0
  33. package/skills/c9n-spec/templates/docs/test-plan.md +30 -0
  34. package/skills/c9n-spec/templates/docs/traceability.md +27 -0
@@ -0,0 +1,50 @@
1
+ # -----------------------------------------------------------------------------
2
+ # {{PACKAGE_NAME}} (Next.js app) — Bun multi-stage build.
3
+ # Public env is read at RUNTIME via next-runtime-env (<PublicEnvScript>), so this
4
+ # image bakes no NEXT_PUBLIC_* — Coolify injects them at run, like the API image.
5
+ # Generated by c9n-pipeline; see the ADR this skill points you to.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ FROM oven/bun:{{BUN_VERSION}} AS base
9
+ WORKDIR /app
10
+
11
+ # Install dependencies with bun
12
+ FROM base AS deps
13
+ COPY package.json bun.lock ./
14
+ {{WORKSPACE_MANIFEST_COPIES}}
15
+ COPY packages/ ./packages/
16
+ RUN bun install
17
+
18
+ # Rebuild the source code only when needed
19
+ FROM base AS builder
20
+ WORKDIR /app
21
+ COPY --from=deps /app/node_modules ./node_modules
22
+ COPY . .
23
+
24
+ # Next.js expects {{APP_DIR}}/.env to exist; intentionally empty — no public env
25
+ # is baked at build (it is injected at runtime via next-runtime-env).
26
+ RUN touch {{APP_DIR}}/.env
27
+
28
+ RUN cd {{APP_DIR}} && bun run build
29
+
30
+ # Production image — serve the Next.js standalone output
31
+ FROM base AS runner
32
+ WORKDIR /app
33
+
34
+ ENV NODE_ENV=production \
35
+ PORT={{APP_PORT}} \
36
+ HOSTNAME="0.0.0.0"
37
+
38
+ RUN groupadd --system --gid 1001 nodejs && \
39
+ useradd --system --uid 1001 nextjs
40
+
41
+ # Leverage Next.js output file tracing to keep the image small
42
+ COPY --from=builder --chown=nextjs:nodejs /app/{{APP_DIR}}/.next/standalone ./
43
+ COPY --from=builder --chown=nextjs:nodejs /app/{{APP_DIR}}/.next/static ./{{APP_DIR}}/.next/static
44
+ COPY --from=builder --chown=nextjs:nodejs /app/{{APP_DIR}}/public ./{{APP_DIR}}/public
45
+
46
+ USER nextjs
47
+
48
+ EXPOSE {{APP_PORT}}
49
+
50
+ CMD ["bun", "{{APP_DIR}}/server.js"]
@@ -0,0 +1,18 @@
1
+ .next
2
+ node_modules
3
+ **/node_modules
4
+ **/.next
5
+ **/dist
6
+ .git
7
+ .turbo
8
+ **/.turbo
9
+ npm-debug.log
10
+ yarn-error.log
11
+ bun-debug.log
12
+ .env
13
+ **/.env
14
+ .env.*
15
+ **/.env.*
16
+
17
+ # Next.js telemetry
18
+ .next/telemetry
@@ -0,0 +1,13 @@
1
+ # One BUILD job per app. Alpha only — the image is built once at the tag push
2
+ # and redeployed to Beta/Production by base tag (no rebuild). {{APP_KEY}} is a
3
+ # lowercase id unique per app (e.g. api, web). {{ORG_REF}} is the org workflow
4
+ # ref (e.g. turborepo) — keep it identical across every job in this file.
5
+ build-{{APP_KEY}}-alpha:
6
+ name: Build
7
+ if: github.event_name != 'release' && startsWith(github.ref, 'refs/tags/v')
8
+ uses: codepassion-team/cicd/.github/workflows/build.yml@{{ORG_REF}}
9
+ with:
10
+ environment: Alpha
11
+ build_path: ./{{APP_DIR}}
12
+ package_name: {{PACKAGE_NAME}}
13
+ secrets: inherit
@@ -0,0 +1,17 @@
1
+ # One DEPLOY job per app per environment. {{DEPLOY_NAME}} is the org deploy.yml
2
+ # name input that resolves the Coolify UUID var: it is uppercased to
3
+ # ${{DEPLOY_NAME_UPPER}}_UUID, so it MUST be a key the org deploy.yml wires
4
+ # (currently only API and WEB). Stamp the right {{IF_CONDITION}} per environment
5
+ # from c9n-semver-deployment:
6
+ # Alpha -> needs: build-{{APP_KEY}}-alpha ; if: github.event_name != 'release' && startsWith(github.ref, 'refs/tags/v')
7
+ # Beta -> (no needs) ; if: github.event_name == 'release' && github.event.release.prerelease == true && startsWith(github.event.release.tag_name, 'v')
8
+ # Production -> (no needs) ; if: github.event_name == 'release' && github.event.release.prerelease == false && startsWith(github.event.release.tag_name, 'v')
9
+ deploy-{{APP_KEY}}-{{ENV_KEY}}:
10
+ name: Deploy
11
+ if: {{IF_CONDITION}}
12
+ {{NEEDS_LINE}}
13
+ uses: codepassion-team/cicd/.github/workflows/deploy.yml@{{ORG_REF}}
14
+ with:
15
+ name: {{DEPLOY_NAME}}
16
+ environment: {{ENVIRONMENT}}
17
+ secrets: inherit
@@ -0,0 +1,16 @@
1
+ # Inject in place of {{MIGRATION_CHECK}} in ci.yml ONLY when a DB is detected
2
+ # (a migration-generate script exists in some package.json AND a migrations dir
3
+ # exists). Substitute {{MIGRATION_SCRIPT}} and {{MIGRATIONS_DIR}} with the real
4
+ # detected names — do not assume drizzle:generate / packages/supabase/migrations.
5
+ # If no DB, {{MIGRATION_CHECK}} is the empty string and ci.yml ends at Build.
6
+ - name: Verify migrations are up to date
7
+ run: bun run {{MIGRATION_SCRIPT}} -- --name check
8
+ - name: Check for uncommitted migration changes
9
+ run: |
10
+ if git diff --name-only --exit-code {{MIGRATIONS_DIR}}; then
11
+ echo "Migrations are up to date"
12
+ else
13
+ echo "Detected uncommitted migration changes. Run 'bun run {{MIGRATION_SCRIPT}}' locally and commit the result."
14
+ git diff {{MIGRATIONS_DIR}}
15
+ exit 1
16
+ fi
@@ -0,0 +1,38 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: ['main', 'develop']
5
+ pull_request:
6
+ types: [opened, synchronize]
7
+ jobs:
8
+ build:
9
+ name: Check
10
+ timeout-minutes: 15
11
+ runs-on: ubuntu-latest
12
+ env:
13
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
14
+ TURBO_TEAM: ${{ vars.TURBO_TEAM }}
15
+ steps:
16
+ - name: Check out code
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 2
20
+ - name: Cache turbo build setup
21
+ uses: actions/cache@v4
22
+ with:
23
+ path: .turbo
24
+ key: ${{ runner.os }}-turbo-${{ github.sha }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-turbo-
27
+ - uses: oven-sh/setup-bun@v2
28
+ - name: Setup Node.js environment
29
+ uses: actions/setup-node@v4
30
+ with:
31
+ node-version: 24
32
+ - name: Install dependencies
33
+ run: bun install
34
+ - name: Check types
35
+ run: bun run check-types
36
+ - name: Build
37
+ run: bun run build
38
+ {{MIGRATION_CHECK}}
@@ -0,0 +1,21 @@
1
+ name: Deployment
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - 'v*.*.*'
8
+ release:
9
+ types: [published]
10
+
11
+ # Assembled by c9n-pipeline from the partials below. The triggers and the
12
+ # event->environment mapping follow c9n-semver-deployment (single source of
13
+ # truth): tag push -> Alpha, prerelease -> Beta, release -> Production.
14
+ #
15
+ # Stamp one BUILD job per app (Alpha only — built once, redeployed by base tag),
16
+ # then one DEPLOY job per app per environment the project actually has. Prune
17
+ # environments the project does not use.
18
+
19
+ jobs:
20
+ {{BUILD_JOBS}}
21
+ {{DEPLOY_JOBS}}
@@ -0,0 +1,172 @@
1
+ # Sentry Bun+Elysia+Next.js — Reference
2
+
3
+ ## package.json (`packages/sentry/`)
4
+
5
+ ```json
6
+ {
7
+ "name": "@repo/sentry",
8
+ "type": "module",
9
+ "exports": {
10
+ "./bun": { "import": "./src/bun.ts" },
11
+ "./client": { "import": "./src/client.ts" },
12
+ "./server": { "import": "./src/server.ts" },
13
+ "./edge": { "import": "./src/edge.ts" },
14
+ "./pdpa": { "import": "./src/pdpa.ts" }
15
+ },
16
+ "dependencies": {
17
+ "@sentry/elysia": "^10",
18
+ "@sentry/nextjs": "^10"
19
+ },
20
+ "peerDependencies": {
21
+ "elysia": "*",
22
+ "next-runtime-env": "*"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## PDPA scrubber
28
+
29
+ ```ts
30
+ // src/pdpa.ts
31
+ import type { Event } from "@sentry/core"
32
+
33
+ const PII_KEY = /phone|otp|lat|lng|latitude|longitude|member_?id|token|secret|password/i
34
+ const DROP_HEADERS = ["authorization", "cookie", "set-cookie"]
35
+
36
+ function redactKeys(obj: unknown): unknown {
37
+ if (!obj || typeof obj !== "object") return obj
38
+ if (Array.isArray(obj)) return obj.map(redactKeys)
39
+ return Object.fromEntries(
40
+ Object.entries(obj as Record<string, unknown>).map(([k, v]) => [
41
+ k,
42
+ PII_KEY.test(k) ? "[redacted]" : redactKeys(v)
43
+ ])
44
+ )
45
+ }
46
+
47
+ export function pdpaBeforeSend(event: Event): Event | null {
48
+ if (event.request) {
49
+ event.request.data = undefined
50
+ event.request.query_string = undefined
51
+ event.request.cookies = undefined
52
+ if (event.request.headers) {
53
+ DROP_HEADERS.forEach(h => { delete (event.request!.headers as Record<string, string>)[h] })
54
+ }
55
+ }
56
+ if (event.extra) event.extra = redactKeys(event.extra) as Record<string, unknown>
57
+ return event
58
+ }
59
+ ```
60
+
61
+ ## src/bun.ts
62
+
63
+ ```ts
64
+ export * from "@sentry/elysia"
65
+ import * as Sentry from "@sentry/elysia"
66
+ import { pdpaBeforeSend } from "./pdpa.js"
67
+
68
+ export function initBun(): void {
69
+ const dsn = process.env.SENTRY_DSN
70
+ if (!dsn) return
71
+ Sentry.init({
72
+ dsn,
73
+ environment: process.env.ENVIRONMENT || "development",
74
+ tracesSampleRate: 0.1,
75
+ sendDefaultPii: false,
76
+ beforeSend: pdpaBeforeSend,
77
+ initialScope: { tags: { app: "api" } }
78
+ })
79
+ }
80
+ ```
81
+
82
+ ## src/client.ts (runtime env — ADR 0005)
83
+
84
+ ```ts
85
+ export * from "@sentry/nextjs"
86
+ import * as Sentry from "@sentry/nextjs"
87
+ import { env } from "next-runtime-env" // ← NOT process.env
88
+ import { pdpaBeforeSend } from "./pdpa.js"
89
+
90
+ export function initClient(): void {
91
+ const dsn = env("NEXT_PUBLIC_SENTRY_DSN") // runtime, not build-time
92
+ if (!dsn) return
93
+ Sentry.init({
94
+ dsn,
95
+ environment: env("NEXT_PUBLIC_ENVIRONMENT") || "development",
96
+ tracesSampleRate: 0.1,
97
+ sendDefaultPii: false,
98
+ beforeSend: pdpaBeforeSend,
99
+ tags: { app: "web" }
100
+ })
101
+ }
102
+ ```
103
+
104
+ ## apps/api/src/index.ts wiring
105
+
106
+ ```ts
107
+ import "./lib/sentry.js" // ← must be FIRST import
108
+ // ... other imports ...
109
+ import { withElysia } from "@repo/sentry/bun"
110
+
111
+ const app = withElysia(new Elysia()) // wraps for auto error capture
112
+ .use(...)
113
+ // remove any console.error in onError — withElysia handles it
114
+ ```
115
+
116
+ ## apps/web/next.config.js
117
+
118
+ ```js
119
+ import { withSentryConfig } from "@repo/sentry/client"
120
+ const nextConfig = { transpilePackages: ["@repo/sentry"], ... }
121
+ export default withSentryConfig(nextConfig, {
122
+ silent: true,
123
+ hideSourceMaps: true,
124
+ tunnelRoute: "/monitoring" // guards against in-app-browser/CSP drops
125
+ })
126
+ ```
127
+
128
+ ## apps/web/instrumentation.ts
129
+
130
+ ```ts
131
+ export async function register() {
132
+ if (process.env.NEXT_RUNTIME === "nodejs") {
133
+ await import("./sentry.server.config")
134
+ }
135
+ if (process.env.NEXT_RUNTIME === "edge") {
136
+ await import("./sentry.edge.config")
137
+ }
138
+ }
139
+ export { captureRequestError as onRequestError } from "@sentry/nextjs"
140
+ ```
141
+
142
+ ## apps/web/instrumentation-client.ts
143
+
144
+ ```ts
145
+ import { initClient, captureRouterTransitionStart } from "@repo/sentry/client"
146
+ initClient()
147
+ export const onRouterTransitionStart = captureRouterTransitionStart
148
+ ```
149
+
150
+ ## turbo.json globalEnv additions
151
+
152
+ ```json
153
+ "globalEnv": ["SENTRY_DSN", "ENVIRONMENT"]
154
+ ```
155
+
156
+ Do NOT add `NEXT_PUBLIC_*` to globalEnv — they are runtime-injected via `PublicEnvScript`.
157
+
158
+ ## Sentry project setup
159
+
160
+ 1. sentry.io → **Create Project** → platform: **Next.js** → name: `<project>`
161
+ 2. Copy DSN from **Project Settings → Client Keys (DSN)**
162
+ 3. Same DSN in both Coolify services (one project, two env var names)
163
+ 4. Redeploy both services after setting vars
164
+
165
+ ## ADR checklist (write ADR when adopting)
166
+
167
+ - Why `@sentry/elysia` not `@sentry/bun` + custom plugin
168
+ - Why `@sentry/elysia` not `@sentry/node` (compiled binary landmine)
169
+ - Client env split reasoning (ADR 0005 or equivalent)
170
+ - PDPA/privacy scrubbing rationale
171
+ - Alpha-state risk acceptance if applicable
172
+ - Generic env naming rationale
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: c9n-sentry
3
+ description: Scaffold Sentry error tracking in a Bun + ElysiaJS + Next.js monorepo via a shared @repo/sentry package. Use when user wants to add Sentry, set up error tracking, or wire error monitoring to an ElysiaJS API and/or Next.js frontend in a Turborepo monorepo.
4
+ ---
5
+
6
+ # Sentry — Bun + Elysia + Next.js
7
+
8
+ ## Three landmines (check first)
9
+
10
+ 1. **`@sentry/node` under `bun --compile` fails silently** — valid DSN, zero events. Use `@sentry/elysia` (built on `@sentry/bun`). Never let `@sentry/node` load on the API.
11
+ 2. **Runtime public env** — if the project uses `next-runtime-env` (ADR 0005 pattern), the browser DSN MUST use `env("NEXT_PUBLIC_SENTRY_DSN")` not `process.env`. Server/edge/api use `process.env`. Wrong = undefined DSN in prod = dead Sentry.
12
+ 3. **PDPA / PII** — add `beforeSend` scrubber + `sendDefaultPii: false`. Strip request body/query/cookies, drop auth headers, recursively redact PII keys. See [REFERENCE.md](REFERENCE.md#pdpa-scrubber).
13
+
14
+ ## Quick start
15
+
16
+ ```
17
+ packages/sentry/ ← @repo/sentry (shared)
18
+ src/pdpa.ts ← beforeSend scrubber (shared by all inits)
19
+ src/bun.ts ← initBun() for apps/api
20
+ src/client.ts ← initClient() for browser (uses env() not process.env)
21
+ src/server.ts ← initServer() for Next.js server runtime
22
+ src/edge.ts ← initEdge() for Next.js edge runtime
23
+ package.json ← exports map: ./bun ./client ./server ./edge ./pdpa
24
+ apps/api/src/lib/sentry.ts ← import { initBun } from "@repo/sentry/bun"; initBun()
25
+ apps/api/src/index.ts ← first import: "./lib/sentry.js", then withElysia(new Elysia())
26
+ apps/web/instrumentation.ts ← register() → dynamic import server/edge config
27
+ apps/web/instrumentation-client.ts ← initClient()
28
+ apps/web/sentry.server.config.ts / sentry.edge.config.ts
29
+ apps/web/next.config.js ← withSentryConfig + transpilePackages: ["@repo/sentry"]
30
+ ```
31
+
32
+ ## Env vars
33
+
34
+ | Service | Key | Read by |
35
+ |---------|-----|---------|
36
+ | API (Coolify) | `SENTRY_DSN`, `ENVIRONMENT` | `process.env` |
37
+ | Web (Coolify) | `NEXT_PUBLIC_SENTRY_DSN`, `NEXT_PUBLIC_ENVIRONMENT` | `env()` from next-runtime-env (client) / `process.env` (server/edge) |
38
+
39
+ One Sentry project, same DSN in both vars. Add `initialScope: { tags: { app: "api" } }` to `initBun()` so api vs web events are distinguishable in the shared project.
40
+
41
+ ## Verification checklist
42
+
43
+ - [ ] `bun install --frozen-lockfile` clean
44
+ - [ ] `bun run check-types` (api + web) clean
45
+ - [ ] `bun run build --compile` on API — confirms `@sentry/node` never loaded (the landmine test)
46
+ - [ ] Web Sentry bundle builds green
47
+ - [ ] After deploy: `window.__ENV.NEXT_PUBLIC_SENTRY_DSN` populated in devtools (runtime env proof)
48
+ - [ ] Trigger a test error → event appears in Sentry tagged correct environment
49
+ - [ ] Open event payload — no phone/otp/lat/lng/member_id (PDPA proof)
50
+
51
+ ## Reference
52
+
53
+ See [REFERENCE.md](REFERENCE.md) for full file contents, PDPA scrubber code, and `turbo.json` config.
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: c9n-spec
3
+ description: Scaffold the C9N spec-driven, ISO/IEC 29110-aligned agentic documentation system INTO a repo — AGENTS.md (protocol + stack) with a CLAUDE.md bridge, CONTEXT.md glossary, DESIGN.md, the docs/ tree (SRS, architecture, traceability, test-plan, ADRs, feature stubs, agent docs), and the PR-template merge gate. Use when bootstrapping a new C9N project, "init docs", "set up the spec-driven docs", "add the agentic workflow files", or porting the ddg-jewelry doc system to another repo. Complements c9n-deliverables (that generates docs OUT of a codebase; this seeds the doc system INTO one).
4
+ ---
5
+
6
+ Bootstraps the Code Passion (C9N) spec-driven development doc system into a target repo. Drops
7
+ a self-contained, agent-readable documentation skeleton so a fresh project starts with the same
8
+ approval gates, traceability, and glossary discipline as the reference implementation
9
+ (ddg-jewelry). Fully generic — adapt the placeholders to whatever stack the project uses.
10
+
11
+ Bundled `templates/` are the source skeleton. **Copy them, then substitute tokens** — never edit
12
+ the templates in place for a specific project.
13
+
14
+ ## What gets scaffolded
15
+
16
+ | File | Role |
17
+ |------|------|
18
+ | `AGENTS.md` | **Canonical** agent context: the full ISO/IEC 29110 spec-driven protocol (inlined, so the repo is self-contained) + C9N stack + module patterns. References the sibling `c9n-*` convention skills rather than copying them. |
19
+ | `CLAUDE.md` | Bridge that `@AGENTS.md`-imports the canonical file (so Claude Code's memory auto-loads the protocol; other tools read AGENTS.md directly). |
20
+ | `CONTEXT.md` | Ubiquitous-language glossary skeleton (no implementation detail). |
21
+ | `DESIGN.md` | Visual design-system rules — **only if the repo has a frontend.** |
22
+ | `docs/SRS.md` | Requirements master registry (feature short-codes + system NFRs). |
23
+ | `docs/architecture.md` | Software-design as-is map. |
24
+ | `docs/traceability.md` | Requirement → design → test master index. |
25
+ | `docs/test-plan.md` | Master test strategy. |
26
+ | `docs/adr/0001-spec-driven-iso29110-docs.md` | Seed ADR: why this doc system exists. |
27
+ | `docs/adr/_TEMPLATE.md` | ADR format for future decisions. |
28
+ | `docs/features/_TEMPLATE.md` | Per-feature deep-doc stub (Requirements · Design · Test Plan · Test Cases · Traceability). |
29
+ | `docs/agents/{issue-tracker,triage-labels,domain}.md` | Agent-process docs (GitHub `gh`, triage vocab, domain-doc consumption). |
30
+ | `.github/pull_request_template.md` | The Definition-of-Done merge gate. |
31
+
32
+ ## Workflow
33
+
34
+ Run each step in order; this is a table of contents — the rules are below.
35
+
36
+ 1. **Detect repo shape.** Read the target's root `package.json`/workspaces. Decide:
37
+ monorepo vs single app; **frontend present?** (`apps/web`, or `next`/`astro`/`vite`/`react`
38
+ in any `package.json`) → include `DESIGN.md`. **Backend/API present?** → keep the API
39
+ module-patterns section in AGENTS.md; otherwise tell the user it's deletable.
40
+ 2. **No-clobber.** For every target path, **skip if it already exists** — never overwrite. Collect
41
+ skipped paths for the final report. (Re-running the skill must be safe and idempotent.)
42
+ 3. **Copy templates** into the target repo, substituting tokens (below). Skip `DESIGN.md` if no
43
+ frontend. Skip the API section guidance if no backend.
44
+ 4. **Optional scan — OFF by default.** Only if the user **explicitly** asks to seed from code
45
+ ("scan the codebase", "seed the glossary", "reverse-document"): read the codebase and fill
46
+ - `CONTEXT.md` — first real glossary terms (actors, core entities) from the domain;
47
+ - `docs/architecture.md` — the actual module map + data-model relationships;
48
+ - `docs/features/` — one as-built stub per shipped module (low-confidence, no test cases),
49
+ and register each in `docs/SRS.md` with a fresh short-code.
50
+ Without this request, leave the placeholders untouched.
51
+ 5. **Report.** Print created vs skipped files, then next steps: pick the first feature, write its
52
+ SRS section (Gate 1), get sign-off, then Design + Test Plan (Gate 2) — no production code
53
+ before Gate 2.
54
+
55
+ ## Token substitution
56
+
57
+ When copying, replace these placeholders:
58
+
59
+ | Token | Source |
60
+ |-------|--------|
61
+ | `{{PROJECT_NAME}}` | Target root dir name, or `package.json` `name` (humanized). |
62
+ | `{{YEAR}}` / `{{DATE}}` | Current year / ISO date (for the seed ADR). |
63
+ | `{{DECIDER}}` | Ask, or default to the repo owner. |
64
+ | Stack rows in AGENTS.md | Keep C9N defaults; trim rows the detected stack doesn't use. |
65
+
66
+ ## Conventions (referenced, not copied)
67
+
68
+ The scaffolded `AGENTS.md` points at the sibling C9N skills for engineering conventions — it does
69
+ **not** inline them, so they have a single source of truth:
70
+
71
+ - Commits → `c9n-commit-messages` · Branching → `c9n-git-branching` · PRs → `c9n-pull-requests`
72
+ - Clean code → `c9n-clean-code-typescript` · Lint/types → `c9n-typescript-eslint`
73
+ - Formatting → `c9n-code-formatting` · Review → `c9n-code-review`
74
+
75
+ For C9N-internal repos every dev has these installed, so the references always resolve. If you
76
+ scaffold into a repo where they may not be installed, tell the user to
77
+ `npx @codepassion/skills install claude`.
78
+
79
+ ## Gotchas
80
+
81
+ - **Combined install mode does not carry `templates/`.** `install.sh combined` copies only the
82
+ generated `skills/c9n` SKILL.md body; the bundled templates are absent. Install `c9n-spec` via
83
+ `install.sh claude` (or `project`/`codex`) so the templates come along. Same limitation as
84
+ `c9n-deliverables`' scripts.
85
+ - **AGENTS.md vs CLAUDE.md.** AGENTS.md is the real file. CLAUDE.md exists only so Claude Code's
86
+ memory auto-load reaches the protocol — it does so via the **`@AGENTS.md` import** (Claude Code's
87
+ memory-import syntax), not a markdown link (a link is inert and pulls nothing into context). Don't
88
+ duplicate content into CLAUDE.md. If a target tool doesn't support `@`-imports, it reads AGENTS.md
89
+ directly anyway, so nothing is lost.
90
+ - **Don't grade the stubs.** If you run the optional scan, as-built stubs describe *current*
91
+ behavior at low confidence with **no** test cases — deepen on touch, per the protocol. Don't
92
+ invent acceptance criteria for code you only read.
@@ -0,0 +1,29 @@
1
+ <!-- See AGENTS.md › Spec-Driven Development Protocol for the workflow and behavior-change rule. -->
2
+
3
+ ## What & why
4
+
5
+ <!-- Ticket ID + one-line summary. Link the approved SRS/Design if this is a feature. -->
6
+
7
+ ## Spec-driven gate
8
+
9
+ - [ ] For a **new feature**: SRS approved (Gate 1) and Design + Test Plan approved (Gate 2) **before** this code.
10
+ - [ ] This PR links the relevant `docs/features/<name>.md` (or master SRS section).
11
+
12
+ ## Behavior-change check
13
+
14
+ > Does this change **observable behavior, a requirement, an interface, or a test outcome**?
15
+
16
+ - [ ] **No** — refactor / rename / dep-bump / typo / format. Doc updates N/A. _(skip the next section)_
17
+ - [ ] **Yes** — complete the doc-update checklist below.
18
+
19
+ ### Doc updates (only if "Yes" above)
20
+
21
+ - [ ] SRS updated (new/changed requirement) — `docs/SRS.md` or `docs/features/<name>.md`
22
+ - [ ] Design updated (behavior/architecture) — `docs/architecture.md` or feature `## Design` (+ ADR if hard-to-reverse)
23
+ - [ ] Test cases updated/added (incl. regression for bug fixes)
24
+ - [ ] Traceability updated — `docs/traceability.md` or feature `## Traceability`
25
+
26
+ ## Verification
27
+
28
+ - [ ] Tests pass locally
29
+ - [ ] Lint/format clean (no semicolons, double quotes)