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
6 changes: 3 additions & 3 deletions .claude/commands/feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Agent, Task, SendMessage, Ta

You are a **senior engineer on Ultimate** — a Bun-only, opinionated full-stack framework whose *primary user is an AI agent*. Read [`CLAUDE.md`](../../CLAUDE.md) and [`docs/architecture/15-adding-a-feature.md`](../../docs/architecture/15-adding-a-feature.md) before designing anything. The seven design axioms override any instinct that conflicts with them.

**Done means merged and green — nothing less counts.** understand → falsify the spec → explore → slice → build → **`bun run verify` green** → PR → **merged** → **CI green on `main`** → docs, wiki and `examples/dummy/` left true → **npm published**, when a release was in scope. This repo is pre-alpha and deploys nowhere: there is no production, so the arc genuinely ends at merged (or at a published `@ultimat3/*` version). A green local gate is not done; an open PR is not done; a version bump that never published is not done. Report what you actually verified, not what you assume happened.
**Done means merged and green — nothing less counts.** understand → falsify the spec → explore → slice → build → **`bun run verify` green** → PR → **merged** → **CI green on `main`** → docs, wiki and `examples/dummy/` left true → **npm published**, when a release was in scope. This repo deploys nowhere itself: there is no production, so the arc genuinely ends at merged (or at a published `@ultimat3/*` version). A green local gate is not done; an open PR is not done; a version bump that never published is not done. Report what you actually verified, not what you assume happened.

## Request
$ARGUMENTS
Expand All @@ -30,7 +30,7 @@ When you do hive, a big task is not one agent doing more; it is a **team sharing
- **Agents are long-lived teammates.** New work in a package someone holds goes to them via `SendMessage`, keeping their context and their file lock. A second agent on the same paths means two writers and a lost fix.
- **Work in waves; each wave re-tasks the next.** Wave 1's findings decide wave 2's slices. Don't plan wave 3 before wave 1 reports — it will be wrong.
- **Keep a visible ledger** (`TaskCreate`/`TaskUpdate`) so ownership survives a context handoff.
- **Expect the hive to contradict you.** A good agent reports "premise H1 is false, here is the line." Drop it. In a pre-alpha repo where the spec runs ahead of the code, this happens constantly and is the hive working correctly.
- **Expect the hive to contradict you.** A good agent reports "premise H1 is false, here is the line." Drop it. Where the spec runs ahead of the code, this happens constantly and is the hive working correctly.

### Who runs which checks

Expand Down Expand Up @@ -58,7 +58,7 @@ There is no `test:changed`-style command here, and there should not be: a comman

1. **Understand.** Restate the goal in a line. Name **which of the eight primitives** it is (`entity · policy · action · mutator · query · job · route · task`) and **which tier** it lives in. If it fits none of the eight, it does not ship — do not invent a ninth; if it fits no tier, the design is wrong, so fix the design rather than widening the table. URLs in the ask → `WebFetch` the *mechanism*, then translate it onto this stack (Bun-only, Postgres, SolidJS, containers).

2. **Distrust the paperwork.** This repo is **pre-alpha**: `docs/idea/` is the design spec — what is intended, not what exists — and `docs/architecture/` documents internals that may have moved. Before planning work off either, check them against the code and `git log`; `docs/idea/14-roadmap.md` claims milestone state that the packages may contradict in both directions. Merged commit subjects are the cheapest ground truth. State plainly which claims you falsified, and correct the doc in the same PR.
2. **Distrust the paperwork.** `docs/idea/` is the design spec — what is intended, not what exists — and `docs/architecture/` documents internals that may have moved. Before planning work off either, check them against the code and `git log`; `docs/idea/14-roadmap.md` claims milestone state that the packages may contradict in both directions. Merged commit subjects are the cheapest ground truth. State plainly which claims you falsified, and correct the doc in the same PR.

3. **Prove it against the reference app.** There is no production to query, so `examples/dummy/` is the proving ground: it exercises every primitive once, idiomatically, and a framework change that does not show up there is unverified. Reach for `bun run x -- doctor --json` and `bun run x -- <cmd> --json` — every command and every error is `--json` for exactly this reason, and every framework error carries an executable `fix:`. **Run the `fix:` before improvising.** A finding backed by a real CLI trace or a failing dummy-app run outranks one derived from reading alone.

Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Hand-written, deliberately short. The *facts* about this codebase are generated

## What this repo is

The **Ultimate** web framework. Bun-only, Postgres + Drizzle, SolidJS, SCSS tokens. A monorepo of `@ultimat3/*` packages plus the `x` CLI. Pre-alpha.
The **Ultimate** web framework. Bun-only, Postgres, SolidJS, SCSS tokens. A monorepo of 27 `@ultimat3/*` packages — the `x` CLI among them — plus the unscoped `create-ultimate`. All 28 publish to npm at **1.0.0** in lockstep, `As of 2026-08`.

