tribunal-kit 6.0.0 → 7.0.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.
- package/.agent/.manifest.json +78 -0
- package/.agent/ARCHITECTURE.md +19 -241
- package/.agent/agents/accessibility-reviewer.md +23 -16
- package/.agent/agents/ai-code-reviewer.md +25 -21
- package/.agent/agents/anti-pattern-reviewer.md +12 -7
- package/.agent/agents/api-architect.md +1 -0
- package/.agent/agents/backend-specialist.md +23 -22
- package/.agent/agents/cloud-engineer.md +1 -0
- package/.agent/agents/code-archaeologist.md +1 -0
- package/.agent/agents/complexity-reviewer.md +10 -7
- package/.agent/agents/database-architect.md +3 -2
- package/.agent/agents/db-latency-auditor.md +6 -2
- package/.agent/agents/debugger.md +3 -2
- package/.agent/agents/dependency-reviewer.md +1 -0
- package/.agent/agents/devops-engineer.md +9 -8
- package/.agent/agents/documentation-writer.md +6 -5
- package/.agent/agents/explorer-agent.md +1 -0
- package/.agent/agents/frontend-reviewer.md +21 -17
- package/.agent/agents/frontend-specialist.md +23 -20
- package/.agent/agents/game-developer.md +1 -0
- package/.agent/agents/interaction-reviewer.md +10 -5
- package/.agent/agents/logic-reviewer.md +3 -0
- package/.agent/agents/minimalist-reviewer.md +6 -0
- package/.agent/agents/mobile-developer.md +7 -6
- package/.agent/agents/mobile-reviewer.md +14 -13
- package/.agent/agents/orchestrator.md +3 -0
- package/.agent/agents/penetration-tester.md +1 -0
- package/.agent/agents/performance-optimizer.md +6 -5
- package/.agent/agents/performance-reviewer.md +6 -6
- package/.agent/agents/pipeline-reviewer.md +144 -0
- package/.agent/agents/precedence-reviewer.md +1 -0
- package/.agent/agents/product-manager.md +1 -0
- package/.agent/agents/product-owner.md +1 -0
- package/.agent/agents/product-reviewer.md +12 -7
- package/.agent/agents/project-planner.md +3 -0
- package/.agent/agents/qa-automation-engineer.md +50 -43
- package/.agent/agents/resilience-reviewer.md +1 -0
- package/.agent/agents/schema-reviewer.md +1 -0
- package/.agent/agents/security-auditor.md +24 -24
- package/.agent/agents/seo-specialist.md +33 -23
- package/.agent/agents/sql-reviewer.md +5 -4
- package/.agent/agents/supervisor-agent.md +12 -2
- package/.agent/agents/swarm-worker-contracts.md +13 -13
- package/.agent/agents/swarm-worker-registry.md +51 -51
- package/.agent/agents/system-architect.md +1 -0
- package/.agent/agents/test-coverage-reviewer.md +25 -22
- package/.agent/agents/test-engineer.md +12 -11
- package/.agent/agents/throughput-optimizer.md +45 -40
- package/.agent/agents/type-safety-reviewer.md +5 -4
- package/.agent/agents/ui-ux-auditor.md +6 -4
- package/.agent/agents/ui-visual-auditor.md +3 -0
- package/.agent/agents/ux-reviewer.md +11 -6
- package/.agent/agents/visual-reviewer.md +11 -6
- package/.agent/agents/vitals-reviewer.md +5 -4
- package/.agent/history/memory/.memory.idx +3716 -1
- package/.agent/history/memory/MEMORY.md +246 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2034 -263
- package/.agent/rules/GEMINI.md +12 -10
- package/.agent/rules/GEMINI_PLANNER.md +19 -21
- package/.agent/scripts/_colors.js +52 -54
- package/.agent/scripts/_utils.js +52 -53
- package/.agent/scripts/auto_preview.js +39 -43
- package/.agent/scripts/bundle_analyzer.js +47 -60
- package/.agent/scripts/case_law_manager.js +200 -294
- package/.agent/scripts/checklist.js +73 -94
- package/.agent/scripts/cicd_validator.js +305 -0
- package/.agent/scripts/compile_router.py +4 -111
- package/.agent/scripts/context_broker.js +317 -412
- package/.agent/scripts/contract_engine.js +402 -0
- package/.agent/scripts/dependency_analyzer.js +112 -124
- package/.agent/scripts/graph_builder.js +75 -103
- package/.agent/scripts/graph_visualizer.js +10 -12
- package/.agent/scripts/graph_zoom.js +38 -55
- package/.agent/scripts/guardrail_engine.js +195 -145
- package/.agent/scripts/impact_classifier.js +55 -30
- package/.agent/scripts/inner_loop_validator.js +108 -159
- package/.agent/scripts/integrity_manifest.js +59 -67
- package/.agent/scripts/lint_runner.js +65 -75
- package/.agent/scripts/marathon_harness.js +131 -208
- package/.agent/scripts/migrate_skills_frontmatter.py +4 -63
- package/.agent/scripts/minify_context.js +29 -33
- package/.agent/scripts/minimal_change_engine.js +95 -87
- package/.agent/scripts/mutation_runner.js +46 -62
- package/.agent/scripts/pipeline_engine.js +320 -209
- package/.agent/scripts/prompt_compiler.js +118 -93
- package/.agent/scripts/schema_validator.js +73 -121
- package/.agent/scripts/security_scan.js +88 -117
- package/.agent/scripts/session_manager.js +52 -69
- package/.agent/scripts/signal_detector.js +24 -22
- package/.agent/scripts/skill_evolution.js +184 -245
- package/.agent/scripts/skill_integrator.js +35 -48
- package/.agent/scripts/socratic_gate_policy.js +15 -12
- package/.agent/scripts/strengthen_skills.js +29 -33
- package/.agent/scripts/swarm_dispatcher.js +120 -151
- package/.agent/scripts/test_runner.js +54 -56
- package/.agent/scripts/token_budget_broker.js +9 -7
- package/.agent/scripts/trace_engine.js +126 -0
- package/.agent/scripts/verify_all.js +76 -93
- package/.agent/scripts/visual_audit.js +16 -21
- package/.agent/skill_topic_map.json +237 -0
- package/.agent/skills/12-principles-of-animation/SKILL.md +7 -0
- package/.agent/skills/60fps-animation/SKILL.md +7 -0
- package/.agent/skills/accessible-animation/SKILL.md +5 -1
- package/.agent/skills/adapt/SKILL.md +7 -1
- package/.agent/skills/advanced-rag-pipelines/SKILL.md +1 -0
- package/.agent/skills/agent-organizer/SKILL.md +1 -0
- package/.agent/skills/agentic-patterns/SKILL.md +33 -25
- package/.agent/skills/agentic-workflows-2026/SKILL.md +80 -0
- package/.agent/skills/ai-app-hardening/SKILL.md +59 -0
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +7 -6
- package/.agent/skills/animation-on-scroll/SKILL.md +24 -15
- package/.agent/skills/animation-systems/SKILL.md +11 -10
- package/.agent/skills/antfu-conventions/SKILL.md +7 -2
- package/.agent/skills/api-patterns/SKILL.md +14 -10
- package/.agent/skills/api-security-auditor/SKILL.md +15 -14
- package/.agent/skills/app-builder/SKILL.md +1 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +2 -2
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +12 -12
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +3 -3
- package/.agent/skills/apple-design/SKILL.md +8 -7
- package/.agent/skills/architecture/SKILL.md +3 -2
- package/.agent/skills/audit-and-fix/SKILL.md +8 -5
- package/.agent/skills/authentication-best-practices/SKILL.md +9 -8
- package/.agent/skills/backend-security-expert/SKILL.md +1 -0
- package/.agent/skills/baseline-ui/SKILL.md +8 -7
- package/.agent/skills/bash-linux/SKILL.md +1 -0
- package/.agent/skills/behavioral-modes/SKILL.md +1 -0
- package/.agent/skills/better-colors/SKILL.md +11 -7
- package/.agent/skills/better-typography/SKILL.md +30 -16
- package/.agent/skills/better-ui/SKILL.md +17 -10
- package/.agent/skills/bolder/SKILL.md +6 -0
- package/.agent/skills/brainstorming/SKILL.md +6 -4
- package/.agent/skills/browser-native-ai/SKILL.md +5 -4
- package/.agent/skills/build-primitive/SKILL.md +5 -0
- package/.agent/skills/building-native-ui/SKILL.md +1 -0
- package/.agent/skills/cicd-pro/SKILL.md +2 -1
- package/.agent/skills/clarify/SKILL.md +19 -14
- package/.agent/skills/clean-code/SKILL.md +16 -15
- package/.agent/skills/cloud-architect/SKILL.md +1 -0
- package/.agent/skills/cobejs/SKILL.md +7 -9
- package/.agent/skills/code-review-checklist/SKILL.md +1 -0
- package/.agent/skills/codebase-design/SKILL.md +7 -2
- package/.agent/skills/colorize/SKILL.md +8 -3
- package/.agent/skills/compact-landing/SKILL.md +8 -3
- package/.agent/skills/company-logos/SKILL.md +6 -0
- package/.agent/skills/config-validator/SKILL.md +10 -9
- package/.agent/skills/containerization-pro/SKILL.md +6 -5
- package/.agent/skills/context-engineering-pro/SKILL.md +70 -0
- package/.agent/skills/create-design-md/SKILL.md +13 -5
- package/.agent/skills/critique/SKILL.md +10 -8
- package/.agent/skills/csharp-developer/SKILL.md +1 -0
- package/.agent/skills/data-validation-schemas/SKILL.md +28 -23
- package/.agent/skills/database-design/SKILL.md +2 -1
- package/.agent/skills/delight/SKILL.md +6 -0
- package/.agent/skills/deployment-procedures/SKILL.md +2 -1
- package/.agent/skills/design-lab/SKILL.md +5 -0
- package/.agent/skills/devops-engineer/SKILL.md +3 -2
- package/.agent/skills/devops-incident-responder/SKILL.md +2 -1
- package/.agent/skills/diagnosing-bugs/SKILL.md +12 -2
- package/.agent/skills/distill/SKILL.md +7 -2
- package/.agent/skills/documentation-templates/SKILL.md +3 -2
- package/.agent/skills/domain-modeling/SKILL.md +12 -4
- package/.agent/skills/duckdb-analytical-sql/SKILL.md +59 -0
- package/.agent/skills/edge-ai-mobile/SKILL.md +50 -0
- package/.agent/skills/edge-computing/SKILL.md +9 -8
- package/.agent/skills/emil-design-eng/SKILL.md +43 -27
- package/.agent/skills/error-resilience/SKILL.md +34 -16
- package/.agent/skills/expo-router-v4/SKILL.md +81 -0
- package/.agent/skills/extract-design-system/SKILL.md +12 -11
- package/.agent/skills/fabel-protocol/SKILL.md +24 -17
- package/.agent/skills/fixing-accessibility/SKILL.md +23 -16
- package/.agent/skills/fixing-metadata/SKILL.md +24 -13
- package/.agent/skills/fixing-motion-performance/SKILL.md +7 -5
- package/.agent/skills/framer-motion-expert/SKILL.md +29 -15
- package/.agent/skills/frontend-design/SKILL.md +21 -13
- package/.agent/skills/frontend-security-expert/SKILL.md +1 -0
- package/.agent/skills/game-design-expert/SKILL.md +1 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +1 -0
- package/.agent/skills/generative-ui-expert/SKILL.md +3 -2
- package/.agent/skills/geo-fundamentals/SKILL.md +2 -1
- package/.agent/skills/git-pro/SKILL.md +10 -9
- package/.agent/skills/github-operations/SKILL.md +2 -1
- package/.agent/skills/gpt-taste/SKILL.md +7 -0
- package/.agent/skills/gsap-core/SKILL.md +26 -22
- package/.agent/skills/gsap-frameworks/SKILL.md +6 -5
- package/.agent/skills/gsap-performance/SKILL.md +4 -3
- package/.agent/skills/gsap-plugins/SKILL.md +34 -33
- package/.agent/skills/gsap-react/SKILL.md +9 -8
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +34 -33
- package/.agent/skills/gsap-timeline/SKILL.md +18 -15
- package/.agent/skills/gsap-utils/SKILL.md +25 -24
- package/.agent/skills/harden/SKILL.md +9 -3
- package/.agent/skills/harness-protocol/SKILL.md +1 -0
- package/.agent/skills/i18n-localization/SKILL.md +10 -9
- package/.agent/skills/impeccable/SKILL.md +5 -0
- package/.agent/skills/improve-codebase-architecture/SKILL.md +10 -5
- package/.agent/skills/improve-ui/SKILL.md +12 -5
- package/.agent/skills/intelligent-routing/SKILL.md +7 -6
- package/.agent/skills/knowledge-graph/SKILL.md +1 -0
- package/.agent/skills/landing-page/SKILL.md +1 -0
- package/.agent/skills/lint-and-validate/SKILL.md +9 -4
- package/.agent/skills/llm-engineering/SKILL.md +55 -54
- package/.agent/skills/local-first/SKILL.md +20 -19
- package/.agent/skills/local-first-architecture/SKILL.md +6 -1
- package/.agent/skills/lottie-animation/SKILL.md +7 -3
- package/.agent/skills/marquee-loop/SKILL.md +1 -0
- package/.agent/skills/masked-reveal/SKILL.md +17 -4
- package/.agent/skills/mcp-builder/SKILL.md +13 -10
- package/.agent/skills/micro-interaction/SKILL.md +20 -5
- package/.agent/skills/mobile-design/SKILL.md +26 -15
- package/.agent/skills/monorepo-management/SKILL.md +3 -2
- package/.agent/skills/morphing-icons/SKILL.md +16 -6
- package/.agent/skills/motion-engineering/SKILL.md +19 -15
- package/.agent/skills/nextjs-react-expert/SKILL.md +26 -21
- package/.agent/skills/nodejs-best-practices/SKILL.md +89 -76
- package/.agent/skills/observability/SKILL.md +45 -44
- package/.agent/skills/opentelemetry-observability/SKILL.md +59 -0
- package/.agent/skills/page-transition-animation/SKILL.md +6 -3
- package/.agent/skills/parallel-agents/SKILL.md +7 -2
- package/.agent/skills/performance-profiling/SKILL.md +24 -13
- package/.agent/skills/plan-writing/SKILL.md +1 -0
- package/.agent/skills/platform-engineer/SKILL.md +3 -2
- package/.agent/skills/platform-engineering-opentofu/SKILL.md +68 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +60 -0
- package/.agent/skills/playwright-best-practices/SKILL.md +29 -28
- package/.agent/skills/polish/SKILL.md +13 -12
- package/.agent/skills/powershell-windows/SKILL.md +1 -0
- package/.agent/skills/pricing-page/SKILL.md +8 -3
- package/.agent/skills/product-aware-heuristics/SKILL.md +122 -72
- package/.agent/skills/progressive-blur/SKILL.md +9 -4
- package/.agent/skills/project-idioms/SKILL.md +1 -0
- package/.agent/skills/property-based-testing/SKILL.md +58 -0
- package/.agent/skills/python-patterns/SKILL.md +1 -0
- package/.agent/skills/python-pro/SKILL.md +1 -0
- package/.agent/skills/quieter/SKILL.md +6 -0
- package/.agent/skills/react-doctor/SKILL.md +6 -0
- package/.agent/skills/react-specialist/SKILL.md +32 -28
- package/.agent/skills/readme-builder/SKILL.md +1 -0
- package/.agent/skills/realtime-patterns/SKILL.md +34 -33
- package/.agent/skills/red-team-tactics/SKILL.md +1 -0
- package/.agent/skills/redesign-skill/SKILL.md +6 -0
- package/.agent/skills/review-animations/SKILL.md +5 -2
- package/.agent/skills/review-animations/STANDARDS.md +37 -23
- package/.agent/skills/rust-pro/SKILL.md +1 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +4 -3
- package/.agent/skills/server-management/SKILL.md +1 -0
- package/.agent/skills/shadcn-ui-expert/SKILL.md +28 -22
- package/.agent/skills/shape/SKILL.md +9 -2
- package/.agent/skills/skill-creator/SKILL.md +1 -0
- package/.agent/skills/soft-skill/SKILL.md +6 -0
- package/.agent/skills/sounds-on-the-web/SKILL.md +1 -0
- package/.agent/skills/sql-pro/SKILL.md +1 -0
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +1 -0
- package/.agent/skills/svg-animation/SKILL.md +16 -7
- package/.agent/skills/swiftui-expert/SKILL.md +1 -0
- package/.agent/skills/swiss-design/SKILL.md +5 -0
- package/.agent/skills/system-design-pro/SKILL.md +1 -0
- package/.agent/skills/systematic-debugging/SKILL.md +1 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +25 -11
- package/.agent/skills/taste-skill/SKILL.md +6 -0
- package/.agent/skills/tdd-workflow/SKILL.md +5 -0
- package/.agent/skills/test-result-analyzer/SKILL.md +1 -0
- package/.agent/skills/testing-patterns/SKILL.md +123 -115
- package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +5 -0
- package/.agent/skills/thinking-protocol/SKILL.md +3 -0
- package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +9 -8
- package/.agent/skills/transitions-dev/SKILL.md +19 -6
- package/.agent/skills/trend-researcher/SKILL.md +1 -0
- package/.agent/skills/typescript-advanced/SKILL.md +23 -18
- package/.agent/skills/typeset/SKILL.md +10 -1
- package/.agent/skills/ui-reasoning-engine/SKILL.md +67 -48
- package/.agent/skills/ui-skill-packs/SKILL.md +6 -1
- package/.agent/skills/ui-skills-root/SKILL.md +39 -38
- package/.agent/skills/ui-ux-pro-max/SKILL.md +34 -26
- package/.agent/skills/ui-ux-researcher/SKILL.md +1 -0
- package/.agent/skills/vector-search-pgvector/SKILL.md +78 -0
- package/.agent/skills/vue-expert/SKILL.md +22 -19
- package/.agent/skills/vulnerability-scanner/SKILL.md +22 -21
- package/.agent/skills/web-accessibility-auditor/SKILL.md +2 -1
- package/.agent/skills/web-design-guidelines/SKILL.md +16 -10
- package/.agent/skills/web-quality-audit/SKILL.md +5 -0
- package/.agent/skills/webapp-testing/SKILL.md +14 -13
- package/.agent/skills/webgpu-performance/SKILL.md +1 -0
- package/.agent/skills/whimsy-injector/SKILL.md +9 -5
- package/.agent/skills/workflow-optimizer/SKILL.md +1 -0
- package/.agent/skills/zero-trust-passkeys/SKILL.md +90 -0
- package/.agent/templates/DESIGN.md +119 -110
- package/.agent/templates/design-tokens.json +9 -6
- package/.agent/workflows/acf.md +1 -0
- package/.agent/workflows/api-tester.md +1 -0
- package/.agent/workflows/audit.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/changelog.md +1 -0
- package/.agent/workflows/contract.md +60 -0
- package/.agent/workflows/create.md +1 -0
- package/.agent/workflows/debug.md +1 -0
- package/.agent/workflows/deploy.md +1 -0
- package/.agent/workflows/enhance.md +1 -0
- package/.agent/workflows/fix-ci.md +89 -0
- package/.agent/workflows/fix.md +1 -0
- package/.agent/workflows/generate.md +1 -0
- package/.agent/workflows/marathon.md +1 -0
- package/.agent/workflows/migrate.md +1 -0
- package/.agent/workflows/minimal.md +9 -7
- package/.agent/workflows/orchestrate.md +1 -0
- package/.agent/workflows/performance-benchmarker.md +1 -0
- package/.agent/workflows/pipeline.md +26 -21
- package/.agent/workflows/plan.md +1 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/refactor.md +3 -2
- package/.agent/workflows/review-ai.md +4 -3
- package/.agent/workflows/review.md +1 -0
- package/.agent/workflows/session.md +1 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/strengthen-skills.md +1 -0
- package/.agent/workflows/super-prompt.md +1 -0
- package/.agent/workflows/swarm.md +15 -3
- package/.agent/workflows/test.md +8 -7
- package/.agent/workflows/tribunal-backend.md +3 -2
- package/.agent/workflows/tribunal-cicd.md +104 -0
- package/.agent/workflows/tribunal-database.md +1 -0
- package/.agent/workflows/tribunal-frontend.md +8 -6
- package/.agent/workflows/tribunal-full.md +15 -14
- package/.agent/workflows/tribunal-mobile.md +6 -5
- package/.agent/workflows/tribunal-performance.md +1 -0
- package/.agent/workflows/tribunal-speed.md +1 -0
- package/.agent/workflows/tribunal-ui.md +29 -21
- package/.agent/workflows/ui-ux-pro-max.md +19 -15
- package/CONTRIBUTING.md +3 -3
- package/README.md +160 -88
- package/SECURITY.md +11 -11
- package/bin/mcp-server.js +512 -233
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +45 -48
- package/dist/cli.js +26 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/memory.js +3 -2
- package/dist/commands/native.js +36 -0
- package/dist/commands/status.js +6 -0
- package/dist/esm/index.mjs +32 -0
- package/dist/index.d.ts +58 -3
- package/package.json +20 -16
- package/scripts/benchmark.js +62 -86
- package/scripts/changelog.js +67 -73
- package/scripts/fix-vbc.js +13 -15
- package/scripts/fix-vbc.ps1 +2 -118
- package/scripts/stress_benchmark.js +358 -0
- package/scripts/sync-version.js +71 -41
- package/scripts/validate-payload.js +23 -30
- package/scripts/visual_audit.js +23 -13
|
@@ -19,6 +19,7 @@ last-updated: 2026-07-29
|
|
|
19
19
|
## Mandatory Pre-Flight Context Inspection
|
|
20
20
|
|
|
21
21
|
Before designing test automation suites or Playwright specs, you MUST inspect:
|
|
22
|
+
|
|
22
23
|
1. `package.json` / `playwright.config.ts` / `vitest.config.ts` → Read existing test runners, timeouts, and CI configurations
|
|
23
24
|
2. Component ARIA roles & accessible labels (`getByRole`, `getByLabelText`) → Verify accessible DOM selectors over brittle CSS classes
|
|
24
25
|
3. MSW handlers (`src/mocks/handlers.ts`) & API contracts → Audit mock network responses and status codes for integration suites
|
|
@@ -54,27 +55,27 @@ Write tests that fail when real user-facing behavior breaks — nothing less, no
|
|
|
54
55
|
// ❌ DON'T unit test: component rendering, API calls, DB queries
|
|
55
56
|
|
|
56
57
|
// ✅ DO unit test: business logic isolated
|
|
57
|
-
import { describe, it, expect } from
|
|
58
|
-
import { calculateDiscount } from
|
|
58
|
+
import { describe, it, expect } from 'vitest';
|
|
59
|
+
import { calculateDiscount } from './pricing';
|
|
59
60
|
|
|
60
|
-
describe(
|
|
61
|
+
describe('calculateDiscount()', () => {
|
|
61
62
|
// Always test the happy path
|
|
62
|
-
it(
|
|
63
|
+
it('applies 10% to orders over $100', () => {
|
|
63
64
|
expect(calculateDiscount(150)).toBe(135);
|
|
64
65
|
});
|
|
65
66
|
|
|
66
67
|
// Always test all boundary cases
|
|
67
|
-
it(
|
|
68
|
+
it('applies no discount at exactly $100 (exclusive boundary)', () => {
|
|
68
69
|
expect(calculateDiscount(100)).toBe(100);
|
|
69
70
|
});
|
|
70
71
|
|
|
71
72
|
// Always test error/invalid input
|
|
72
|
-
it(
|
|
73
|
+
it('throws RangeError on negative input', () => {
|
|
73
74
|
expect(() => calculateDiscount(-50)).toThrow(RangeError);
|
|
74
75
|
});
|
|
75
76
|
|
|
76
77
|
// Always test zero and extreme values
|
|
77
|
-
it(
|
|
78
|
+
it('returns 0 for $0 order', () => {
|
|
78
79
|
expect(calculateDiscount(0)).toBe(0);
|
|
79
80
|
});
|
|
80
81
|
});
|
|
@@ -145,38 +146,38 @@ test('shows error on failed load', async () => {
|
|
|
145
146
|
|
|
146
147
|
```typescript
|
|
147
148
|
// playwright.config.ts
|
|
148
|
-
import { defineConfig, devices } from
|
|
149
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
149
150
|
|
|
150
151
|
export default defineConfig({
|
|
151
|
-
testDir:
|
|
152
|
+
testDir: './e2e',
|
|
152
153
|
fullyParallel: true,
|
|
153
154
|
retries: process.env.CI ? 2 : 0, // Retry in CI for flakiness
|
|
154
|
-
reporter: [[
|
|
155
|
+
reporter: [['html'], ['github']],
|
|
155
156
|
use: {
|
|
156
|
-
baseURL:
|
|
157
|
-
trace:
|
|
158
|
-
video:
|
|
159
|
-
screenshot:
|
|
157
|
+
baseURL: 'http://localhost:3000',
|
|
158
|
+
trace: 'on-first-retry', // Record trace only on failure
|
|
159
|
+
video: 'on-first-retry', // Record video only on failure
|
|
160
|
+
screenshot: 'only-on-failure',
|
|
160
161
|
},
|
|
161
162
|
projects: [
|
|
162
|
-
{ name:
|
|
163
|
-
{ name:
|
|
163
|
+
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
164
|
+
{ name: 'Mobile Safari', use: { ...devices['iPhone 14'] } },
|
|
164
165
|
],
|
|
165
166
|
});
|
|
166
167
|
|
|
167
168
|
// e2e/auth.spec.ts
|
|
168
|
-
import { test, expect } from
|
|
169
|
+
import { test, expect } from '@playwright/test';
|
|
169
170
|
|
|
170
171
|
// Store auth state to avoid logging in every test
|
|
171
|
-
test.use({ storageState:
|
|
172
|
-
|
|
173
|
-
test(
|
|
174
|
-
await page.goto(
|
|
175
|
-
await page.getByRole(
|
|
176
|
-
await page.getByRole(
|
|
177
|
-
await expect(page.getByText(
|
|
178
|
-
await page.getByRole(
|
|
179
|
-
await expect(page).toHaveURL(
|
|
172
|
+
test.use({ storageState: 'e2e/auth.json' });
|
|
173
|
+
|
|
174
|
+
test('user can complete checkout flow', async ({ page }) => {
|
|
175
|
+
await page.goto('/products');
|
|
176
|
+
await page.getByRole('button', { name: 'Add to cart' }).first().click();
|
|
177
|
+
await page.getByRole('link', { name: 'Cart' }).click();
|
|
178
|
+
await expect(page.getByText('1 item')).toBeVisible();
|
|
179
|
+
await page.getByRole('button', { name: 'Checkout' }).click();
|
|
180
|
+
await expect(page).toHaveURL('/checkout');
|
|
180
181
|
});
|
|
181
182
|
```
|
|
182
183
|
|
|
@@ -186,15 +187,15 @@ test("user can complete checkout flow", async ({ page }) => {
|
|
|
186
187
|
|
|
187
188
|
```typescript
|
|
188
189
|
// ❌ BRITTLE (fails on UI refactor)
|
|
189
|
-
page.locator(
|
|
190
|
-
getByTestId(
|
|
191
|
-
container.querySelector(
|
|
190
|
+
page.locator('.cart-btn > span.label');
|
|
191
|
+
getByTestId('btn-0'); // Index-based
|
|
192
|
+
container.querySelector('#submit-47f3'); // Generated ID
|
|
192
193
|
|
|
193
194
|
// ✅ RESILIENT (survives refactoring + validates accessibility)
|
|
194
|
-
getByRole(
|
|
195
|
-
getByLabelText(
|
|
196
|
-
getByPlaceholderText(
|
|
197
|
-
getByText(
|
|
195
|
+
getByRole('button', { name: /add to cart/i }); // Role + name
|
|
196
|
+
getByLabelText('Email address'); // Form label association
|
|
197
|
+
getByPlaceholderText('Search products'); // Input placeholder
|
|
198
|
+
getByText('Free shipping on orders over $50'); // Visible text
|
|
198
199
|
```
|
|
199
200
|
|
|
200
201
|
---
|
|
@@ -203,25 +204,31 @@ getByText("Free shipping on orders over $50"); // Visible text
|
|
|
203
204
|
|
|
204
205
|
```typescript
|
|
205
206
|
// Test server routes with supertest — no browser needed
|
|
206
|
-
import request from
|
|
207
|
-
import app from
|
|
207
|
+
import request from 'supertest';
|
|
208
|
+
import app from '../src/app';
|
|
208
209
|
|
|
209
|
-
describe(
|
|
210
|
-
it(
|
|
211
|
-
const response = await request(app)
|
|
210
|
+
describe('POST /api/auth/login', () => {
|
|
211
|
+
it('returns JWT on valid credentials', async () => {
|
|
212
|
+
const response = await request(app)
|
|
213
|
+
.post('/api/auth/login')
|
|
214
|
+
.send({ email: 'alice@example.com', password: 'correct' })
|
|
215
|
+
.expect(200);
|
|
212
216
|
|
|
213
217
|
expect(response.body).toMatchObject({ token: expect.any(String) });
|
|
214
218
|
});
|
|
215
219
|
|
|
216
|
-
it(
|
|
217
|
-
await request(app)
|
|
220
|
+
it('returns 401 on invalid credentials', async () => {
|
|
221
|
+
await request(app)
|
|
222
|
+
.post('/api/auth/login')
|
|
223
|
+
.send({ email: 'alice@example.com', password: 'wrong' })
|
|
224
|
+
.expect(401);
|
|
218
225
|
});
|
|
219
226
|
|
|
220
|
-
it(
|
|
227
|
+
it('returns 429 after 10 failed attempts', async () => {
|
|
221
228
|
for (let i = 0; i < 10; i++) {
|
|
222
|
-
await request(app).post(
|
|
229
|
+
await request(app).post('/api/auth/login').send({ password: 'wrong' });
|
|
223
230
|
}
|
|
224
|
-
await request(app).post(
|
|
231
|
+
await request(app).post('/api/auth/login').send({ password: 'wrong' }).expect(429); // Rate limit hit
|
|
225
232
|
});
|
|
226
233
|
});
|
|
227
234
|
```
|
|
@@ -20,6 +20,7 @@ You have one job: ensure the code does not crash the system or fail silently whe
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before auditing fault tolerance, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Active environment configs (`package.json`, `.env.example`) → Check for timeout values, retry limits, and environment variable fallbacks
|
|
24
25
|
2. Network boundary calls → Verify `AbortController`, `fetch` timeout wrappers, or DB connection pool retry configurations
|
|
25
26
|
3. Top-level process entry points (`index.ts`, `server.ts`, `app/layout.tsx`) → Verify error boundaries and global exception handlers
|
|
@@ -20,6 +20,7 @@ You have one job: ensure no untrusted data enters the application without strict
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before auditing validation boundaries, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. `package.json` / `requirements.txt` → Check for Zod, Valibot, ArkType, Pydantic, or native validation libraries
|
|
24
25
|
2. Schema declaration directories (`schemas/`, `lib/validations/`, `models/`) → Ensure schemas are centralized and shared
|
|
25
26
|
3. Target API entry points → Verify request body, path params, query parameters, and header parsing
|
|
@@ -51,13 +51,11 @@ element.innerHTML = userInput; // Executes embedded scripts
|
|
|
51
51
|
const query = `UPDATE orders SET status = '${status}' WHERE id = ${orderId}`;
|
|
52
52
|
|
|
53
53
|
// ✅ Parameterized query
|
|
54
|
-
const result = await db.query(
|
|
54
|
+
const result = await db.query('SELECT * FROM users WHERE email = $1', [email]);
|
|
55
55
|
|
|
56
56
|
// ✅ exec validation
|
|
57
|
-
const ALLOWED_REPOS = new Set([
|
|
58
|
-
|
|
59
|
-
]);
|
|
60
|
-
if (!ALLOWED_REPOS.has(repoUrl)) throw new Error("Unauthorized repo");
|
|
57
|
+
const ALLOWED_REPOS = new Set([/* allowlist */]);
|
|
58
|
+
if (!ALLOWED_REPOS.has(repoUrl)) throw new Error('Unauthorized repo');
|
|
61
59
|
|
|
62
60
|
// ✅ textContent for user-generated text (no script execution)
|
|
63
61
|
element.textContent = userInput;
|
|
@@ -72,31 +70,31 @@ element.textContent = userInput;
|
|
|
72
70
|
jwt.verify(token, secret); // Attacker can forge with algorithm: 'none'
|
|
73
71
|
|
|
74
72
|
// ❌ WEAK SECRET: Under 32 chars = brute-forceable
|
|
75
|
-
const JWT_SECRET =
|
|
73
|
+
const JWT_SECRET = 'password123';
|
|
76
74
|
|
|
77
75
|
// ❌ NO EXPIRY: Token valid forever
|
|
78
76
|
jwt.sign({ userId }, secret); // Missing expiresIn
|
|
79
77
|
|
|
80
78
|
// ❌ HARDCODED CREDENTIAL
|
|
81
|
-
const DB_PASSWORD =
|
|
79
|
+
const DB_PASSWORD = 'admin1234';
|
|
82
80
|
|
|
83
81
|
// ✅ Secure JWT
|
|
84
82
|
jwt.verify(token, process.env.JWT_SECRET!, {
|
|
85
|
-
algorithms: [
|
|
86
|
-
issuer:
|
|
87
|
-
audience:
|
|
83
|
+
algorithms: ['HS256'], // Explicit algorithm enforcement
|
|
84
|
+
issuer: 'api.myapp.com',
|
|
85
|
+
audience: 'myapp-client',
|
|
88
86
|
});
|
|
89
87
|
|
|
90
88
|
// ✅ Environment variable with existence guard
|
|
91
89
|
const JWT_SECRET = process.env.JWT_SECRET;
|
|
92
90
|
if (!JWT_SECRET || JWT_SECRET.length < 32) {
|
|
93
|
-
throw new Error(
|
|
91
|
+
throw new Error('JWT_SECRET must be at least 32 characters');
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
// ✅ Short expiry + refresh token pattern
|
|
97
95
|
jwt.sign({ userId }, JWT_SECRET, {
|
|
98
|
-
expiresIn:
|
|
99
|
-
algorithm:
|
|
96
|
+
expiresIn: '15m', // Short-lived access token
|
|
97
|
+
algorithm: 'HS256',
|
|
100
98
|
});
|
|
101
99
|
```
|
|
102
100
|
|
|
@@ -106,7 +104,7 @@ jwt.sign({ userId }, JWT_SECRET, {
|
|
|
106
104
|
|
|
107
105
|
```typescript
|
|
108
106
|
// ❌ CRITICAL: User controls the URL — can hit internal services
|
|
109
|
-
app.get(
|
|
107
|
+
app.get('/proxy', async (req, res) => {
|
|
110
108
|
const response = await fetch(req.query.url); // http://169.254.169.254/metadata (AWS IMDS!)
|
|
111
109
|
res.json(await response.json());
|
|
112
110
|
});
|
|
@@ -115,7 +113,7 @@ app.get("/proxy", async (req, res) => {
|
|
|
115
113
|
await fetch(webhookUrl); // Could be http://internal-db:5432
|
|
116
114
|
|
|
117
115
|
// ✅ SAFE: URL allowlist validation
|
|
118
|
-
const ALLOWED_HOSTS = new Set([
|
|
116
|
+
const ALLOWED_HOSTS = new Set(['api.stripe.com', 'hooks.slack.com']);
|
|
119
117
|
const url = new URL(webhookUrl);
|
|
120
118
|
if (!ALLOWED_HOSTS.has(url.hostname)) {
|
|
121
119
|
throw new Error(`Unauthorized webhook host: ${url.hostname}`);
|
|
@@ -127,7 +125,7 @@ function isPrivateIP(hostname: string): boolean {
|
|
|
127
125
|
return /^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|127\.|169\.254\.)/.test(hostname);
|
|
128
126
|
}
|
|
129
127
|
if (isPrivateIP(new URL(url).hostname)) {
|
|
130
|
-
throw new Error(
|
|
128
|
+
throw new Error('Private network access forbidden');
|
|
131
129
|
}
|
|
132
130
|
```
|
|
133
131
|
|
|
@@ -137,15 +135,15 @@ if (isPrivateIP(new URL(url).hostname)) {
|
|
|
137
135
|
|
|
138
136
|
```typescript
|
|
139
137
|
// ❌ IDOR: User can access any resource by changing the ID parameter
|
|
140
|
-
app.get(
|
|
138
|
+
app.get('/user/:id/documents', async (req, res) => {
|
|
141
139
|
const docs = await db.documents.findMany({ where: { userId: req.params.id } });
|
|
142
140
|
return res.json(docs); // Missing: does req.session.userId === req.params.id?
|
|
143
141
|
});
|
|
144
142
|
|
|
145
143
|
// ✅ SAFE: Scoped to authenticated user's own data
|
|
146
|
-
app.get(
|
|
147
|
-
if (req.session.userId !== req.params.id && req.session.role !==
|
|
148
|
-
return res.status(403).json({ error:
|
|
144
|
+
app.get('/user/:id/documents', requireAuth, async (req, res) => {
|
|
145
|
+
if (req.session.userId !== req.params.id && req.session.role !== 'admin') {
|
|
146
|
+
return res.status(403).json({ error: 'Forbidden' });
|
|
149
147
|
}
|
|
150
148
|
const docs = await db.documents.findMany({ where: { userId: req.params.id } });
|
|
151
149
|
return res.json(docs);
|
|
@@ -158,7 +156,7 @@ app.get("/user/:id/documents", requireAuth, async (req, res) => {
|
|
|
158
156
|
|
|
159
157
|
```typescript
|
|
160
158
|
// ❌ CORS wildcard in production — any origin can call your API
|
|
161
|
-
app.use(cors({ origin:
|
|
159
|
+
app.use(cors({ origin: '*' }));
|
|
162
160
|
|
|
163
161
|
// ❌ Verbose error exposing internals
|
|
164
162
|
app.use((err, req, res, next) => {
|
|
@@ -166,7 +164,7 @@ app.use((err, req, res, next) => {
|
|
|
166
164
|
});
|
|
167
165
|
|
|
168
166
|
// ✅ Restrictive CORS
|
|
169
|
-
const allowedOrigins = (process.env.ALLOWED_ORIGINS ??
|
|
167
|
+
const allowedOrigins = (process.env.ALLOWED_ORIGINS ?? '').split(',');
|
|
170
168
|
app.use(
|
|
171
169
|
cors({
|
|
172
170
|
origin: (origin, cb) => {
|
|
@@ -178,8 +176,8 @@ app.use(
|
|
|
178
176
|
|
|
179
177
|
// ✅ Safe error response — log internally, generic to client
|
|
180
178
|
app.use((err: Error, req, res, next) => {
|
|
181
|
-
logger.error({ err, path: req.path },
|
|
182
|
-
res.status(500).json({ error:
|
|
179
|
+
logger.error({ err, path: req.path }, 'Unhandled error');
|
|
180
|
+
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
183
181
|
});
|
|
184
182
|
```
|
|
185
183
|
|
|
@@ -188,11 +186,13 @@ app.use((err: Error, req, res, next) => {
|
|
|
188
186
|
## 4. Prompt Injection Defense & LLM Call Security
|
|
189
187
|
|
|
190
188
|
### Prompt Injection Defenses
|
|
189
|
+
|
|
191
190
|
- Ensure user-provided input is never concatenated directly into top-level system prompts.
|
|
192
191
|
- Verify that user inputs are isolated in `<user_provided_context>` or custom XML tags, and system prompts explicitly instruct the model to ignore instructions within those tags.
|
|
193
192
|
- Verify that HTML/XML tags are stripped or sanitized from user input before sending to LLM APIs.
|
|
194
193
|
|
|
195
194
|
### LLM Call Audit Checklist
|
|
195
|
+
|
|
196
196
|
- Flag any hardcoded API keys. They must be loaded from environment variables.
|
|
197
197
|
- Verify model strings against official current lists (no invented names like `claude-4-opus` or `gpt-5`).
|
|
198
198
|
- Ensure all LLM API calls are asynchronous and properly awaited.
|
|
@@ -17,6 +17,7 @@ last-updated: 2026-07-29
|
|
|
17
17
|
## Mandatory Pre-Flight Context Inspection
|
|
18
18
|
|
|
19
19
|
Before generating metadata, sitemaps, or structured data, you MUST inspect:
|
|
20
|
+
|
|
20
21
|
1. `app/layout.tsx` / `next.config.js` → Read base URL, default metadata options, and OpenGraph defaults
|
|
21
22
|
2. Page templates (`app/**/page.tsx`) → Verify heading hierarchy (single `<h1>` per page) and Schema.org JSON-LD scripts
|
|
22
23
|
3. AI bot middleware / GEO paths → Audit `sitemap.ts`, `robots.ts`, and crawler detection rules
|
|
@@ -25,20 +26,24 @@ Before generating metadata, sitemaps, or structured data, you MUST inspect:
|
|
|
25
26
|
|
|
26
27
|
```typescript
|
|
27
28
|
// app/products/[slug]/page.tsx
|
|
28
|
-
import { Metadata } from
|
|
29
|
+
import { Metadata } from 'next';
|
|
29
30
|
|
|
30
31
|
// Static metadata
|
|
31
32
|
export const metadata: Metadata = {
|
|
32
|
-
title:
|
|
33
|
-
description:
|
|
33
|
+
title: 'Product Name | Brand',
|
|
34
|
+
description: 'Compelling 155-character description that matches search intent.',
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
// Dynamic metadata (fetched per-page)
|
|
37
|
-
export async function generateMetadata({
|
|
38
|
+
export async function generateMetadata({
|
|
39
|
+
params,
|
|
40
|
+
}: {
|
|
41
|
+
params: Promise<{ slug: string }>;
|
|
42
|
+
}): Promise<Metadata> {
|
|
38
43
|
const { slug } = await params;
|
|
39
44
|
const product = await getProduct(slug);
|
|
40
45
|
|
|
41
|
-
if (!product) return { title:
|
|
46
|
+
if (!product) return { title: 'Not Found' };
|
|
42
47
|
|
|
43
48
|
return {
|
|
44
49
|
title: `${product.name} | Brand`,
|
|
@@ -56,12 +61,12 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
|
|
|
56
61
|
alt: product.name,
|
|
57
62
|
},
|
|
58
63
|
],
|
|
59
|
-
siteName:
|
|
60
|
-
type:
|
|
64
|
+
siteName: 'Your Brand',
|
|
65
|
+
type: 'website',
|
|
61
66
|
},
|
|
62
67
|
|
|
63
68
|
twitter: {
|
|
64
|
-
card:
|
|
69
|
+
card: 'summary_large_image',
|
|
65
70
|
title: product.name,
|
|
66
71
|
description: product.seoDescription,
|
|
67
72
|
images: [product.imageUrl],
|
|
@@ -81,21 +86,23 @@ export default async function ProductPage({ params }) {
|
|
|
81
86
|
const product = await getProduct(slug);
|
|
82
87
|
|
|
83
88
|
const jsonLd = {
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
'@context': 'https://schema.org',
|
|
90
|
+
'@type': 'Product',
|
|
86
91
|
name: product.name,
|
|
87
92
|
image: product.imageUrl,
|
|
88
93
|
description: product.description,
|
|
89
94
|
sku: product.sku,
|
|
90
95
|
offers: {
|
|
91
|
-
|
|
96
|
+
'@type': 'Offer',
|
|
92
97
|
price: product.price,
|
|
93
|
-
priceCurrency:
|
|
94
|
-
availability: product.inStock
|
|
98
|
+
priceCurrency: 'USD',
|
|
99
|
+
availability: product.inStock
|
|
100
|
+
? 'https://schema.org/InStock'
|
|
101
|
+
: 'https://schema.org/OutOfStock',
|
|
95
102
|
url: `https://yoursite.com/products/${slug}`,
|
|
96
103
|
},
|
|
97
104
|
aggregateRating: {
|
|
98
|
-
|
|
105
|
+
'@type': 'AggregateRating',
|
|
99
106
|
ratingValue: product.averageRating,
|
|
100
107
|
reviewCount: product.reviewCount,
|
|
101
108
|
},
|
|
@@ -103,7 +110,10 @@ export default async function ProductPage({ params }) {
|
|
|
103
110
|
|
|
104
111
|
return (
|
|
105
112
|
<>
|
|
106
|
-
<script
|
|
113
|
+
<script
|
|
114
|
+
type="application/ld+json"
|
|
115
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
|
116
|
+
/>
|
|
107
117
|
{/* page content */}
|
|
108
118
|
</>
|
|
109
119
|
);
|
|
@@ -116,29 +126,29 @@ export default async function ProductPage({ params }) {
|
|
|
116
126
|
|
|
117
127
|
```typescript
|
|
118
128
|
// app/sitemap.ts
|
|
119
|
-
import { MetadataRoute } from
|
|
129
|
+
import { MetadataRoute } from 'next';
|
|
120
130
|
|
|
121
131
|
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
|
122
132
|
const products = await getAllProducts();
|
|
123
133
|
|
|
124
|
-
const productUrls = products.map(
|
|
134
|
+
const productUrls = products.map(product => ({
|
|
125
135
|
url: `https://yoursite.com/products/${product.slug}`,
|
|
126
136
|
lastModified: product.updatedAt,
|
|
127
|
-
changeFrequency:
|
|
137
|
+
changeFrequency: 'weekly' as const,
|
|
128
138
|
priority: 0.8,
|
|
129
139
|
}));
|
|
130
140
|
|
|
131
141
|
return [
|
|
132
142
|
{
|
|
133
|
-
url:
|
|
143
|
+
url: 'https://yoursite.com',
|
|
134
144
|
lastModified: new Date(),
|
|
135
|
-
changeFrequency:
|
|
145
|
+
changeFrequency: 'daily',
|
|
136
146
|
priority: 1.0,
|
|
137
147
|
},
|
|
138
148
|
{
|
|
139
|
-
url:
|
|
149
|
+
url: 'https://yoursite.com/products',
|
|
140
150
|
lastModified: new Date(),
|
|
141
|
-
changeFrequency:
|
|
151
|
+
changeFrequency: 'daily',
|
|
142
152
|
priority: 0.9,
|
|
143
153
|
},
|
|
144
154
|
...productUrls,
|
|
@@ -177,7 +187,7 @@ When AI engines (Perplexity, ChatGPT Search) index your site, they need:
|
|
|
177
187
|
// Next.js Edge Middleware: serve bare markdown to AI bots
|
|
178
188
|
// middleware.ts
|
|
179
189
|
export function middleware(req: NextRequest) {
|
|
180
|
-
const ua = req.headers.get(
|
|
190
|
+
const ua = req.headers.get('user-agent') ?? '';
|
|
181
191
|
const isAIBot = /ChatGPT-User|PerplexityBot|ClaudeBot|GPTBot/i.test(ua);
|
|
182
192
|
|
|
183
193
|
if (isAIBot) {
|
|
@@ -21,6 +21,7 @@ SQL mistakes are quiet, catastrophic, and permanent. Injection vulnerabilities e
|
|
|
21
21
|
## Mandatory Pre-Flight Context Inspection
|
|
22
22
|
|
|
23
23
|
Before auditing SQL queries or ORM calls, you MUST inspect:
|
|
24
|
+
|
|
24
25
|
1. `schema.prisma` / `drizzle.schema.ts` / DB migrations → Inspect table schema, existing indices, and foreign key relations
|
|
25
26
|
2. ORM & DB driver in `package.json` → Confirm parameterization syntax (`$1` in pg vs `?` in mysql vs Prisma objects)
|
|
26
27
|
3. Query invocation sites → Check for raw SQL strings (`SELECT ... ${input}`) or `for` loops making queries inside loop bodies
|
|
@@ -40,7 +41,7 @@ await db.execute(query);
|
|
|
40
41
|
const result = await db.execute(`SELECT * FROM orders WHERE id = ${orderId}`);
|
|
41
42
|
|
|
42
43
|
// ✅ SAFE: Parameterized query (Postgres/pg driver)
|
|
43
|
-
const result = await client.query(
|
|
44
|
+
const result = await client.query('SELECT * FROM users WHERE email = $1', [userInput]);
|
|
44
45
|
|
|
45
46
|
// ✅ SAFE: Prisma — never interpolates user input into SQL
|
|
46
47
|
const user = await prisma.user.findUnique({
|
|
@@ -73,14 +74,14 @@ const users = await prisma.user.findMany({
|
|
|
73
74
|
// ❌ N+1: GraphQL resolver without DataLoader
|
|
74
75
|
const resolver = {
|
|
75
76
|
User: {
|
|
76
|
-
posts:
|
|
77
|
+
posts: parent => db.posts.findAll({ where: { userId: parent.id } }), // Fires per user!
|
|
77
78
|
},
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
// ✅ FIXED: DataLoader batches all requests into one query
|
|
81
|
-
const postsLoader = new DataLoader(async
|
|
82
|
+
const postsLoader = new DataLoader(async userIds => {
|
|
82
83
|
const posts = await db.posts.findAll({ where: { userId: userIds } });
|
|
83
|
-
return userIds.map(
|
|
84
|
+
return userIds.map(id => posts.filter(p => p.userId === id));
|
|
84
85
|
});
|
|
85
86
|
```
|
|
86
87
|
|
|
@@ -18,6 +18,7 @@ last-updated: 2026-07-29
|
|
|
18
18
|
## Mandatory Pre-Flight Context Inspection
|
|
19
19
|
|
|
20
20
|
Before decomposing goals into worker dispatches, you MUST inspect:
|
|
21
|
+
|
|
21
22
|
1. `swarm-worker-registry.md` → Read the primary routing table and specialist worker capabilities
|
|
22
23
|
2. Active codebase file layout (`task.md`, file structure) → Ensure worker target file paths do not overlap across parallel tasks
|
|
23
24
|
3. System constraints & dependencies (`package.json`, environment variables) → Verify context passed to workers is grounded in current repo state
|
|
@@ -78,8 +79,17 @@ Every worker receives a structured JSON dispatch. No unstructured natural langua
|
|
|
78
79
|
"scope": "Refactor the UserCard component to use Server Components and remove client-side state that belongs on the server.",
|
|
79
80
|
"files_to_read": ["src/components/UserCard.tsx", "src/app/users/[id]/page.tsx"],
|
|
80
81
|
"files_to_write": ["src/components/UserCard.tsx", "src/components/UserCardClient.tsx"],
|
|
81
|
-
"context_summary": [
|
|
82
|
-
|
|
82
|
+
"context_summary": [
|
|
83
|
+
"The app uses Next.js 15 App Router",
|
|
84
|
+
"Authentication is handled via next-auth v5 (now 'auth' package)",
|
|
85
|
+
"Database uses Prisma 6 with PostgreSQL",
|
|
86
|
+
"No existing tests for this component"
|
|
87
|
+
],
|
|
88
|
+
"constraints": [
|
|
89
|
+
"Do NOT modify any files outside the listed files_to_write",
|
|
90
|
+
"Store only interactive state in the Client Component",
|
|
91
|
+
"Maintain identical visual output — no design changes"
|
|
92
|
+
],
|
|
83
93
|
"output_format": {
|
|
84
94
|
"status": "COMPLETE | BLOCKED | ERROR",
|
|
85
95
|
"files_modified": ["list of files actually changed"],
|
|
@@ -18,16 +18,16 @@ interface WorkerRequest {
|
|
|
18
18
|
|
|
19
19
|
// The category of work being requested.
|
|
20
20
|
type:
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
21
|
+
| 'research' // Understand or explain something
|
|
22
|
+
| 'generate_code' // Write new code
|
|
23
|
+
| 'review_code' // Audit existing code
|
|
24
|
+
| 'debug' // Find and fix a bug
|
|
25
|
+
| 'plan' // Produce a structured plan only (no code)
|
|
26
|
+
| 'design_schema' // Design a database or data schema
|
|
27
|
+
| 'write_docs' // Write documentation or comments
|
|
28
|
+
| 'security_audit' // OWASP security review
|
|
29
|
+
| 'optimize' // Refactor for performance
|
|
30
|
+
| 'test'; // Write or run tests
|
|
31
31
|
|
|
32
32
|
// The agent to route this WorkerRequest to.
|
|
33
33
|
// MUST match a filename in .agent/agents/ (without the .md extension).
|
|
@@ -77,9 +77,9 @@ interface WorkerResult {
|
|
|
77
77
|
|
|
78
78
|
// Outcome of the Worker's execution.
|
|
79
79
|
status:
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
80
|
+
| 'success' // Task completed. Output is valid.
|
|
81
|
+
| 'failure' // Task failed but retries remain.
|
|
82
|
+
| 'escalate'; // Task failed after max_retries. Requires human intervention.
|
|
83
83
|
|
|
84
84
|
// The agent's output if status is "success".
|
|
85
85
|
// Empty string if status is "failure" or "escalate".
|