* chore(#604): rename get-shit-done/ runtime directory to gsd-core/ Renames the installed runtime directory `get-shit-done/` to `gsd-core/` so the on-disk name matches the package (`@opengsd/gsd-core`), repo, and binary (`gsd-tools`). The npm package name and binary are unchanged; npx/npm consumers are unaffected. Mechanical (bulk, ~90% of the diff): - `git mv get-shit-done gsd-core` - Swept path/identifier references across the repo via `perl -pe 's/get-shit-done(?!-\w)/gsd-core/g'`. The negative lookahead preserves the five legitimate slug variants that are NOT the directory: get-shit-done-{OLD,cc,classic,cli,redux} (old package/repo names). - Build/manifest wiring: package.json (bin, files, coverage globs), tsconfig.build.json (outDir), ~86 .gitignore build-output entries, stryker.config.mjs, scan-ignore files, install.js path strings. - Frozen (not rewritten): CHANGELOG.md history; translated docs (README.<locale>.md and docs/{ja-JP,ko-KR,pt-BR,zh-CN}/). New logic (review here): - src/installer-migrations/003-rename-get-shit-done-to-gsd-core.cts: a proper ADR-0008 installer migration. On upgrade it walks the legacy `~/.claude/get-shit-done/` tree, classifies each file via the prior install manifest, and emits remove-managed / backup-and-remove for managed files while PRESERVING unknown user-added files. Symlink-safe (skips a symlinked root and symlinked entries; bounds-checks every path under configDir). The framework rolls back on install failure. Emptied dirs may remain (framework has no recursive dir-removal primitive) — documented. - scripts/lint-legacy-dir-name.cjs: CI regression guard forbidding the bare `get-shit-done` directory token (split token to avoid self-match; case- insensitive; `(?!-\w)` lookahead allows the slug variants; allowlists CHANGELOG, translated docs, and `gsd-allow-legacy-name` marker lines). Wired into the lint-tests CI job. - Restored scripts/lint-package-identity-drift.cjs detection regexes (the mechanical sweep had wrongly rewritten the old-name patterns it exists to detect) and marked them as intentional legacy references. - TDD tests for the migration and the guard; do.md slash-command guard regex tightened so a `/gsd-core/bin` path segment is not mistaken for a command; changeset + docs/installer-migrations.md row added. Breaking: the installed runtime path moves `~/.claude/get-shit-done/` -> `~/.claude/gsd-core/`. Migration 003 removes the stale legacy dir's managed files (preserving user files) on upgrade. Users with custom hooks/configs hardcoding the old path must update them. Closes #604 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unsweep pending changesets + allowlist injection-example docs CI fixes for the rename PR: - Do not sweep pending .changeset/*.md (ephemeral release-note fragments, like CHANGELOG); reverted those body edits so 5 pre-existing malformed fragments (missing type/pr) no longer enter the PR diff and trip docs-lint. Allowlisted .changeset/ in the legacy-name guard accordingly. - Allowlisted TEST-EXAMPLES.md and docs/explanation/security-model.md in prompt-injection-scan.sh: they contain intentional injection examples / security-model prose; the path-reference rewrites are kept. CodeQL alerts on this PR are pre-existing (alert lines unchanged by this PR; none in the new migration/guard) and are out of scope for the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): resolve CodeQL alerts surfaced on this PR The rename diff touched files carrying pre-existing CodeQL findings; per the no-pre-existing-dismissal rule, fixing every surfaced alert rather than waving them off. All behavior-preserving: - scripts/ci-test-scope.cjs: build the config-path match from string .includes() instead of a RegExp over an arg-derived value (js/regex-injection). - src/profile-output.cts: escape backslashes before pipe-escaping desc/safeName so the table-cell escape is complete (js/incomplete-sanitization). - tests/{bug-2643,bug-2808,docs-parity-live-registry}: two-pass HTML-comment strip so a bare/unclosed `<!--` cannot survive (js/incomplete-multi-character-sanitization). - tests/inline-plan-threshold: drop the no-op `\s`->`\s` identity replace, keep the meaningful POSIX-class conversion (js/identity-replacement). Verified: build:lib green; the touched test files + ci-test-scope + profile-output suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): correctly resolve remaining CodeQL alerts (regex-injection + sanitization) The prior commit's fixes for two alerts were ineffective: - ci-test-scope.cjs js/regex-injection: the alert is the CLI-arg-derived `file` reaching static regex `.test(file)` calls (not the config rule). Removed ALL regex over file/t — startsWith/includes/=== string checks + an isWindowsHint helper — so there is no regex sink for the tainted value. - js/incomplete-multi-character-sanitization (3 test files): a single `.replace(/<!--...-->/g,'')` can let `<!--` re-form. Replaced with a fixpoint loop (replace until stable) plus a final bare-opener strip. Verified: no regex over file/t remains; ci-test-scope + the 3 test suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): make ci-test-scope + comment-strippers regex-free to clear CodeQL CodeQL flags the regex PATTERNS syntactically (regex-injection on the --files arg split; incomplete-multi-character-sanitization on the <!--...--> replace), so loop fixes do not satisfy it. Made these paths regex-free: - ci-test-scope.cjs splitFiles: char-by-char separator tokenizer (no /[,\\s]+/). - 3 test files: indexOf/slice HTML-comment stripper (no .replace(/<!--/)). Behavior preserved; ci-test-scope + the 3 suites pass; guard clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unblock security base64 scan on the large rename diff The security job hit its 10m timeout: base64-scan.sh choked on the binary test fixture tests/feat-3594-parser-property-style.test.cjs (embedded NUL/ non-UTF8 bytes -> thousands of bogus blobs + "ignored null byte" warnings), and the ~800-file rename diff is slow to scan regardless. - scripts/base64-scan.sh: skip binary-by-content files (grep -Iq .) — they can't carry base64-obfuscated *text* and feeding NUL bytes through the per-line scanner is pathologically slow. collect_files already filtered binary *extensions*; this catches binary *content* in text extensions. - .github/workflows/security-scan.yml: raise the security job timeout 10m->30m to accommodate very large diffs (the scan itself is unchanged). Verified locally: scan skips the fixture, 0 "ignored null byte" warnings, 0 findings, exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): sweep get-shit-done refs introduced by merging next The branch was updated with next (#614/#384/#618 etc.), which reference the get-shit-done/ dir (still named that on next). Swept the stale references in the merged files to gsd-core so the rename stays consistent and lint:legacy-name passes: - commands/gsd/discuss-phase.md (runtime-launcher shim paths) - src/core.cts (getAgentsDir layout comments) - tests/bug-384-agents-runtime-aware.test.cjs (require path to runtime lib) Verified: guard 0 violations; build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): exclude gsd-core/ path segments from bug-3683 command cross-ref invariant The #614 runtime-launcher shim added to discuss-phase.md references `${_GSD_RUNTIME_ROOT}/gsd-core/bin/...`. bug-3683's REF_PATTERN excluded path-y refs only via lookbehind, but `}` precedes `/gsd-core/` in the shim, so it mis-read the directory path as a dangling `/gsd-core` command ref (same class as the #604 bug-2954 fix). Added a trailing `(?![\w-]*\/)` so `/gsd-<x>/...` path segments are not treated as slash-command references. Verified locally on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22 image) full suite: 0 failures - bug-3683 + bug-2954 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): lazily resolve findProjectRoot in gsd-tools (harden flaky CI) CI intermittently failed state.test's gsd-tools subprocess with "findProjectRoot is not a function" (flip-flopping across legs; not reproducible on mac full suite, gsd-test linux full suite, test:unit, or state.test x8). findProjectRoot is a re-export from core.cjs (sourced from project-root.cjs); binding it via destructure at module-load can be undefined under a load-ordering edge. Resolve it lazily at call time via a small wrapper so the lookup happens after core.cjs is fully initialized. Verified green on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22) full suite: 0 failures - state.test.cjs: 106/106; gsd-tools loads cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): allowlist verification-patterns.md placeholder examples in secret scan The rename git-mv'd references/verification-patterns.md into gsd-core/, pulling it into the secret-scan diff. It documents stub/placeholder RED-FLAG env-var examples (illustrative Stripe test-key / database-URL / API-key placeholders) — not real credentials. Added it to .secretscanignore with the strict annotation, mirroring the existing gsd-core/workflows/plan-phase.md exception. Verified locally: secret-scan-lint --strict OK; secret-scan --diff origin/next exits 0 with 0 findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
310
gsd-core/templates/codebase/concerns.md
Normal file
310
gsd-core/templates/codebase/concerns.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# Codebase Concerns Template
|
||||
|
||||
Template for `.planning/codebase/CONCERNS.md` - captures known issues and areas requiring care.
|
||||
|
||||
**Purpose:** Surface actionable warnings about the codebase. Focused on "what to watch out for when making changes."
|
||||
|
||||
---
|
||||
|
||||
## File Template
|
||||
|
||||
```markdown
|
||||
# Codebase Concerns
|
||||
|
||||
**Analysis Date:** [YYYY-MM-DD]
|
||||
|
||||
## Tech Debt
|
||||
|
||||
**[Area/Component]:**
|
||||
- Issue: [What's the shortcut/workaround]
|
||||
- Why: [Why it was done this way]
|
||||
- Impact: [What breaks or degrades because of it]
|
||||
- Fix approach: [How to properly address it]
|
||||
|
||||
**[Area/Component]:**
|
||||
- Issue: [What's the shortcut/workaround]
|
||||
- Why: [Why it was done this way]
|
||||
- Impact: [What breaks or degrades because of it]
|
||||
- Fix approach: [How to properly address it]
|
||||
|
||||
## Known Bugs
|
||||
|
||||
**[Bug description]:**
|
||||
- Symptoms: [What happens]
|
||||
- Trigger: [How to reproduce]
|
||||
- Workaround: [Temporary mitigation if any]
|
||||
- Root cause: [If known]
|
||||
- Blocked by: [If waiting on something]
|
||||
|
||||
**[Bug description]:**
|
||||
- Symptoms: [What happens]
|
||||
- Trigger: [How to reproduce]
|
||||
- Workaround: [Temporary mitigation if any]
|
||||
- Root cause: [If known]
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**[Area requiring security care]:**
|
||||
- Risk: [What could go wrong]
|
||||
- Current mitigation: [What's in place now]
|
||||
- Recommendations: [What should be added]
|
||||
|
||||
**[Area requiring security care]:**
|
||||
- Risk: [What could go wrong]
|
||||
- Current mitigation: [What's in place now]
|
||||
- Recommendations: [What should be added]
|
||||
|
||||
## Performance Bottlenecks
|
||||
|
||||
**[Slow operation/endpoint]:**
|
||||
- Problem: [What's slow]
|
||||
- Measurement: [Actual numbers: "500ms p95", "2s load time"]
|
||||
- Cause: [Why it's slow]
|
||||
- Improvement path: [How to speed it up]
|
||||
|
||||
**[Slow operation/endpoint]:**
|
||||
- Problem: [What's slow]
|
||||
- Measurement: [Actual numbers]
|
||||
- Cause: [Why it's slow]
|
||||
- Improvement path: [How to speed it up]
|
||||
|
||||
## Fragile Areas
|
||||
|
||||
**[Component/Module]:**
|
||||
- Why fragile: [What makes it break easily]
|
||||
- Common failures: [What typically goes wrong]
|
||||
- Safe modification: [How to change it without breaking]
|
||||
- Test coverage: [Is it tested? Gaps?]
|
||||
|
||||
**[Component/Module]:**
|
||||
- Why fragile: [What makes it break easily]
|
||||
- Common failures: [What typically goes wrong]
|
||||
- Safe modification: [How to change it without breaking]
|
||||
- Test coverage: [Is it tested? Gaps?]
|
||||
|
||||
## Scaling Limits
|
||||
|
||||
**[Resource/System]:**
|
||||
- Current capacity: [Numbers: "100 req/sec", "10k users"]
|
||||
- Limit: [Where it breaks]
|
||||
- Symptoms at limit: [What happens]
|
||||
- Scaling path: [How to increase capacity]
|
||||
|
||||
## Dependencies at Risk
|
||||
|
||||
**[Package/Service]:**
|
||||
- Risk: [e.g., "deprecated", "unmaintained", "breaking changes coming"]
|
||||
- Impact: [What breaks if it fails]
|
||||
- Migration plan: [Alternative or upgrade path]
|
||||
|
||||
## Missing Critical Features
|
||||
|
||||
**[Feature gap]:**
|
||||
- Problem: [What's missing]
|
||||
- Current workaround: [How users cope]
|
||||
- Blocks: [What can't be done without it]
|
||||
- Implementation complexity: [Rough effort estimate]
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
**[Untested area]:**
|
||||
- What's not tested: [Specific functionality]
|
||||
- Risk: [What could break unnoticed]
|
||||
- Priority: [High/Medium/Low]
|
||||
- Difficulty to test: [Why it's not tested yet]
|
||||
|
||||
---
|
||||
|
||||
*Concerns audit: [date]*
|
||||
*Update as issues are fixed or new ones discovered*
|
||||
```
|
||||
|
||||
<good_examples>
|
||||
```markdown
|
||||
# Codebase Concerns
|
||||
|
||||
**Analysis Date:** 2025-01-20
|
||||
|
||||
## Tech Debt
|
||||
|
||||
**Database queries in React components:**
|
||||
- Issue: Direct Supabase queries in 15+ page components instead of server actions
|
||||
- Files: `app/dashboard/page.tsx`, `app/profile/page.tsx`, `app/courses/[id]/page.tsx`, `app/settings/page.tsx` (and 11 more in `app/`)
|
||||
- Why: Rapid prototyping during MVP phase
|
||||
- Impact: Can't implement RLS properly, exposes DB structure to client
|
||||
- Fix approach: Move all queries to server actions in `app/actions/`, add proper RLS policies
|
||||
|
||||
**Manual webhook signature validation:**
|
||||
- Issue: Copy-pasted Stripe webhook verification code in 3 different endpoints
|
||||
- Files: `app/api/webhooks/stripe/route.ts`, `app/api/webhooks/checkout/route.ts`, `app/api/webhooks/subscription/route.ts`
|
||||
- Why: Each webhook added ad-hoc without abstraction
|
||||
- Impact: Easy to miss verification in new webhooks (security risk)
|
||||
- Fix approach: Create shared `lib/stripe/validate-webhook.ts` middleware
|
||||
|
||||
## Known Bugs
|
||||
|
||||
**Race condition in subscription updates:**
|
||||
- Symptoms: User shows as "free" tier for 5-10 seconds after successful payment
|
||||
- Trigger: Fast navigation after Stripe checkout redirect, before webhook processes
|
||||
- Files: `app/checkout/success/page.tsx` (redirect handler), `app/api/webhooks/stripe/route.ts` (webhook)
|
||||
- Workaround: Stripe webhook eventually updates status (self-heals)
|
||||
- Root cause: Webhook processing slower than user navigation, no optimistic UI update
|
||||
- Fix: Add polling in `app/checkout/success/page.tsx` after redirect
|
||||
|
||||
**Inconsistent session state after logout:**
|
||||
- Symptoms: User redirected to /dashboard after logout instead of /login
|
||||
- Trigger: Logout via button in mobile nav (desktop works fine)
|
||||
- File: `components/MobileNav.tsx` (line ~45, logout handler)
|
||||
- Workaround: Manual URL navigation to /login works
|
||||
- Root cause: Mobile nav component not awaiting supabase.auth.signOut()
|
||||
- Fix: Add await to logout handler in `components/MobileNav.tsx`
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**Admin role check client-side only:**
|
||||
- Risk: Admin dashboard pages check isAdmin from Supabase client, no server verification
|
||||
- Files: `app/admin/page.tsx`, `app/admin/users/page.tsx`, `components/AdminGuard.tsx`
|
||||
- Current mitigation: None (relying on UI hiding)
|
||||
- Recommendations: Add middleware to admin routes in `middleware.ts`, verify role server-side
|
||||
|
||||
**Unvalidated file uploads:**
|
||||
- Risk: Users can upload any file type to avatar bucket (no size/type validation)
|
||||
- File: `components/AvatarUpload.tsx` (upload handler)
|
||||
- Current mitigation: Supabase bucket limits to 2MB (configured in dashboard)
|
||||
- Recommendations: Add file type validation (image/* only) in `lib/storage/validate.ts`
|
||||
|
||||
## Performance Bottlenecks
|
||||
|
||||
**/api/courses endpoint:**
|
||||
- Problem: Fetching all courses with nested lessons and authors
|
||||
- File: `app/api/courses/route.ts`
|
||||
- Measurement: 1.2s p95 response time with 50+ courses
|
||||
- Cause: N+1 query pattern (separate query per course for lessons)
|
||||
- Improvement path: Use Prisma include to eager-load lessons in `lib/db/courses.ts`, add Redis caching
|
||||
|
||||
**Dashboard initial load:**
|
||||
- Problem: Waterfall of 5 serial API calls on mount
|
||||
- File: `app/dashboard/page.tsx`
|
||||
- Measurement: 3.5s until interactive on slow 3G
|
||||
- Cause: Each component fetches own data independently
|
||||
- Improvement path: Convert to Server Component with single parallel fetch
|
||||
|
||||
## Fragile Areas
|
||||
|
||||
**Authentication middleware chain:**
|
||||
- File: `middleware.ts`
|
||||
- Why fragile: 4 different middleware functions run in specific order (auth -> role -> subscription -> logging)
|
||||
- Common failures: Middleware order change breaks everything, hard to debug
|
||||
- Safe modification: Add tests before changing order, document dependencies in comments
|
||||
- Test coverage: No integration tests for middleware chain (only unit tests)
|
||||
|
||||
**Stripe webhook event handling:**
|
||||
- File: `app/api/webhooks/stripe/route.ts`
|
||||
- Why fragile: Giant switch statement with 12 event types, shared transaction logic
|
||||
- Common failures: New event type added without handling, partial DB updates on error
|
||||
- Safe modification: Extract each event handler to `lib/stripe/handlers/*.ts`
|
||||
- Test coverage: Only 3 of 12 event types have tests
|
||||
|
||||
## Scaling Limits
|
||||
|
||||
**Supabase Free Tier:**
|
||||
- Current capacity: 500MB database, 1GB file storage, 2GB bandwidth/month
|
||||
- Limit: ~5000 users estimated before hitting limits
|
||||
- Symptoms at limit: 429 rate limit errors, DB writes fail
|
||||
- Scaling path: Upgrade to Pro ($25/mo) extends to 8GB DB, 100GB storage
|
||||
|
||||
**Server-side render blocking:**
|
||||
- Current capacity: ~50 concurrent users before slowdown
|
||||
- Limit: Vercel Hobby plan (10s function timeout, 100GB-hrs/mo)
|
||||
- Symptoms at limit: 504 gateway timeouts on course pages
|
||||
- Scaling path: Upgrade to Vercel Pro ($20/mo), add edge caching
|
||||
|
||||
## Dependencies at Risk
|
||||
|
||||
**react-hot-toast:**
|
||||
- Risk: Unmaintained (last update 18 months ago), React 19 compatibility unknown
|
||||
- Impact: Toast notifications break, no graceful degradation
|
||||
- Migration plan: Switch to sonner (actively maintained, similar API)
|
||||
|
||||
## Missing Critical Features
|
||||
|
||||
**Payment failure handling:**
|
||||
- Problem: No retry mechanism or user notification when subscription payment fails
|
||||
- Current workaround: Users manually re-enter payment info (if they notice)
|
||||
- Blocks: Can't retain users with expired cards, no dunning process
|
||||
- Implementation complexity: Medium (Stripe webhooks + email flow + UI)
|
||||
|
||||
**Course progress tracking:**
|
||||
- Problem: No persistent state for which lessons completed
|
||||
- Current workaround: Users manually track progress
|
||||
- Blocks: Can't show completion percentage, can't recommend next lesson
|
||||
- Implementation complexity: Low (add completed_lessons junction table)
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
**Payment flow end-to-end:**
|
||||
- What's not tested: Full Stripe checkout -> webhook -> subscription activation flow
|
||||
- Risk: Payment processing could break silently (has happened twice)
|
||||
- Priority: High
|
||||
- Difficulty to test: Need Stripe test fixtures and webhook simulation setup
|
||||
|
||||
**Error boundary behavior:**
|
||||
- What's not tested: How app behaves when components throw errors
|
||||
- Risk: White screen of death for users, no error reporting
|
||||
- Priority: Medium
|
||||
- Difficulty to test: Need to intentionally trigger errors in test environment
|
||||
|
||||
---
|
||||
|
||||
*Concerns audit: 2025-01-20*
|
||||
*Update as issues are fixed or new ones discovered*
|
||||
```
|
||||
</good_examples>
|
||||
|
||||
<guidelines>
|
||||
**What belongs in CONCERNS.md:**
|
||||
- Tech debt with clear impact and fix approach
|
||||
- Known bugs with reproduction steps
|
||||
- Security gaps and mitigation recommendations
|
||||
- Performance bottlenecks with measurements
|
||||
- Fragile code that breaks easily
|
||||
- Scaling limits with numbers
|
||||
- Dependencies that need attention
|
||||
- Missing features that block workflows
|
||||
- Test coverage gaps
|
||||
|
||||
**What does NOT belong here:**
|
||||
- Opinions without evidence ("code is messy")
|
||||
- Complaints without solutions ("auth sucks")
|
||||
- Future feature ideas (that's for product planning)
|
||||
- Normal TODOs (those live in code comments)
|
||||
- Architectural decisions that are working fine
|
||||
- Minor code style issues
|
||||
|
||||
**When filling this template:**
|
||||
- **Always include file paths** - Concerns without locations are not actionable. Use backticks: `src/file.ts`
|
||||
- Be specific with measurements ("500ms p95" not "slow")
|
||||
- Include reproduction steps for bugs
|
||||
- Suggest fix approaches, not just problems
|
||||
- Focus on actionable items
|
||||
- Prioritize by risk/impact
|
||||
- Update as issues get resolved
|
||||
- Add new concerns as discovered
|
||||
|
||||
**Tone guidelines:**
|
||||
- Professional, not emotional ("N+1 query pattern" not "terrible queries")
|
||||
- Solution-oriented ("Fix: add index" not "needs fixing")
|
||||
- Risk-focused ("Could expose user data" not "security is bad")
|
||||
- Factual ("3.5s load time" not "really slow")
|
||||
|
||||
**Useful for phase planning when:**
|
||||
- Deciding what to work on next
|
||||
- Estimating risk of changes
|
||||
- Understanding where to be careful
|
||||
- Prioritizing improvements
|
||||
- Onboarding new Claude contexts
|
||||
- Planning refactoring work
|
||||
|
||||
**How this gets populated:**
|
||||
Explore agents detect these during codebase mapping. Manual additions welcome for human-discovered issues. This is living documentation, not a complaint list.
|
||||
</guidelines>
|
||||
Reference in New Issue
Block a user