No ORM dependency, `As of 2026-08`: `entity()` is the one table declaration, and `postgresDriver()` (`packages/entity/src/pg-driver.ts`, `pg-sql.ts`) is hand-written parameterised SQL. Generated apps declare their tables the same way — `packages/db/` holds those declarations plus plain-SQL migrations.

Semver applies from 1.0.0: breaking the eight primitive shapes, the `x` CLI surface, the tier table, or an `X_*` code needs a major.

## Before you start

Expand Down
65 changes: 47 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,58 @@

All notable changes to Ultimate. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Framework packages version in **lockstep** — a release bumps every `@ultimat3/*` package to the same version. See [PUBLISHING.md](PUBLISHING.md).
Framework packages version in **lockstep** — a release bumps every package to the same version, in one commit, under one tag. Pin `@ultimat3/*` exactly; a mixed-version install is a combination nobody tested. See [PUBLISHING.md](PUBLISHING.md).

Semver applies from 1.0.0. A breaking change to a documented API needs a major — [Upgrading](https://github.com/developerz-ai/ultimate/wiki/Upgrading) says what "documented API" covers.

## [Unreleased]

Nothing yet.

## [1.0.0] - 2026-08-10

First release. 27 `@ultimat3/*` packages plus the unscoped `create-ultimate` — 28 in all — publish at 1.0.0 to npm, in tier order.

1.0.0 itself is the **manual bootstrap**: a trusted publisher can only be attached to a package that already exists, so this one version is published by hand by an npm org member. Every release after it goes through the workflow over OIDC trusted publishing, no `NPM_TOKEN` — see [PUBLISHING.md](PUBLISHING.md).

### Added

- Repository foundation: monorepo layout, tier-enforced package boundaries, Biome + strict TypeScript, free-runner CI, npm OIDC trusted publishing.
- The eight primitives as typed package skeletons: `entity`, `policy`, `action`, `mutator`, `query`, `job`, `route`, `task`.
- `@ultimat3/core` — `UltimateError` and the error contract, ALS request context, typed env, roles, clock, structured logging, OpenTelemetry spans, graceful drain.
- `@ultimat3/schema` — Standard Schema interface with a built-in default provider and JSON Schema projection.
- `@ultimat3/http` — the owned `Bun.serve` lifecycle with an explicit, ordered request pipeline.
- `@ultimat3/action` — one declaration projecting to HTTP route, OpenAPI entry, typed client, MCP tool, job handle, and contract tests.
- `@ultimat3/jobs` — Postgres queue driver, durable steps with memoized replay, transactional outbox on by default, cron tasks with a required timezone.
- `@ultimat3/realtime` — tier 1 channels and presence, tier 2 live queries with per-subscriber policy, tier 3 offline queue and rebase.
- `@ultimat3/i18n` · `@ultimat3/money` · `@ultimat3/time` — the cross-cutting concerns, enforced rather than documented.
- `@ultimat3/ui` — SCSS-module design system with semantic tokens for both colour schemes.
- `@ultimat3/render` · `@ultimat3/pwa` · `@ultimat3/seo` — five render modes, generated service worker, build-error SEO gates.
- `@ultimat3/mcp` · `@ultimat3/ai` · `@ultimat3/manifest` — the AI-first layer, including the built-in MCP dev server.
- `@ultimat3/admin` — the `/_x` dev dashboard and `defineAdmin()` for generated apps.
- `@ultimat3/cli` — the `x` binary, and `create-ultimate` for `bunx create-ultimate myapp`.
- `examples/dummy` — the reference app exercising every primitive and every cross-cutting concern.
- Documentation: `docs/idea/` (design), `docs/architecture/` (internals), `wiki/` (reference), `site/` (GitHub Pages), `llms.txt`.
- **The eight primitives**, shapes frozen under semver: `entity`, `policy`, `action`, `mutator`, `query`, `job`, `route`, `task`. There is no ninth — a new capability arrives as a factory over an existing primitive, which is why `llm()` returns an `action`.
- **One authz object across every surface.** A `policy` decides the HTTP call, the typed client call, the job run, the MCP tool call and the live-query subscription. No trusted-tool mode, no second permission table.
- **`@ultimat3/core`** — `UltimateError` and the error contract, ALS request context, `defineEnv`, roles, clock, structured logging, OpenTelemetry spans, graceful drain, signed cursors, `defineService`.
- **`@ultimat3/schema`** — Standard Schema over a built-in default provider, JSON Schema projection, and one `formatIssues` shared by every package that reports a validation failure.
- **`@ultimat3/entity` + `@ultimat3/db`** — a Postgres driver (`postgresDriver()`) and an in-memory one over one shared plan/cursor layer, so the two cannot drift; PGlite and database branching, so `x dev` needs no Docker.
- **`@ultimat3/action` + `@ultimat3/query`** — one declaration projecting to an HTTP route, an OpenAPI operation, a typed client method, a job handle, an MCP tool and contract tests, all through a single `invoke` path.
- **`@ultimat3/http`** — the owned `Bun.serve` lifecycle with an explicit, ordered request pipeline.
- **`@ultimat3/jobs`** — Postgres queue driver, durable steps with memoized replay, transactional outbox on by default, cron `task`s with a required IANA timezone and leader election.
- **`@ultimat3/realtime`** — tiers 1–2: channels, presence, live queries with per-subscriber policy, an incremental matcher, a Postgres logical-replication change feed (`pgoutput` over `Bun.connect`), and a NATS bus for fanout.
- **`@ultimat3/render` · `pwa` · `seo`** — five render modes with `stream` the default, the `site/` → `app/` surface boundary as a build error, a generated service worker, and SEO gates that fail the build rather than the audit.
- **`@ultimat3/cache`** — four tiers and one tag invalidation graph; an untagged cached query fails the gate.
- **`@ultimat3/mcp` · `ai` · `manifest`** — the AI-first surface: an MCP dev server whose tool catalog is per-connection and fail-closed, a read-only SQL guard with four independent defenses, `x.manifest.json`, `llm()` with token-and-money budgets and a scope-partitioned semantic cache, `PgVectorStore` fusing pgvector cosine and Postgres FTS through RRF, and evals that gate on score delta from a committed baseline.
- **`@ultimat3/auth` · `mail` · `storage`** — OAuth authorization-code exchange with id-token verification, ESMTP and Resend transports, S3 storage.
- **`@ultimat3/i18n` · `money` · `time`** — enforced, not documented: no hardcoded user-facing string, no float money, no date without an explicit IANA `timeZone`.
- **`@ultimat3/ui` · `admin`** — an SCSS-module design system on semantic tokens for both colour schemes, and the `/_x` dashboard.
- **`@ultimat3/cli`** — the `x` binary. `x dev` boots the real app in any role, and every fact it reports comes from a framework package rather than a second implementation inside the CLI.
- **`create-ultimate`** — `bunx create-ultimate myapp` scaffolds a monorepo whose unmodified generated code passes `x verify`.
- **`x verify`, 17 steps**, with no way to run fewer: typecheck, lint, boundaries, filesize, package-shape, errors, unit, contract, live, job, e2e, eval, drift, contract-diff, budgets, manifest, roadmap.
- **The error contract, as gate steps.** Every failure carries a stable `X_*` code, a cause, a runnable `fix:` and a `--json` form. `x verify` fails a `fix:` that names no command, and an `X_*` code with no documented row.

### Fixed

- A lockstep release now rewrites sibling `@ultimat3/*` pins, not only each package's own version. Moving versions alone would have published `@ultimat3/jobs@1.0.0` naming `@ultimat3/core@0.0.1` — a version that is not on the registry, so every install of the release would fail.
- Version skew is a `package-shape` finding (`X_RELEASE_VERSION_SKEW`), so it fails the gate instead of reaching npm.
- A changelog entry inserts under `[Unreleased]` instead of appending, which keeps the file newest-first past the second release.

### Notes

Pre-alpha. Nothing here is production-ready. Milestones 0–5 are the path to usable — see [docs/idea/14-roadmap.md](docs/idea/14-roadmap.md). Remote drivers (Redis, NATS, real S3, Postgres logical replication) are interface-complete and throw `X_NOT_IMPLEMENTED` with a fix line rather than pretending to work.
Not claimed at 1.0.0, named here rather than left to be discovered:

| Open | Where it stands |
|---|---|
| Realtime capacity | no published benchmark. The 50k-socket forced-restart number is unmeasured; documented capacity figures are targets, not results |
| Two-platform deploy proof | `x build --target docker\|binary\|static`, both compose files and the Helm chart ship. The demo app on Compose **and** K8s from one image, with an invisible rolling restart, is [milestone 11](docs/idea/14-roadmap.md) and is not yet demonstrated |
| Deferred to v2 | realtime tier 3 local-first (`persist: true`), the plugin API, multi-region replication, and the Redis/NATS **job** drivers — each behind an interface that ships today, throwing `X_NOT_IMPLEMENTED` with a runnable `fix:` rather than pretending to work |

## [0.0.1] - 2026-07-26

Repository bootstrap: monorepo layout, tier-enforced package boundaries, Biome and strict TypeScript, free-runner CI, npm OIDC trusted publishing, and the design docs. Never published to npm.
13 changes: 11 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@ This repo is the framework itself: a monorepo of `@ultimat3/*` packages, the `x`

CLI binary: `x`. npm scope: `@ultimat3`. Import paths: `@ultimat3/<pkg>`.

**Status:** pre-alpha. Architecture + docs + package skeletons landed; milestones 0–5 are the path to usable. See [`docs/idea/14-roadmap.md`](docs/idea/14-roadmap.md).
**Status:** 1.0.0, `As of 2026-08`. 27 `@ultimat3/*` packages plus the unscoped `create-ultimate` —
28 in all — publish to npm at 1.0.0 in lockstep: one version, one commit, one tag, through OIDC
trusted publishing. Semver applies from here — a breaking change to a documented API needs a major,
and the eight primitive shapes, the `x` CLI surface and the tier table are now as stable as the
`X_*` codes already were. Two things stay open: the realtime capacity benchmark (the 50k-socket
forced-restart number is unmeasured — every capacity figure in the docs is a target, not a result),
and roadmap milestone 11's two-platform deploy proof (`x build --target docker|binary|static`, the
dev/prod compose files and the Helm chart all ship; the demo app running on Compose **and** K8s
from one image with an invisible rolling restart is not yet demonstrated). See
[`docs/idea/14-roadmap.md`](docs/idea/14-roadmap.md) for the milestone detail.

