baldart 4.82.0 → 4.83.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 CHANGED
@@ -5,6 +5,38 @@ 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
+ ## [4.83.0] - 2026-07-01
9
+
10
+ **Versioned root-file primitives — BALDART now generates `AGENTS.md` + `CLAUDE.md` from SOTA skeletons.** Previously `AGENTS.md` was a bulk symlink into the framework payload (not customizable without losing auto-update) and `CLAUDE.md` was not shipped at all. Now both are **generated real files**, produced on every install/update from **versioned skeletons** under `framework/templates/primitives/`.
11
+
12
+ Each skeleton mixes three tiers: **STATIC** (universal SOTA prose, shipped verbatim) · **`{{ slot }}`** (project facts filled *deterministically* at write-time from `baldart.config.yml` + `package.json`/README probes — concrete values, so Codex/Cursor/Aider read real commands, never raw `${…}`) · **`[OVERLAY]`** (project opinions authored in `.baldart/overlays/{AGENTS,CLAUDE}.md`, merged via the existing OVERRIDE/APPEND/PREPEND engine). This split follows the 2026 research consensus (short hand-authored skeleton + project depth in the overlay; auto-generating a whole file with an LLM measurably reduces agent task success).
13
+
14
+ **`AGENTS.md` is the cross-tool SSOT** (read natively by Claude Code + Codex + others). **`CLAUDE.md` is a thin Claude-native stub** that deliberately does **not** import `AGENTS.md` (Claude Code loads both automatically → an `@AGENTS.md` would double-load the protocol) — it holds only Claude-only mechanics (Plan Mode / `AskUserQuestion` / Task tool / output-style / hooks). The writer (`src/utils/root-primitives.js`) reuses `overlay-merger.js` and the same `baldart-generated` marker, so the `framework-edit-gate` already blocks direct edits to the generated files (edit the overlay).
15
+
16
+ **Existing hand-written files are adopted zero-loss:** a consumer's hand-authored `AGENTS.md`/`CLAUDE.md` (no marker) is preserved **verbatim** into `.baldart/overlays/<name>.md`, then the root is regenerated as skeleton + overlay. Adoption is **interactive-gated** — in autonomous/CI mode a hand-written file is never mutated (the writer emits a blocker and skips it). Wired into `add` (post-configure), `update` (aligned + post-pull paths, idempotent + byte-stable), `doctor` (`regenerate-root-primitives` / `adopt-root-primitives` actions), and `migrate` (legacy symlink → generated file). Each skeleton carries its own `primitive_version` + a sibling `*.CHANGELOG.md` kept out of the generated file.
17
+
18
+ **MINOR** — additive capability. **No new `baldart.config.yml` key** (slots resolve from existing config + repo probes) → the schema-change propagation rule does NOT apply. Degrades safely: missing commands omit rows, non-multimodal/Codex consumers ignore `CLAUDE.md`, autonomous runs never mutate hand-written files. Authoritative design: [`framework/docs/ROOT-PRIMITIVES.md`](framework/docs/ROOT-PRIMITIVES.md).
19
+
20
+ ### Added
21
+
22
+ - **`framework/templates/primitives/AGENTS.md` + `CLAUDE.md`** — the versioned SOTA skeletons (STATIC + `{{slot}}` + `[OVERLAY]` hook), each with a `primitive_version` banner.
23
+ - **`framework/templates/primitives/AGENTS.CHANGELOG.md` + `CLAUDE.CHANGELOG.md`** — internal per-primitive changelogs (kept out of the generated file).
24
+ - **`src/utils/root-primitives.js`** — the writer: slot resolver + minimal zero-dep template engine (`{{ }}` / `{{#flag}}` / `{{> partial}}`) + overlay merge + `baldart-generated` marker + state machine (generated / symlink / handwritten / absent) + `rootPrimitiveStatus()` for doctor.
25
+ - **`framework/docs/ROOT-PRIMITIVES.md`** — consumer-facing design/lifecycle/adoption doc.
26
+
27
+ ### Changed
28
+
29
+ - **`src/utils/symlinks.js`** — `createBulkSymlinks()` no longer symlinks `AGENTS.md`; `createAllSymlinks()` calls the new `writeRootPrimitives()`; `verifySymlinks()` no longer expects `AGENTS.md` to be a symlink.
30
+ - **`src/commands/add.js`** — writes root primitives after `configure` populates the config (final concrete values).
31
+ - **`src/commands/update.js`** — regenerates root primitives on both the aligned-install and post-pull paths (`reconcileRootPrimitives`); adds `CLAUDE.md` to `BALDART_MANAGED_PATTERNS`.
32
+ - **`src/commands/doctor.js`** — detects stale/adoptable root primitives and offers `regenerate-root-primitives` / `adopt-root-primitives`.
33
+ - **`src/commands/migrate.js`** — converts a legacy `AGENTS.md` symlink into the generated file (Step 2b), idempotent.
34
+ - **`README.md`** — install description + repo-tree updated (AGENTS.md/CLAUDE.md generated, not symlinked).
35
+
36
+ ### Removed
37
+
38
+ - **`framework/AGENTS.md`** — the old bulk-symlink source; its STATIC content now lives in `framework/templates/primitives/AGENTS.md` (single SSOT).
39
+
8
40
  ## [4.82.0] - 2026-07-01
