Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .claude/skills/acture-command-record-shape/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,22 @@ type CommandRecord<P = unknown, R = unknown> = {

/** Tier (research-5). Authoritative source is the JSDoc tag on the defineCommand
* call site (@stable / @experimental / @internal / @deprecated). The build step
* mirrors the tag into this field. Authors normally do NOT write this field
* manually — they write the JSDoc tag. */
* (@acture/build-tier) mirrors the tag into this field. Authors normally do NOT
* write this field manually — they write the JSDoc tag. */
tier?: "stable" | "experimental" | "internal" | "deprecated";

/** Free-text reason injected by the build step from @deprecated <reason>.
* Adapter packages (@acture/mcp, @acture/ai-vercel) prepend
* `[DEPRECATED — <reason>]` to the description; @acture/devtools surfaces
* it in the inspector. Added in v1.0 (Phase 4) under the rule of three. */
deprecationReason?: string;

/** Module-scoped Symbol attached by the build step when a command is tagged
* @internal. The runtime checks identity at dispatch — cross-module callers
* cannot see the token because it lives in the registering module's closure.
* Authors do NOT write this manually. Added in v1.0 (Phase 4). */
internalToken?: symbol;

/** Default ranking score in palette (optional). */
defaultScore?: number | ((ctx: Context) => number);

Expand Down
18 changes: 13 additions & 5 deletions .claude/skills/acture-tier-system/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ registry.toPaletteCommands({ tiers: ['stable', 'experimental'] }); // dev

- NOT in `tools/list` by default.
- Appears only when server constructed with `tiers: ['stable', 'experimental']`. Opt-in is a server-construction option, NOT a per-request header (the MCP spec does not yet support per-request tier negotiation).
- On first dispatch in production: `console.warn(...)` once per process. Suppressible via `ACTURE_SUPPRESS_EXPERIMENTAL_WARNINGS=1`.
- On first dispatch when `enableTierWarnings(registry)` is wired up: `console.warn(...)` once per command per process. Suppressible via `ACTURE_SUPPRESS_EXPERIMENTAL_WARNINGS=1` env var, or by passing `enabled: false` to `enableTierWarnings`. Implemented in `packages/core/src/tier-warnings.ts`. Not automatic — the host must opt in by calling `enableTierWarnings(registry)` once at app boot.
- Graduation: removing `@experimental` + adding `@stable` is a **MINOR** change (pure expansion of the default surface).

## What `@deprecated` does at runtime
Expand All @@ -80,14 +80,22 @@ Module-level closure plus symbol-keyed access is the closest TypeScript gets to
## `acture compare-schemas` CLI (research-5 §6)

```bash
acture compare-schemas <base> [<head>] # default head = working tree
acture compare-schemas --against main # buf-style ref syntax
acture compare-schemas <base> [<head>] # base/head are paths to snapshot JSON files OR git refs
acture compare-schemas --fail-on major # CI gate
acture compare-schemas --tier stable # only check stable-tier commands
acture compare-schemas --format json # machine output
acture compare-schemas --allow-description-edits # per-invocation, NOT a config setting
acture compare-schemas --snapshot-path .acture/snapshot.json # when args are git refs
```

Walks registry in both refs, projects every command through the schema bridge, compares **tool envelopes** (not just inputSchema).
Lives in `packages/cli/` (`@acture/cli`). Reads two pre-rendered snapshots and diffs them. The snapshot is produced by `snapshotRegistry(registry)` (programmatic) or by `acture snapshot <config>` (CLI subcommand, v1.1+):

```bash
acture snapshot ./registry.mjs --out .acture/snapshot.json # write to file
acture snapshot ./registry.mjs # write to stdout
acture snapshot ./registry.mjs --tiers stable,experimental # filter tiers
```

For `.ts` configs the user runs Node ≥22.6 with `--experimental-strip-types`, or uses `tsx node_modules/.bin/acture snapshot ./registry.ts`. Field-level diff is shallow (top-level `properties` and one level of `enum`/`type`); deep-object diff is a v1.2 polish.

## Change classifications (research-5 §6.1)

Expand Down
13 changes: 11 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,18 @@ Full discussion is in `docs/redesign_takeaways.md` §3 and the `acture-hard-dont
- Generalizing beyond what `v1_plan.md` commits to. Rule of three.
- Modifying the central paper (`docs/command_dispatch_journal_article.md`). It is canonical.

## Current state (Phase 3 DONE, 2026-05-13)
## Current state (v1.1, Phase 4 + v1.1 increment DONE, 2026-05-13)

Ten packages ship in the workspace: `acture`, `@acture/state-zustand`, `@acture/state-redux`, `@acture/palette-react` (with parameterized-command UX), `@acture/hotkeys`, `@acture/forms-autoform`, `@acture/forms-rjsf`, `@acture/mcp`, `@acture/ai-vercel`, `@acture/migration`. Three worked examples: `examples/greenfield/graph-editor/`, `examples/drop-in/`, and `examples/migration/zustand-wrap/{before,after}/`. **Phase 4 is next** (tier-system enforcement, `acture compare-schemas` CLI, devtools, hardening) — see `docs/next_session.md`.
Thirteen packages ship in the workspace at v1.1.0 (or v1.0.0 if untouched in v1.1):

- Core: `acture` — gained `enableTierWarnings`, `deprecationReason`, `internalToken`, `DispatchOptions`.
- State: `@acture/state-zustand`, `@acture/state-redux`.
- UI: `@acture/palette-react` (parameterized-command UX), `@acture/hotkeys`, `@acture/forms-autoform`, `@acture/forms-rjsf`.
- Surfaces: `@acture/mcp`, `@acture/ai-vercel` — both honour the tier filter and prepend `[DEPRECATED — <reason>]`.
- Migration: `@acture/migration`.
- Tooling: `@acture/build-tier` (JSDoc tier mirror), `@acture/cli` (`compare-schemas`, `snapshot`), `@acture/devtools` (Inspector + instrumented dispatch log).

Three worked examples: `examples/greenfield/graph-editor/` (now wires the Inspector), `examples/drop-in/`, `examples/migration/zustand-wrap/{before,after}/`. **v1.2 is next** — see `docs/next_session.md` for the backlog (codemods, DOM-event interception, etc.).

## Phase progression

Expand Down
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@ pnpm add @acture/mcp # MCP server projection
pnpm add @acture/ai-vercel # Vercel AI tool definitions
pnpm add @acture/migration # strangler-fig adoption primitives
# …plus @acture/forms-autoform and @acture/forms-rjsf for parameterized commands.

# Dev / CI tooling (post-v1.0):
pnpm add -D @acture/build-tier # build-step @stable/@experimental/@internal/@deprecated mirror
pnpm add -D @acture/cli # `acture compare-schemas` / `acture snapshot` CLI
pnpm add -D @acture/devtools # embeddable <Inspector /> for dev builds
```

> The `acture` name is also reserved on PyPI as a placeholder; a real Python companion is post-v1. `pip install acture` gives you a no-op package whose only purpose is to keep the name ours.

## Status

**v0.2.0 (Phase 3 DONE, 2026-05-13).** Ten packages ship in the workspace:
**v1.1.0 (Phase 4 DONE + v1.1 increment, 2026-05-13).** Thirteen packages ship in the workspace:

| Package | Role |
| --- | --- |
| [`acture`](packages/core) | core registry, dispatcher, when-clause DSL, schema bridge |
| [`acture`](packages/core) | core registry, dispatcher, when-clause DSL, schema bridge, `enableTierWarnings` |
| [`@acture/state-zustand`](packages/state-zustand) | StateAdapter for zustand+immer |
| [`@acture/state-redux`](packages/state-redux) | StateAdapter for Redux Toolkit |
| [`@acture/palette-react`](packages/palette-react) | command palette with parameterized-command UX |
Expand All @@ -35,16 +40,27 @@ pnpm add @acture/migration # strangler-fig adoption primitives
| [`@acture/mcp`](packages/mcp) | MCP server projection |
| [`@acture/ai-vercel`](packages/ai-vercel) | Vercel AI SDK tool definitions |
| [`@acture/migration`](packages/migration) | strangler-fig primitives: `wrapMutation`, `actureMiddleware`, `chooseImplementation`, `shadowCompare` |
| [`@acture/build-tier`](packages/build-tier) | build-step plugin that mirrors `@stable`/`@experimental`/`@internal`/`@deprecated` JSDoc into runtime `tier` |
| [`@acture/cli`](packages/cli) | `acture compare-schemas` (CI gating) + `acture snapshot` (registry → JSON) |
| [`@acture/devtools`](packages/devtools) | embeddable `<Inspector />` and `instrumentRegistry` dispatch log |

Worked examples:

- [`examples/greenfield/graph-editor/`](examples/greenfield/graph-editor) — greenfield path.
- [`examples/greenfield/graph-editor/`](examples/greenfield/graph-editor) — greenfield path. Now wires `@acture/devtools`.
- [`examples/drop-in/`](examples/drop-in) — 5-minute bolt-on path.
- [`examples/migration/zustand-wrap/`](examples/migration/zustand-wrap) — strangler-fig path with side-by-side [`before/`](examples/migration/zustand-wrap/before) and [`after/`](examples/migration/zustand-wrap/after) apps. 6 wrapped commands + 2 graduated.

Five migration-track agent skills live under [`.claude/skills/`](.claude/skills/): `migration-diagnose`, `migration-plan`, `migration-scaffold`, `migration-wrap`, `migration-graduate`.
Agent skills live under [`.claude/skills/`](.claude/skills/): five migration-track skills (`migration-diagnose`, `migration-plan`, `migration-scaffold`, `migration-wrap`, `migration-graduate`) plus the architecture / tier / schema / hard-don'ts primer skills.

What's new in this version:

- **Tier system enforced.** Mark a command `@experimental`, `@internal`, or `@deprecated <reason>` in JSDoc; the build step mirrors the tag into runtime metadata. `registry.list({ tiers })` and the MCP / AI / palette projections filter accordingly. `@internal` commands carry a module-scoped Symbol token and reject cross-module `dispatch`.
- **`acture compare-schemas`.** Diff two registry snapshots, classify per research-5 §6.1, gate CI with `--fail-on major`. Description changes are MAJOR by default; downgradable per-invocation via `--allow-description-edits`.
- **`acture snapshot`.** Load a registry config (`./registry.mjs` default-exporting the registry) and emit a JSON snapshot suitable for `compare-schemas`.
- **`<Inspector registry={...} />`.** Embeddable React dev-tool with a command list (tier-filterable), dispatch log, and live when-clause evaluator. Mount it behind a toggle in any greenfield app.
- **`enableTierWarnings(registry)`.** Once-per-process `console.warn` on first dispatch of each `@experimental` command. Suppress with `ACTURE_SUPPRESS_EXPERIMENTAL_WARNINGS=1`.

Phase 4 (tier-system enforcement, `acture compare-schemas` CLI, devtools, hardening) is next — see [`docs/next_session.md`](docs/next_session.md).
What's next: see [`docs/next_session.md`](docs/next_session.md) for the v1.2 plan.

## Three paths

Expand Down
2 changes: 2 additions & 0 deletions docs/implementation_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ Phase 3 is done when these are in `phase-3-reflection.md`.

## Phase 4 — Stability, tier system, devtools

**Status:** ✅ DONE — 2026-05-13

**Goal:** Move from "works" to "production-ready" and ship v1.0.

### Scope
Expand Down
Loading
Loading