baldart 3.14.0 → 3.15.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/CHANGELOG.md +70 -15
- package/VERSION +1 -1
- package/framework/.claude/agents/api-perf-cost-auditor.md +47 -10
- package/framework/.claude/agents/coder.md +61 -10
- package/framework/.claude/agents/prd-card-writer.md +29 -19
- package/framework/.claude/agents/security-reviewer.md +1 -1
- package/framework/.claude/skills/bug/references/logging-patterns.md +45 -8
- package/framework/.claude/skills/new/SKILL.md +180 -86
- package/framework/.claude/skills/prd/SKILL.md +30 -2
- package/framework/.claude/skills/prd/assets/card-template.yml +43 -26
- package/framework/.claude/skills/prd/assets/epic-template.yml +3 -2
- package/framework/.claude/skills/prd/assets/prd-template.md +90 -14
- package/framework/.claude/skills/prd/assets/state-template.md +18 -0
- package/framework/.claude/skills/prd/references/api-perf-gate.md +102 -52
- package/framework/.claude/skills/prd/references/audit-phase.md +13 -13
- package/framework/.claude/skills/prd/references/discovery-phase.md +214 -28
- package/framework/.claude/skills/prd/references/prd-writing-phase.md +65 -23
- package/framework/.claude/skills/prd/references/research-phase.md +22 -4
- package/framework/.claude/skills/prd/references/ui-design-phase.md +115 -3
- package/framework/.claude/skills/prd/references/validation-phase.md +2 -2
- package/framework/docs/PROJECT-CONFIGURATION.md +41 -1
- package/framework/templates/baldart.config.template.yml +25 -0
- package/package.json +1 -1
- package/src/commands/configure.js +72 -0
- package/src/commands/update.js +13 -1
- package/src/utils/git.js +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,66 @@ All notable changes to BALDART will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.15.0] - 2026-05-23
|
|
9
|
+
|
|
10
|
+
Two changes ship together. **(1) PRD becomes mockup-aware** — formal intake of existing mockups between Kickoff and Discovery, with a per-screen decision tree in Step 3 that skips generation for screens already covered. **(2) Framework becomes stack-aware** — four new `stack.*` cardinal scalars (`database`, `auth_provider`, `framework`, `deployment`) drive vocabulary, gate sections, anti-pattern checklists, and deploy commands across `/prd`, `coder`, `api-perf-cost-auditor`, `/new`, `code-reviewer`, `security-reviewer`, `bug`. Project-identity assumptions previously hard-coded (mayo personas, real test credentials, Italian merchant business names) are removed from the framework and now resolved from `identity.audience_segments[]` + `.baldart/overlays/prd.md`. Sanitization sweep removed all PII (phone numbers, real usernames, real passwords, real store names) from the published payload.
|
|
11
|
+
|
|
12
|
+
### Added — Mockup-aware PRD
|
|
13
|
+
|
|
14
|
+
- **Step 1.6 — Mockup Intake** in [framework/.claude/skills/prd/references/discovery-phase.md](framework/.claude/skills/prd/references/discovery-phase.md). New mandatory step between Kickoff (Step 1) and Discovery (Step 2). Asks the user "Hai dei mockup a disposizione?" — if yes, asks for format (chat images / local paths / mixed), STOPs, and on receipt: copies local files into `${paths.prd_dir}/<slug>/mockups/` (with collision-safe rename), analyzes every mockup against the **Mockup analysis schema** (screens, user_flow, components, states_visible, copy_excerpts, gaps, design_system_alignment with violations when `features.has_design_system: true`), and populates `## UI Design` in the state file before entering Discovery. If "no", marks `mockups.status: none` and proceeds with the standard flow — fully backwards-compatible for projects without mockups.
|
|
15
|
+
- **Step 3 decision tree (Full / Hybrid / Skip)** in [framework/.claude/skills/prd/references/ui-design-phase.md](framework/.claude/skills/prd/references/ui-design-phase.md). Replaces the legacy "skip if UI N/A" precondition. The tree reads `mockups.status` + `screens_in_scope[]` from the state file and routes per-screen: covered-by-mockups screens skip 3a (options) and 3b (generation) — only Component Registry Lookup, approval gate (3c), and inventory (3d) run; uncovered screens invoke the `ui-design` subskill scoped to that single screen, passing the existing mockups as "design language anchor" so the new screen stays consistent. Includes a canonical 5-screen example (3 covered + 2 new) showing exactly which subskill invocations happen and how the final inventory merges.
|
|
16
|
+
- **"Design Reference & Mockup Inventory" section in the PRD template** ([framework/.claude/skills/prd/assets/prd-template.md](framework/.claude/skills/prd/assets/prd-template.md)). New section inserted between Documentation Impact and Section 1 (Problem Statement). Tracks `mockups.status`, `step_3_mode`, the screen inventory table (mapping each screen to its user story + mockup path + origin), the component-mapping table when a design system is in play (reused + new components + token violations), and the source-files traceability list (original user paths → canonical `mockups/` paths, or `chat://image-N` for inline images).
|
|
17
|
+
- **Mockup-aware fields in the state template** ([framework/.claude/skills/prd/assets/state-template.md](framework/.claude/skills/prd/assets/state-template.md)). Extends `## UI Design` with `mockups.{status,format,original_paths,canonical_paths}`, `mockup_analysis.{screens,user_flow,design_system_alignment}`, `step_3_mode`, `design.html_path`, `screens_in_scope`, `ui_inventory`. Single source of truth for everything Step 1.6 produces and Step 3 + PRD Writing consume.
|
|
18
|
+
- **PRD writing acknowledges mockup canonicality** in [framework/.claude/skills/prd/references/prd-writing-phase.md](framework/.claude/skills/prd/references/prd-writing-phase.md). The canonical sources resolution step now adds the `mockups/` directory as a canonical visual reference when `mockups.status` ∈ {`provided`, `partial`}, and the PRD sections checklist includes a new "Design Reference & Mockup Inventory" entry plus revised UI Specifications guidance to avoid duplication.
|
|
19
|
+
- **Hard Rule 16 (Mockup Intake) + Step 1.6 in the flow overview + progress-bar row** in [framework/.claude/skills/prd/SKILL.md](framework/.claude/skills/prd/SKILL.md). Codifies the new step as MANDATORY in the hard-rules section, adds the row `1.6 Mockup intake` to both the in-progress and completed progress-bar templates (with the `Mockup` and `Step 3 mode` summary lines), and adds a "Mockup-driven pre-population" note to the Quick Reference Comprehension Dimensions explaining how dimension 5 (UI impact) and partially dimension 2 (User journey) are pre-resolved from `mockup_analysis` when mockups are provided.
|
|
20
|
+
- **New-Screen Check during Discovery** in [framework/.claude/skills/prd/references/discovery-phase.md](framework/.claude/skills/prd/references/discovery-phase.md). When a user answer reveals a UI screen NOT in `mockup_analysis.screens[]`, the skill no longer treats it as a generic scope expansion (which would offer `/prd-add`). Instead it appends the screen to `screens_in_scope[]` with `covered_by_mockups: false` and logs inline that Step 3 will generate that single screen in Hybrid mode. The Scope Expansion Check still applies for non-UI entities (new endpoints, roles, collections).
|
|
21
|
+
|
|
22
|
+
### Added — Stack-aware framework
|
|
23
|
+
|
|
24
|
+
- **Four new `stack.*` scalar keys** in [framework/templates/baldart.config.template.yml](framework/templates/baldart.config.template.yml): `stack.database` (enum: firestore/supabase/postgres/mysql/mongodb/dynamodb/sqlite/none), `stack.auth_provider` (firebase-auth/supabase-auth/clerk/auth0/cognito/nextauth/lucia/custom/none), `stack.framework` (nextjs/remix/sveltekit/astro/nuxt/rails/django/fastapi/express/none), `stack.deployment` (vercel/firebase/aws/gcp/cloudflare/render/fly/self-hosted/none). Empty string preserves the always-ask contract — skills prompt the user when a needed scalar is unset and suggest `npx baldart configure`.
|
|
25
|
+
- **`baldart configure` autodetection + prompts for the 4 stack scalars** in [src/commands/configure.js](src/commands/configure.js). Autodetection probes `package.json` deps (`firebase`/`@supabase/*`/`pg`/`mongoose`/`@clerk/*`/`@auth0/*`/`next-auth`/`lucia`/`@aws-sdk/client-cognito-identity-provider`/`next`/`@remix-run/*`/`@sveltejs/kit`/`astro`/`nuxt`/`express`), file presence (`vercel.json`/`firebase.json`/`wrangler.toml`/`fly.toml`/`render.yaml`/`Gemfile`/`manage.py`/`requirements.txt`), and content patterns (Django/FastAPI in requirements, rails gem in Gemfile). Detected values pre-fill the interactive prompt. AUTODETECTED box surfaces all 4 values to the user.
|
|
26
|
+
- **`baldart update` schema-drift detector covers scalar `stack.*` keys** in [src/commands/update.js](src/commands/update.js). Extends the existing detector (which already flagged missing `features.*`, `paths.*`, `git.*` keys after an update) to enumerate `tpl.stack[*]` and report only the string-typed top-level scalars as `stack.<key>`. Sub-object keys (`charting`/`animation`/`testing`/`monorepo`/`design_system_signals`) are intentionally ignored — their drift is handled by their dedicated configure prompts. On missing scalars, the detector auto-offers `baldart configure`.
|
|
27
|
+
- **Database vocabulary branching in PRD writing** in [framework/.claude/skills/prd/references/prd-writing-phase.md](framework/.claude/skills/prd/references/prd-writing-phase.md). The Schema Verification Gate header now reads "MANDATORY if feature touches the persistence layer" instead of "if feature touches Firestore"; vocabulary adapts ({entity} = collection|table, {field} = field|column); the schema-registry path resolves via overlay → `stack.database` convention (Firestore `field-registry.json`, SQL `prisma/schema.prisma` or migrations dir, Mongo collection markdown). The PRD-template's Section 5 "Data Model" now ships **5 variants** (Firestore Composite, Relational B-tree+RLS, MongoDB compound, DynamoDB GSI/LSI, None) — the writer keeps only the variant matching `stack.database`.
|
|
28
|
+
- **api-perf-gate refactored as universal-core + stack addenda** in [framework/.claude/skills/prd/references/api-perf-gate.md](framework/.claude/skills/prd/references/api-perf-gate.md). Gate 5 (keyword scan): universal keywords + "Stack-specific keyword addenda" table activated only by the matching `stack.database`. Gates 1–3: universal checklist + "Stack-specific addenda" per `stack.database` (firestore listener/index/ID-hotspot rules, postgres/supabase RLS+EXPLAIN+JSONB rules, mongo compound-field-order+embed rules, dynamodb GSI+hot-partition rules) and per `stack.framework` (nextjs Route Handler `revalidate`/`use cache`, remix `headers`+`shouldRevalidate`, sveltekit runtime declaration, astro `prerender`). Reference Data section split into "Database pricing & cost-model snapshots" (4 stacks), "Runtime limits by `stack.deployment`" (Vercel/Cloudflare/AWS/Firebase table), "Framework caching primitives by `stack.framework`" (4 frameworks). User cites only the variant matching their config.
|
|
29
|
+
- **coder.md Database Index Invariant** in [framework/.claude/agents/coder.md](framework/.claude/agents/coder.md). Renamed from "Firestore Index Invariant"; ships per-stack instructions (Firestore composite + `firestore.indexes.json`, Postgres/Supabase `EXPLAIN` + migration with covering/GIN/RLS, MongoDB `createIndex` with equality→range→sort field order, DynamoDB GSI/LSI in CDK/Terraform, None/unset → skip with warning).
|
|
30
|
+
- **prd-card-writer Field Grounding Rule per-stack registry resolution** in [framework/.claude/agents/prd-card-writer.md](framework/.claude/agents/prd-card-writer.md). The Grep target for field verification is no longer hard-coded to `docs/references/field-registry.json` — it resolves via `.baldart/overlays/prd.md § Schema Registry` first, then by convention matching `stack.database` (Firestore field-registry, Prisma schema, SQL migrations, Mongo collection docs, DynamoDB table definition). Universal identifiers (`id`/`uuid`/PK, `createdAt`/`created_at`, `updatedAt`/`updated_at`) are exempt regardless of stack.
|
|
31
|
+
- **api-perf-cost-auditor reads stack scalars at session start** in [framework/.claude/agents/api-perf-cost-auditor.md](framework/.claude/agents/api-perf-cost-auditor.md). The agent's "Project Context" section is no longer hard-coded to "Next.js 16 + Firestore + Vercel Fluid Compute" — it now lists universal hard rules + addenda tables for `stack.framework`, `stack.database`, `stack.deployment`, and cites the resolved values in every audit header so the user knows which variant applied. Perf budgets move out of the agent into `${paths.references_dir}/perf-budgets.md` (consumer-owned); absence is flagged as a `BUDGETS_GAP` warning instead of using framework-baked numbers.
|
|
32
|
+
- **security-reviewer multi-stack access-rule coverage** in [framework/.claude/agents/security-reviewer.md](framework/.claude/agents/security-reviewer.md). Rule 6 (cloud/infra risks) lists the access-rule variant per `stack.database`: Firebase security rules, Supabase RLS policies, MongoDB validators + collection access, DynamoDB IAM policies, Postgres GRANT/REVOKE + RLS.
|
|
33
|
+
- **`/new` Production Readiness Checklist becomes stack-aware** in [framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md). Detection table and auto-executable commands branch on `stack.deployment` + `stack.database`. Firebase commands are no longer the default — they're one branch among many (vercel deploy, supabase db push, CDK/Terraform apply, firebase deploy). When `stack.deployment` is empty, the skill infers from config-file presence and falls back to asking the user — never auto-executes a guess.
|
|
34
|
+
- **`/new` end-to-end flow generalized for non-Firestore stacks** in [framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md). Five additional spots got the same treatment so a Supabase / Postgres / Mongo / DynamoDB project doesn't see Firestore-only instructions: pre-flight `data_fields` warning triggers on `db_indexes` (any dialect) and reads "touches the persistence layer" instead of "touches Firestore"; Codex parallel-conflict analyzer asks about same-{entity} writes in the project's vocabulary; DEEP-review trigger keys off `db_indexes` (legacy `firestore_indexes` still recognized); the Coder Briefing's index section ships per-`stack.database` instructions (Firestore JSON snippet, SQL migration / Prisma `@@index`, Mongo `createIndex`, DynamoDB GSI/LSI in IaC) and explicitly tells the agent which artifact to stage; post-implementation verification of compound queries branches into 4 dialects with their own missing-index severity; Docs Routing Reminder uses `{entity}` vocabulary and points at the stack-matched index artifact; and the post-deploy "DB Index Verification" section (previously Firestore-only with curl to the Firestore REST API) now opens with a Skip rule and 4 dialect variants (Firestore REST API, Postgres `pg_indexes` + `pg_stat_progress_create_index`, Mongo `getIndexes` + `currentOp`, DynamoDB `describe-table` GSI status). The Firestore variant retains its full procedure verbatim — no regression for Firestore consumers.
|
|
35
|
+
- **bug/logging-patterns.md framework-agnostic** in [framework/.claude/skills/bug/references/logging-patterns.md](framework/.claude/skills/bug/references/logging-patterns.md). The Next.js 16 logging section is now one of four (Next.js, Remix, SvelteKit, Astro/Nuxt) plus a generic `pino`/`winston` fallback. DB-tracing env var examples document the per-stack equivalent (`DEBUG_FIRESTORE=true`, `SUPABASE_DEBUG=true`, `DEBUG=knex:query`, `DEBUG=mongoose:*`).
|
|
36
|
+
- **Persona references generalized to `identity.audience_segments[]`** in [framework/.claude/skills/prd/references/discovery-phase.md](framework/.claude/skills/prd/references/discovery-phase.md), [framework/.claude/skills/prd/references/prd-writing-phase.md](framework/.claude/skills/prd/references/prd-writing-phase.md), [framework/.claude/skills/prd/references/audit-phase.md](framework/.claude/skills/prd/references/audit-phase.md), [framework/.claude/skills/prd/assets/card-template.yml](framework/.claude/skills/prd/assets/card-template.yml), [framework/.claude/skills/prd/assets/epic-template.yml](framework/.claude/skills/prd/assets/epic-template.yml), [framework/.claude/skills/prd/assets/prd-template.md](framework/.claude/skills/prd/assets/prd-template.md). Hard-coded persona literals (`CUSTOMER`/`MERCHANT`/`MERCHANT_STAFF`/`SUPER_ADMIN`) are gone from the framework — replaced by `{{from identity.audience_segments[]}}` placeholders and explicit instructions to loop over the project-declared segments. AC grouping in PRD writing now reads "one group per persona drawn from `identity.audience_segments[]`, plus cross-cutting groups".
|
|
37
|
+
- **`db_indexes` field replaces `firestore_indexes` in card YAML** in [framework/.claude/skills/prd/assets/card-template.yml](framework/.claude/skills/prd/assets/card-template.yml). The card template renames the section; entries gain a `dialect` field matching `stack.database` and a `kind` field (composite/covering/partial/GIN/GSI/LSI/unique/fulltext). The legacy `firestore_indexes` name remains accepted as an alias so v3.14.x cards keep working — the validator in [framework/.claude/skills/prd/references/validation-phase.md](framework/.claude/skills/prd/references/validation-phase.md) recognizes both. Metric `has_firestore_indexes_pct` in [framework/.claude/skills/prd/SKILL.md](framework/.claude/skills/prd/SKILL.md) renamed to `has_db_indexes_pct`.
|
|
38
|
+
- **PROJECT-CONFIGURATION.md § 4.4 documents the 4 new scalars** in [framework/docs/PROJECT-CONFIGURATION.md](framework/docs/PROJECT-CONFIGURATION.md). New "Stack-cardinal scalars" subsection enumerates the 8 skills/agents that branch on them, the always-ask contract on empty values, and the schema-drift detector behavior.
|
|
39
|
+
|
|
40
|
+
### Removed — PII sanitization
|
|
41
|
+
|
|
42
|
+
- **Test credentials (phone, username, password, store name) removed from the published payload.** [framework/.claude/skills/prd/references/discovery-phase.md](framework/.claude/skills/prd/references/discovery-phase.md), [framework/.claude/skills/prd/assets/prd-template.md](framework/.claude/skills/prd/assets/prd-template.md), [framework/.claude/skills/prd/assets/card-template.yml](framework/.claude/skills/prd/assets/card-template.yml) no longer ship any real credential as "example". The discovery Test Strategy step now (a) consults `.baldart/overlays/prd.md § Test Credentials` first, (b) asks the user one structured question per persona if the overlay is silent, (c) stores a credential REFERENCE (secret-manager path, `.env.test:VAR_NAME`) in the state file instead of the literal secret, and (d) explicitly forbids the framework from carrying real PII.
|
|
43
|
+
|
|
44
|
+
### Notes
|
|
45
|
+
|
|
46
|
+
- **One CLI change — `baldart configure`.** v3.15.0 adds autodetection + prompts for the 4 `stack.*` scalars and extends the `baldart update` schema-drift detector to flag missing scalar `stack.*` keys. Consumers upgrading from v3.14.x get the new prompts on the next `baldart configure` invocation; the detector triggers automatically on the next `baldart update`.
|
|
47
|
+
- **The schema-change propagation rule applied end-to-end** for the 4 new scalars: template ✓, configure prompt ✓, update detector ✓, doctor not extended (the always-ask contract in skills already covers the empty case), CHANGELOG ✓.
|
|
48
|
+
- **Backwards-compatibility for v3.14.x cards.** Cards with the legacy `firestore_indexes` field still validate (the writer-side renamed it to `db_indexes`, but the validator and downstream agents accept both names). Cards with `type: firestore` in `data_sources` are equivalent to `type: db, db_dialect: firestore`.
|
|
49
|
+
- **Active PRD sessions started under v3.14.x** do not have `## UI Design` populated with the mockup fields; the skill treats `pending`/missing as `mockups.status: none` and falls into the Full Step-3 branch (legacy behavior). New sessions on v3.15.0+ pick up Step 1.6 automatically.
|
|
50
|
+
- **Step 3 Hybrid mode preserves the design-system cascade.** When `features.has_design_system: true`, the BLOCKING reads of `${paths.design_system}/INDEX.md` + `tokens-reference.md` run BOTH in Step 1.6 (during mockup analysis, to flag violations early) AND in Step 3 (during per-screen Component Registry Lookup, to validate covered + new screens uniformly). Violations bubble up to the unified 3c approval gate.
|
|
51
|
+
- **Sanitization is final, not a heuristic.** Grep across `framework/` for `3486417303`, `antonio.baldassarre2336`, `bRkS2bzqyesK`, `Bar Roma` returns zero hits after this release. Consumers who already had `.baldart/overlays/prd.md` with their real credentials are unaffected — the overlay never leaves the consumer repo.
|
|
52
|
+
- **Verification is manual** (no test suite — `npm test` is no-op stub). Scenarios to dogfood after install: (1) `npx baldart update` on a v3.14.x consumer → schema-drift detector flags 4 new `stack.*` keys → `baldart configure` autodetection pre-fills them; (2) `/prd` on a Supabase project (`stack.database: supabase`) → Schema Verification Gate uses Variant B (Relational), api-perf-gate adds postgres+supabase addenda, audit-phase enforces RLS; (3) `/prd` on a Firestore project (`stack.database: firestore`) → behavior identical to v3.14.x (no regression); (4) `/prd` with mockups → mockup intake + Hybrid Step 3; (5) `/new` on a Cloudflare deployment (`stack.deployment: cloudflare`) → no `firebase deploy` commands proposed.
|
|
53
|
+
|
|
54
|
+
## [3.14.1] - 2026-05-23
|
|
55
|
+
|
|
56
|
+
Hotfix for the `.framework/` gitignore self-heal shipped in v3.14.0. The detector misread `git check-ignore -v` output: when `check-ignore` matched a negation pattern (`!.framework`), it still reported the match, and `checkFrameworkIgnored` flagged the path as ignored. The result: every consumer who hit the self-heal on first run got `.framework/ is STILL ignored after auto-heal` and `process.exit(1)` — the heal *had* actually worked (the negation was in place), but the verifier didn't recognize its own fix. Reported during the v3.13.0 → v3.14.0 update in a downstream consumer.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- **`GitUtils.checkFrameworkIgnored()` recognizes negation patterns** in `src/utils/git.js`. Per `gitignore(5)`, a leading `!` flips the match semantics: `check-ignore` still prints the pattern (matching ≠ ignored), but the path is RE-INCLUDED, not ignored. The detector now inspects the pattern, returns `{ ignored: false, negatedBy }` on a negation match, and `ensureFrameworkNotIgnored`'s post-heal recheck reports `stillIgnored: false` as expected. Smoke-tested end-to-end: `.gitignore` with `.framework` → heal → recheck reports not-ignored → idempotent second call is a no-op → `git add .framework/foo` succeeds.
|
|
61
|
+
- **CHANGELOG consolidation for v3.14.0.** The original 3.14.0 entry had a duplicate `### Added` / `### Notes` block (LSP-only Notes + gitignore-only Notes side by side). Merged into a single Notes section so the release reads as one feature shipped, not two.
|
|
62
|
+
|
|
63
|
+
### Notes
|
|
64
|
+
|
|
65
|
+
- **v3.14.0 is functionally broken on first install of the heal.** Consumers who upgrade `npm i -g baldart@latest` get 3.14.1 directly and never observe the regression. Consumers who already updated to 3.14.0 (CLI binary or `npx baldart`) should reinstall: `npm i -g baldart@latest`, then re-run `baldart` — the heal converges on the second pass because the negation block already in `.gitignore` short-circuits the detector cleanly.
|
|
66
|
+
- **No framework payload changes.** Single-file fix in `src/utils/git.js` plus CHANGELOG.
|
|
67
|
+
|
|
8
68
|
## [3.14.0] - 2026-05-23
|
|
9
69
|
|
|
10
70
|
BALDART closes the **LSP install completeness gap** AND adds a long-overdue **`.framework/` gitignore self-heal** so install / update / push never trip over a stale or pre-existing ignore rule.
|
|
@@ -13,8 +73,15 @@ BALDART closes the **LSP install completeness gap** AND adds a long-overdue **`.
|
|
|
13
73
|
|
|
14
74
|
Since v3.10.0, opting into `features.has_lsp_layer: true` installed the language-server binary (typescript-language-server, pyright, gopls, rust-analyzer, ruby-lsp) into the consumer repo — but the matching native Claude Code plugin (`<lang>-lsp@claude-plugins-official`) was left for the user to install manually via `/plugin install`. Almost nobody did, so Claude itself never invoked the LSP and code-exploration silently fell back to Grep. The "opt-in to LSP" UX was effectively broken: users thought they had it, agents behaved as if they didn't. v3.14.0 wires the two layers together — when the user opts into LSP, BALDART now installs the binary AND enables the native plugin in the same `configure` step, idempotently and gated on `claude` being in `tools.enabled`.
|
|
15
75
|
|
|
76
|
+
### `.framework/` `.gitignore` self-heal
|
|
77
|
+
|
|
78
|
+
The other historical sharp edge in BALDART: consumers who had `.framework` (or a parent pattern like `framework/` or `*framework*`) in `.gitignore` saw every `baldart push` and most `baldart update` autofix flows blow up with `paths are ignored by one of your .gitignore files`, leaving half-finished `chore:` commits on HEAD and requiring a manual `git reset --hard` to recover. The path is a git subtree managed by BALDART — it MUST be tracked — and the failure mode was both confusing (the user never added `.framework` to ignore on purpose) and unfixable from inside the broken flow. v3.14.0 detects the collision and rewrites `.gitignore` idempotently at the top of every install / update / push, so a single `baldart` invocation always converges to a working state.
|
|
79
|
+
|
|
16
80
|
### Added
|
|
17
81
|
|
|
82
|
+
- **`GitUtils.checkFrameworkIgnored()` + `GitUtils.ensureFrameworkNotIgnored()`** in `src/utils/git.js` — central, idempotent self-heal for the `.framework/` ↔ `.gitignore` collision. `checkFrameworkIgnored` runs `git check-ignore -v --no-index -- .framework` and returns `{ ignored, source, line, pattern, raw }` (degrade-open: simple-git throws on non-zero exit, treated as "not ignored"). `ensureFrameworkNotIgnored` strips standalone `.framework` / `.framework/` / `/.framework` rules from the project `.gitignore`, appends a single negation block (`!.framework` + `!.framework/**`) with a marker comment so re-runs are no-ops, then re-runs the check and surfaces `stillIgnored` if a rule still wins from outside the repo (parent-dir `.gitignore`, exotic `core.excludesFile`). Returns `{ wasFixed, stillIgnored, removedLines, appendedNegation, source, pattern, recheck }`. Never throws — callers can safely wrap it in best-effort try/catch.
|
|
83
|
+
- **`baldart add` / `baldart update` / `baldart push` auto-heal `.gitignore`** — each command calls `ensureFrameworkNotIgnored()` at the top of its flow, before `git subtree add` / `git subtree pull` / any `git add` runs. Healing prints a yellow warning so the user sees what changed, then continues without prompting (purely local file rewrite, fully idempotent). If a rule outside the project still wins, the flow exits with a clear, actionable message instead of failing deep in the autofix step with the cryptic `paths are ignored` git error.
|
|
84
|
+
- **`baldart doctor` `.gitignore` diagnostic + `unignore-framework` action** — `detectState` populates `state.frameworkIgnored` with the same payload; the status table renders a yellow `.gitignore IGNORES .framework/ (<source>:<line>) — will be auto-healed` row when triggered, and the planner inserts an `autoOk: true` action that calls the same helper. So `baldart` (no-arg doctor mode) detects, reports, and self-heals in a single invocation. Backfills the heal for consumers predating v3.14.0 that hit the broken-push state.
|
|
18
85
|
- **`claudePluginId()` returns real plugin ids** in every LSP adapter (`src/utils/lsp-adapters/{typescript,python,go,rust,ruby}.js`). Previously a `null` placeholder; now resolves to `typescript-lsp@claude-plugins-official`, `pyright-lsp@claude-plugins-official`, `gopls-lsp@claude-plugins-official`, `rust-analyzer-lsp@claude-plugins-official`, `ruby-lsp@claude-plugins-official` respectively. All plugins live in the Anthropic-published [`anthropics/claude-plugins-official`](https://github.com/anthropics/claude-plugins-official) marketplace.
|
|
19
86
|
- **`LspInstaller.installClaudePlugins(serverNames, opts)`** in `src/utils/lsp-installer.js` — high-level installer that (1) verifies the `claude` CLI is on PATH, (2) idempotently registers the `claude-plugins-official` marketplace via `claude plugin marketplace add anthropics/claude-plugins-official --scope user` (no-op when already registered — list is parsed first), (3) reads `claude plugin list --json` to skip plugins already installed at any scope, (4) runs `claude plugin install <id> --scope user` per missing plugin. Defaults to `--scope user` so a single install is reused across every project on the machine (LSP plugins are machine-wide useful — project scope would create N copies). Always returns `{ installed, skipped, manual, marketplace }`; never throws.
|
|
20
87
|
- **`LspInstaller.ensureClaudeMarketplace()`, `isClaudeCliAvailable()`, `listInstalledClaudePlugins()`, `verifyClaudePlugins(serverNames)`** — supporting primitives, all idempotent and degrade-open (parsing failure returns empty set → next install is attempted rather than incorrectly skipped).
|
|
@@ -32,21 +99,9 @@ Since v3.10.0, opting into `features.has_lsp_layer: true` installed the language
|
|
|
32
99
|
- **Marketplace and plugins live at `--scope user`, not project.** Three reasons: (1) LSP plugins are machine-wide useful — typescript-lsp installed once at user scope is reused by every TS project on the machine, not duplicated N times; (2) marketplace install at user scope means subsequent `baldart configure` runs in sibling projects skip the marketplace add entirely (idempotent); (3) project-scope plugins live under `.claude/` in the consumer repo, which would either need committing (noisy diffs) or `.gitignore` adjustments (extra protocol burden). User scope avoids all three.
|
|
33
100
|
- **Idempotency is checked twice.** Marketplace add reads `claude plugin marketplace list --json` first; plugin install reads `claude plugin list --json` first. Re-running `baldart configure` (or `baldart doctor` with the action accepted) is a no-op when everything is in place — no spurious install commands, no error noise.
|
|
34
101
|
- **Gate on `claude` in `tools.enabled`.** When the consumer has `tools.enabled: [codex]` (Codex-only), the plugin install is a silent no-op — Codex has no equivalent plugin model and Claude marketplace mutation would be off-target. Doctor diagnostics for missing plugins are similarly gated.
|
|
35
|
-
- **No framework payload changes.** All work is inside `src/` — adapters, installer, configure command, doctor command
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`.framework/` is a git subtree — it MUST be tracked. If anything in the gitignore chain (project `.gitignore`, `.git/info/exclude`, global `core.excludesFile`) matches `.framework`, every subsequent `git add` on files under that directory fails with `paths are ignored by one of your .gitignore files` — and `git subtree pull` itself errors out. Pre-v3.14.0 we relied on the user noticing and removing the rule manually; v3.14.0 detects and self-heals.
|
|
40
|
-
|
|
41
|
-
### Added
|
|
42
|
-
|
|
43
|
-
- **`GitUtils.checkFrameworkIgnored()` and `ensureFrameworkNotIgnored()`** in `src/utils/git.js` — `check-ignore -v --no-index .framework` to detect the offending source / line / pattern, then idempotently strip standalone `.framework` rules from the project `.gitignore` and append a one-time `!.framework` + `!.framework/**` negation block marked with `# BALDART: .framework/ is a git subtree — never ignore (auto-managed)`. Re-checks after writing — if the rule lives in a location we cannot rewrite from here (parent-dir `.gitignore` outside the repo, non-standard `core.excludesFile`), surfaces the leftover state via `{ stillIgnored: true, recheck }` so the caller can hard-fail with actionable output.
|
|
44
|
-
- **Self-heal call in `baldart add`** (before `git subtree add`), **`baldart update`** (before `git subtree pull`), **`baldart push`** (before any `git add`). All three flows degrade gracefully — if `check-ignore` itself fails, the heal step prints a warning and continues; if the rule persists after heal, the command exits 1 with the resolution path printed.
|
|
45
|
-
|
|
46
|
-
### Notes (gitignore)
|
|
47
|
-
|
|
48
|
-
- **Idempotent across re-runs.** The negation marker is checked before appending; the strip step is a `filter` over current lines. Running `add` / `update` / `push` repeatedly on a healthy repo is a no-op.
|
|
49
|
-
- **No false positives on .framework-related paths.** The strip filter matches only the six exact forms (`.framework`, `.framework/`, `/.framework`, `/.framework/`, `.framework/*`, `/.framework/*`) — `.frameworks/` or `framework/something.bak` patterns are preserved untouched.
|
|
102
|
+
- **No framework payload changes.** All work is inside `src/` — adapters, installer, configure command, doctor command, and `GitUtils`. No framework agent/skill/command/protocol module touched, so existing consumers see the new behavior the next time they run `baldart configure` or `baldart doctor` after upgrading the CLI (`npm i -g baldart@latest`).
|
|
103
|
+
- **`.gitignore` heal is idempotent across re-runs.** The negation marker is checked before appending; the strip step is a `filter` over current lines. Running `add` / `update` / `push` repeatedly on a healthy repo is a no-op (the negation block is added once, future calls match the marker and skip).
|
|
104
|
+
- **`.gitignore` heal has no false positives.** The strip filter matches only the exact forms (`.framework`, `.framework/`, `/.framework`, `/.framework/`, `.framework/*`, `/.framework/*`) — `.frameworks/` or `framework/something.bak` patterns are preserved untouched.
|
|
50
105
|
|
|
51
106
|
## [3.13.0] - 2026-05-23
|
|
52
107
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.15.0
|
|
@@ -39,16 +39,53 @@ To prevent context bloat:
|
|
|
39
39
|
- Max **5 search_docs MCP calls**.
|
|
40
40
|
- Never read files outside `git diff --name-only` (or scope passed by orchestrator) unless tracing a callgraph that proves a regression.
|
|
41
41
|
|
|
42
|
-
## Project Context (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
42
|
+
## Project Context (read from `baldart.config.yml`)
|
|
43
|
+
|
|
44
|
+
Read `stack.framework`, `stack.database`, `stack.deployment` at the start of
|
|
45
|
+
every audit. The rules below adapt automatically; cite the resolved values in
|
|
46
|
+
your findings header so the user knows which variant you applied.
|
|
47
|
+
|
|
48
|
+
**Universal hard rules** (apply to any stack):
|
|
49
|
+
- Every list query MUST include a `limit` (or equivalent pagination size).
|
|
50
|
+
- Pagination MUST be cursor/keyset-based, never offset-based on hot paths.
|
|
51
|
+
- No N+1 reads in loops — batch / join / `$lookup` / `getAll` per stack.
|
|
52
|
+
- Multi-attribute queries require their matching index shipped in the same commit
|
|
53
|
+
as the query (see Database Index Invariant in coder.md per `stack.database`).
|
|
54
|
+
|
|
55
|
+
**Stack-specific addenda** (apply only when matching):
|
|
56
|
+
|
|
57
|
+
- `stack.framework: nextjs` → Default runtime Fluid Compute (Node.js 24 LTS).
|
|
58
|
+
Edge runtime is not the recommended default. GET Route Handlers are dynamic
|
|
59
|
+
by default since v15 — opt in to caching via `revalidate` / `'use cache'`.
|
|
60
|
+
- `stack.framework: remix` → Set `headers` for Cache-Control explicitly.
|
|
61
|
+
Rely on CDN-level caching.
|
|
62
|
+
- `stack.framework: sveltekit` → Choose Edge vs Node runtime per route;
|
|
63
|
+
declare `prerender` for static pages.
|
|
64
|
+
|
|
65
|
+
- `stack.database: firestore` → Hard rules from AGENTS.md NFR Performance:
|
|
66
|
+
every `where()` includes `.limit()`; pagination uses `startAfter()`; no
|
|
67
|
+
`getDoc()` in loops; composite queries update `firestore.indexes.json` in
|
|
68
|
+
the same commit.
|
|
69
|
+
- `stack.database: postgres | supabase | mysql | sqlite` → `EXPLAIN` every
|
|
70
|
+
new query on a >10k-row table; surface Seq Scan as a HIGH finding.
|
|
71
|
+
Supabase: every new table needs RLS aligned with the auth contract (CRITICAL).
|
|
72
|
+
- `stack.database: mongodb` → Compound index field order: equality → range →
|
|
73
|
+
sort. Aggregations on hot paths must use indexes (no `$match` after
|
|
74
|
+
`$project` that strips the indexed field).
|
|
75
|
+
- `stack.database: dynamodb` → Every non-PK access pattern has a GSI / LSI.
|
|
76
|
+
Reject `FilterExpression` on hot paths.
|
|
77
|
+
|
|
78
|
+
- `stack.deployment: vercel` → Active CPU + provisioned memory + invocations
|
|
79
|
+
billing (not wall-clock GB-s). Payload limit 4.5 MB. Max duration 300s
|
|
80
|
+
Hobby / 800s Pro.
|
|
81
|
+
- `stack.deployment: cloudflare` → 30s CPU per request; 100 MB payload.
|
|
82
|
+
- `stack.deployment: aws` → Lambda 6 MB sync / 256 KB async, max 900s.
|
|
83
|
+
- `stack.deployment: firebase` → 32 MB payload, max 540s (gen 2).
|
|
84
|
+
|
|
85
|
+
**Project performance budgets** are NOT hard-coded here. They live in
|
|
86
|
+
`${paths.references_dir}/perf-budgets.md` (consumer-owned). If that file does
|
|
87
|
+
not exist, derive ad-hoc defaults from the stack snapshot above and flag the
|
|
88
|
+
absence in your audit summary as a `BUDGETS_GAP` warning.
|
|
52
89
|
|
|
53
90
|
## Scope Boundary (MUST — read first)
|
|
54
91
|
|
|
@@ -161,16 +161,67 @@ This rule is enforced by:
|
|
|
161
161
|
- `.claude/skills/new/SKILL.md § Phase 3.7 trigger #6` (mutation-after-helper
|
|
162
162
|
call invokes per-card `/codexreview` before commit).
|
|
163
163
|
|
|
164
|
-
##
|
|
165
|
-
|
|
166
|
-
When writing or modifying
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
## Database Index Invariant (MUST)
|
|
165
|
+
|
|
166
|
+
When writing or modifying queries that combine filters and orderings on
|
|
167
|
+
different attributes, ensure the matching index exists and ships in the same
|
|
168
|
+
commit as the query. Apply the variant matching `stack.database` from
|
|
169
|
+
`baldart.config.yml`:
|
|
170
|
+
|
|
171
|
+
**Variant — Firestore (`stack.database: firestore`)**
|
|
172
|
+
|
|
173
|
+
Where `where()` + `orderBy()` on different fields, or multiple `where()` on
|
|
174
|
+
different fields:
|
|
175
|
+
|
|
176
|
+
1. Check `firestore.indexes.json` for a composite index matching the exact
|
|
177
|
+
pattern (collection, fields, order).
|
|
178
|
+
2. If missing: add it and stage with your commit.
|
|
179
|
+
3. For dynamic queries (`let query = ...; if (x) query = query.where(...)`)
|
|
180
|
+
add a JSDoc: `/** @requires-index: collectionGroup(field1 ASC, field2 DESC) */`
|
|
181
|
+
4. All-equality queries (only `==` filters, no `orderBy` on a different
|
|
182
|
+
field) do NOT need composite indexes.
|
|
183
|
+
|
|
184
|
+
Missing indexes cause **500 errors in production** (`FAILED_PRECONDITION`,
|
|
185
|
+
error code 9) invisible until runtime.
|
|
186
|
+
|
|
187
|
+
**Variant — Relational (`stack.database` ∈ {postgres, supabase, mysql, sqlite})**
|
|
188
|
+
|
|
189
|
+
When the query uses `WHERE col_a = ? AND col_b > ? ORDER BY col_c`, or any
|
|
190
|
+
JOIN/sort/filter combination that can produce a sequential scan on a hot
|
|
191
|
+
table:
|
|
192
|
+
|
|
193
|
+
1. Run `EXPLAIN` (or `EXPLAIN ANALYZE` in dev) on the new query. Verify the
|
|
194
|
+
planner picks an Index Scan or Index Only Scan, not Seq Scan, on tables
|
|
195
|
+
with >10k rows.
|
|
196
|
+
2. If a Seq Scan appears: add a composite or covering index in a new migration
|
|
197
|
+
(`migrations/<ts>_add_<entity>_<purpose>_idx.sql`, or
|
|
198
|
+
`prisma migrate dev` / `supabase migration new` per project conventions).
|
|
199
|
+
3. Stage the migration with the same commit as the query change.
|
|
200
|
+
4. For JSONB queries: ensure a GIN index exists on the JSONB column when
|
|
201
|
+
the query filters on it.
|
|
202
|
+
5. For Supabase: every new table also requires an RLS policy aligned with the
|
|
203
|
+
PRD permissions section.
|
|
204
|
+
|
|
205
|
+
**Variant — MongoDB (`stack.database: mongodb`)**
|
|
206
|
+
|
|
207
|
+
1. Check the collection's indexes via `db.<collection>.getIndexes()` (or the
|
|
208
|
+
schema file the project uses as registry).
|
|
209
|
+
2. For compound queries, ensure the index field order follows
|
|
210
|
+
equality → range → sort.
|
|
211
|
+
3. Add the index in code (`createIndex`) or migration, in the same commit.
|
|
212
|
+
|
|
213
|
+
**Variant — DynamoDB (`stack.database: dynamodb`)**
|
|
214
|
+
|
|
215
|
+
1. Every non-PK access pattern needs either a GSI or LSI declared in the
|
|
216
|
+
table definition (CDK / Terraform / SAM template).
|
|
217
|
+
2. Update the table definition in the same commit as the new query.
|
|
218
|
+
3. Avoid `FilterExpression` on hot paths — pick a GSI instead.
|
|
219
|
+
|
|
220
|
+
**Variant — None / unset**
|
|
221
|
+
|
|
222
|
+
If `stack.database` is empty or `"none"`, skip this section. If you encounter
|
|
223
|
+
persistence code while `stack.database` is empty, surface a warning suggesting
|
|
224
|
+
`npx baldart configure`.
|
|
174
225
|
|
|
175
226
|
## Incremental Verification (MUST)
|
|
176
227
|
|
|
@@ -15,7 +15,15 @@ You are **PRD Card Writer** — a specialist agent that converts an approved PRD
|
|
|
15
15
|
1. **Read the PRD `## Schema Verification` section** (generated during Step 4 of the PRD skill).
|
|
16
16
|
Every field you write MUST appear in that table with status `✅ existing` or `🆕 new`.
|
|
17
17
|
|
|
18
|
-
2. **For each `✅ existing` field**: call `Grep("fieldName",
|
|
18
|
+
2. **For each `✅ existing` field**: call `Grep("fieldName", <schema-registry-path>)`.
|
|
19
|
+
The registry path is resolved per the project:
|
|
20
|
+
- `.baldart/overlays/prd.md § Schema Registry` defines it explicitly when present;
|
|
21
|
+
- otherwise the convention follows `stack.database`:
|
|
22
|
+
- firestore → `${paths.references_dir}/field-registry.json`
|
|
23
|
+
- postgres/supabase/mysql/sqlite → `prisma/schema.prisma` OR `${paths.references_dir}/schema.md` OR the latest migration under the project's migrations dir;
|
|
24
|
+
- mongodb → `${paths.references_dir}/collections/<name>.md` or a JSON schema file in the validator dir;
|
|
25
|
+
- dynamodb → the CDK / Terraform table definition file.
|
|
26
|
+
Then:
|
|
19
27
|
- ≥1 match → set `ts_verified: true` in the card's `data_fields` entry.
|
|
20
28
|
- 0 matches → HALT. Do NOT use this field. Ask: "Field not found in registry — is it new or a typo?"
|
|
21
29
|
|
|
@@ -23,9 +31,9 @@ You are **PRD Card Writer** — a specialist agent that converts an approved PRD
|
|
|
23
31
|
|
|
24
32
|
4. **NEVER invent a field name** not in the Schema Verification snapshot, even if it "sounds right".
|
|
25
33
|
|
|
26
|
-
5. **Exempt from verification** (do not include in `data_fields`): `id
|
|
34
|
+
5. **Exempt from verification** (do not include in `data_fields`): the project's universal identifiers — `id`/`uuid`/PK, `createdAt`/`created_at`, `updatedAt`/`updated_at`.
|
|
27
35
|
|
|
28
|
-
6. **Populate `data_fields`** for every card that reads/writes
|
|
36
|
+
6. **Populate `data_fields`** for every card that reads/writes the persistence layer (see Required Fields).
|
|
29
37
|
|
|
30
38
|
## Mission
|
|
31
39
|
|
|
@@ -127,7 +135,7 @@ applies even when N=1.
|
|
|
127
135
|
4. **Reusing the FEAT-XXXX integer**. Each epic reserves the full integer space.
|
|
128
136
|
5. **Epic with implementation fields**. The epic NEVER has `files_likely_touched`
|
|
129
137
|
pointing to code (only docs), `validation_commands`, `existing_patterns`,
|
|
130
|
-
`data_fields`, `data_sources` beyond `[]`, or `firestore_indexes
|
|
138
|
+
`data_fields`, `data_sources` beyond `[]`, or `db_indexes` (legacy `firestore_indexes` alias also forbidden on epics).
|
|
131
139
|
|
|
132
140
|
### Why MANDATORY
|
|
133
141
|
|
|
@@ -188,31 +196,33 @@ Every card MUST include ALL fields from the template:
|
|
|
188
196
|
- `data_sources` — MANDATORY for EVERY card (never omit, even if empty):
|
|
189
197
|
- High-level inventory of every data source or destination the card touches.
|
|
190
198
|
- One entry per distinct source. Supported types:
|
|
191
|
-
- `
|
|
199
|
+
- `db`: {entity} name in `path` (collection/table/index per `stack.database`); set `db_dialect` to the matching value. Field-level detail lives in `data_fields` (below).
|
|
192
200
|
- `file`: repo-relative path, `operations` (READ|WRITE|APPEND|CREATE|DELETE), `format` (JSONL|YAML|JSON|markdown|binary).
|
|
193
201
|
- `api`: URL or endpoint pattern; READ = GET, WRITE = POST/PUT/PATCH/DELETE.
|
|
194
202
|
- `env`: env var name; `operations: [READ]`.
|
|
203
|
+
- **Legacy:** `firestore` is still accepted (treated as `db` with `db_dialect: firestore`).
|
|
195
204
|
- For **pure docs/config/scaffolding cards** that read and write no data: set `data_sources: []` (explicit empty list — confirms the writer verified there are no sources; never silently omit the field).
|
|
196
|
-
- For **
|
|
197
|
-
- For **file-based tooling cards** (scripts, CLIs, hooks): list each file or directory the card reads from or writes to. This is the primary documentation for non-
|
|
198
|
-
- `data_fields` — MANDATORY if card reads/writes
|
|
199
|
-
- For each field the card touches (excluding `id
|
|
200
|
-
- `
|
|
201
|
-
- `field`: exact
|
|
202
|
-
- `type`:
|
|
205
|
+
- For **persistence-touching cards**: include `type: db` entries here AND populate `data_fields` below. The two fields serve different purposes: `data_sources` is the traceable overview; `data_fields` is the field-level grounding for mechanical validation.
|
|
206
|
+
- For **file-based tooling cards** (scripts, CLIs, hooks): list each file or directory the card reads from or writes to. This is the primary documentation for non-DB data flows.
|
|
207
|
+
- `data_fields` — MANDATORY if card reads/writes the persistence layer:
|
|
208
|
+
- For each field the card touches (excluding universal identifiers — `id`/`uuid`/PK, `createdAt`/`created_at`, `updatedAt`/`updated_at`):
|
|
209
|
+
- `entity`: exact collection or table name (must match key in the schema registry resolved per Field Grounding Rule step 2)
|
|
210
|
+
- `field`: exact identifier (verified via Grep per Field Grounding Rule above)
|
|
211
|
+
- `type`: language-native type from the schema (TypeScript interface / Prisma model / SQL column / Mongo validator)
|
|
203
212
|
- `status`: `existing` | `new` | `modified` | `deprecated_removed`
|
|
204
213
|
- `ts_verified`: `true` (after Grep confirms field in registry) or `false` (new fields only)
|
|
205
|
-
- `source`:
|
|
214
|
+
- `source`: schema file path (e.g. `src/types/booking.ts`, `prisma/schema.prisma:42`, `migrations/2024_...sql`)
|
|
206
215
|
- `schema_ref`: PRD section link — ONLY for `status: new` fields
|
|
207
216
|
- Omit this block entirely for UI-only, docs-only, or config-only cards.
|
|
208
|
-
- `
|
|
209
|
-
- For each card that introduces or modifies a
|
|
210
|
-
(
|
|
217
|
+
- `db_indexes` — propagated from PRD Section 5 `### Database Indexes & Query Optimization` table:
|
|
218
|
+
- For each card that introduces or modifies a query needing a multi-attribute index
|
|
219
|
+
(Firestore composite, SQL B-tree/covering, Mongo compound, DynamoDB GSI/LSI),
|
|
211
220
|
include the matching `IDX-N` entries from the PRD index table.
|
|
212
|
-
- Each entry: `
|
|
221
|
+
- Each entry: `entity`, `dialect` (matches `stack.database`), `fields`, `kind`, `query_location`, `prd_ref`.
|
|
213
222
|
- If the PRD has no index table or this card has no compound queries: omit the field entirely.
|
|
214
|
-
- **CRITICAL**: missing indexes
|
|
215
|
-
The coder MUST
|
|
223
|
+
- **CRITICAL**: missing indexes degrade performance or break production (Firestore: FAILED_PRECONDITION 500; SQL: sequential scan on hot path; DynamoDB: throttle on hot partition).
|
|
224
|
+
The coder MUST ship the index in the same commit as the query — per `stack.database` (firestore.indexes.json, migration file, createIndex call, table definition).
|
|
225
|
+
- Legacy field name `firestore_indexes` is still accepted for pre-3.15.0 cards.
|
|
216
226
|
- `documentation_impact` — list of docs to update when card is DONE:
|
|
217
227
|
- New `route.ts` -> `docs/references/api/<module>.md` + `api/index.md`
|
|
218
228
|
- New collection -> `docs/references/data-model.md` + `collections/<domain>.md`
|
|
@@ -43,7 +43,7 @@ Before reviewing:
|
|
|
43
43
|
3. **Flag security anti-patterns**: unsafe libraries, insecure framework usage, dangerous data flows.
|
|
44
44
|
4. **Review comprehensively**: authentication, authorization, session handling, secrets management, cryptography, input validation, output encoding, deserialization, file handling, logging, error handling.
|
|
45
45
|
5. **Assess attack vectors**: SSRF, XSS, CSRF, SQL/NoSQL injection, command injection, path traversal, RCE, IDOR, broken access control, race conditions, insecure randomness, data leakage.
|
|
46
|
-
6. **Evaluate cloud/infra risks**: IAM over-permissioning, public exposure, insecure storage, CI/CD secret leakage, supply chain risks, Firebase security rules.
|
|
46
|
+
6. **Evaluate cloud/infra risks**: IAM over-permissioning, public exposure, insecure storage, CI/CD secret leakage, supply chain risks, persistence-layer access rules (variant per `stack.database`: Firebase security rules, Supabase RLS policies, MongoDB validators + role-based collection access, DynamoDB IAM policies, Postgres GRANT/REVOKE + RLS).
|
|
47
47
|
7. **Assess privacy/data protection**: PII exposure, credential leakage, tokens in logs, internal ID exposure.
|
|
48
48
|
8. **Evaluate dependencies**: third-party integration risks visible in code or manifests.
|
|
49
49
|
9. **Propose remediations**: concrete, minimal, production-ready fixes.
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# Logging Patterns & Debug Environment Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Pick the section matching `stack.framework` from `baldart.config.yml`. The
|
|
4
|
+
> first section (Next.js) is the most common; sections for other frameworks
|
|
5
|
+
> follow the same intent: maximize signal during a debug session, with a way
|
|
6
|
+
> to turn it off cleanly when done.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
## Next.js 16 Built-In Logging (`stack.framework: nextjs`)
|
|
9
|
+
|
|
10
|
+
Add to `next.config.ts` during debug sessions:
|
|
6
11
|
|
|
7
12
|
```typescript
|
|
8
13
|
logging: {
|
|
@@ -17,17 +22,49 @@ logging: {
|
|
|
17
22
|
|
|
18
23
|
`browserToTerminal` (v16.2+) is the most powerful: it streams client-side `console.*` to the dev server terminal with file:line:col source location. No code changes needed.
|
|
19
24
|
|
|
25
|
+
## Remix Built-In Logging (`stack.framework: remix`)
|
|
26
|
+
|
|
27
|
+
- Enable `loader` / `action` timing via `DEBUG=remix:*` env.
|
|
28
|
+
- For request logging, instrument `entry.server.ts` with a `handleRequest`
|
|
29
|
+
wrapper that logs method/path/duration.
|
|
30
|
+
- Browser console forwarding: not built-in; use a small client-side logger
|
|
31
|
+
posting to `/__debug` route handler during the session.
|
|
32
|
+
|
|
33
|
+
## SvelteKit (`stack.framework: sveltekit`)
|
|
34
|
+
|
|
35
|
+
- Enable verbose `vite` logging via `vite --debug` for build-time issues.
|
|
36
|
+
- `handle` hook in `hooks.server.ts` is the natural choke point: log
|
|
37
|
+
method/path/duration there during a session.
|
|
38
|
+
|
|
39
|
+
## Astro / Nuxt / Other
|
|
40
|
+
|
|
41
|
+
- Use the framework's request hook (Astro middleware, Nuxt `defineEventHandler`
|
|
42
|
+
wrapper) to log structured request/response data.
|
|
43
|
+
- Stick to plain `console.log` with a unique prefix that's easy to grep and
|
|
44
|
+
remove (e.g. `[BUG-1234]`).
|
|
45
|
+
|
|
46
|
+
## Generic fallback (any framework)
|
|
47
|
+
|
|
48
|
+
When the framework has no built-in equivalent, add `pino` or `winston` to the
|
|
49
|
+
project and emit JSON logs at every interesting choke point (request entry,
|
|
50
|
+
DB call, external API call). Remove on session close.
|
|
51
|
+
|
|
20
52
|
## Environment Variables for Debug Sessions
|
|
21
53
|
|
|
22
54
|
Set in `.env.local` during investigation, remove after:
|
|
23
55
|
|
|
24
56
|
```bash
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
57
|
+
# Examples — pick the ones matching this project's stack:
|
|
58
|
+
DEBUG_MODULES=<module>.<verb> # server-side module filter (project-specific)
|
|
59
|
+
DEBUG_DB=true # generic DB op tracing — name varies by stack:
|
|
60
|
+
# firestore → DEBUG_FIRESTORE=true
|
|
61
|
+
# supabase → SUPABASE_DEBUG=true
|
|
62
|
+
# postgres → DEBUG=knex:query (or your ORM's flag)
|
|
63
|
+
# mongo → DEBUG=mongoose:* (if using mongoose)
|
|
64
|
+
DEBUG_NETWORK=true # request/response logging
|
|
65
|
+
DEBUG_PROXY=true # proxy/middleware logging
|
|
66
|
+
NEXT_PUBLIC_DEBUG_COMPONENTS=<module> # Next.js only — client component logs (rebuild required)
|
|
67
|
+
NEXT_OTEL_VERBOSE=1 # Next.js only — verbose OpenTelemetry spans
|
|
31
68
|
NEXT_TURBOPACK_TRACING=1 # Turbopack bundler trace → .next/dev/trace-turbopack
|
|
32
69
|
```
|
|
33
70
|
|