9
41
 
10
42
  **Mockup→code extracted into a dedicated self-verifying skill `/ui-implement` + skills are now versioned.** The mockup→code fidelity knowledge (v4.73→v4.78) was **inlined inside `/new`**: the "Design Reference" briefing (image/HTML/code-src branching), the design-source declaration + Step 7b grounding, and the Phase 2.6 `/e2e-review` invocation. This release **externalizes** it into one specialized, self-verifying skill and, separately, introduces **per-skill versioning + a canonical structure** across all skills.
package/README.md CHANGED
@@ -66,7 +66,8 @@ npx baldart status
66
66
  ### What `add` (first install) does
67
67
 
68
68
  - Downloads the framework via Git subtree into `.framework/`
69
- - Creates symlinks for auto-updateable files (AGENTS.md, agents/)
69
+ - Creates a symlink for the cross-tool `agents/` reference dir
70
+ - Generates the root-file primitives `AGENTS.md` (cross-tool SSOT) + `CLAUDE.md` (Claude entry) from versioned skeletons — filling project facts from `baldart.config.yml` and merging `.baldart/overlays/{AGENTS,CLAUDE}.md`
70
71
  - Per-item-merges framework agents/commands/skills into `.claude/` (real directories where your own files coexist)
71
72
  - Detects Codex on the machine and mirrors skills into `.agents/skills/` if found
72
73
  - Copies customizable templates (hooks, UI guidelines, backlog cards)
