From 2b0ee98806acae500f462be36911c4f59e357886 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Wed, 8 Apr 2026 12:45:33 -0400 Subject: [PATCH 1/3] Add domain probes, stub detection, and symptom triage from GSD patterns - references/domain-probes.md: domain-specific gray-area questions for feature brainstorming (auth, API, database, UI, etc.) - references/stub-patterns.md: mechanical grep patterns for detecting unfinished work (empty impls, placeholders, hardcoded values, skipped tests) - debug-checklists.md: symptom-to-category triage table for routing to the right domain checklist when the bug type isn't obvious - feature.md: reference domain probes in brainstorm step - self-audit.md: reference stub patterns in stale code section --- commands/feature.md | 5 +- commands/references/debug-checklists.md | 16 +++++ commands/references/domain-probes.md | 79 +++++++++++++++++++++++++ commands/references/stub-patterns.md | 63 ++++++++++++++++++++ commands/self-audit.md | 2 + 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 commands/references/domain-probes.md create mode 100644 commands/references/stub-patterns.md diff --git a/commands/feature.md b/commands/feature.md index a2bf79f..ee4241b 100644 --- a/commands/feature.md +++ b/commands/feature.md @@ -8,6 +8,8 @@ Complete feature lifecycle: brainstorm → plan → implement → test → lint ## Step 1: Brainstorm +Identify the feature's domain (auth, API, database, UI, etc.) and read the matching section from `references/domain-probes.md` to surface gray areas. Use the probes to ask targeted questions via `AskUserQuestion` — only for genuinely ambiguous decisions, not obvious ones. Skip probing if the user's input already resolves the gray areas. + ``` Feature: {user's input} @@ -16,8 +18,9 @@ Think through the design: - What's the simplest approach that works? - What are the risks or unknowns? - Are there edge cases to handle upfront? +- What gray areas need user input before planning? (use domain probes) -Produce a short design summary. Don't write code yet. +Produce a short design summary with decisions locked. Don't write code yet. ``` ## Step 2: Plan diff --git a/commands/references/debug-checklists.md b/commands/references/debug-checklists.md index 010f48c..8acc084 100644 --- a/commands/references/debug-checklists.md +++ b/commands/references/debug-checklists.md @@ -2,6 +2,22 @@ Domain-specific checklists for inclusion in debug agent prompts. Include only the relevant checklist based on the identified bug domain. +## Symptom Triage + +When the bug domain isn't obvious, use the symptom to route to the right checklist: + +| Symptom | Check first | +|---------|------------| +| "Cannot read property of undefined/null" | API Bugs (response shape), Auth Bugs (missing token) | +| "X is not a function" | API Bugs (import/module), Async Bugs (missing await) | +| Works sometimes, fails sometimes | Async/Concurrency Bugs | +| Works locally, fails in CI/prod | Auth Bugs (env config), Database Bugs (schema drift) | +| Wrong data displayed | Database Bugs (stale data), API Bugs (query params) | +| Timeout or hang | Database Bugs (pool exhaustion), Performance Bugs | +| Memory leak / growing resource usage | Async Bugs (listener leak), Performance Bugs | +| 401/403 after deploy | Auth Bugs (token/session mismatch) | +| Slow response | Performance Bugs | + ## API Bugs - Does the route exist and match the HTTP method? - Is auth middleware applied and in the correct order? diff --git a/commands/references/domain-probes.md b/commands/references/domain-probes.md new file mode 100644 index 0000000..78495af --- /dev/null +++ b/commands/references/domain-probes.md @@ -0,0 +1,79 @@ +# Domain-Aware Probing Patterns + +When brainstorming a feature, identify its domain and use the matching probes to surface gray areas before planning. Load only the relevant domain — not the full file. + +## Authentication + +| User mentions | Probe | +|---|---| +| "login" / "auth" | OAuth, email/password, magic link, or SSO? | +| "sign up" | Required fields? Email verification? | +| "MFA" / "2FA" | TOTP, SMS, or passkey? Recovery flow? | +| "session" | Duration? Refresh strategy? Multi-device? | +| "roles" / "permissions" | RBAC, ABAC, or simple admin/user? Granularity? | + +## Real-Time / WebSockets + +| User mentions | Probe | +|---|---| +| "real-time" / "live" | WebSocket, SSE, or polling? Acceptable latency? | +| "notifications" | In-app, push, email, or all three? Batching? | +| "collaboration" | Conflict resolution strategy? Presence indicators? | +| "chat" / "messaging" | Message persistence? Read receipts? Typing indicators? | + +## Dashboard / Data Display + +| User mentions | Probe | +|---|---| +| "dashboard" | Data sources? How many distinct views? | +| "charts" / "graphs" | Interactive or static? Drill-down? Export? | +| "metrics" / "KPIs" | Refresh — real-time, polling, or on-demand? Acceptable staleness? | +| "admin panel" | Role-based visibility? Actions beyond viewing? | +| "table" / "list" | Pagination, infinite scroll, or load-all? Sorting? Filtering? | + +## API Design + +| User mentions | Probe | +|---|---| +| "API" / "endpoints" | REST, GraphQL, or RPC? Versioning strategy? | +| "pagination" | Cursor, offset, or keyset? Default page size? | +| "rate limiting" | Per-user, per-key, or global? Limits? | +| "webhooks" | Retry policy? Signature verification? | +| "file upload" | Max size? Allowed types? Direct-to-storage or through API? | + +## Database / Storage + +| User mentions | Probe | +|---|---| +| "database" | SQL or NoSQL? Why? Expected scale? | +| "migration" | Zero-downtime required? Rollback strategy? | +| "caching" | What layer? TTL? Invalidation strategy? | +| "search" | Full-text, fuzzy, or exact? Dedicated search engine? | +| "file storage" | Local, S3, or CDN? Access control? | + +## UI / Frontend + +| User mentions | Probe | +|---|---| +| "form" | Validation — client, server, or both? Multi-step? | +| "mobile" | Responsive web, native, or PWA? Offline support? | +| "dark mode" / "theme" | System preference, user toggle, or both? | +| "loading" / "skeleton" | Skeleton screens, spinners, or progressive? | +| "empty state" | What shows when there's no data? CTA? | + +## Testing + +| User mentions | Probe | +|---|---| +| "tests" | Unit, integration, e2e, or all? Coverage target? | +| "CI" | Which provider? Required checks before merge? | +| "staging" | Separate environment? Data strategy (seed, copy, synthetic)? | + +## Deployment + +| User mentions | Probe | +|---|---| +| "deploy" | Manual, CI/CD, or GitOps? Rollback strategy? | +| "environment" | How many? (dev, staging, prod) Config management? | +| "Docker" / "container" | Orchestration? Health checks? Resource limits? | +| "serverless" | Cold start acceptable? Timeout limits? | diff --git a/commands/references/stub-patterns.md b/commands/references/stub-patterns.md new file mode 100644 index 0000000..3add9c5 --- /dev/null +++ b/commands/references/stub-patterns.md @@ -0,0 +1,63 @@ +# Stub & Placeholder Detection Patterns + +Mechanical grep patterns for detecting unfinished work. Use in self-audit's Stale Code section or tri-review to flag incomplete implementations. + +## TODO/FIXME Comments + +```bash +grep -rn 'TODO\|FIXME\|HACK\|XXX\|PLACEHOLDER' \ + --include='*.go' --include='*.ts' --include='*.js' \ + --include='*.py' --include='*.rs' --include='*.rb' . 2>/dev/null +``` + +## Empty or Trivial Implementations + +```bash +# Functions that return nothing useful +grep -rn 'return nil$\|return null\|return undefined\|return {}\|return \[\]' \ + --include='*.go' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null + +# Python pass-only functions +grep -rn '^\s*pass$' --include='*.py' . 2>/dev/null + +# Empty catch/error blocks +grep -rn 'catch.*{}\|catch.*{\s*}' --include='*.ts' --include='*.js' . 2>/dev/null +grep -rn 'except.*:\s*$' --include='*.py' -A1 . 2>/dev/null | grep 'pass' +``` + +## Placeholder Text + +```bash +# UI placeholders left in +grep -rni 'lorem ipsum\|coming soon\|under construction\|placeholder' \ + --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' \ + --include='*.html' --include='*.vue' --include='*.svelte' . 2>/dev/null + +# Template brackets left in +grep -rn '\[TODO\]\|\|{TODO}' \ + --include='*.md' --include='*.ts' --include='*.go' . 2>/dev/null +``` + +## Hardcoded Values Where Dynamic Expected + +```bash +# Hardcoded IDs or secrets (not in test files) +grep -rn 'api_key\s*=\s*"[^"]\+"\|password\s*=\s*"[^"]\+"' \ + --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | grep -v '_test\.\|\.test\.\|\.spec\.' + +# Hardcoded URLs (not config/const files) +grep -rn 'http://localhost\|127\.0\.0\.1' \ + --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | grep -v 'config\|const\|test\|spec' +``` + +## Disabled or Skipped Tests + +```bash +# Skipped tests +grep -rn '\.Skip\|t\.Skip\|xit(\|xdescribe(\|@pytest\.mark\.skip\|@unittest\.skip' \ + --include='*.go' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null + +# Commented-out test blocks +grep -rn '// func Test\|// it(\|// test(\|# def test_' \ + --include='*.go' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null +``` diff --git a/commands/self-audit.md b/commands/self-audit.md index 9cb447f..fc58d8a 100644 --- a/commands/self-audit.md +++ b/commands/self-audit.md @@ -91,6 +91,8 @@ grep -rn 'api_key\s*=\s*"[^"]*"' --include='*.go' --include='*.ts' --include='*. grep -rn 'TODO\|FIXME\|HACK\|XXX' --include='*.go' --include='*.ts' --include='*.py' --include='*.rs' . 2>/dev/null | wc -l ``` +For deeper stub detection (empty implementations, placeholder text, hardcoded values, skipped tests), run the patterns from `references/stub-patterns.md`. Only use these when the basic TODO count suggests stale code worth investigating. + ### Documentation ```bash From e53410f40b9aa8c04bf77769646f2cbc90729878 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Wed, 8 Apr 2026 12:50:05 -0400 Subject: [PATCH 2/3] Address tri-agent review findings stub-patterns.md: - Add false-positive caveat for return nil/null/{}/[] - Fix grep portability: use -E flag instead of \s for macOS compat - Remove fragile Python except pipe pattern - Add *.tsx/*.jsx to TODO, hardcoded-value, and catch-block patterns - Add overall "matches require manual review" disclaimer self-audit.md: - Run stub detection unconditionally, not gated on TODO count feature.md: - Support multiple domains per feature (auth + API + UI) - Skip probing when no domain section matches debug-checklists.md: - Merge duplicate Quick Symptom Lookup into Performance Bugs checklist to eliminate DRY violation with Symptom Triage table --- commands/feature.md | 2 +- commands/references/debug-checklists.md | 17 +++++------------ commands/references/stub-patterns.md | 23 +++++++++++++---------- commands/self-audit.md | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/commands/feature.md b/commands/feature.md index ee4241b..c9fc738 100644 --- a/commands/feature.md +++ b/commands/feature.md @@ -8,7 +8,7 @@ Complete feature lifecycle: brainstorm → plan → implement → test → lint ## Step 1: Brainstorm -Identify the feature's domain (auth, API, database, UI, etc.) and read the matching section from `references/domain-probes.md` to surface gray areas. Use the probes to ask targeted questions via `AskUserQuestion` — only for genuinely ambiguous decisions, not obvious ones. Skip probing if the user's input already resolves the gray areas. +Identify the feature's relevant domains (auth, API, database, UI, etc. — features often span multiple) and read each matching section from `references/domain-probes.md` to surface gray areas. If no section matches, skip domain probing. Use the probes to ask targeted questions via `AskUserQuestion` — only for genuinely ambiguous decisions, not obvious ones. Skip probing if the user's input already resolves the gray areas. ``` Feature: {user's input} diff --git a/commands/references/debug-checklists.md b/commands/references/debug-checklists.md index 8acc084..2192295 100644 --- a/commands/references/debug-checklists.md +++ b/commands/references/debug-checklists.md @@ -46,15 +46,8 @@ When the bug domain isn't obvious, use the symptom to route to the right checkli ## Performance Bugs - Profile first — the slow part is almost never where you think -- Check for N+1 queries, missing indexes, unbounded loops -- Memory leak? Compare heap snapshots over time -- Connection pool or thread pool exhaustion? - -### Quick Symptom Lookup - -| Symptom | Likely Cause | Investigation | -|---------|--------------|---------------| -| Slow API response | N+1 queries | Log SQL count per request | -| Slow page render | Expensive recomputation | Profile render cycle | -| Gradual memory growth | Leak (listeners, connections) | Heap snapshots over time | -| Intermittent slowness | Lock contention / pool exhaustion | Connection pool metrics | +- Slow API response? Log SQL count per request — likely N+1 queries +- Slow page render? Profile the render cycle — likely expensive recomputation +- Gradual memory growth? Heap snapshots over time — likely leaked listeners or connections +- Intermittent slowness? Check connection pool metrics — likely lock contention or pool exhaustion +- Check for missing indexes and unbounded loops diff --git a/commands/references/stub-patterns.md b/commands/references/stub-patterns.md index 3add9c5..25b9267 100644 --- a/commands/references/stub-patterns.md +++ b/commands/references/stub-patterns.md @@ -2,27 +2,30 @@ Mechanical grep patterns for detecting unfinished work. Use in self-audit's Stale Code section or tri-review to flag incomplete implementations. +All matches require manual review — these are heuristics, not definitive indicators. + ## TODO/FIXME Comments ```bash grep -rn 'TODO\|FIXME\|HACK\|XXX\|PLACEHOLDER' \ - --include='*.go' --include='*.ts' --include='*.js' \ + --include='*.go' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' \ --include='*.py' --include='*.rs' --include='*.rb' . 2>/dev/null ``` ## Empty or Trivial Implementations ```bash -# Functions that return nothing useful -grep -rn 'return nil$\|return null\|return undefined\|return {}\|return \[\]' \ +# Functions that return nothing useful — high false-positive rate. +# Filter results manually: return nil/null/{}/[] is often legitimate. +# Strongest signal when combined with TODO/FIXME nearby. +grep -rn 'return nil\|return null\|return undefined' \ --include='*.go' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null # Python pass-only functions -grep -rn '^\s*pass$' --include='*.py' . 2>/dev/null +grep -rn 'pass$' --include='*.py' . 2>/dev/null -# Empty catch/error blocks -grep -rn 'catch.*{}\|catch.*{\s*}' --include='*.ts' --include='*.js' . 2>/dev/null -grep -rn 'except.*:\s*$' --include='*.py' -A1 . 2>/dev/null | grep 'pass' +# Empty catch/error blocks (use grep -E for extended regex portability) +grep -rEn 'catch[^{]*\{\s*\}' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' . 2>/dev/null ``` ## Placeholder Text @@ -35,7 +38,7 @@ grep -rni 'lorem ipsum\|coming soon\|under construction\|placeholder' \ # Template brackets left in grep -rn '\[TODO\]\|\|{TODO}' \ - --include='*.md' --include='*.ts' --include='*.go' . 2>/dev/null + --include='*.md' --include='*.ts' --include='*.tsx' --include='*.go' . 2>/dev/null ``` ## Hardcoded Values Where Dynamic Expected @@ -43,11 +46,11 @@ grep -rn '\[TODO\]\|\|{TODO}' \ ```bash # Hardcoded IDs or secrets (not in test files) grep -rn 'api_key\s*=\s*"[^"]\+"\|password\s*=\s*"[^"]\+"' \ - --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | grep -v '_test\.\|\.test\.\|\.spec\.' + --include='*.go' --include='*.ts' --include='*.tsx' --include='*.py' . 2>/dev/null | grep -v '_test\.\|\.test\.\|\.spec\.' # Hardcoded URLs (not config/const files) grep -rn 'http://localhost\|127\.0\.0\.1' \ - --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | grep -v 'config\|const\|test\|spec' + --include='*.go' --include='*.ts' --include='*.tsx' --include='*.py' . 2>/dev/null | grep -v 'config\|const\|test\|spec' ``` ## Disabled or Skipped Tests diff --git a/commands/self-audit.md b/commands/self-audit.md index fc58d8a..491f4ae 100644 --- a/commands/self-audit.md +++ b/commands/self-audit.md @@ -91,7 +91,7 @@ grep -rn 'api_key\s*=\s*"[^"]*"' --include='*.go' --include='*.ts' --include='*. grep -rn 'TODO\|FIXME\|HACK\|XXX' --include='*.go' --include='*.ts' --include='*.py' --include='*.rs' . 2>/dev/null | wc -l ``` -For deeper stub detection (empty implementations, placeholder text, hardcoded values, skipped tests), run the patterns from `references/stub-patterns.md`. Only use these when the basic TODO count suggests stale code worth investigating. +For deeper stub detection (empty implementations, placeholder text, hardcoded values, skipped tests), run the patterns from `references/stub-patterns.md`. Run unconditionally — a repo can have zero TODOs but still contain empty catch blocks, placeholder UI copy, or hardcoded localhost URLs. ### Documentation From 69e482230adad43f70b5fa3e83a7ed2373a1f404 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Wed, 8 Apr 2026 12:58:10 -0400 Subject: [PATCH 3/3] Address PR review-toolkit findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stub-patterns.md: - Split return-nothing grep by language (nil→Go, null/undefined→TS/JS, None→Python) - Fix pass$ regex to use word-boundary pattern (was matching bypass, overpass) - Add test_ prefix to Python test file exclusion self-audit.md: - Align inline TODO grep with stub-patterns.md canonical list (add tsx/jsx/rb/PLACEHOLDER) - Defer hardcoded secrets check to stub-patterns.md (was inconsistent: missing tsx, no test exclusion) --- commands/references/stub-patterns.md | 13 +++++++------ commands/self-audit.md | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/commands/references/stub-patterns.md b/commands/references/stub-patterns.md index 25b9267..dabd139 100644 --- a/commands/references/stub-patterns.md +++ b/commands/references/stub-patterns.md @@ -16,13 +16,14 @@ grep -rn 'TODO\|FIXME\|HACK\|XXX\|PLACEHOLDER' \ ```bash # Functions that return nothing useful — high false-positive rate. -# Filter results manually: return nil/null/{}/[] is often legitimate. +# Filter results manually: these returns are often legitimate. # Strongest signal when combined with TODO/FIXME nearby. -grep -rn 'return nil\|return null\|return undefined' \ - --include='*.go' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null +grep -rn 'return nil' --include='*.go' . 2>/dev/null +grep -rn 'return null\|return undefined' --include='*.ts' --include='*.js' . 2>/dev/null +grep -rn 'return None' --include='*.py' . 2>/dev/null -# Python pass-only functions -grep -rn 'pass$' --include='*.py' . 2>/dev/null +# Python pass-only functions (indented pass on its own line) +grep -rEn '^[[:space:]]+pass[[:space:]]*$' --include='*.py' . 2>/dev/null # Empty catch/error blocks (use grep -E for extended regex portability) grep -rEn 'catch[^{]*\{\s*\}' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' . 2>/dev/null @@ -46,7 +47,7 @@ grep -rn '\[TODO\]\|\|{TODO}' \ ```bash # Hardcoded IDs or secrets (not in test files) grep -rn 'api_key\s*=\s*"[^"]\+"\|password\s*=\s*"[^"]\+"' \ - --include='*.go' --include='*.ts' --include='*.tsx' --include='*.py' . 2>/dev/null | grep -v '_test\.\|\.test\.\|\.spec\.' + --include='*.go' --include='*.ts' --include='*.tsx' --include='*.py' . 2>/dev/null | grep -v '_test\.\|\.test\.\|\.spec\.\|test_' # Hardcoded URLs (not config/const files) grep -rn 'http://localhost\|127\.0\.0\.1' \ diff --git a/commands/self-audit.md b/commands/self-audit.md index 491f4ae..7082295 100644 --- a/commands/self-audit.md +++ b/commands/self-audit.md @@ -75,9 +75,8 @@ Record: total coverage %, lowest-coverage packages, untested files. # Python: pip-audit or safety check # Rust: cargo audit -# Hardcoded secrets -grep -rn 'password\s*=\s*"[^"]*"' --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | head -5 -grep -rn 'api_key\s*=\s*"[^"]*"' --include='*.go' --include='*.ts' --include='*.py' . 2>/dev/null | head -5 +# Hardcoded secrets — use the patterns from references/stub-patterns.md +# "Hardcoded Values Where Dynamic Expected" section (excludes test files, includes .tsx) ``` ### Stale Code @@ -87,8 +86,10 @@ grep -rn 'api_key\s*=\s*"[^"]*"' --include='*.go' --include='*.ts' --include='*. # Unused dependencies # go mod tidy -diff (shows removable deps) # npm prune --dry-run -# TODO/FIXME/HACK count -grep -rn 'TODO\|FIXME\|HACK\|XXX' --include='*.go' --include='*.ts' --include='*.py' --include='*.rs' . 2>/dev/null | wc -l +# TODO/FIXME/HACK count — matches stub-patterns.md canonical list +grep -rn 'TODO\|FIXME\|HACK\|XXX\|PLACEHOLDER' \ + --include='*.go' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' \ + --include='*.py' --include='*.rs' --include='*.rb' . 2>/dev/null | wc -l ``` For deeper stub detection (empty implementations, placeholder text, hardcoded values, skipped tests), run the patterns from `references/stub-patterns.md`. Run unconditionally — a repo can have zero TODOs but still contain empty catch blocks, placeholder UI copy, or hardcoded localhost URLs.