Development Workflow
Speckit pipeline
Features move through 7 phases, each with mandatory + advisory hooks (.specify/extensions.yml):
3-layer mandatory-hook enforcement (spec 019 + 020 + 2026-04-23 cohort)
Because subagents writing code directly don't invoke /speckit.implement, the harness-level hooks were silently skipped. Three mechanical layers catch this now:
- Pre-push —
scripts/ci-local.sh(13 steps) runspattern-consistency.mjs+docs-coverage.mjson everygit push - CI —
.github/workflows/implementation-hooks.ymlre-runs the 2 scriptable gates on every PR touchingapps/**/packages/**/research-engine/** - PR body —
.github/workflows/pr-checklist-enforcement.ymlparses PR body, FAILS merge if any of 4 checkboxes unchecked
Bypass via [skip-hooks] marker (doc-only / hotfix PRs only).
11 harness hooks (.claude/settings.json)
Block anti-patterns at the moment they'd be introduced:
| Hook type | What it prevents |
|---|---|
| Pre-bash denies | force-push main · reset --hard on shared · branch -D main · --no-verify · git config writes · dep installs without package-security-scan · rm -rf on protected paths |
| Pre-edit blocks | DEV_BYPASS_AMR · DLP_INTERCEPTOR_DISABLED outside test · placeholder secrets outside .env.example · MSAL localStorage · Buffer.from.toString('base64') in encryption-adjacent files · hardcoded secret fallbacks · dynamic = 'force-dynamic' removal · UX anti-patterns (mock names, inline style=, z-index >100) · new dashboard page.tsx without Screen Profile |
| Advisories | constitution + BAA-registry pre-edit reminders · post-edit HIPAA + UX nudges · Stop-hook notice on uncommitted security-sensitive changes |
Full list: docs/develop/hooks.md
Testing discipline (per-controller, per CLAUDE.md)
Every new controller ships with:
- Role-matrix test — every role × route → expected 200/403
- Consent-guard test — no consent / expired / wrong-scope / correct / break-glass / intake-bootstrap
- CSRF probe (state-changing routes) — missing/mismatched token → 403
- DTO-validation probe — good + bad inputs including
$-prefixed keys → 400 - PHI-in-logs grep — zero hits of MRN/SSN/DOB tokens
ML routes carry 3 additional: 6. Auth probe — 401 without JWT 7. Rate-limit probe — 429 on over-limit 8. Schema-invalid response — generic 500, no model output leak
CI gates (10+ per PR)
| Gate | What it checks |
|---|---|
| gitleaks (PR changeset) | No secrets introduced |
| gitleaks (full history) | Scheduled full-history sweep |
| trufflehog | Historical secret sweep (verified only) |
| Semgrep SAST | Security-sensitive paths — 30+ rules |
| Trivy | Filesystem vulnerability scan |
| npm audit | JS/TS prod dep vulns |
| pip-audit | Python prod dep vulns |
| group3-contract-tests | 32+ contracts tests + memory-sdk tests |
| Compliance checklist | 80+ probes from compliance-checklist.yml |
| pattern-consistency gate | Diff audit against CLAUDE.md + skills |
| docs-coverage gate | Diff audit against docs/ + specs/ |
| mandatory hooks checklist | PR body has all 4 hook checkboxes |
Skill decision tree
I want to:
├── Add a new feature end-to-end → /speckit-auto
├── Add a new NestJS module (PHI) → /hipaa-add-module
├── Add a new endpoint to existing module → /hipaa-add-endpoint
├── Add a new ML route → /hipaa-add-ml-route
├── Add a new dashboard page.tsx → /add-screen-profile + /speckit-auto
├── Review a PR → /hipaa-review
├── Sweep full codebase → /hipaa-security-scan
├── Add or change a dependency → /package-security-scan or /dependency-upgrade
├── Rotate a KEK or JWT signing key → /hipaa-rotate-key
├── Respond to a security incident → /hipaa-incident-response
└── Understand Claude Code itself → /claude-code-guide
Full inventory (51 skills): docs/develop/skills.md
First 10 minutes (onboarding)
git clone https://github.com/raviraghu1/PatientRx && cd PatientRx
npm install
pip install -e packages/patientrx-contracts[dev]
pip install -e research-engine/packages/patientrx-guardrails[dev]
pip install -e research-engine/packages/patientrx-memory-sdk[dev]
docker compose --profile mongo up -d
docker exec patientrx-mongo mongosh --quiet --eval \
'try { rs.status().ok } catch(e) { rs.initiate({_id:"rs0",members:[{_id:0,host:"localhost:27017"}]}).ok }'
npm run dev # brings up api + web + ml in parallel
Next stop: the root README — 7 path playbooks + skill decision tree + first-day setup.