## Design axioms (override any instinct that conflicts)

Expand All @@ -29,7 +38,7 @@ CLI binary: `x`. npm scope: `@ultimat3`. Import paths: `@ultimat3/<pkg>`.
| Task | Command |
|---|---|
| install | `bun install` |
| **the gate** | `bun run verify` — `x verify` at the repo root: typecheck, lint, boundaries, sizes, shape, every test type, drift, contracts, budgets, manifest. Green = shippable. |
| **the gate** | `bun run verify` — `x verify` at the repo root, 17 steps: typecheck, lint, boundaries, filesize, package-shape, errors, unit, contract, live, job, e2e, eval, drift, contract-diff, budgets, manifest, roadmap. Green = shippable. |
| typecheck | `bun run typecheck` |
| lint | `bun run lint` · fix: `bun run lint:fix` |
| test (all) | `bun run test` — every framework suite, opt-in ones included. The reference app is gated separately: `cd examples/dummy && bun run ../../packages/cli/src/bin.ts verify` |
Expand Down
27 changes: 22 additions & 5 deletions PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,35 @@ automatically.
other by tier, so a mixed-version install is a combination nobody tested. There is no independent
package version, no changeset-per-package, and no "just bump the one that changed".

The rule is enforced, not documented: `x verify`'s **package-shape** step reports
`X_RELEASE_VERSION_SKEW` for a published package off the lockstep version, and for a sibling
`@ultimat3/*` pin left behind. Skew fails the gate rather than reaching the registry, where it
would surface as a failed install of a version that cannot be unpublished.

