Skip to content

Commit d1222bd

Browse files
committed
0.2.1: distribution architecture + Wave 2 features
Bundled release commit. All five user-facing CLIs aligned to 0.2.1: atom, atom-setup, nucleus, learnings, model-race. New atom-update-check worker ships at 0.1.0. Repo-level VERSION (which `atom upgrade` polls) was already at 0.2.1. Wave 3 (distribution architecture): - atom-setup new <name> + ATOM_SOURCE_DIR (#9) - docs/MIGRATING.md + atom migrate-install (#8) - install.sh curl one-liner + README/SECURITY rewrite (#10) - bin/atom-update-check + atom upgrade --snooze (#11) Wave 2 (user-facing features, previously held under [Unreleased]): - nucleus review + backlog nudge (#8a) - Inline constitution generation in wizard §9 (#7) - 5 stack presets + 15 seed learnings (#6, already in [0.2.1] from 32e82de) CHANGELOG [Unreleased] folded into [0.2.1] — 2026-05-14. Tests asserted the old 0.1.3 version string at test-atom-setup.sh:1.2; updated to 0.2.1. 199/199 green (164 fast + 35 slow atom-setup, 20 nucleus). Ready to tag v0.2.1 once user confirms.
1 parent a5e6899 commit d1222bd

7 files changed

Lines changed: 29 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ All notable changes to atom land here. Format: [Keep a Changelog](https://keepac
44

55
## [Unreleased]
66

7-
In progress — remaining v0.2 items. See `docs/planning/v0.2.md`.
7+
No changes pending. v0.3 candidate list at `docs/planning/v0.3.md`.
88

9-
### Added
10-
11-
- **`nucleus review` command + CLI backlog nudge.** `nucleus add` and `nucleus search` now print a one-line footer when you have ≥10 unpromoted entries or any entry older than 14 days, debounced to once per 24h via a new `config.lastNudgeAt` field. `nucleus review` lists unpromoted entries grouped by project (oldest first), each with a copy-paste `nucleus promote <ULID>` line, supports `--limit`, `--project`, `--type`, and `--json`. New helper `bin/nucleus/src/lib/promote-state.js` exposes `getBacklog`, `shouldNudge`, `markNudged`, `formatNudge`; detection of "already promoted" entries reuses the path convention `~/.atom/learnings/<type>/<key>.md` from `promote.js`. New test harness `scripts/test-nucleus.sh` covers the thresholds, debounce, filters, and the promoted-entry skip (20 / 20 passing).
12-
- **Sharper Claude promotion-surfacing in the nucleus skill.** `scaffold/.claude/skills/nucleus/SKILL.md` and `scaffold/AGENTS.md` now instruct Claude to surface 1–2 promotion candidates after ≥3 captures in a session, or when the user signals end-of-task ("ship it", "we're done", `/clear`). Behavior is explicit: list the captures, propose the strongest generalization candidates, and print the `nucleus promote <ULID>` command rather than invoking it (because `nucleus promote` opens `$EDITOR` interactively, which doesn't work in agent flows).
9+
## [0.2.1] — 2026-05-14
1310

14-
### Changed
15-
16-
- **Honest nucleus capture framing across the README and scaffold.** The previous copy described `claude-managed` capture as "automated" — implying a daemon or hook. There isn't one: capture only happens when Claude is following AGENTS.md / SKILL.md during a session. `README.md`, `scaffold/README.md`, `scaffold/AGENTS.md`, and `scaffold/.claude/skills/nucleus/SKILL.md` now describe capture as Claude-led-during-sessions and promote as always-manual ("graduation needs human judgment"). The AGENTS.md and SKILL.md "when to capture" sections were rewritten from passive ("at session boundaries") to active triggers (after a non-obvious bug fix, after a design decision with rationale, on `/clear`). The wizard's `claude-managed` hint and `auto-timer` hint were rewritten to match — auto-timer is now labeled as reserved since the daemon doesn't ship yet. The post-setup cheatsheet now points at `nucleus review` for backlog triage.
11+
Bundled release for Wave 2 (user-facing features) + Wave 3 (distribution architecture). All five CLIs aligned to 0.2.1; new `bin/atom-update-check` ships at 0.1.0.
1712

18-
- **Inline constitution generation in wizard §9.** When the user opts in, the writer now produces `<project>/CONSTITUTION.md` (a v0.1.0 draft) populated from §1 (project name, description, visibility, multi-agent y/n) and §2 (stack, deploy target). Replaces the previous deferred-TODO flow where the cheatsheet pointed users at `speckit-constitution` and most of them forgot. The draft follows `docs/HOW_TO_WRITE_CONSTITUTION.md`'s methodology: at-most-5 principles (placeholders with stack-specific hints in HTML comments), locked tech stack pinned to the chosen preset, agent ownership matrix (solo or multi-agent based on §1), phase-gate skeleton, semver policy, change log seed. Implementation: new `bin/atom-setup/src/lib/constitution.js` exporting `renderConstitution(answers)`; `writer.js` calls it after `writeLicense` when `answers.constitution === true`. Cheatsheet now points at the file ("Refine CONSTITUTION.md") instead of asking the user to run a second command. The `speckit-constitution` skill in Claude Code is still recommended as a downstream verification pass once the user has drafted real principles.
13+
### Added — distribution architecture
1914

20-
## [0.2.1] — 2026-05-09
15+
- **`atom-setup new <name>`.** Separates "atom source" from "the project being bootstrapped." The wizard now reads `scaffold/` and `extras/` from `$ATOM_SOURCE_DIR` (default `~/.atom/atom/`) and writes into a fresh `./name/` directory, leaving the source byte-identical. The legacy in-place mode (running `atom-setup` inside an atom clone) still works for one release with a one-line deprecation notice pointing at the new verb. Refuses non-empty targets; refuses when `$ATOM_SOURCE_DIR` doesn't look like an atom checkout. `writer.js`'s `applyState` gained `opts.mode` (`'new'` | `'in-place'`) and `opts.sourceDir`; in `new` mode it skips `REMOVE_BEFORE_PROMOTE`/`REMOVE_AFTER_PROMOTE` since the target starts empty. See `docs/planning/v0.2.md` §9.
16+
- **`install.sh` at the repo root.** Curl-pipe one-liner: `curl -fsSL https://raw.githubusercontent.com/machbuilds/atom/main/install.sh | bash` clones to `~/.atom/atom/` and installs all six globals (`atom`, `atom-setup`, `nucleus`, `learnings`, `model-race`, `atom-update-check`). Idempotent: re-running on an existing install short-circuits with a hint to run `atom upgrade`. Env overrides `ATOM_HOME`, `ATOM_GIT_URL`, `ATOM_BRANCH` for tests. README Quick Start rewritten to lead with the one-liner; the manual `git clone` + `npm install -g .` path is documented immediately below ("Don't trust curl-pipe-bash? Install manually."). `SECURITY.md` adds a "Trust model for the curl-pipe installer" section covering what's trusted, what the script does, and what we'll add when there's a concrete threat model (signed checksums, tag pinning, `npm ci`).
17+
- **`atom migrate-install`** subcommand for relocating a 0.1.x in-place install to `~/.atom/atom/`. One shot: clones fresh, re-installs every CLI globally, leaves the old in-place clone alone (user's data, their call). Refuses if `~/.atom/atom/` already exists. New `docs/MIGRATING.md` walks through both the auto path (one command) and the manual four-step path, with troubleshooting for `EACCES` and stale shell lookups.
18+
- **`bin/atom-update-check/`** — lazy update notifier. Every atom CLI prints a one-line notice on startup when a newer release is published upstream ("atom 0.2.5 is available. (run `atom upgrade`, or snooze: `atom upgrade --snooze 7d`)"). State at `~/.atom/state/update-check.json` tracks `lastChecked`, `latestVersion`, `lastNotified`, `snoozeUntil`. Per-CLI startup cost is ~2ms (one JSON read + a synchronous decision; the network poll runs in a detached child `atom-update-check tick`). Throttle: 6h between polls, 24h between repeat notices. Snooze tiers: 24h, 48h, 7d via `atom upgrade --snooze <tier>`, which delegates to the worker so there's only one writer of the state file. Env overrides `ATOM_STATE_DIR`, `ATOM_VERSION_URL`, `ATOM_VERSION_FILE`, `ATOM_INSTALL`, `ATOM_UPDATE_CHECK_DISABLED` for tests. Inlined client lives at `bin/atom-update-check/src/client.js` and is mirrored byte-identically into each CLI's `src/lib/update-check-client.js` (drift detection in Test 20.1).
2119

22-
### Added
20+
### Added — Wave 2 features
2321

22+
- **`nucleus review` command + CLI backlog nudge.** `nucleus add` and `nucleus search` now print a one-line footer when you have ≥10 unpromoted entries or any entry older than 14 days, debounced to once per 24h via a new `config.lastNudgeAt` field. `nucleus review` lists unpromoted entries grouped by project (oldest first), each with a copy-paste `nucleus promote <ULID>` line, supports `--limit`, `--project`, `--type`, and `--json`. New helper `bin/nucleus/src/lib/promote-state.js` exposes `getBacklog`, `shouldNudge`, `markNudged`, `formatNudge`; detection of "already promoted" entries reuses the path convention `~/.atom/learnings/<type>/<key>.md` from `promote.js`. New test harness `scripts/test-nucleus.sh` covers the thresholds, debounce, filters, and the promoted-entry skip (20 / 20 passing).
23+
- **Sharper Claude promotion-surfacing in the nucleus skill.** `scaffold/.claude/skills/nucleus/SKILL.md` and `scaffold/AGENTS.md` now instruct Claude to surface 1–2 promotion candidates after ≥3 captures in a session, or when the user signals end-of-task ("ship it", "we're done", `/clear`). Behavior is explicit: list the captures, propose the strongest generalization candidates, and print the `nucleus promote <ULID>` command rather than invoking it (because `nucleus promote` opens `$EDITOR` interactively, which doesn't work in agent flows).
2424
- **Five new stack presets** under `extras/<category>/<preset>/`, raising the wizard's preset coverage from 1 to 6:
2525
- **Python / FastAPI** (`extras/web/python-fastapi/`) — `pyproject.toml` pinned to Python 3.12 + FastAPI + Pydantic v2; `app/main.py` with `/healthz` and lifespan; multi-stage Dockerfile (builder venv → runtime, non-root, healthcheck); Railway as default deploy target.
2626
- **Swift / Vapor** (`extras/web/swift-vapor/`) — `Package.swift` pinned to Vapor 4 + Swift 5.10; `Sources/App/configure.swift` binds `0.0.0.0:PORT`; multi-stage Dockerfile with static-Swift-stdlib build; Fly.io as default deploy target.
@@ -31,6 +31,11 @@ In progress — remaining v0.2 items. See `docs/planning/v0.2.md`.
3131
- **Stack-specific Quick Start in the project README.** Each preset ships a `README.snippet.md` that the writer splices into `<root>/README.md` (replacing a `{{QUICK_START}}` placeholder), and `{{PROJECT_NAME}}` / `{{DESCRIPTION}}` are substituted from the wizard's answers. Before this, bootstrapped projects had no README; now they have one tuned to whatever stack was picked.
3232
- **Language values in `LEARNINGS_TAXONOMY.md`'s `applies_to` vocabulary**`node`, `python`, `rust`, `go`, `swift`. Pre-v0.2 the taxonomy said language tags belong only in `tags:`; with per-language presets, language-level filtering became necessary so a Pydantic learning doesn't ship to a Rust project.
3333

34+
### Changed
35+
36+
- **Honest nucleus capture framing across the README and scaffold.** The previous copy described `claude-managed` capture as "automated" — implying a daemon or hook. There isn't one: capture only happens when Claude is following AGENTS.md / SKILL.md during a session. `README.md`, `scaffold/README.md`, `scaffold/AGENTS.md`, and `scaffold/.claude/skills/nucleus/SKILL.md` now describe capture as Claude-led-during-sessions and promote as always-manual ("graduation needs human judgment"). The AGENTS.md and SKILL.md "when to capture" sections were rewritten from passive ("at session boundaries") to active triggers (after a non-obvious bug fix, after a design decision with rationale, on `/clear`). The wizard's `claude-managed` hint and `auto-timer` hint were rewritten to match — auto-timer is now labeled as reserved since the daemon doesn't ship yet. The post-setup cheatsheet now points at `nucleus review` for backlog triage.
37+
- **Inline constitution generation in wizard §9.** When the user opts in, the writer now produces `<project>/CONSTITUTION.md` (a v0.1.0 draft) populated from §1 (project name, description, visibility, multi-agent y/n) and §2 (stack, deploy target). Replaces the previous deferred-TODO flow where the cheatsheet pointed users at `speckit-constitution` and most of them forgot. The draft follows `docs/HOW_TO_WRITE_CONSTITUTION.md`'s methodology: at-most-5 principles (placeholders with stack-specific hints in HTML comments), locked tech stack pinned to the chosen preset, agent ownership matrix (solo or multi-agent based on §1), phase-gate skeleton, semver policy, change log seed. Implementation: new `bin/atom-setup/src/lib/constitution.js` exporting `renderConstitution(answers)`; `writer.js` calls it after `writeLicense` when `answers.constitution === true`. Cheatsheet now points at the file ("Refine CONSTITUTION.md") instead of asking the user to run a second command. The `speckit-constitution` skill in Claude Code is still recommended as a downstream verification pass once the user has drafted real principles.
38+
3439
### Fixed
3540

3641
- **`<project>/learnings/` was being deleted after copy.** `manifest.js`'s `REMOVE_AFTER_PROMOTE` had `'learnings'` in it — a leftover from v0.1.0 when the repo carried a maintainer-curated `learnings/` directory. v0.1.1 removed that directory but the cleanup entry stayed, silently wiping every user playbook learning + every preset seed learning that landed in `<project>/learnings/`. Removed the entry; verified by new test assertions (`8.7`, `9.5`, `10.5`, `11.6`, `12.7`).
@@ -43,7 +48,13 @@ In progress — remaining v0.2 items. See `docs/planning/v0.2.md`.
4348

4449
### Tests
4550

46-
- 32 new assertions in `scripts/test-atom-setup.sh` covering: every preset's signature files at root, `/healthz` route presence in web presets, no Dockerfile in CLI / library presets, the docker-tier-skips-preset behavior, README placeholder substitution, README snippet splice + cleanup. Suite total: **92 / 92** passing.
51+
- Wave 3 added six test sections to `scripts/test-atom-setup.sh`:
52+
- **Test 14–17** for `atom-setup new`: full round-trip with byte-identical-source check, target-collision refusal, missing-source refusal, deprecation notice on legacy in-place mode.
53+
- **Test 18** for `atom migrate-install`: dry-run output, refusal-when-exists, help text. Test 18d (gated by `ATOM_TEST_SLOW=1`) runs the full clone + 6× `npm install -g` round-trip in a scratch npm prefix.
54+
- **Test 19** for `install.sh`: structural checks + the slow round-trip (gated) verifying fresh install, idempotent re-run, success message.
55+
- **Test 20** for `atom-update-check`: drift detection across the 5 inlined client copies, tick writes state, notice prints once, 24h debounce, `ATOM_UPDATE_CHECK_DISABLED` kill-switch, snooze sets + clears `lastNotified`, bogus duration rejected, future `snoozeUntil` suppresses notice, `atom upgrade --snooze` delegation, `--help` advertises the flag.
56+
- Wave 2's stack-preset additions contributed 32 assertions covering: every preset's signature files at root, `/healthz` route presence in web presets, no Dockerfile in CLI / library presets, the docker-tier-skips-preset behavior, README placeholder substitution, README snippet splice + cleanup.
57+
- Suite totals on v0.2.1: **164 / 164 fast, 179 / 179 with `ATOM_TEST_SLOW=1`** (atom-setup) + **20 / 20** (nucleus).
4758

4859
## [0.2.0] — 2026-05-08
4960

bin/atom-setup/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@atom/atom-setup",
3-
"version": "0.1.3",
3+
"version": "0.2.1",
44
"description": "Interactive wizard that transforms a cloned atom checkout into a personalized project.",
55
"type": "module",
66
"bin": {

bin/atom/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@atom/atom",
3-
"version": "0.1.3",
3+
"version": "0.2.1",
44
"description": "Top-level help dispatcher for atom's tooling. Lists every CLI in one place.",
55
"type": "module",
66
"bin": {

bin/learnings/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@atom/learnings",
3-
"version": "0.1.3",
3+
"version": "0.2.1",
44
"description": "Your local playbook of generalized patterns. Lives at ~/.atom/learnings, optionally synced to a private GitHub repo. Auto-copied into every new atom-bootstrapped project.",
55
"type": "module",
66
"bin": {

bin/model-race/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@atom/model-race",
3-
"version": "0.1.3",
3+
"version": "0.2.1",
44
"description": "Run the same feature spec through multiple AI models in parallel via Git worktrees. Compare, score, merge the winner.",
55
"type": "module",
66
"bin": {

bin/nucleus/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@atom/nucleus",
3-
"version": "0.1.4",
3+
"version": "0.2.1",
44
"description": "Cross-project learning store. Captures session learnings into ~/.nucleus, syncs across machines via GitHub.",
55
"type": "module",
66
"bin": {

scripts/test-atom-setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ section "Test 1: pre-flight detection runs and --version works"
111111

112112
$SETUP --version > "$LOG_DIR/t1-version.log" 2>&1
113113
assert "1.1 atom-setup --version exits 0" test $? -eq 0
114-
assert_grep "1.2 prints 0.1.3" "0.1.3" "$LOG_DIR/t1-version.log"
114+
assert_grep "1.2 prints 0.2.1" "0.2.1" "$LOG_DIR/t1-version.log"
115115

116116
$SETUP --help > "$LOG_DIR/t1-help.log" 2>&1
117117
assert_grep "1.3 --help mentions --bare" "\\-\\-bare" "$LOG_DIR/t1-help.log"

0 commit comments

Comments
 (0)