# Changelog

All notable changes to OpenLife CLI (`@openlife/cli`) are documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
Project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Detailed per-milestone notes (story-level breakdown, commit map, scorecard
deltas) live in `docs/v<N>-changelog.md`.

## [Unreleased]

Future work: v1.18.4 SvelteKit template; v1.18.5 SSH git URLs +
branch/ref selection + private repo support; v1.19.1 AI-driven preflight
remediation; cross-machine bridge (#9).

---

## [1.19.0] — 2026-05-22

**Regression-killer CI + multi-environment deploy promote.**

### Added
- **`.github/workflows/template-smoke.yml`** — CI matrix per template:
  scaffold → install → build. Prevents v1.18.2-class regressions
  (template builds but engine tests passed) before they reach npm.
- **`openlife deploy promote <env>`** — new subcommand. Promotes an
  existing deployment to a target environment. Hybrid model: Vercel
  uses native alias swap (`vercel promote`), Cloudflare uses
  versioned alias swap (`wrangler versions deploy <id>@100%`),
  Railway redeploys to target env (`railway up --environment <env>`),
  Fly redeploys to target app (`fly deploy --app <name>`).
- **`DeployAdapter.promote(opts: PromoteOptions)`** — new required
  interface method. Custom adapters must implement it.
- **4 new test scenarios** (`test:deploy-adapters` scenarios 12–15):
  promote contract per adapter (Vercel, Railway, Cloudflare, Fly).

### Migration notes
- Public CLI: no breaking changes.
- Custom `DeployAdapter` implementations: add `promote()` method.

Full details: `docs/v1.19-changelog.md`.

---

## [1.18.3] — 2026-05-22

**Documentation patch.** Codifies the full `v1.15→v1.18` SaaS Forge
arc as a single end-to-end guide. No code changes.

### Added
- **`docs/saas-forge.md`** — the 5-command path from idea to production
  SaaS, with **real CLI output** captured from smoke tests on 2026-05-22:
  - Step-by-step walkthrough of scaffold → design pull → story execute
    → ship → deploy
  - Real Claude execution output from smoke 3 (story 1.1 converged in
    71.8s, single iteration)
  - Persona routing table (BUG/FEATURE/DESIGN/etc → persona sequence)
  - All 4 deploy adapters (Vercel/Railway/Cloudflare/Fly) with their
    preflight checks
  - Full safety summary across all 5 commands
  - Worked example: "add a billing tab" from zero to deploy
  - Troubleshooting matrix (8 common failures + diagnostics)
  - Release timeline with smoke-status flags
- **README.md** — new "🏗️ Build a SaaS in 5 commands" section after
  v1.11 changelog, before Installation. Surfaces the 5 commands with
  one-line descriptions + safety note + link to the full guide.
- **Comandos diários** section now lists the SaaS Forge commands.

### Changed
- `package.json` — `docs/saas-forge.md` added to `files[]`, version
  1.18.2 → 1.18.3.

### Smokes verified (all 4)
- **Smoke 1** — All 6 template deps exist at declared versions (next@16,
  react@19, @clerk/nextjs@6, stripe@17, @supabase/ssr@0.5, svix@1.30)
- **Smoke 2** — Scaffolded Next.js template `npm install && npm run
  build && npm run dev` SUCCEEDS (after v1.18.2 hotfixes)
- **Smoke 3** — `openlife story execute` with real Claude CLI converged
  on synthetic story in 71.8s, single iteration, committed locally,
  AC checkbox flipped, branch protection respected
- **Smoke 4** — This documentation pass (current release)

---

---

## [1.18.2] — 2026-05-22

**Template hotfix.** The `nextjs-supabase-clerk-stripe` template shipped
in v1.16.0 had 5 latent bugs that only surfaced when a user ran the
full `npm install && npm run build && npm run dev` flow. None were
caught by the v1.16/v1.17/v1.18.x test suite because that suite only
verified file copy + token substitution.

Detailed per-bug analysis in `docs/v1.18.2-changelog.md`.

### Fixed
- **🔴 Stripe apiVersion** — `'2024-12-18.acacia'` → `'2025-02-24.acacia'`
  (Stripe SDK 17.x requires the latter; the old value failed TypeScript
  type-check at build time).
- **🔴 Route group `(dashboard)` conflict** — renamed
  `app/(dashboard)/` → `app/dashboard/`. The parens made it a route
  group with no URL segment, so `(dashboard)/page.tsx` collided with
  `app/page.tsx` at `/`. Now `/dashboard` and `/dashboard/billing`
  resolve correctly. Middleware matcher updated to `/dashboard(.*)`.
- **🔴 Root layout SSG** — added `export const dynamic = 'force-dynamic';`
  to `app/layout.tsx`. ClerkProvider wraps `_not-found` (auto-generated
  404 page); Next 16 tried to SSG it at build time and failed with
  "Missing publishableKey". Forcing dynamic prevents the SSG attempt.
- **🔴 Middleware negative-lookahead regex** — replaced
  `'/api/(?!webhooks)(.*)'` (unsupported by `path-to-regexp` v6) with
  an explicit public allowlist (`/`, `/sign-in(.*)`, `/sign-up(.*)`,
  `/api/webhooks/(.*)`) + `if (!isPublicRoute(req)) auth.protect()`.
  This is the pattern Clerk's docs recommend.
- **🟡 middleware.ts deprecation note** — added a long-form comment
  explaining the Next 16.2+ deprecation in favor of `proxy.ts` (same
  shape, renamed) + migration guidance. Clerk still recommends
  `middleware.ts`, so we keep the original name.

### Changed (catalog)
- `.catalog/skills/stripe-billing-wire/SKILL.md` — apiVersion bump
  + clarifying comment.

### Engine unchanged
- Scaffold engine, CLI, deploy adapters, story executor — no changes.
- Same 1234 files, same ~2.0MB tarball.

### Lesson learned
- Unit tests verified file copy. Real builds were never run in CI.
  v1.19.0 will add a CI step that scaffolds each bundled template and
  runs `npm install && npm run build` to catch this class of regression
  early.

---

## [1.18.1] — 2026-05-22

Patch closing v1.18.0 deferred items.

### Added
- **`CloudflareAdapter`** — wraps `wrangler` CLI for Workers + Pages.
  Detects `wrangler.toml` / `wrangler.jsonc`. Preflight checks `name`
  field + `CLOUDFLARE_API_TOKEN` in CI. Native `wrangler rollback <id>`.
- **`FlyAdapter`** — wraps `fly` (falls back to `flyctl`). Detects
  `fly.toml`. Preflight checks `app` field + `FLY_API_TOKEN` in CI.
  Native `fly releases rollback <version>`. `--preview` maps to
  `--strategy=canary`.
- **`RailwayAdapter.rollback`** — replaces v1.18.0 "not_supported" stub
  with `railway redeploy --yes <deployment-id>`. Requires `--to <id>`.
- **`scaffold custom --from=<git-url>`** — accepts github.com,
  gitlab.com, bitbucket.org, codeberg.org URLs + GitHub `owner/repo`
  shorthand. Validates via `SecurityDownloadGuard.validateUrl` +
  explicit allowlist. Caches at `~/.openlife/templates/.git-cache/<hash>/`
  (idempotent re-runs). `git clone --depth=1 --quiet`. Refuses `git@`
  SSH URLs (deferred to v1.18.3).
- **3 new test scenarios** in `test_deploy_adapters.ts` (registry has
  all 4 adapters, CloudflareAdapter preflight, FlyAdapter preflight).
  Renamed scenario 8 to reflect Railway rollback now requires `--to`.

### Changed
- `DeployRegistry.ensureDefaults` registers 4 adapters (was 2).
- `DeployRegistry.autoDetect` reads 4 marker types (was 2).
- `openlife deploy list` shows all 4 with install status.
- `package.json` — version 1.18.0 → 1.18.1,
  `docs/v1.18.1-changelog.md` in `files[]`.

### Tarball
- 2.0MB unchanged, 7.6MB → 7.7MB unpacked (+50KB), 1231 → 1235 files.

---

---

## [1.18.0] — 2026-05-22

**Ship + Deploy + SaaS Skills** — closes the v1.15→v1.18 SaaS Forge arc.
The full path from idea → SaaS-in-production is now composable:

```bash
openlife scaffold meu-app --template=...    # v1.16
openlife design pull stripe                 # v1.15
openlife story execute 1.1                  # v1.17
openlife ship                               # v1.18 (THIS)
openlife deploy --provider=vercel           # v1.18 (THIS)
```

Detailed per-subsystem notes in `docs/v1.18-changelog.md`.

### Added
- **`openlife ship` CLI** — `src/cli/ShipCommand.ts`. Vortex-delegated
  push + PR creation. Authorizes a single GitOps.push() call via
  try/finally pattern, builds PR title from story tag + body from
  description + AC + File List, opens via `gh pr create --body-file -`.
  Flags: `--story`, `--remote`, `--target`, `--no-pr`, `--dry-run`, `--json`.
- **`GitOps.push() + _authorizePush()`** — extends v1.17 GitOps. The
  flag is module-scoped and released immediately by ShipCommand; any
  other caller hitting push gets `gitops_refused: not_authorized`.
  Protected-branch ban still applies.
- **`openlife deploy` CLI** — `src/cli/DeployCommand.ts` + subcommands
  `rollback`, `list`. Pluggable adapter pattern.
- **`DeployAdapter` interface** — `src/orchestrator/deploy/DeployAdapter.ts`.
  Four lifecycle methods: detect, preflight, deploy, rollback.
  Auto-detection from filesystem markers (`vercel.json`, `.vercel/`,
  `railway.toml`, `railway.json`) + CLI probing.
- **`VercelAdapter`** — wraps `vercel` CLI. Preflight detects unlinked
  projects, invalid vercel.json, missing CI tokens. Production
  (`vercel --prod`) and preview deploys. Native `vercel rollback`.
- **`RailwayAdapter`** — wraps `railway up`. Preflight detects missing
  config, missing build strategy. Native rollback deferred to v1.18.1.
- **4 SaaS skills** (markdown only, applied by host CLI):
  - `clerk-wire` — Clerk auth: middleware + auth routes + UserButton +
    server helpers + webhook
  - `stripe-billing-wire` — Stripe: SDK + plans + checkout + portal +
    subscription webhook + RLS-aware DB sync
  - `supabase-rls-wire` — Postgres: users + subscriptions + orgs +
    org_members tables with self-select RLS policies
  - `vercel-deploy-wire` — Deploy prep: vercel.json + env-var
    registration + webhook URL setup + custom domain
- **13 new test scenarios** across `test_ship_command.ts` (5) and
  `test_deploy_adapters.ts` (8) — all green.

### Safety
- Push remains @vortex-exclusive — ShipCommand is the ONE caller
  authorized via `GitOps._authorizePush()`.
- Protected-branch ban applies to ship.
- Dirty tree refused.
- Deploy adapters 10min default timeout with SIGKILL escalation.
- Preflight by default; `--skip-preflight` available for advanced users.
- No automatic webhook configuration — skills document the steps but
  never call provider APIs to register webhooks.

### Changed
- `src/index.ts` — registers ShipCommand + DeployCommand lazily.
- `src/orchestrator/util/GitOps.ts` — adds `push()` method + module-level
  `_pushAuthorized` flag gated by `_authorizePush()`.
- `package.json` — 3 new test scripts, chain into `test:all`,
  `docs/v1.18-changelog.md` in `files[]`, version 1.17.0 → 1.18.0.

### Catalog stats
- 46 squads, 57 → 61 skills (+4 SaaS skills).

### Tarball
- 1.95MB → 2.0MB (+50KB), 1218 → 1232 files (+14).

---

## [1.17.0] — 2026-05-22

**Autonomous Story Loop** — Track B Phase 2 of the v1.15→v1.18 SaaS
Forge arc. Turns story-driven discipline into a single command:
`openlife story execute 1.1` cycles through personas, mutates the
story file as ACs land, commits locally per progress, and transitions
status — without git push (delegated to `openlife ship` in v1.18).

Detailed per-subsystem notes in `docs/v1.17-changelog.md`.

### Added
- **`src/orchestrator/util/GitOps.ts`** — local git utility:
  `getCurrentBranch / getDirtyFiles / isClean / isOnProtectedBranch /
  createBranch / stageFiles / commit` + `branchNameFromStory()`. Refuses
  push at args level (push is `@vortex` exclusive).
- **`src/orchestrator/util/ResponseStructureExtractor.ts`** — pure
  regex utilities (`extractFilePaths / extractCodeBlocks /
  extractACsChecked / extractTestCmd / parseAll`) used by adapters.
- **`src/orchestrator/story/PersonaRouter.ts`** — maps story title
  prefix to persona sequence: `[BUG]/[FIX]→builder+sentinel`,
  `[FEATURE]→genesis+architect+builder+sentinel`, `[DESIGN]→prism+builder+sentinel`,
  `[DATA]→mesh+builder+sentinel`, `[DOCS]→lyra+sentinel`, etc.
- **`src/orchestrator/story/HostInvoker.ts`** — pluggable adapter
  registry. Routes via `opts.provider` or `OPENLIFE_HOST_ADAPTER` env.
- **4 host adapters:** `ClaudeAdapter`, `GeminiAdapter`, `CodexAdapter`
  (reuses `TaskExecutor.extractCodexFinalMessage`), `MockAdapter`
  (deterministic test double driven by `OPENLIFE_MOCK_ADAPTER_SCRIPT`).
- **`src/orchestrator/story/StoryStateTracker.ts`** — atomic mutations
  of `*.story.md`: `checkAC`, `appendDevAgentRecord`, `appendFileList`,
  `transitionStatus` (delegates role-gating to `StoryLifecycle`).
- **`src/orchestrator/story/HandoffArtifact.ts`** — YAML serialization
  with 3-tier trim keeping output ≤2000 chars (~500 tokens).
- **`src/orchestrator/story/StoryExecutor.ts`** — main loop. Branch
  guard → persona sequence → iterate (compose prompt → invoke host →
  parse → mutate → run tests → commit if AC progress) → transition +
  QA gate. Max-iters cap (default 10, ceiling 50). No-progress
  watchdog (3 strikes).
- **`openlife story execute <id>` CLI** with 8 flags: `--max-iters`,
  `--persona`, `--stop-after`, `--force`, `--dry-run-tests`,
  `--plan-only`, `--adapter`, `--json`.
- **40 new test scenarios** across 7 files — all green with
  MockAdapter (no real CLIs spawned in CI).

### Safety
- No automatic `git push` — refused at GitOps args level.
- Branch protection — refuses to operate on `main/master/develop/production`.
- Dirty working tree refused by default (`--force` overrides).
- Max-iters hardcoded ceiling 50.
- No-progress watchdog (3 stale iters → halt).
- Adapter timeout 5min default with SIGKILL escalation.
- Atomic story file mutation via `AtomicWriter.writeStringAtomic`.
- Test cmd whitelist (npm/yarn/pnpm/bun/pytest/jest/vitest/mocha/cargo/go/deno).
- Role-gated status transitions.

### Changed
- `src/cli/StoryCommand.ts` — registers `execute` subcommand via lazy
  require.
- `package.json` — 8 new test scripts, `test:story-loop` chain,
  `docs/v1.17-changelog.md` in `files[]`, version 1.16.0 → 1.17.0.

### Tarball
- 1.9MB → 1.95MB (+50KB), 1199 → 1218 files (+19).

---

## [1.16.0] — 2026-05-22

**SaaS Scaffold + First Template** — Track B phase 1 of the v1.15→v1.18
SaaS Forge arc. Ships the scaffold engine and the first production-grade
bundled template (Next.js + Supabase + Clerk + Stripe).

Detailed per-subsystem notes in `docs/v1.16-changelog.md`. Authoring
guide in `docs/scaffold.md`.

### Added
- **Scaffold engine** — `src/orchestrator/scaffold/ScaffoldEngine.ts`
  + `TemplateRegistry.ts`. Copies template files into a target dir
  with `{{token}}` substitution, `__token__.ext` filename renames,
  `manifest.exclude[]` honoring (files + dirs + extension globs),
  empty-target enforcement (force:true overrides), dry-run mode,
  unresolved-token scanning.
- **`openlife scaffold` CLI** — `list / info <id> / apply <name>
  --template=<id> / custom <name> --from=<path>`. Lazy-registered to
  keep --help fast.
- **`templates/nextjs-supabase-clerk-stripe/`** — 25-file bundled
  template producing a working Next.js 16 SaaS:
  - Clerk middleware + sign-in/sign-up routes + `UserButton` + server helpers
  - Supabase Postgres clients (anon + service-role) with RLS migration
    (`users` + `subscriptions` tables, self-select policies)
  - Stripe SDK + plan definitions + customer lookup + subscription
    webhook handler
  - Clerk → Supabase user sync webhook
  - Tailwind v3.4 + globals.css ready for shadcn/ui
  - `vercel.json` deploy config + `.env.example` documenting 8 keys
- **TemplateManifest schema** — id, name, description, stack, required_env,
  post_install_steps, exclude, required_node_version.
- **Built-in substitution vars** — `{{project_name}}`,
  `{{description}}`, `{{node_version}}`. User vars via
  `--var key=value` (repeatable).
- **7 new test scenarios** in `test_scaffold_engine.ts` — all pass.
  Includes real-bundled-template smoke (24 files copied,
  substitutions verified, key files present).

### Changed
- `src/index.ts` — registers ScaffoldCommand lazily.
- `package.json` — `templates/**` added to `files[]`, new test
  scripts, version 1.15.0 → 1.16.0.

### Security
- Token substitution is pure string replacement — no eval, no shell
  expansion, no code execution at scaffold time.
- `--from=<git-url>` deferred to v1.16.1 (requires
  `SecurityDownloadGuard.downloadAndScan` integration). Currently
  only local paths.
- Bundled templates ship no real credentials — `.env.example` only.

### Out of scope (deferred)
- SvelteKit-Postgres-Lucia template → v1.16.1
- Git URL templates → v1.16.1
- Template marketplace with rating → v1.19+
- Mobile (Expo/RN) templates → v1.19+

### Tarball
- 1.9MB → 1.95MB (+50KB)
- Unpacked 7.3MB → 7.5MB (+200KB)
- 1166 → 1196 files (+30)

---

## [1.15.0] — 2026-05-21

**Design.md Hub** — Track A of the v1.15→v1.18 SaaS Forge arc. Lifts
the DesignMd subsystem from a single importer into a queryable hub
with rich artifacts, URL-based extraction, search, and drift detection.

Detailed per-subsystem notes in `docs/v1.15-changelog.md`. Full guide
in `docs/design-hub.md`.

### Added
- **Bundled catalog** — 5 brands (apple, claude, stripe, vercel,
  linear.app) ship in the npm tarball under
  `vendor/awesome-design-md-core/design-md/` with full rich artifacts
  (DESIGN.md + tokens.json + preview.html + render-contract +
  style-fingerprint + quality-score + agent-prompt).
- **`DesignMdImporter.pullCatalog(catalog, opts)`** — new method.
  `core` → bundled, `full` → `OPENLIFE_DESIGN_CATALOG_PATH` env or
  `opts.source`, `<path>` → arbitrary local dir.
- **Rich-artifacts propagation** — `pullCatalog` and richer
  `importFromVendor` modes copy tokens.json/preview.html/etc.
  alongside DESIGN.md. Surfaces `archetype` + `qualityScore` into
  `meta.json` automatically.
- **URL extraction skill** — bundled Alan Nicolas'
  [design-md](https://github.com/oalanicolas) Claude Code Skill at
  `.catalog/skills/design-md-extractor/` (MIT). Full pipeline:
  HTML/CSS static analysis → token detection → LLM-written
  DESIGN.md → preview.html + drift + quality score.
- **`DesignMdExtractor` TS wrapper** — provider routing via
  `ModelTierRouter`, URL safety (SSRF guards distinct from
  `SecurityDownloadGuard.validateUrl` — read-only HTML has different
  threat model than package download), 24h cache keyed by URL hash,
  optional `--catalog` publish into `design/profiles/`.
- **`openlife design` CLI** with 7 subcommands:
  - `pull [catalog]` — import core/full/path
  - `list [--json]` — enumerate imported profiles
  - `show <id>` — print DESIGN.md + meta header
  - `search <query> [--archetype --source --quality --json]` —
    ranked full-text search
  - `diff <a> <b> [--json]` — token-level diff (colors + typography +
    archetype + qualityScore)
  - `drift <profile> <url> [--json]` — re-extract URL and diff;
    emits `in-sync ✓` / `minor drift` / `notable drift` / `major drift ⚠`
  - `extract <url>` — full pipeline with all skill flags
- **`DesignMdRegistry.search(query, filters)`** — full-text with
  ranking: id/title=3, archetype/qualityScore meta=2, body fallback=1.
- **`DesignMdRegistry.findByArchetype(name)`** — filter helper.
- **`DesignMdRegistry.findByTokenColor(hex, deltaE)`** — RGB-distance
  filter for "designs with this color".
- **`DesignMdRegistry.diff(a, b)`** — structured token-level diff
  reading tokens.json or falling back to DESIGN.md frontmatter.
- **22 new test scenarios** across `test_design_catalog_import`,
  `test_design_extractor`, `test_design_registry_search` — all pass.
  Includes real-bundled-core smoke (apple↔claude delta=167 tokens).

### Changed
- **`DesignProfileMeta` schema** — added optional `archetype`,
  `qualityScore`, `artifacts[]` fields. Backward-compatible (legacy
  importer paths leave them undefined).
- **Dependencies** — added `cheerio@^1.2`, `turndown@^7.2`,
  `yaml@^2.8` (the extractor skill's runtime).

### Security
- Extractor URL safety blocks 11 SSRF vectors (localhost / RFC1918 /
  link-local / cloud-metadata / IPv6 loopback / `*.local` / `*.internal`)
  + non-http(s) protocols.
- `pullCatalog('full')` without source fails-closed with actionable
  error.
- `OPENROUTER_API_KEY` read from env only — never logged, never
  written to any persisted artifact.

### Tarball
- 1.4MB → 1.9MB (+500KB)
- Unpacked 5.2MB → 7.2MB (+2.0MB)
- 1016 → 1166 files (+150)

### Out of scope (deferred)
Remote `pull --catalog=full` over HTTPS (v1.15.1). CIE2000 perceptual
color distance. Conversational design intents (descobrir / comparar
in tryHandleDesignConversation — deferred to v1.16 alongside
scaffold-time auto-suggestions).

---

## [1.14.0] — 2026-05-21

The closing milestone of the **Complete Context System**: Codebase
Graph (tree-sitter), Context Composer, and per-CLI Tier Router.
Every `openlife ask` now auto-injects relevant stories + code chunks
+ symbols into the system prompt, and the user can drive
everything from a single signed-in CLI (claude / gemini / codex /
ollama) without ever touching an API key.

Detailed per-subsystem notes in `docs/v1.14-changelog.md`.
Full architecture in `docs/complete-context.md`.

### Added
- `src/orchestrator/graph/` — `TreeSitterRegistry`,
  `SymbolExtractor`, `DependencyExtractor`, `GraphStore`,
  `GraphBuilder`.
- `src/orchestrator/context/` — `ContextSource`, `ContextBudget`,
  `ContextComposer`.
- `src/orchestrator/router/` — `ProviderCapabilityCatalog`,
  `ProviderProbe`, `ModelTierRouter`.
- `openlife graph {build,status,find,callers,deps,usages}` CLI.
- `openlife provider {list,detect,doctor,setup,use,models,set-mode,set-preference}` CLI.
- Zero-config first-run autoconfig (`ModelTierRouter.ensureConfigured`)
  wired into `openlife ask`.
- Composer integration in `Gatekeeper.handleFastPath` — opt-out via
  `OPENLIFE_CONTEXT_COMPOSER=off`.
- Three new tests: `test_codebase_graph`, `test_context_composer`,
  `test_model_tier_router`. Wired into `test:all` and `test:context`.

### Notes
- Default inference mode `cli-only`: no paid API key required as
  long as a `claude` / `gemini` / `codex` CLI is signed in.
- `cli-only` does NOT silently fall back to a paid API. Switch to
  `hybrid` via `openlife provider set-mode hybrid` for that.
- Composer is opt-out, not opt-in — existing `openlife ask` flows
  automatically benefit.

### Dependencies
Added: `tree-sitter@0.21`, `tree-sitter-typescript`,
`tree-sitter-javascript@0.21`, `tree-sitter-python@0.21`, `tiktoken`.

---

## [1.13.0] — 2026-05-21

The **Codebase RAG** milestone. OpenLife now indexes source files,
embeds them with a local-first provider, and supports semantic
retrieval. Lays the groundwork for the v1.14 Context Composer.

Detailed per-subsystem notes in `docs/v1.13-changelog.md`.

### Added
- `src/orchestrator/rag/` — `EmbeddingProvider`, `OllamaEmbeddingProvider`
  (default), `OpenAIEmbeddingProvider`, `EmbeddingRegistry`,
  `VectorStore`, `SqliteVectorStore` (sqlite-vec), `VectorStoreRegistry`,
  `Chunker`, `Indexer`, `Retriever`.
- `openlife index {build,update,status,query,purge}` CLI surface.
- Three new tests: `test_chunker`, `test_embedding_providers`,
  `test_indexer`. Wired into `test:all` and the new `test:rag`
  aggregator.

### Notes
- Local-first by default — Ollama with `nomic-embed-text` (768d).
  Opt into OpenAI embeddings via `OPENLIFE_EMBEDDING_PROVIDER=openai`.
- Vector store is SQLite + `sqlite-vec` at
  `~/.openlife/index/codebase.db`. Mode 0o600.
- Incremental indexing detects mtime delta per file.

### Dependencies
Added: `better-sqlite3`, `@types/better-sqlite3`, `sqlite-vec`.

---

## [1.12.0] — 2026-05-21

The **Story Loader** milestone. OpenLife finally reads the
`docs/stories/<epic-id>/*.story.md` corpus at runtime — parsed into
typed `Story`/`Epic` objects, queryable via CLI, HTTP, the
core↔agent bridge, and Telegram `/core story`.

Detailed per-subsystem notes in `docs/v1.12-changelog.md`. First
release of the Complete Context System roadmap (v1.12 stories →
v1.13 RAG → v1.14 graph + composer).

### Added
- `src/orchestrator/story/` — `StorySchema`, `StoryParser`,
  `StoryRegistry`, `StoryLifecycle`, `StoryWriter`.
- `openlife story {list,show,validate,transition}` CLI surface.
- `GET /api/v1/stories`, `GET /api/v1/stories/:id`,
  `GET /api/v1/epics`, `GET /api/v1/epics/:id`,
  `POST /api/v1/stories/:id/transition` — all behind `bridgeAuth`.
- `openlife bridge story {list,show,transition,epics}` —
  daemon-mediated remote queries.
- `/core story <id>` and `/core stories` Telegram handlers in
  `CoreRemoteCommand`.
- Three new tests: `test_story_parser`, `test_story_registry`,
  `test_story_lifecycle`. Wired into `test:all` and the new
  `test:story` aggregator.

### Notes
- Story files use bolded markdown fields (`**StoryId:** \`3.3\``),
  not YAML frontmatter — the parser handles that natively. No
  changes required to existing story files.
- State machine: `Draft → Ready → InProgress → InReview → Done`
  with role-gated transitions. Role read from
  `OPENLIFE_USER_ROLE` (default `dev`).
- Status updates are atomic via `writeStringAtomic` and append a
  `## Change Log` entry by default.

---

## [1.11.0] — 2026-05-20

The **Core ↔ Agent Bridge** milestone. The two install profiles
(openlife-core CLI and openlife-agent daemon) now discover each other,
share eternal persistent memory, and can command each other
bidirectionally — including via Telegram.

Detailed per-subsystem notes in `docs/v1.11-changelog.md`. Designer
manifesto in `MANIFESTO.md`.

### Added
- **Mutual discovery** via `~/.openlife/gateway-manifest.json` (atomic
  write, mode `0o600`, 32-byte hex token, refreshed on the existing 30s
  watchdog tick, removed on graceful shutdown). New `AgentDiscovery`
  reader with cwd-local precedence and `fresh/stale/dead/missing`
  classification matching StatusCommand thresholds.
- **`openlife bridge {status, push, pull, listen, memory}`** CLI
  subcommand group under `bridge` namespace (preserves legacy
  `openlife agent <verb>` aliases). Lazy-loaded.
- **HTTP endpoints:** `POST /api/v1/core/run` and `GET /api/v1/events`
  (Server-Sent Events with `Last-Event-Id` resumption and 1000-event
  ring buffer). Both authed via Basic Auth with the manifest token
  (user fixed to `openlife-core`).
- **Reverse IPC** via `~/.openlife/cli-inbox/` ULID file queue with TTL
  cleanup, ack/reply round-trip. `CorePresence` published on every CLI
  invocation. Telegram `/core ...` family: `status`, `memory`,
  `agents`, `run`, `flow`.
- **Two cloud memory providers:** `HonchoMemoryProvider` (env:
  `HONCHO_API_KEY`, `HONCHO_APP_ID`) and `SupermemoryMemoryProvider`
  (env: `SUPERMEMORY_API_KEY`). Graceful degradation on missing config
  or transient errors — never throws.
- **Pluggable primary memory:** `OPENLIFE_MEMORY_PROVIDER` env var
  selects backend (`local`, `mem0`, `honcho`, `supermemory`,
  `redis-ams`, `mempalace`, `zep-graphiti`). When primary != local,
  also writes through to local cache.
- **`keep: true`** field on `MemoryRecord` for eternal records that
  bypass retention policy expiry regardless of type.
- **`WatchdogHeartbeat.onTick` callback** — manifest refresh
  piggybacks on the existing 30s cadence without a second timer.
- **7 new tests:** `test_gateway_manifest`, `test_agent_discovery`,
  `test_cli_inbox`, `test_local_memory_atomic`,
  `test_memory_provider_selection`, `test_core_remote_command`,
  `test_agent_bridge_e2e`.
- **New docs:** `docs/core-agent-bridge.md` (full guide),
  `MANIFESTO.md` (designer-voice manifesto), `docs/v1.11-changelog.md`
  (per-subsystem detail).

### Changed
- **`LocalMemoryProvider`** now uses `AtomicWriter` (temp+fsync+rename)
  and `DistributedLock` (5s TTL, auto-takeover) for all writes. Default
  store path moved from `<cwd>/.artifacts/memory-records.json` to
  `OPENLIFE_MEMORY_DIR ?? ~/.openlife/memory/memory-records.json` so
  core and daemon share one file across cwds.
- **`MemoryOrchestrator`** picks the primary provider from
  `OPENLIFE_MEMORY_PROVIDER` when no explicit `providers` array is
  passed. Write-through to local when primary != local. Per-provider
  error handling — one failing provider never halts the search.
- **`OmniMemory.saveFact`** no longer hardcodes `providers: ['local']`.
  Accepts optional `{keep: true}` for eternal records.
- **Telegram `processInput`** detects `/core ` prefix BEFORE classifier
  and routes to `CoreRemoteCommand.handle()`. Inherits the existing
  `OPENLIFE_TELEGRAM_ALLOWED_USER_ID` allowlist.

### Migration
- On first boot of v1.11+, if `<cwd>/.artifacts/memory-records.json`
  exists and the new location is empty, records are copied forward
  automatically. The legacy file is **never deleted** (user-data
  safety).

### Security
- Manifest file mode `0o600`. Token rotates on every daemon start
  (stable across watchdog refreshes). Sigstore provenance attached on
  npm publish via GitHub Actions OIDC.
- Cloud memory tokens read from env/`.env` only — never logged, never
  written to manifest.
- No new network surface: Express still on port 3000 (or `PORT`), SSE
  rides the same port, file-queue is local-only.

### Out of scope (deferred)
Cross-machine bridge (manifest is localhost-only in v1.11), mTLS,
multi-user Telegram, encrypted-at-rest memory. Roadmap in
`docs/v1.11-changelog.md`.

---

## [1.7.4] — 2026-05-14

### Fixed
- `openlife --version` now reads dynamically from `package.json` instead
  of a hardcoded `1.0.0`. After install, the reported version matches
  the npm tag.

## [1.7.3] — 2026-05-14

### Added
- `LICENSE` (MIT) at repository root and registered in `package.json`
  `files[]` so the tarball ships it.
- `.npmignore` to enforce exclusions over `files[]` whitelist when
  needed.

### Changed
- Cleaned external dev-kit branding (AIOX, GSD, AIOS) from every
  user-facing surface: 33 catalog files scrubbed, 8 unused legacy
  catalog entries removed, source comments and test function names
  generalized, `dist-templates/workflows/AIOX_PORT_NOTES.md` renamed
  to `PORTED_WORKFLOWS.md`.
- `.planning/` and `CLAUDE.md` untracked and `.gitignore`'d — they
  remain on disk for the maintainer but never ship publicly.
- Compact, OpenLife-only `CLAUDE.md` content (local-only).

### Removed
- 7 unused `aios-*` agents + 1 squad from `.catalog/` (imported mirrors
  with zero runtime consumers).
- Internal strategy/study docs moved out of public `docs/`.

## [1.7.2] — 2026-05-14

### Changed
- Package renamed from `@open-life/cli` → `@openlife/cli` to match
  the existing npm organization (`openlife`). No code/behavior change.

## [1.7.1] — 2026-05-13

### Fixed
- `SystemDoctor` graceful downgrade when running on Node 20+ builds
  that lack `--permission` flag support (e.g. CI runners). Sandbox
  enforcement check no longer false-fails on unsupported runtimes.

## [1.7.0] — 2026-05-13 — "Enforcement at scale"

See `docs/v1.7-changelog.md` for full per-story breakdown.

### Added
- Toolset enforcement coverage expanded from 2 to **13 categories**
  (memory, tts, cron, mcp, skills, workflows, squads, web, file,
  vision, gateway, plus terminal and delegation from v1.4). Behind
  `OPENLIFE_TOOLSET_ENFORCEMENT=on` (default still off, calendar-gated
  flip in 20.1).
- `OrchestrationLoop` now branches on `OPENLIFE_BRAIN_FORECAST=on` to
  reach `ConsequenceForecaster.forecastWithBrain()` (shipped v1.5,
  unwired until now). Brain verdict / risk amplifiers / opportunity
  factors surfaced into the attempt trace.
- `test_forecast_brain_wiring.ts` regression guard catches the
  "shipped but unwired" class of bug.
- Consolidated `docs/release-process.md` runbook.

### Fixed
- CI lint `any`-budget grep filter (`-h` flag was stripping filenames,
  causing test-file matches to count as production). Production `any`
  count driven to **0** against a filename-aware grep.

### Note on prior measurement
The v1.4–v1.6 `any` counts (172, 109, 83) reflected the broken filter
and were inflated. Real production counts were ~30, ~20, 12–14.
Historical changelogs are not retroactively edited; the correction is
documented in `docs/v1.7-changelog.md`.

## [1.6.0] — 2026-05-13 — "Sandbox rollout"

See `docs/v1.6-changelog.md`.

### Added
- `ProcessSandbox` (Story 18.1): Node 20+ `--permission` flag-based
  process sandboxing. First production wire-in via `openlife doctor`
  with graceful downgrade when unsupported.
- `TaskExecutor` opt-in sandbox (Story 18.2) via
  `OPENLIFE_SANDBOX_TASK_EXEC=on`.
- Distributed lock primitive for multi-process queue coordination.

### Changed
- `RuntimeHealthMonitor` exponential backoff (10s base → 1h cap) with
  10-failure budget per 1h window.

## [1.5.0] — 2026-05-13 — "Evaluation + remote publishing"

See `docs/v1.5-changelog.md` and `docs/v1.5-roadmap.md`.

### Added
- Brain-driven post-mission evaluation (Story 13.1) — automatic
  `quality / governance / actionability` scoring via `eval judge`
  command, results in `.openlife/evaluations/`.
- SHA-chained governance scope ledger (Story 14.2):
  `.openlife/governance-ledger.jsonl` with tamper detection via chain
  walk. PII protection by hashing goals before persistence.
- Remote asset publishing over HTTPS (Story 14.1) —
  `RemotePublisher` + signed manifests for catalog distribution.
- `ConsequenceForecaster.forecastWithBrain()` API (wiring in v1.7).
- Type safety improvements: structured Telegram API parsing, event
  iteration typing.

## [1.4.0] / [1.4.1] — 2026-05-12/13 — "Path to 10/10"

See `docs/v1.4-changelog.md`.

### Added (consolidation milestone — no new pillars)
- Intelligence wiring: `Brain.isAnyProviderAvailable()` opt-in,
  `SquadCreator/SkillCreator.designWithBrain()`, post-mission memory
  consolidation hook.
- Real I/O: `SecurityDownloadGuard.downloadAndScan()` with size cap +
  filename-pattern scanning; `HostInstaller` real implementations for
  Gemini CLI and Codex (no longer stubs); seeded
  `dist-templates/{gemini-cli,codex}/`.
- Toolset enforcement kernel: `assertToolsetAllowed()` at
  `TaskExecutor` and `Brain` CLI sites (terminal + delegation
  categories).
- Workflow condition parser: tokenize → recursive-descent → evaluate
  pipeline supporting `AND/OR/NOT/==/!=` + parens + dotted identifiers.
- CI + perf telemetry: `npm run test:performance-latency`,
  `.github/workflows/{test,build,lint}.yml`.

### v1.4.1 — Maintenance cut
- Backport-eligible bug fixes for v1.4 line.

## [1.3.0] — 2026-05-12 — "Agent OS Integration"

### Added
- 5 blueprint docs covering Agent OS integration architecture.
- Service Mode contract caller fixes (required `actor` parameter).
- v1.3 placeholder commands now have real implementations.
- Capability Pack schema + Capability Genesis Engine — turns free-text
  briefs into draft capability packs (Stories 1.1, 2.1–2.4, 3.1–3.3).

## [1.2.0] — 2026-05-12 — "Royal Stack"

### Added
- Workflow engine: `WorkflowSchema` + `WorkflowParser` +
  `WorkflowEngine` with atomic state persistence and phase-step
  execution model (Story 4.1).
- 4 ported workflows shipped in `dist-templates/workflows/`:
  `story-development-cycle`, `greenfield-fullstack`,
  `brownfield-discovery`, `qa-loop` (Story 4.4).
- Squad + Skill creators with interactive UX and Brain-driven design
  modes (Stories 5.1–5.5).
- Atomic writer + mission checkpoint API (Stories 6.1–6.2).
- Runtime reliability: heartbeat, watchdog, distributed lock,
  exponential backoff health monitor.
- `aiobuilder` CLI surface with 16 sub-commands (`mode`, `create-agent`,
  `create-squad`, `build-skill`, `generate-ui`, `discover`, `plan`,
  `build`, `test`, `preview`, `release`, `infra`, `score`, `evolve`,
  `ship`, `chat`, `canonize`, `create-capability`).

---

[Unreleased]: https://github.com/GOOODZ/openlife-core/compare/v1.7.4...HEAD
[1.7.4]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.7.4
[1.7.3]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.7.3
[1.7.2]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.7.2
[1.7.1]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.7.1
[1.7.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.7.0
[1.6.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.6.0
[1.5.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.5.0
[1.4.1]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.4.1
[1.4.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.4.0
[1.3.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.3.0
[1.2.0]: https://github.com/GOOODZ/openlife-core/releases/tag/v1.2.0