@@ -365,7 +366,8 @@ npx baldart routines disable wiki-review # remove the schedule
365
366
  ```
366
367
  your-project/
367
368
  ├── .framework/ # Framework source (via Git subtree)
368
- ├── AGENTS.md # Symlink .framework/AGENTS.md
369
+ ├── AGENTS.md # Generated from skeleton + config + overlay (cross-tool SSOT)
370
+ ├── CLAUDE.md # Generated Claude Code entry (Claude-native mechanics)
369
371
  ├── agents/ # Symlink → .framework/agents/
370
372
  ├── .claude/
371
373
  │ ├── agents/ # Symlink → .framework/.claude/agents/
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.82.0
1
+ 4.83.0
@@ -15,8 +15,10 @@
15
15
  * as BROKEN in some scenarios (files ignored at session start)
16
16
  *
17
17
  * This hook covers the filesystem-detectable subset of the problem
18
- * (missing/broken symlinks). The model-side defense (the MUST rule in
19
- * `framework/AGENTS.md`) covers the rest. The two are inseparable:
18
+ * (missing/broken symlinks). The model-side defense (the MUST rule in the
19
+ * generated root `AGENTS.md`, shipped from
20
+ * `framework/templates/primitives/AGENTS.md`) covers the rest. The two are
21
+ * inseparable:
20
22
  * without the MUST rule, a `permissionDecision: deny` from this hook
21
23
  * would likely be worked around by the model trying a different
22
24
  * `subagent_type` — the very failure mode this hook exists to prevent.
@@ -0,0 +1,98 @@
1
+ # Root-file primitives — `AGENTS.md` + `CLAUDE.md`
2
+
3
+ Since **v4.83.0** BALDART ships **versioned skeletons** for the two most important
4
+ files in any AI-assisted repo and generates concrete, project-specific versions of
5
+ them on every install/update.
6
+
7
+ - **`AGENTS.md`** — the **cross-tool single source of truth** (read natively by Claude
8
+ Code, Codex, Cursor, Aider, …). Holds the coordination protocol: MUST rules, git
9
+ workflow, gates, execution modes, routing.
10
+ - **`CLAUDE.md`** — a **thin Claude-native stub**. Claude Code loads *both* files
11
+ automatically, so `CLAUDE.md` does **not** import `AGENTS.md` (that would double-load
12
+ the protocol into context). It carries only the Claude-only mechanics: Plan Mode
13
+ (`EnterPlanMode`/`ExitPlanMode`), `AskUserQuestion` discipline, the Task-tool subagent
14
+ roster, output-style, hooks.
15
+
16
+ Before v4.83.0, `AGENTS.md` was a bulk symlink into the framework payload (not
17
+ customizable without losing auto-update) and `CLAUDE.md` was not shipped at all.
18
+
19
+ ## Three tiers
20
+
21
+ Each skeleton mixes exactly three kinds of content:
22
+
23
+ | Tier | What | Who authors it |
24
+ |---|---|---|
25
+ | **STATIC** | universal SOTA prose, identical for every project | the shipped primitive (versioned) |
26
+ | **`{{ slot }}`** | project facts, filled deterministically at write-time | the writer (`src/utils/root-primitives.js`) — pure substitution, never LLM invention |
27
+ | **`[OVERLAY]`** | project opinions / war-stories / KPIs / design rules | the repo owner, in `.baldart/overlays/{AGENTS,CLAUDE}.md` |
28
+
29
+ This split follows the 2026 research consensus: a shipped skeleton stays **short and
30
+ hand-authored**; project depth lives in the overlay (auto-generating a whole
31
+ `AGENTS.md`/`CLAUDE.md` with an LLM measurably *reduces* agent task success).
32
+
33
+ ## Slot resolution (deterministic)
34
+
35
+ The writer resolves every slot from `baldart.config.yml` + repo probes — no new config
36
+ key was introduced:
37
+
38
+ | Slot | Source |
39
+ |---|---|
40
+ | `identity.name` | `identity.brand_name` → `package.json` name → dir basename |
41
+ | `identity.description` | README first paragraph → `package.json` description → visible `<!-- TODO -->` |
42
+ | `stack.summary` | composed from `stack.framework` + `database` + `auth_provider` + `testing.e2e` + `toolchain.installed_tools` |
43
+ | `stack.node` | `package.json` `engines.node` → `.nvmrc` |
44
+ | Commands table | `toolchain.commands.*` → `package.json` scripts (rows with no source are omitted) |
45
+ | Repo map | non-empty `paths.*` + a derived source root |
46
+ | `git.trunk_branch` | `git.trunk_branch` |
47
+ | feature gates | `features.has_backlog` / `has_adrs` / `has_i18n` / `has_design_system` |
48
+
49
+ ## Overlay
50
+
51
+ `.baldart/overlays/AGENTS.md` (and `…/CLAUDE.md`) use the **same** merge engine as agent
52
+ and command overlays (`overlay-merger.js`):
53
+
54
+ - `## [OVERRIDE] <section>` — replace a section from the skeleton.
55
+ - `## [APPEND] <section>` — append to a section.
56
+ - `## [PREPEND] <section>` — prepend to a section.
57
+ - a plain `## <heading>` — add a new section at the end.
58
+
59
+ Author overlays with `/overlay` or by hand. The generated root file carries a
60
+ `baldart-generated` marker and the `framework-edit-gate` hook blocks direct edits to it —
61
+ edit the overlay, not the file.
62
+
63
+ ## Lifecycle
64
+
65
+ - **`baldart add`** — after `configure` populates `baldart.config.yml`, the writer
66
+ generates both files with concrete values.
67
+ - **`baldart update`** — regenerates on both the aligned-install and post-pull paths.
68
+ **Byte-stable**: unchanged inputs produce no diff.
69
+ - **`baldart doctor`** — flags `regenerate-root-primitives` when a file is missing, still
70
+ a legacy symlink, or drifted (skeleton / overlay / config change), and
71
+ `adopt-root-primitives` for a handwritten file.
72
+ - **`baldart migrate`** — converts a legacy `AGENTS.md` symlink into the generated file.
73
+
74
+ ## Adoption (existing hand-written files — zero loss)
75
+
76
+ If a consumer already has a hand-authored `AGENTS.md` or `CLAUDE.md` (no
77
+ `baldart-generated` marker), the writer **adopts** it: the entire file is preserved
78
+ verbatim into `.baldart/overlays/<name>.md`, and the root is regenerated as skeleton +
79
+ overlay (so nothing is lost). You are told to review and re-file — much of a rich
80
+ `CLAUDE.md` typically belongs in the **AGENTS.md** overlay (cross-tool), not CLAUDE.md.
81
+
82
+ **Adoption is interactive-gated.** In autonomous/CI mode (`CI` / `BALDART_AUTONOMOUS` /
83
+ no TTY) a hand-written file is **never mutated**: the writer emits a blocker and skips it,
84
+ so a routine unattended update never silently transforms your file.
85
+
86
+ ## Versioning
87
+
88
+ Each skeleton carries a `primitive_version` (SemVer, its own line of evolution,
89
+ independent of the framework `VERSION`) in its banner, plus a sibling
90
+ `framework/templates/primitives/<NAME>.CHANGELOG.md` kept **out** of the generated file
91
+ so version history never costs context. Bump `primitive_version` + add a changelog entry
92
+ whenever a skeleton changes.
93
+
94
+ ## Files
95
+
96
+ - `framework/templates/primitives/AGENTS.md` · `CLAUDE.md` — the skeletons.
97
+ - `framework/templates/primitives/AGENTS.CHANGELOG.md` · `CLAUDE.CHANGELOG.md` — internal changelogs.
98
+ - `src/utils/root-primitives.js` — the writer (resolve → template → merge → marker → write) + `rootPrimitiveStatus` (doctor).
@@ -0,0 +1,18 @@
1
+ # Changelog — AGENTS.md primitive
2
+
3
+ Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
+ Questo è il changelog INTERNO dello skeleton spedito (`primitive_version`), separato dal
5
+ file `AGENTS.md` generato nel consumer e indipendente dal `VERSION` del framework.
6
+
7
+ ## 1.0.0 — 2026-07-01
8
+
9
+ - Primo skeleton SOTA cross-tool (framework v4.83.0). Sostituisce il bulk symlink di
10
+ `AGENTS.md` con un real-file **generato**: contenuto STATIC universale + slot `{{ }}`
11
+ riempiti a write-time da `baldart.config.yml` (identity/stack/paths/commands/git) +
12
+ hook `[OVERLAY]` per `.baldart/overlays/AGENTS.md`.
13
+ - Struttura: Commands (partial, comandi concreti) · Repo Map (partial) · Non-negotiables
14
+ (universal + feature-gated) · Git Workflow · Workflow Gates · Execution Modes ·
15
+ Priority & Conflict · Routing.
16
+ - Le meccaniche solo-Claude (EnterPlanMode/AskUserQuestion/Task) NON stanno qui: vivono
17
+ nello stub `CLAUDE.md`. La ricchezza project-specific (war-story/KPI/regole design) va
18
+ in overlay, non nello skeleton (best practice 2026: skeleton corto, no auto-generazione).
@@ -0,0 +1,111 @@
1
+ <!-- baldart-primitive: name=AGENTS primitive_version=1.0.0
2
+ This is the SHIPPED SKELETON. The writer (src/utils/root-primitives.js) strips
3
+ this banner, resolves every {{ slot }} / {{> partial }} / {{#flag}} from
4
+ baldart.config.yml (+ package.json/README), merges .baldart/overlays/AGENTS.md,
5
+ stamps a baldart-generated marker, and writes the result to the repo root.
6
+ Tiers: STATIC (verbatim) · {{slot}} (config fill) · [OVERLAY] (project opinions).
7
+ Edit the OVERLAY, never the generated root AGENTS.md. -->
8
+ # {{ identity.name }} — Agent Protocol (AGENTS.md)
9
+
10
+ {{ identity.description }}
11
+ Stack: {{ stack.summary }}.{{ stack.node_suffix }}
12
+
13
+ Mandatory coordination rules for all agents (Claude / Codex / humans). Read by every
14
+ AI tool that supports AGENTS.md. If context is limited, follow **MUST** rules and
15
+ **Routing** first. Claude Code additionally loads `CLAUDE.md`, which adds Claude-native
16
+ mechanics — this file remains the single source of truth for the protocol.
17
+
18
+ {{> commands_section }}
19
+ ## Repo Map
20
+
21
+ {{> repo_map }}
22
+
23
+ ## Non-negotiables (MUST)
24
+
25
+ **Universal (every project):**
26
+ - MUST treat `AGENTS.md` as authoritative for agent rules.
27
+ - MUST understand the codebase before planning/implementing — invoke `codebase-architect`
28
+ (Claude Code: Task tool `subagent_type: codebase-architect`; Codex: the custom agent by
29
+ name at `.codex/agents/codebase-architect.toml`). Only if NEITHER mechanism exists,
30
+ degrade explicitly to inline retrieval (code-graph → LSP → Grep) and SAY SO.
31
+ - MUST NOT silently substitute a different agent when an invocation returns empty / times
32
+ out / is denied — STOP, report verbatim, and wait. Never auto-route to a generic agent.
33
+ - MUST NOT work on files another agent has claimed; parallel work only on independent areas.
34
+ - MUST do a clarity analysis before fixing anything labeled `bug` — no blind guessing.
35
+ - MUST mark missing info UNKNOWN and ask; if blocked, set `BLOCKED` with the blocker.
36
+ - MUST NOT make forbidden assumptions: provider/auth swap, DB-schema change without a
37
+ data-model update, new external dependency without docs, API-contract change without an
38
+ API-reference update.
39
+ - MUST keep docs and code in sync — a code change without the matching doc update is invalid.
40
+ - MUST use commit format `{{ git.commit_format }}`; small, traceable commits.
41
+ - MUST NOT commit with failing lint/type checks. Full build only before opening a PR.
42
+ - MUST pre-sync (`git fetch`, clean status, confirm branch, `--ff-only`) and NEVER push
43
+ directly to `{{ git.trunk_branch }}` — all changes reach it via PR.
44
+ - MUST get owner approval before force-push/reset or deleting an UNMERGED branch (create a
45
+ `backup/<YYYYMMDD>-<reason>` tag first). Deleting an already-merged branch is routine.
46
+ - MUST run the testing gates before DONE (see § Workflow Gates).
47
+
48
+ **Feature-gated (active only when the flag is `true` in `baldart.config.yml`):**
49
+ {{#has_backlog}}
50
+ - Backlog: pick one card (TODO/READY), set `IN_PROGRESS`, assign yourself, branch-per-card
51
+ (`{{ git.feature_prefix }}/<CARD-ID>-slug`), keep status current, document before merge.
52
+ {{/has_backlog}}
53
+ {{#has_adrs}}
54
+ - ADRs: write complete records (Context / Decision / Rationale / Alternatives / Consequences,
55
+ no TODO placeholders) for architectural decisions.
56
+ {{/has_adrs}}
57
+ {{#has_i18n}}
58
+ - i18n: NO hardcoded user-facing strings; every label via `t()` + a key in
59
+ `{{ i18n.registry }}`. Enforced by the anti-hardcoded lint gate.
60
+ {{/has_i18n}}
61
+ {{#has_design_system}}
62
+ - Design system: the BLOCKING read cascade applies before any UI work — read the registry
63
+ `INDEX.md` → the per-component spec → the token SSOT (see § Routing).
64
+ {{/has_design_system}}
65
+ {{#has_project_status}}
66
+ - Status doc: update its Active Code Context before work; keep it < 200 lines; archive
67
+ entries older than 7 days to `work-history.md`.
68
+ {{/has_project_status}}
69
+
70
+ ## Git Workflow
71
+
72
+ Branch naming: `{{ git.feature_prefix }}/<CARD-ID>-slug` (local), `codex/…` or `claude/…`
73
+ (cloud agents), `hotfix/<ID>-slug` (production fixes). Branches are created by the
74
+ orchestrator (`/nw`, `/new`) or the user — **never by the `coder` agent** (it implements on
75
+ the branch it was spawned on). Stage explicit filenames only; never bundle unrelated changes.
76
+
77
+ ## Workflow Gates
78
+
79
+ **Pre-commit (fast, every commit):** lint · type check{{#has_i18n}} · the i18n anti-hardcoded
80
+ gate{{/has_i18n}} · markdown-lint on changed `.md`. Fix all errors before `git add`. Do NOT
81
+ run a full build every commit.
82
+
83
+ **Pre-PR (once, before opening a PR):** full build (must pass) · unit tests (if they exist) ·
84
+ E2E for critical-flow changes.
85
+
86
+ ## Execution Modes
87
+
88
+ | Mode | Branch | Validation |
89
+ |---|---|---|
90
+ | `local` | `{{ git.feature_prefix }}/<CARD-ID>-slug` → PR to `{{ git.trunk_branch }}` | manual run mandatory |
91
+ | `cloud` | `codex/…` or `claude/…` → PR to `{{ git.trunk_branch }}` | CI-first; local advisory |
92
+ | `hotfix` | `hotfix/<BUG-ID>-slug` | owner approval |
93
+
94
+ ## Priority & Conflict
95
+
96
+ Priority: `AGENTS.md` → `agents/index.md` → domain references → ADRs → `archive/`.
97
+ On conflict: stop → read both → decide which is newer → update the other → record the
98
+ decision in an ADR + the backlog card.
99
+
100
+ ## Routing
101
+
102
+ - Docs routing (touch X → read/update Y): `agents/index.md`.
103
+ - Agent invocation routing: `.claude/agents/REGISTRY.md` (SSOT). Update it when adding agents.
104
+ - Domain protocols load on demand from `agents/*.md` (architecture, testing, security,
105
+ design-system-protocol, i18n-protocol, …) — never load them all at once.
106
+
107
+ <!-- OVERLAY: project-specific rules live in `.baldart/overlays/AGENTS.md` and are merged
108
+ below this line. Use `## [APPEND] <section>` to extend a section above, `## [OVERRIDE]
109
+ <section>` to replace one, or a plain `## <heading>` to add a new section. Typical
110
+ content: design-system rules · DB/migration discipline · NFR/KPI targets · security
111
+ specifics · project war-stories & ADR pointers · custom commands. -->
@@ -0,0 +1,15 @@
1
+ # Changelog — CLAUDE.md primitive
2
+
3
+ Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
+ Changelog INTERNO dello stub spedito (`primitive_version`), separato dal `CLAUDE.md`
5
+ generato nel consumer e indipendente dal `VERSION` del framework.
6
+
7
+ ## 1.0.0 — 2026-07-01
8
+
9
+ - Primo stub Claude-native (framework v4.83.0). BALDART inizia a spedire `CLAUDE.md`.
10
+ - Deliberatamente **non** importa `AGENTS.md` (Claude Code carica entrambi i file
11
+ nativamente → un `@AGENTS.md` raddoppierebbe il protocollo in contesto). Contiene solo:
12
+ Plan Mode (EnterPlanMode/plan-auditor/doc-reviewer/ExitPlanMode), User Interaction
13
+ (AskUserQuestion = stop-and-wait), Subagents & tooling (Task tool, output-style, hooks).
14
+ - Hook `[OVERLAY]` per `.baldart/overlays/CLAUDE.md`; le regole cross-tool vanno
15
+ nell'overlay di AGENTS.md, non qui.
@@ -0,0 +1,41 @@
1
+ <!-- baldart-primitive: name=CLAUDE primitive_version=1.0.0
2
+ SHIPPED SKELETON. The writer strips this banner, resolves {{ slot }}/{{#flag}} from
3
+ baldart.config.yml, merges .baldart/overlays/CLAUDE.md, stamps a baldart-generated
4
+ marker, and writes the result to the repo root.
5
+ Claude Code loads BOTH CLAUDE.md and AGENTS.md automatically, so this file does NOT
6
+ import AGENTS.md (that would double-load the protocol). It holds ONLY the Claude-native
7
+ mechanics that would be noise in the cross-tool AGENTS.md. Edit the OVERLAY, never the
8
+ generated root CLAUDE.md. -->
9
+ # {{ identity.name }} — Claude Code entry
10
+
11
+ The full cross-tool coordination protocol (rules, MUST list, git workflow, gates, routing)
12
+ lives in `AGENTS.md`, which Claude Code loads automatically alongside this file — it is the
13
+ SSOT, not restated here. Below are the **Claude-native mechanics only**.
14
+
15
+ ## Plan Mode (Claude-native)
16
+
17
+ - Enter plan mode (`EnterPlanMode`) for any non-trivial task before writing code.
18
+ Trivial = single-line fix / typo / obvious bug.
19
+ - Invoke `codebase-architect` before writing the plan — never plan blind.
20
+ - Launch `plan-auditor` + `doc-reviewer` in parallel to review the plan, incorporate their
21
+ feedback, and state inside the plan that the review gate was honored, BEFORE `ExitPlanMode`.
22
+ - Wait for explicit user approval, then delegate implementation to the `coder` agent (via the
23
+ Task tool). The `coder` writes code + minimal doc stubs only.
24
+
25
+ ## User Interaction (Claude-native, ABSOLUTE)
26
+
27
+ - `AskUserQuestion` = STOP and wait. Never answer your own question.
28
+ - It MUST be the only action in that turn. Never proceed without a real user response.
29
+
30
+ ## Subagents & tooling (Claude-native)
31
+
32
+ - Spawn subagents via the Task tool (`subagent_type: <name>`); the roster + routing is
33
+ `.claude/agents/REGISTRY.md`.
34
+ {{#output_style}}
35
+ - Output style: `{{ output_style }}` is active (select via `/config` → Output Style).
36
+ {{/output_style}}
37
+ - Hooks (PreToolUse / edit gates) are Claude-only and configured in `.claude/settings.json`.
38
+
39
+ <!-- OVERLAY: project-specific Claude tweaks live in `.baldart/overlays/CLAUDE.md` and are
40
+ merged below this line (same OVERRIDE/APPEND/PREPEND model as AGENTS.md). Keep this file
41
+ thin — cross-tool rules belong in the AGENTS.md overlay, not here. -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.82.0",
3
+ "version": "4.83.0",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"
@@ -296,6 +296,21 @@ async function add(repo, options) {
296
296
  UI.info('Skipped. Run `npx baldart configure` before invoking skills.');
297
297
  }
298
298
 
299
+ // Re-write the root primitives (AGENTS.md + CLAUDE.md) now that configure
300
+ // has populated baldart.config.yml — so the slots resolve to the final
301
+ // values (name, stack, commands, paths, trunk branch). createAllSymlinks
302
+ // already wrote them once with whatever config existed; this is idempotent
303
+ // (byte-stable when nothing changed) and just refreshes the concrete facts.
304
+ try {
305
+ const rootPrimitives = require('../utils/root-primitives');
306
+ const res = rootPrimitives.writeRootPrimitives({ cwd: process.cwd(), tools: enabledTools, autonomous: nonInteractive });
307
+ if (res.adopted && res.adopted.length) {
308
+ for (const a of res.adopted) UI.info(`Adopted existing ${a.name}.md → ${a.overlay} (verbatim). Review & re-file when convenient.`);
309
+ }
310
+ } catch (err) {
311
+ UI.warning(`Root primitives step failed: ${err.message}`);
312
+ }
313
+
299
314
  // Post-flight assert — never declare success with missing hooks.
300
315
  // Re-reads .claude/settings.json and confirms every active hook in
301
316
  // HOOK_REGISTRY is present. Guards against the silent partial-install
@@ -343,6 +343,28 @@ async function detectState(cwd, opts = {}) {
343
343
  }
344
344
  } catch (_) { /* never block doctor on probe */ }
345
345
 
346
+ // Root primitives (AGENTS.md + CLAUDE.md) integrity (since v4.83.0).
347
+ // Stale = missing, still a legacy symlink, or drifted vs the current
348
+ // skeleton / overlay / config. A handwritten file is surfaced separately
349
+ // (needs interactive adoption) and is NOT auto-regenerated.
350
+ state.rootPrimitivesStale = [];
351
+ state.rootPrimitivesAdoptable = [];
352
+ try {
353
+ if (state.frameworkPresent) {
354
+ const rp = require('../utils/root-primitives');
355
+ for (const name of rp.PRIMITIVES) {
356
+ if (name === 'CLAUDE') {
357
+ const toolsEnabled = (config && !config.__malformed && config.tools && Array.isArray(config.tools.enabled))
358
+ ? config.tools.enabled : ['claude'];
359
+ if (!toolsEnabled.includes('claude')) continue;
360
+ }
361
+ const st = rp.rootPrimitiveStatus({ cwd, name, cfg: config && !config.__malformed ? config : undefined });
362
+ if (st.state === 'handwritten') state.rootPrimitivesAdoptable.push({ name, reason: st.reason });
363
+ else if (st.stale) state.rootPrimitivesStale.push({ name, reason: st.reason });
364
+ }
365
+ }
366
+ } catch (_) { /* never block doctor on probe */ }
367
+
346
368
  // `.framework/` is a git subtree — gitignore matching it breaks every
347
369
  // future `git add` under that path (the failure mode that hit v3.13.0
348
370
  // consumers during push). Detect any gitignore rule that catches the
@@ -861,6 +883,49 @@ function planActions(state) {
861
883
  });
862
884
  }
863
885
 
886
+ // Root primitives integrity (since v4.83.0). Regenerates AGENTS.md / CLAUDE.md
887
+ // from the versioned skeleton + config + overlay when missing, still a legacy
888
+ // symlink, or drifted. Offline + idempotent. A handwritten file is NOT touched
889
+ // here — it needs interactive adoption (reported below, not auto-run).
890
+ if (state.rootPrimitivesStale && state.rootPrimitivesStale.length > 0) {
891
+ const names = state.rootPrimitivesStale.map((r) => `${r.name}.md`).join(', ');
892
+ actions.push({
893
+ key: 'regenerate-root-primitives',
894
+ label: `Regenerate root primitive(s): ${names}`,
895
+ why: `These root files are out of date vs the shipped skeleton / your overlay / baldart.config.yml (${state.rootPrimitivesStale.map((r) => `${r.name}: ${r.reason}`).join('; ')}). They are BALDART-generated — edit .baldart/overlays/<name>.md, not the file itself.`,
896
+ autoOk: true,
897
+ run: async () => {
898
+ const cfg = loadConfig(process.cwd());
899
+ const enabledTools = (cfg && !cfg.__malformed
900
+ && cfg.tools && Array.isArray(cfg.tools.enabled))
901
+ ? cfg.tools.enabled : ['claude'];
902
+ const res = require('../utils/root-primitives').writeRootPrimitives({ cwd: process.cwd(), tools: enabledTools });
903
+ UI.success(`Regenerated root primitives: ${(res.written || []).map((w) => `${w.name}.md`).join(', ') || '(none changed)'}`);
904
+ },
905
+ });
906
+ }
907
+
908
+ // Handwritten AGENTS.md/CLAUDE.md that predate BALDART's ownership — offer a
909
+ // zero-loss adoption (preserve verbatim into an overlay, then generate). Never
910
+ // auto-run: mutating a hand-authored file must be an explicit choice.
911
+ if (state.rootPrimitivesAdoptable && state.rootPrimitivesAdoptable.length > 0) {
912
+ const names = state.rootPrimitivesAdoptable.map((r) => `${r.name}.md`).join(', ');
913
+ actions.push({
914
+ key: 'adopt-root-primitives',
915
+ label: `Adopt handwritten ${names} into overlay(s)`,
916
+ why: `${names} are hand-authored files with no BALDART marker. Adoption preserves them verbatim into .baldart/overlays/<name>.md (zero loss) and regenerates the root as skeleton + your overlay. Review afterwards — cross-tool rules belong in the AGENTS.md overlay.`,
917
+ autoOk: false,
918
+ run: async () => {
919
+ const cfg = loadConfig(process.cwd());
920
+ const enabledTools = (cfg && !cfg.__malformed
921
+ && cfg.tools && Array.isArray(cfg.tools.enabled))
922
+ ? cfg.tools.enabled : ['claude'];
923
+ const res = require('../utils/root-primitives').writeRootPrimitives({ cwd: process.cwd(), tools: enabledTools, autonomous: false });
924
+ for (const a of (res.adopted || [])) UI.success(`Adopted ${a.name}.md → ${a.overlay} (verbatim). Review & re-file when convenient.`);
925
+ },
926
+ });
927
+ }
928
+
864
929
  if (state.lspEnabled && state.lspBroken && state.lspBroken.length > 0) {
865
930
  actions.push({
866
931
  key: 'lsp-fix',
@@ -75,6 +75,17 @@ async function migrate() {
75
75
  UI.warning(`Found .claude/skills.backup with ${entries.length} entries (from a prior failed update).`);
76
76
  }
77
77
 
78
+ // Root primitives (since v4.83.0): AGENTS.md moved from a bulk symlink to a
79
+ // generated real file, and CLAUDE.md is now shipped. Report a legacy symlink.
80
+ const agentsMdPath = path.join(cwd, 'AGENTS.md');
81
+ let agentsMdLegacySymlink = false;
82
+ try {
83
+ if (fs.lstatSync(agentsMdPath).isSymbolicLink()) {
84
+ agentsMdLegacySymlink = true;
85
+ UI.warning('AGENTS.md is a legacy bulk symlink → will become a generated real file.');
86
+ }
87
+ } catch (_) { /* absent or real file — nothing to report here */ }
88
+
78
89
  // --- Plan ---------------------------------------------------------------
79
90
 
80
91
  const actions = [];
@@ -88,6 +99,11 @@ async function migrate() {
88
99
  if (backupPresent) {
89
100
  actions.push('Restore user skills from .claude/skills.backup into .claude/skills/ (no overwrites).');
90
101
  }
102
+ if (agentsMdLegacySymlink) {
103
+ actions.push('Convert legacy AGENTS.md symlink into a generated real file (skeleton + config + overlay).');
104
+ } else {
105
+ actions.push('Generate/refresh root primitives AGENTS.md + CLAUDE.md (handwritten files are adopted into overlays, zero-loss).');
106
+ }
91
107
  actions.push('Record any name collisions in .baldart/skill-conflicts.json.');
92
108
 
93
109
  UI.section('Planned actions');
@@ -133,6 +149,20 @@ async function migrate() {
133
149
  symlinks.mergeCommands({ tools: enabledTools });
134
150
  UI.info(`Linked ${mergeResult.linked.length} framework skills, kept ${mergeResult.skipped.length} as-is, ${mergeResult.conflicts.length} conflict(s).`);
135
151
 
152
+ // --- Step 2b: root primitives (v4.83.0) --------------------------------
153
+ // Converts a legacy AGENTS.md symlink → generated real file, ships CLAUDE.md,
154
+ // and adopts any handwritten root file into an overlay (interactive, zero-loss).
155
+ UI.section('Step 2b: root primitives (AGENTS.md + CLAUDE.md)');
156
+ try {
157
+ const res = require('../utils/root-primitives').writeRootPrimitives({ cwd, tools: enabledTools, autonomous: false });
158
+ for (const a of (res.adopted || [])) UI.success(`Adopted ${a.name}.md → ${a.overlay} (verbatim, zero-loss). Review & re-file later.`);
159
+ const wrote = (res.written || []).map((w) => `${w.name}.md (${w.from})`);
160
+ UI.info(wrote.length ? `Root primitives written: ${wrote.join(', ')}.` : 'Root primitives already up to date.');
161
+ for (const b of (res.blockers || [])) UI.warning(`Root primitive ${b.name}: ${b.reason}`);
162
+ } catch (err) {
163
+ UI.warning(`Root primitives step skipped: ${err.message}`);
164
+ }
165
+
136
166
  // --- Step 3: restore user skills from .backup --------------------------
137
167
 
138
168
  if (backupPresent) {
@@ -123,6 +123,7 @@ function scaffoldOverlaysForCommits(commits) {
123
123
  const BALDART_MANAGED_PATTERNS = [
124
124
  /^\.framework(\/|$)/,
125
125
  /^AGENTS\.md$/,
126
+ /^CLAUDE\.md$/,
126
127
  /^agents(\.backup)?(\/|$)/,
127
128
  /^\.claude\/(agents|commands|skills|workflows|hooks|routines|settings\.json)(\/|$)/,
128
129
  /^\.baldart(\/|$)/,
@@ -137,6 +138,28 @@ function isBaldartManagedPath(p) {
137
138
  return BALDART_MANAGED_PATTERNS.some((rx) => rx.test(p));
138
139
  }
139
140
 
141
+ // Re-generate the root primitives (AGENTS.md + CLAUDE.md) from the versioned
142
+ // skeletons + baldart.config.yml + overlays. Idempotent + byte-stable, so it is
143
+ // safe to call on both the aligned-install and post-pull paths. Never throws —
144
+ // a failure here must not abort an otherwise-successful update. Adoption of a
145
+ // handwritten file is interactive-gated inside the writer (a CI/autonomous run
146
+ // surfaces a blocker and leaves the file untouched rather than mutating it).
147
+ function reconcileRootPrimitives(cwd, tools, autonomous) {
148
+ try {
149
+ const res = require('../utils/root-primitives').writeRootPrimitives({ cwd, tools, autonomous });
150
+ for (const a of (res.adopted || [])) {
151
+ UI.info(`Adopted existing ${a.name}.md → ${a.overlay} (verbatim, zero-loss). Review & re-file when convenient.`);
152
+ }
153
+ for (const b of (res.blockers || [])) {
154
+ UI.warning(`Root primitive ${b.name}: ${b.reason}`);
155
+ }
156
+ const wrote = (res.written || []).map((w) => `${w.name}.md`);
157
+ if (wrote.length) UI.info(`Root primitives updated: ${wrote.join(', ')}.`);
158
+ } catch (err) {
159
+ UI.warning(`Root primitives step skipped: ${err.message}`);
160
+ }
161
+ }
162
+
140
163
  // Real preview (v4.8.0+) — the old `git log HEAD..FETCH_HEAD -- .framework/`
141
164
  // is always empty under subtree-squash, so the user never saw what changed.
142
165
  // Instead, read the UPSTREAM CHANGELOG and return every entry above the
@@ -912,6 +935,10 @@ async function update(options = {}, unknownArgs = []) {
912
935
  if (reconciled > 0) {
913
936
  UI.info(`Reconciled ${reconciled} newly-shipped item(s) into per-tool dir(s) — payload drift from a prior CLI-skew update, now healed.`);
914
937
  }
938
+ // Re-generate the root primitives too (AGENTS.md + CLAUDE.md): a primitive
939
+ // version bump or a slot/overlay change must land even on an aligned install.
940
+ // --json is programmatic → force autonomous so a handwritten file is never mutated.
941
+ reconcileRootPrimitives(process.cwd(), alignedTools, options && options.json === true ? true : undefined);
915
942
  UI.success(`Already up to date! (v${status.installedVersion})`);
916
943
  emitUpdateJson({ ok: true, action: 'already-current',
917
944
  installed_before: status.installedVersion,
@@ -1242,6 +1269,10 @@ async function update(options = {}, unknownArgs = []) {
1242
1269
  symlinks.mergeOutputStyles({ tools: enabledTools });
1243
1270
  }
1244
1271
 
1272
+ // Re-generate the root primitives (AGENTS.md + CLAUDE.md) after the pull so
1273
+ // a primitive/slot/overlay change lands. Idempotent + byte-stable.
1274
+ reconcileRootPrimitives(process.cwd(), enabledTools, options && options.json === true ? true : undefined);
1275
+
1245
1276
  // Routines wizard (since v2.1.0) — surfaces routines added in the new framework version
1246
1277
  try {
1247
1278
  const routinesCmd = require('./routines');