```sh
bun run scripts/release.ts --bump minor # or --version 0.4.0
git add -A && git commit -m "release: 0.4.0"
git tag v0.4.0 && git push --follow-tags
bun run scripts/release.ts --bump minor # or --version 1.1.0
bun install # regenerate bun.lock, by hand — never Dependabot
bun run verify # the gate, including the lockstep check
git add -A && git commit -m "release: 1.1.0"
git tag v1.1.0 && git push --follow-tags
```

Then publish a GitHub Release for the tag — that is what triggers the workflow.

The release script rewrites **every** workspace manifest, not just the ones that publish: the
reference app under `examples/` is private and never reaches npm, but it resolves `@ultimat3/*`
out of the same lockfile, so one pin left at the old version sends `bun install --frozen-lockfile`
to the registry for a version that is not there.

`bun.lock` is regenerated by hand and committed with the release. **Dependabot cannot write it** —
a dependency PR that touches versions arrives with a lockfile that has to be regenerated locally,
and installing over a conflicted lock produces a resolution nobody reviewed.

## One-time bootstrap (manual, requires npm auth)

A trusted publisher can only be attached to a package that **already exists**. The first version
of each package must be published by hand by a member of the `ultimate` npm org, in tier order:
A trusted publisher can only be attached to a package that **already exists**. The first version —
**1.0.0** — must be published by hand by a member of the `ultimate` npm org, in tier order. Every
release after it goes through the workflow:

```sh
npm login # as an @ultimat3 org member
Expand Down
Loading
Loading