From 577ff8bcc3d99151e11e28bb537eb867fe91383b Mon Sep 17 00:00:00 2001 From: Nahiyan Khan Date: Thu, 9 Jul 2026 12:40:21 -0400 Subject: [PATCH] docs: entrance accuracy pass, plainer welcome path, remove root fingerprint - Update README and AGENTS/CLAUDE init rows to the shipped skeleton starter; add ghost export and steering-eval to command/package tables - Document ghost export on the docs site (cli-reference) - Rewrite entrance docs in plain language: reorder README around install and agent prompts, cut untaught jargon from quickstart/getting-started, rebuild the npm README with the missing beta warning - Enforce the entrance-docs vocabulary in check-terminology.mjs - Remove the root .ghost fingerprint; salvage its voice conventions into CLAUDE.md conventions - Migrate demo fingerprints from legacy haunts/ to flat checks/ (local only) --- .changeset/docs-entrance-accuracy-pass.md | 5 + .ghost/.gitignore | 2 - .ghost/anti-goal.surface-sprawl.md | 19 ---- .ghost/decision.flat-corpus.md | 19 ---- .ghost/glossary.md | 24 ---- .ghost/index.md | 29 ----- .ghost/manifest.yml | 2 - .ghost/principle.byoa-boundary.md | 28 ----- .ghost/principle.voice.md | 25 ----- CLAUDE.md | 12 +- CONTRIBUTING.md | 22 ++-- README.md | 104 ++++++++---------- apps/docs/src/content/docs/cli-reference.mdx | 29 +++++ .../docs/src/content/docs/getting-started.mdx | 79 +++++++------ apps/docs/src/content/docs/quickstart.mdx | 45 ++++---- packages/ghost/README.md | 97 ++++++++++------ scripts/check-terminology.mjs | 35 +++++- 17 files changed, 264 insertions(+), 312 deletions(-) create mode 100644 .changeset/docs-entrance-accuracy-pass.md delete mode 100644 .ghost/.gitignore delete mode 100644 .ghost/anti-goal.surface-sprawl.md delete mode 100644 .ghost/decision.flat-corpus.md delete mode 100644 .ghost/glossary.md delete mode 100644 .ghost/index.md delete mode 100644 .ghost/manifest.yml delete mode 100644 .ghost/principle.byoa-boundary.md delete mode 100644 .ghost/principle.voice.md diff --git a/.changeset/docs-entrance-accuracy-pass.md b/.changeset/docs-entrance-accuracy-pass.md new file mode 100644 index 00000000..aac77d7d --- /dev/null +++ b/.changeset/docs-entrance-accuracy-pass.md @@ -0,0 +1,5 @@ +--- +"@design-intelligence/ghost": patch +--- + +Refresh the entrance docs: accurate skeleton/body init descriptions, a documented `ghost export`, and plainer language on the welcome path. diff --git a/.ghost/.gitignore b/.ghost/.gitignore deleted file mode 100644 index cffd9e8a..00000000 --- a/.ghost/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.events -.pulls diff --git a/.ghost/anti-goal.surface-sprawl.md b/.ghost/anti-goal.surface-sprawl.md deleted file mode 100644 index cf53be1a..00000000 --- a/.ghost/anti-goal.surface-sprawl.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: Guard against speculative surface area. Review-critical for changes that add commands, flags, fields, or vocabulary. -materials: - - packages/ghost/src/commands/*.ts - - .changeset/*.md ---- - -Not: shipping a field, flag, node type, hierarchy, or projection axis because -a future use case might want it. `extends`, `incarnation`, surface routing, -and the graph model all shipped unused and were all cut. - -Instead: ship the smallest surface that solves an observed failure, and cut -surface that has no user. New CLI commands and flags need a changeset, a -manifest regeneration (`pnpm dump:cli-help`), and a worked example in the -skill bundle before they are real. - -Recognize the switch: if a PR adds a concept that no recipe teaches and no -test exercises against a real task, the guard failed. If explaining the -feature requires new vocabulary, that vocabulary is a cost; count it. diff --git a/.ghost/decision.flat-corpus.md b/.ghost/decision.flat-corpus.md deleted file mode 100644 index 99b51c5c..00000000 --- a/.ghost/decision.flat-corpus.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: Why the fingerprint is a flat set of prose nodes and not a graph. Gather when tempted to add structure, edges, inheritance, or routing. -materials: - - docs/purposes.md ---- - -Chosen: a flat corpus. A node is one markdown file; its kind is a filename -prefix declared in the glossary; altitude and conditions live in the prose; -`materials` is the single locator field. - -Rejected: the graph model (edges, hubs, spokes), cross-package `extends` and -inherited nodes, the `incarnation` projection axis, check surface routing, -and a JSON schema for the artifact. Each added authoring cost and routing -logic that agents did not need: the agent reading prose against a task -out-performed every mechanical routing layer we built. - -Reversal condition: evidence that agents systematically fail to select the -right nodes from a flat menu at realistic corpus sizes. Until then, structure -proposals are surface sprawl (see `anti-goal.surface-sprawl`). diff --git a/.ghost/glossary.md b/.ghost/glossary.md deleted file mode 100644 index 3f2c4ff7..00000000 --- a/.ghost/glossary.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -kinds: - - name: principle - - name: anti-goal - posture: guard - - name: decision ---- - -# principle - -Durable stance of the Ghost project: true across the CLI, the skill bundle, -the docs site, and the README unless a narrower condition in the prose limits -it. - -# anti-goal - -What Ghost's own surfaces must never look or sound like: named generic -patterns and rejected neighbors, each stated with its replacement. -Review-critical. - -# decision - -Worked tradeoff trace: what was chosen, what was rejected, why, and what would -reverse it. Gather when tempted to revisit a settled question. diff --git a/.ghost/index.md b/.ghost/index.md deleted file mode 100644 index 14edd6b5..00000000 --- a/.ghost/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: Always read first. The non-negotiables for anything written or built for the Ghost project itself. ---- - -This fingerprint covers Ghost's own surfaces: the CLI output, the skill -bundle recipes, the docs site, the README, and changesets. It is Ghost -dogfooding Ghost. - -The non-negotiables: - -- **Plain, precise, restrained, product-minded.** Every shipped sentence - earns its place. No brand-deck filler ("elevate", "delight", "seamless", - "empower"), no hype, no exclamation points. See `principle.voice`. -- **The vocabulary is policed.** `scripts/check-terminology.mjs` bans the - memory-era vocabulary and other retired terms across shipped prose, - including this fingerprint. Use the current names: fingerprint, node, kind, - glossary, corpus, materials, check, gather, pull, pulse, review. -- **Deterministic CLI, interpretive agent.** The CLI never calls an LLM and - never interprets. Anything requiring reading a brand or grading a diff - belongs to the host agent via the skill. See - `principle.byoa-boundary`. -- **The fingerprint shape does not bend to consumers.** Flat corpus, filename - kinds, prose bodies. Any feature that needs the artifact to change shape - for one consumer is a leak. See `docs/purposes.md`. - -Where this fingerprint is silent (visual design of the docs site, vessel's -component aesthetics), proceed from local convention and label the choice -provisional. For anything that changes the public package's shape or -vocabulary, ask a human. diff --git a/.ghost/manifest.yml b/.ghost/manifest.yml deleted file mode 100644 index 20111829..00000000 --- a/.ghost/manifest.yml +++ /dev/null @@ -1,2 +0,0 @@ -schema: ghost.fingerprint-package/v1 -id: ghost diff --git a/.ghost/principle.byoa-boundary.md b/.ghost/principle.byoa-boundary.md deleted file mode 100644 index 462e375c..00000000 --- a/.ghost/principle.byoa-boundary.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -description: The line between the deterministic CLI and the interpreting agent. Gather when adding or changing any CLI command, flag, or emitted packet. -materials: - - packages/ghost/src/cli.ts - - docs/purposes.md ---- - -Ghost is BYOA: the host agent reads, decides, and writes; the CLI grounds -that work deterministically. Every feature lands on one side of this line. - -The CLI side: validation, the gather menu, node pulls, event tapes, packet -assembly. Repeatable, no LLM, same output for the same input. Its emissions -are evidence for an agent, never verdicts: `ghost review` assembles an -advisory packet; it does not grade the diff. Probes run shell commands and -report output as evidence only. - -The agent side: selecting nodes against a task, interpreting prose, -grading review packets, authoring fingerprints. This lives in the skill -bundle, never in CLI code. - -When a proposed feature needs the CLI to interpret meaning, rank by -relevance beyond mechanical matching, or pass/fail on prose, it belongs in -the skill instead. When a proposed skill step is repeatable and mechanical, -move it into the CLI so agents cannot do it inconsistently. - -A consumer may read the fingerprint through any projection it likes; it may -not change the shape of the fingerprint to suit itself. The shape test lives -in `docs/purposes.md`. diff --git a/.ghost/principle.voice.md b/.ghost/principle.voice.md deleted file mode 100644 index ec82fff6..00000000 --- a/.ghost/principle.voice.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -description: How Ghost's own prose sounds. Gather before writing docs, CLI output, README copy, skill recipes, or changesets. -materials: - - README.md - - packages/ghost/src/skill-bundle/references/capture.md ---- - -Ghost's prose is plain, precise, restrained, and product-minded. When -completeness and compactness compete, compactness wins; link out for depth -instead of inlining it. - -Concrete over aspirational: name the decision a truth forces, not the value -it serves. "The CLI does repeatable work with no LLM" beats "we believe in -deterministic tooling." - -Teach terms by example before defining them. A worked node body carries more -than a paragraph about node bodies; the README leads with a real `.ghost/` -listing, not a concept diagram. - -No em dashes in shipped prose. Short sentences, active voice, present tense. -Changesets are one sentence, user-facing, present tense. - -The vocabulary is versioned and enforced: `scripts/check-terminology.mjs` -fails the build on retired terms. When renaming a concept, retire the old -word everywhere in the same change and add it to the forbidden list. diff --git a/CLAUDE.md b/CLAUDE.md index f2bc09ff..e8e93704 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,6 +91,7 @@ edits and checks. | `packages/ghost` | yes: `@design-intelligence/ghost` | The public package. Ships the `ghost` CLI, node authoring, corpus validation, gather/pull/pulse, review packet assembly, and the unified skill bundle. Shared runtime lives in `packages/ghost/src/ghost-core`. | | `packages/vessel-react` | no | A standalone shadcn component registry plus `vessel-mcp` MCP server: the opinionated default reference body. Design-system-agnostic; nothing in Ghost requires it. | | `packages/vessel-light` | no | Vessel's design language as a portable `.ghost/` fingerprint package for agents writing raw HTML/CSS. No build, no dependencies. | +| `packages/steering-eval` | no | Before/after evaluation harness: measures what handing an agent a `.ghost` fingerprint buys, as a deterministic `report.html`. | | `apps/docs` | no | Docs site. | ## CLI Commands @@ -99,13 +100,14 @@ Core workflow: | Command | Description | | --- | --- | -| `ghost init` | Scaffold `.ghost/` with a manifest, starter glossary, and a starter `index.md`. `--with checks` also adds the checks directory. | +| `ghost init` | Scaffold `.ghost/` with the skeleton starter: manifest, glossary, `index.md`, grammar nodes, and unanswered signature dials. `--template minimal` writes only the manifest/glossary/index starter; `--body vessel-light` installs a full inhabited fingerprint instead. `--with checks` also adds the checks directory. | | `ghost checks init` | Scaffold `.ghost/checks/` with an example review assertion. | | `ghost validate` | Validate the package: manifest shape, node validity, material locators, check references, and glossary kind prefixes. | | `ghost gather [ask…]` | Emit the fingerprint menu for the agent to select from. | | `ghost pull […]` | Emit selected nodes' bodies and materials; append the selection to the local `.ghost/.events` tape. | | `ghost review` | Emit an advisory review packet for a diff using material-backed nodes and checks (requires `.ghost/checks/`). | | `ghost pulse` | Summarize local gather/pull events from `.ghost/.events`. | +| `ghost export` | Package the fingerprint as a portable tarball with a materials audit (`--strict` fails on stranded locators). | | `ghost skill install` | Install the unified `ghost` skill bundle. | Advanced/maintenance: @@ -151,6 +153,14 @@ Use `patch` for fixes and docs, `minor` for new commands/flags/exports, and ## Conventions +- Shipped prose is plain, precise, restrained, and product-minded. When + completeness and compactness compete, compactness wins; link out for depth. + Concrete over aspirational: name the decision a truth forces, not the value + it serves. Teach terms by worked example before defining them. No em dashes, + no brand-deck filler, no exclamation points. `scripts/check-terminology.mjs` + enforces the retired-vocabulary list; run `pnpm check:terminology` before + pushing, and when renaming a concept, retire the old word everywhere in the + same change and add it to the forbidden list. - Keep publishable runtime code self-contained in `packages/ghost`; no `workspace:*` runtime dependencies in the packed public artifact. - The canonical on-disk form is a flat `.ghost/` package: `manifest.yml` plus diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6f28a5d..3c3f390c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,9 @@ # Contributing to Ghost -Ghost is pre-1.0 and moving fast. This doc is organized around what gets a -PR declined, because that's the information you actually need. Everything -below is enforced — by review, by CI, or both. +Contributions are welcome: fixes, docs, dogfooding reports, and friction you +hit as a user are all valuable. Ghost is pre-1.0 and moving fast, so this doc +is organized around what gets a PR declined, because that's the information +you need. Everything below is enforced by review, by CI, or both. ## Invariants @@ -10,8 +11,9 @@ These are project-defining. A PR that violates one gets declined regardless of quality elsewhere. 1. **The CLI computes; it never decides.** No LLM calls in the CLI, ever. - Ghost is BYOA: the host agent does all interpretive work. The CLI's value - is determinism — same input, same output, no key required. + Ghost is BYOA (bring your own agent): the host agent does all interpretive + work. The CLI's value is determinism: same input, same output, no key + required. 2. **The fingerprint corpus stays flat.** No hierarchy, no inheritance, no edges between nodes. A node's identity is its filename; its kind is a glossary-declared prefix. Altitude lives in prose, not structure. @@ -26,12 +28,12 @@ of quality elsewhere. `scripts/check-terminology.mjs` fails CI on banned phrasings. The script is the source of truth; these are the clusters and their reasons: -- **The "memory" compounds.** Ghost holds nothing — an agent holds nothing it +- **The "memory" compounds.** Ghost holds nothing; an agent holds nothing it isn't handed. The fingerprint is a steering packet, not recall. - **The "judg-" words.** The CLI computes; the host agent decides. Review output is advisory. -- **Product-UI-centric framing.** Ghost is brand through every medium — - screens, emails, empty states, sentences — so phrases that anchor it to +- **Product-UI-centric framing.** Ghost is brand through every medium + (screens, emails, empty states, sentences), so phrases that anchor it to product UI alone are banned. - **Bare next-major version markers.** No speculative roadmap language in the tree. @@ -48,7 +50,7 @@ the list. - Added, removed, or renamed a CLI command or flag? Run `pnpm dump:cli-help` and commit the regenerated manifest, or the drift check declines for you. - **Changesets:** `@design-intelligence/ghost` is the only public - package. Write the changeset file yourself — `patch` for fixes and docs, + package. Write the changeset file yourself: `patch` for fixes and docs, `minor` for new commands/flags/exports, `major` for removed or renamed public behavior. One sentence, user-facing, present tense. @@ -57,7 +59,7 @@ the list. Surfaces in this repo carry their own fingerprints: `apps/docs/.ghost` and `packages/vessel-react/.ghost`. If you touch a surface, `ghost gather` from its fingerprint before you build, and expect review against it. This is where -you experience Ghost as a user — treat friction you hit here as a bug worth +you experience Ghost as a user; treat friction you hit here as a bug worth reporting. ## Governance diff --git a/README.md b/README.md index 83d933a6..165d5cf3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Ghost **Ghost is your brand, packed for agents.** A `.ghost/` folder of plain-prose -truths — your stance, your voice, your trust moves — checked into the repo and +truths (your stance, your voice, your trust moves) checked into the repo and read by any agent before it makes anything: a screen, an email, an empty state, a sentence. @@ -13,27 +13,13 @@ state, a sentence. asset.logo.md # points at the actual SVGs ``` -Today those decisions live in reviewers' heads — "that's not our voice," again, +Today those decisions live in reviewers' heads: "that's not our voice," again, on every surface. The agent that built the thing never saw them. Ghost writes them down once, where the agent looks first. One portable packet; Claude Code, Codex, Cursor, and Goose all read the same one. One package, `@design-intelligence/ghost`. One CLI, `ghost`. -## Thesis - -Agents changed the unit of design work. When they make the screens, the -emails, and the sentences, polishing any one of them moves nothing; the next -generation starts from the model's average again. The work that compounds is -architectural: decide where that average serves, decide where the brand must -win, and put those decisions where the agent reads before it makes. - -Ghost is that artifact: a fingerprint checked into the repo, carrying the -truths, the materials they point at, and the conditions they hold under. -Buttons stay buttons. The moments that carry your brand get your stance -instead of the default. The few author it once. Every agent it travels to -builds from it. - [Documentation](https://block.github.io/ghost/) · [npm](https://www.npmjs.com/package/@design-intelligence/ghost) ## Install @@ -43,9 +29,6 @@ npm install -D @design-intelligence/ghost npx ghost skill install ``` -Every `ghost` command is also available as `ghost-fingerprint` when another tool -on your machine owns the `ghost` bin. - ## Use It Ghost is **bring-your-own-agent**. Install the skill bundle so Claude Code, @@ -59,41 +42,43 @@ Brief this work from the Ghost fingerprint. Review this diff against the Ghost checks. ``` -The CLI does deterministic work. The agent does interpretation. +Ghost never calls an LLM itself; your agent does the thinking. No API key, +no lock-in. ## The Loop ```bash -ghost init # scaffold .ghost/ with the steering starter (fingerprint only) +ghost init # scaffold .ghost/ with the skeleton starter ghost checks init # opt in to review assertions -ghost validate # check package shape, nodes, materials, and checks -ghost gather # before building: list every node for this task +ghost validate # make sure the fingerprint is well-formed +ghost gather # before building: list every truth relevant to this task ghost pull # read the picked truths' full bodies -ghost review # during review: assemble a diff + matched nodes + checks packet -ghost export # package the fingerprint as a portable artifact with a locator audit -ghost pulse # while tuning: summarize local gather/pull events +ghost review # during review: match a diff to truths and checks +ghost export # package the fingerprint as a portable artifact +ghost pulse # while tuning: see what agents reached for ``` -`gather` and `pull` append structured JSONL events to `.ghost/.events`, a gitignored events tape. That's for tuning descriptions and seeing what agents reached -for. The events tape is local tuning signal, not canonical fingerprint state. +Ghost keeps a private local log of what agents reached for; `ghost pulse` +reads it so you can tune descriptions. It stays on your machine and never +enters version control. + +Run `ghost --help` for the core workflow and `ghost --help` for +flags; the [CLI reference](https://block.github.io/ghost/docs/cli) covers +every command. -## CLI Commands +## Thesis -| Command | Description | -| --- | --- | -| `ghost init` | Scaffold `.ghost/` with the steering starter: manifest, glossary, `index.md`, and demo nodes for stance, composition, anti-goals, patterns, exemplars, materials, and decisions. `--template minimal` writes only the small manifest/glossary/index starter. `--with checks` also adds the checks directory. | -| `ghost checks init` | Scaffold `.ghost/checks/` with an example review assertion. | -| `ghost validate` | Validate the package: manifest, node validity, material locators, check references, and glossary kind prefixes. | -| `ghost gather [ask…]` | Emit the fingerprint menu for the agent to select from; log the exposed ids. Wild-posture kinds are excluded by default; `--wild` opts in. | -| `ghost pull […]` | Emit selected node bodies and material locators; log selected and missed ids. | -| `ghost review` | Emit an advisory review packet from a diff, matched material-backed nodes, and checks (requires `.ghost/checks/`). | -| `ghost export` | Package the fingerprint as a portable artifact with a locator audit. | -| `ghost pulse` | Summarize local gather/pull events: abandoned gathers, hit rates, cold nodes, and misses. | -| `ghost skill install` | Install the skill bundle for your host agent. | -| `ghost manifest` | Emit a self-describing JSON manifest of commands and flags _(advanced)_. | +Agents changed the unit of design work. When they make the screens, the +emails, and the sentences, polishing any one of them moves nothing; the next +generation starts from the model's average again. The work that compounds is +architectural: decide where that average serves, decide where the brand must +win, and put those decisions where the agent reads before it makes. -Run `ghost --help` for the core workflow, `ghost --help --all` for everything, -and `ghost --help` for flags. +Ghost is that artifact: a fingerprint checked into the repo, carrying the +truths, the materials they point at, and the conditions they hold under. +Buttons stay buttons. The moments that carry your brand get your stance +instead of the default. The few author it once. Every agent it travels to +builds from it. ## How It Works @@ -126,10 +111,11 @@ Use the full lockup when recognition matters. Use the glyph only when space is constrained or when brand presence should recede. ``` -`materials` is one list of locators for the concrete stuff the truth is about: -repo-relative paths/globs or absolute HTTPS URLs. Components, patterns, logos, -motion files, illustrations, and external asset libraries all use the same field. -Guidance stays in prose; `materials` only says where the material is. +`materials` is a list of paths or URLs pointing at the concrete stuff the +truth is about: repo-relative paths/globs or absolute HTTPS URLs. Components, +patterns, logos, motion files, illustrations, and external asset libraries all +use the same field. Guidance stays in prose; `materials` only says where the +material is. **Checks** are optional review assertions in a flat `.ghost/checks/` directory. Core `ghost init` ships no checks; add them explicitly: @@ -152,15 +138,13 @@ references: Grade whether the change preserves the logo guidance in `asset.logo`. ``` -`ghost gather` and `ghost pull` are feed-forward. `ghost review` is feed-back: it -reads a diff, matches touched files to node `materials`, offers relevant checks, -and emits an advisory packet for the host agent to weigh. - -Reserved at the package root: `manifest.yml`, `glossary.md`, and `checks/`. -Every other `*.md` is a node. Renaming a node changes its id. +`gather` and `pull` run before your agent builds. `review` runs after: it +reads a diff, matches touched files to node `materials`, offers relevant +checks, and emits an advisory packet for the host agent to weigh. Review +output never enters generation context. -The packet is the product; the CLI is the courier. Everything above — -gather, pull, review, checks, the events tape — is machinery around the +The packet is the product; the CLI is the courier. Everything above +(gather, pull, review, checks, the local log) is machinery around the fingerprint, and the fingerprint outlives all of it. ## Portable by Design @@ -171,10 +155,10 @@ sentence), and repo-native (it moves with a clone, a fork, a new hire's first checkout). When you need it as a standalone artifact: ```bash -ghost export # package the fingerprint as a portable brand artifact, with a locator audit +ghost export ``` -The export audits every `materials` locator so the packet doesn't silently +The export audits every `materials` entry so the packet doesn't silently point at things that moved. ## Project Status: Beta @@ -188,9 +172,10 @@ point at things that moved. | Path | Role | Published? | | ---- | ---- | --- | -| [`packages/ghost`](./packages/ghost) | The public `ghost` CLI, node authoring, corpus validation, gather/pull, review packet assembly, and the skill bundle. | yes: `@design-intelligence/ghost` | +| [`packages/ghost`](./packages/ghost) | The public `ghost` CLI, node authoring, fingerprint validation, gather/pull, review packet assembly, and the skill bundle. | yes: `@design-intelligence/ghost` | | [`packages/vessel-react`](./packages/vessel-react) | A standalone shadcn component registry plus `vessel-mcp` MCP server. | no | | [`packages/vessel-light`](./packages/vessel-light) | Vessel's design language as a portable `.ghost/` fingerprint for agents writing raw HTML/CSS. | no | +| [`packages/steering-eval`](./packages/steering-eval) | Before/after evaluation harness: measures what a `.ghost` fingerprint buys as a self-contained `report.html`. | no | | [`apps/docs`](./apps/docs) | Docs site. | no | ## Development @@ -203,7 +188,8 @@ pnpm check pnpm dump:cli-help ``` -No API key is required to run Ghost. +Every `ghost` command is also available as `ghost-fingerprint` when another +tool on your machine owns the `ghost` bin. ## License diff --git a/apps/docs/src/content/docs/cli-reference.mdx b/apps/docs/src/content/docs/cli-reference.mdx index 26d17987..d563a26f 100644 --- a/apps/docs/src/content/docs/cli-reference.mdx +++ b/apps/docs/src/content/docs/cli-reference.mdx @@ -235,6 +235,35 @@ advice for the reviewing agent, not an enforcement level. + + +### Package a portable artifact: `export` + +`export` packages the fingerprint as a portable brand artifact: a tarball of +the `.ghost/` directory plus a stamped `export.yml` (schema, package id, CLI +version, export time). The events tape stays out of the archive; pass +`--no-checks` to leave the checks directory out too. + +The export also audits every node's `materials` entry and reports which ones +travel with the archive (bundled files and URLs) and which are **stranded**: +repo-relative paths that point outside the package and won't exist wherever +the archive lands. Stranded entries are reported, not fatal; pass `--strict` +to exit `2` when any exist. + +`export` refuses to package a fingerprint with validation errors. Run +`ghost validate` and fix them first. + + + +```bash +ghost export # write -fingerprint.tgz with an audit summary +ghost export --out dist/brand.ghost.tgz +ghost export --strict # fail if any materials won't travel +ghost export --format json # audit as JSON for host tooling +``` + + + ### Install the skill: `skill` diff --git a/apps/docs/src/content/docs/getting-started.mdx b/apps/docs/src/content/docs/getting-started.mdx index 3dd3cebe..c26c001b 100644 --- a/apps/docs/src/content/docs/getting-started.mdx +++ b/apps/docs/src/content/docs/getting-started.mdx @@ -1,6 +1,6 @@ --- title: Getting Started -description: Install Ghost, author a brand fingerprint as a flat set of prose truths, and gather the right context before your agent builds. +description: Install Ghost, write your brand's truths as prose, and give your agent the right context before it builds. kicker: Docs section: guide order: 10 @@ -11,7 +11,7 @@ slug: getting-started -Start with [Five-Minute Ghost](/docs/quickstart) — one file, one repeated +Start with [Five-Minute Ghost](/docs/quickstart): one file, one repeated decision, no vocabulary. This guide is the full loop for when you're ready to author a glossary and gather context end to end. @@ -19,31 +19,31 @@ author a glossary and gather context end to end. Ghost is your brand as a **portable steering packet**: its truths, its stance, its conditions, written as prose your agent reads **before** it makes anything. -A truth is stated once, at the altitude it is actually true, and the agent -manifests it into whatever it is making — a screen, an email, a landing page, a +A truth is stated once, at the altitude where it holds, and the agent +manifests it into whatever it is making: a screen, an email, a landing page, a sentence. The packet is agent-agnostic and travels with the repo. The public package is `@design-intelligence/ghost`, and it installs one CLI: `ghost`. -The core loop is **feed-forward**: it grounds generation before your agent -builds. An optional feed-back side — the checks directory and `ghost review` — -assembles advisory review packets after, but never grades output itself. You -work through a short loop: +The core loop grounds generation **before** your agent builds. An optional +review side, the checks directory and `ghost review`, helps the same agent +check its work **after**, but Ghost never grades output itself. You work +through a short loop: ```bash ghost init # scaffold .ghost/ with the skeleton starter -ghost validate # artifact shape + node validity + kind-prefix check +ghost validate # make sure the fingerprint is well-formed ghost gather # emit the menu for this task; your agent selects the truths it needs ghost pull # read the selected truths' full bodies ghost pulse # inspect the local signal while tuning the fingerprint ``` When you want review assertions too, opt in with `ghost checks init` and -run `ghost review` against a diff — [Checks And Review](/docs/checks-and-review) +run `ghost review` against a diff; [Checks And Review](/docs/checks-and-review) covers that side of the loop. -The CLI does the deterministic work; your agent does the interpretation. The -rest of this guide walks the loop; the **How It Works** section at the end -covers the data model underneath it. +Ghost never calls an LLM itself; your agent does the thinking, so there's no +API key and no lock-in. The rest of this guide walks the loop; the **How It +Works** section at the end covers the model underneath it. @@ -73,14 +73,19 @@ The skill tells the agent what to read, what to write, and how to gather. Start with one truth, not the whole brand. The hardest part is picking the first -one, so pick the decision whose review feedback you keep repeating — the checkout -you always flag for trust, the voice you always re-tone, the empty state you -always rewrite. Write that one down as a node, and grow the fingerprint decision +one, so pick the decision whose review feedback you keep repeating: the checkout +you flag for trust, the voice you re-tone, the empty state you +rewrite. Write that one down as a node, and grow the fingerprint decision by decision. One high-confidence truth beats an empty catalog. -The CLI handles the deterministic package work. Your agent handles the authoring: -interviewing you, working with the material you show it, drafting node prose, -and asking you to curate the claims. `ghost init` stamps `anti-goal.median` into every template and body; the median node is Ghost's measured knowledge of unsteered model behavior — model truth, not brand truth — owned (pruned, adapted) by you after init. The skeleton starter also includes `manifest.yml`, a `glossary.md` declaring the grammar/signature/register/anti-goal kinds, a core `index.md`, six grammar nodes of value-free decision logic, and four signature nodes as unanswered dials. Nothing in the skeleton is fiction: grammar and the median floor hold for any brand, and each dial tells the agent to ask you or flag the gap rather than freehand a value. Answering the dials is how the skeleton becomes your brand. Use `ghost init --template minimal` when you only want the small manifest/glossary/index starter. +The CLI scaffolds; your agent authors: interviewing you, working with the +material you show it, drafting node prose, and asking you to curate the claims. +`ghost init` writes a starter you adapt: a glossary, an index, truths that hold +for any brand, and a few files left as unanswered **dials** that +tell the agent to ask you rather than invent a value. Answering the dials is how +the starter becomes your brand. Prefer a bare start? `ghost init --template +minimal` writes only the manifest, glossary, and index. The full starter +anatomy is in the [CLI reference](/docs/cli). ```bash ghost init @@ -88,7 +93,7 @@ ghost validate ``` Prefer starting from a working brand instead of an empty anatomy? Install a -**body** — the same skeleton with a real brand's values plugged in: answered +**body**, the same skeleton with a real brand's values plugged in: answered dials, a `materials/` tree with tokens and fonts, worked reference compositions, and its own checks: @@ -96,21 +101,21 @@ compositions, and its own checks: ghost init --body vessel-light ``` -The body's manifest keeps its own id (`vessel-light`) until you adapt it — -renaming the id is deliberately the first step of making the brand yours. +The body's manifest keeps its own id (`vessel-light`) until you adapt it; +renaming the id is the first step of making the brand yours. Each node's prose records a durable brand truth. While drafting, ask three -questions of every truth: **why** (the stance — what this brand is, who it -serves, what must remain true), **with what** (the materials — building blocks, +questions of every truth: **why** (the stance: what this brand is, who it +serves, what must remain true), **with what** (the materials: building blocks, files, assets, and source links agents may inspect or use), and **how it is -assembled** (the patterns that make it intentional — hierarchy, density, +assembled** (the patterns that make it intentional: hierarchy, density, restraint, repetition, trust, and flow). These are drafting prompts, never frontmatter fields. Node frontmatter carries only `description` plus free-form passthrough keys. A node's **kind** comes from its filename prefix (`principle.density.md` → kind `principle`), and the kinds are declared in `glossary.md`. When a truth is -narrower than universal, state its **condition** in the prose — the situation it +narrower than universal, state its **condition** in the prose: the situation it applies in, never a filename destination. For a fuller human-agent workflow, read [Fingerprint Authoring](/docs/fingerprint-authoring). @@ -118,7 +123,7 @@ applies in, never a filename destination. For a fuller human-agent workflow, rea -Before generating, gather the fingerprint menu. `gather` does no selection — it +Before generating, gather the fingerprint menu. `gather` does no selection: it emits every node's id, kind, and description, and your agent reads the ask against it and pulls the truths it judges relevant: @@ -133,10 +138,11 @@ against the actual task, then manifests the truths into whatever it is building. Run it before generation, so the agent builds with the brand in hand rather than discovering the gaps in review. -Each `gather` and `pull` also appends a structured JSONL event to -`.ghost/.events`, a gitignored events tape. That one is for you: tweak a node's -description, re-run the task, and `ghost pulse` shows whether the truth appeared -on the menu, got pulled, was missed by name, or stayed cold. +Each `gather` and `pull` also adds a line to a private local log at +`.ghost/.events`; it stays on your machine and never enters version control. +That one is for you: tweak a node's description, re-run the task, and `ghost +pulse` shows whether the truth appeared on the menu, got pulled, was missed by +name, or stayed cold. ```bash ghost pulse @@ -145,14 +151,15 @@ ghost pulse Read `pulse` as a tuning signal, not a score. A cold node may need a sharper `description`; a repeated miss may mean the id or glossary vocabulary is not what agents expect; an abandoned gather means the menu did not lead to a useful -selection. The events tape is local tuning signal, not canonical fingerprint state. +selection. The log is local tuning signal, not canonical fingerprint state. -`ghost validate` checks the package deterministically: artifact shape, per-node -validity, and that each node's kind prefix is declared in the glossary. +`ghost validate` checks that the fingerprint is well-formed: the manifest and +each node parse, `materials` entries resolve, and every node's kind prefix is +declared in the glossary. ```bash ghost validate @@ -167,7 +174,7 @@ edits are drafts; checked-in nodes are canonical. -You can run the whole loop above without this section — your agent handles the +You can run the whole loop above without this section; your agent handles the format. Read on when you want to understand how the folder of files is wired. The fingerprint is a **flat set of prose nodes**: @@ -188,7 +195,7 @@ There is no hierarchy, no inheritance, and no edges between nodes. A node's identity is its file path with `.md` dropped (`marketing.email.md` is the node `marketing.email`). Its **kind** is the filename's first dotted segment, and must be a kind declared in `glossary.md`; a bare name (`voice.md`) has -no kind. Folders are a human-browsing convenience only — the model reads a +no kind. Folders are a human-browsing convenience only; the model reads a flat menu. Altitude lives in the prose: a universal truth is stated plainly; a narrower diff --git a/apps/docs/src/content/docs/quickstart.mdx b/apps/docs/src/content/docs/quickstart.mdx index 15843a63..5f80cd3a 100644 --- a/apps/docs/src/content/docs/quickstart.mdx +++ b/apps/docs/src/content/docs/quickstart.mdx @@ -12,14 +12,14 @@ slug: quickstart You keep leaving the same review comment. "Don't introduce a new button style on checkout." "This empty state needs a way -out, not just a message." "Slow down — this form is doing three things at once." +out, not just a message." "Slow down, this form is doing three things at once." Your agent can build the screen. What it can't do is remember the decision you'd make when it does. So you catch the same drift in review, every time, on every surface. -Ghost is one move against that: **write the decision down once, in your repo, and -your agent reads it before it builds** — not after you flag it. +Ghost is one move against that: **write the decision down once, in your repo, +and your agent reads it before it builds.** @@ -38,18 +38,18 @@ Then ask your agent, in plain English: Set up Ghost for this repo, starting with the checkout surface. ``` -That's it. Your agent scaffolds a small `.ghost/` folder and writes your first -file. You don't need to learn the format to start — you just need to know which -decision you keep repeating. +Your agent scaffolds a small `.ghost/` folder and writes your first file. You +don't need to learn the format to start, only to know which decision you keep +repeating. - + Pick the one decision whose feedback you repeat most. Say it's about trust at checkout. Your agent writes that as a single small file, -`.ghost/principle.trust.md` — the filename's first segment (`principle`) is its -*kind*, declared in the package's `glossary.md`: +`.ghost/principle.trust.md`; the name tells future readers what kind of truth +it is: ```markdown --- @@ -57,16 +57,16 @@ description: Trust at the payment moment. --- Near the moment of payment, reduce felt risk. Keep reassurance close to the -action — proximity beats completeness. Never introduce a new visual system here. +action; proximity beats completeness. Never introduce a new visual system here. ``` A few lines of plain prose, checked into your repo next to the code. That's the -whole artifact. No schema to memorize, no config to wire up. You wrote the -comment you were going to leave anyway — once, in a place your agent can read. +whole artifact: the comment you were going to leave anyway, written once, in a +place your agent can read. - + Now the loop runs the other direction. Before your agent builds on checkout, it reads what you wrote: @@ -76,26 +76,25 @@ Brief this checkout change from Ghost first. ``` The comment you used to leave in review is now context the agent has up front. -That's the entire idea: **give the agent the decision before it builds, not -after.** +The agent gets your decision before it builds. -And notice what you actually made. That file isn't a note about one screen — -it's the first truth in a **portable steering packet**. The same +And notice what you made: the first truth in a **portable steering packet**, +not a note about one screen. The same `principle.trust.md` steers the confirmation email, the receipt page, the -error message when the card declines. Any agent reads it — Claude Code, Codex, -Cursor, Goose — and it travels with every clone and fork of the repo. +error message when the card declines. Any agent reads it (Claude Code, Codex, +Cursor, Goose) and it travels with every clone and fork of the repo. Don't fingerprint the whole brand. One good file beats an empty catalog. The -next time you catch yourself repeating a decision — the settings form you always -re-pace, the voice you always re-tone — write that one down too. The fingerprint +next time you catch yourself repeating a decision (the settings form you +re-pace, the voice you re-tone), write that one down too. The fingerprint grows decision by decision. -When you're ready for the full workflow — the glossary, gathering context, -validating — read [Getting Started](/docs/getting-started). When you want to know +When you're ready for the full workflow (the glossary, gathering context, +validating), read [Getting Started](/docs/getting-started). When you want to know how the folder of files works underneath, that guide's **How It Works** section has it. You don't need either to get your first win. diff --git a/packages/ghost/README.md b/packages/ghost/README.md index 82db75cc..4c9ed295 100644 --- a/packages/ghost/README.md +++ b/packages/ghost/README.md @@ -1,56 +1,75 @@ # @design-intelligence/ghost -**Your brand, packed for agents: a portable steering packet of prose truths, -checked into the repo, read before anything is made and reviewable after.** +**Ghost is your brand, packed for agents.** A `.ghost/` folder of plain-prose +truths (your stance, your voice, your trust moves) checked into the repo and +read by any agent before it makes anything: a screen, an email, an empty +state, a sentence. -This package ships one CLI: `ghost`. Every command is also available as -`ghost-fingerprint` for when another tool owns the `ghost` bin. +Today those decisions live in reviewers' heads: "that's not our voice," again, +on every surface. The agent that built the thing never saw them. Ghost writes +them down once, where the agent looks first. -The scope is the thesis: the few still write the taste; they no longer gate it. -You hand the brand over as a packet of authority that travels to wherever work -ships. +[Documentation](https://block.github.io/ghost/) ## Install ```bash npm install -D @design-intelligence/ghost -npx ghost --help +npx ghost skill install ``` -## Shape +## Use It + +Ghost is **bring-your-own-agent**. Install the skill bundle so Claude Code, +Codex, Cursor, Goose, or another host agent knows how to author and use the +fingerprint, then ask in plain English: ```text -.ghost/ - manifest.yml # schema + package id - glossary.md # category vocabulary - index.md # front door node - principle.trust.md # prose truth - asset.logo.md # prose truth, optionally with materials - checks/ # optional review assertions; never gathered as nodes +Set up the Ghost fingerprint for this repo. +Write down the decision I keep repeating about checkout. +Brief this work from the Ghost fingerprint. +Review this diff against the Ghost checks. ``` -A node is markdown with `description`, optional `materials`, and a prose body. -`materials` accepts repo-relative paths/globs and HTTPS URLs. - -Checks live under `.ghost/checks/` (scaffold with `ghost checks init`) and -declare `references` to the nodes they review. -`ghost review` reads a diff, matches touched files to node materials, offers -relevant checks, and emits an advisory packet for the host agent. +Ghost never calls an LLM itself; your agent does the thinking. No API key, +no lock-in. -## Use +## The Loop ```bash -ghost init -ghost checks init -ghost validate -ghost gather "checkout settings" -ghost pull principle.trust -ghost review --diff=- -ghost pulse +ghost init # scaffold .ghost/ with the skeleton starter +ghost checks init # opt in to review assertions +ghost validate # make sure the fingerprint is well-formed +ghost gather # before building: list every truth relevant to this task +ghost pull # read the picked truths' full bodies +ghost review # during review: match a diff to truths and checks +ghost export # package the fingerprint as a portable artifact +ghost pulse # while tuning: see what agents reached for ``` -`ghost manifest` emits a self-describing JSON index of commands and flags. -`ghost skill install` installs the host-agent skill bundle. +Run `ghost --help` for the core workflow and `ghost --help` for +flags. + +## Shape + +```text +.ghost/ + manifest.yml # schema + package id + glossary.md # your kind vocabulary + what each kind means + index.md # the curated front door + principle.trust.md # a brand truth of kind `principle` + asset.logo.md # a truth that may point at concrete materials + checks/ # optional review assertions; separate from your truths +``` + +A node is markdown with a `description`, optional `materials`, and a prose +body. `materials` is a list of paths or URLs pointing at the concrete stuff +the truth is about. + +Checks live under `.ghost/checks/` (scaffold with `ghost checks init`) and +declare `references` to the truths they review. `ghost review` reads a diff, +matches touched files to node `materials`, offers relevant checks, and emits +an advisory packet for the host agent to weigh. ## Library @@ -70,6 +89,18 @@ Available subpath exports: `@design-intelligence/ghost`, `@design-intelligence/ghost/cli`, and `@design-intelligence/ghost/scan`. +## Project Status: Beta + +Ghost is pre-1.0 and under active development. The CLI, fingerprint schema, +on-disk `.ghost/` package shape, and public JavaScript exports may change in +breaking ways before a stable 1.0 release. Breaking changes may ship in minor +versions; patch versions are reserved for fixes that should not require +migration. Pin the version you depend on and review release notes before +upgrading. + +Every `ghost` command is also available as `ghost-fingerprint` for when +another tool owns the `ghost` bin. + ## License Apache-2.0 diff --git a/scripts/check-terminology.mjs b/scripts/check-terminology.mjs index a5f0bd14..8eecb3d5 100644 --- a/scripts/check-terminology.mjs +++ b/scripts/check-terminology.mjs @@ -14,7 +14,6 @@ const ROOTS = [ "packages/ghost/src", "packages/ghost/test", "packages/vessel-react/README.md", - ".ghost", ".changeset", ]; @@ -68,6 +67,30 @@ const FORBIDDEN_PHRASES = [ "judged", ]; +/** + * Entrance docs hold a stricter bar: implementation vocabulary that is fine in + * contributor docs and reference pages must not leak into the welcome path. + * Say "materials", "paths or URLs", "private local log", "before you build / + * when you review" instead. + */ +const ENTRANCE_DOCS = new Set([ + "README.md", + "packages/ghost/README.md", + "apps/docs/src/content/docs/quickstart.mdx", + "apps/docs/src/content/docs/getting-started.mdx", +]); + +const ENTRANCE_FORBIDDEN_PHRASES = [ + "JSONL", + "gitignored", + "events tape", + "feed-forward", + "feed-back", + "locator", + "corpus", + "deterministic", +]; + const DISALLOWED_VERSION_MARKER = `${"v"}${"2"}`; const FORBIDDEN_PATTERNS = [ @@ -98,6 +121,11 @@ const forbiddenPatterns = FORBIDDEN_PHRASES.map((phrase) => ({ pattern: new RegExp(escapeRegExp(phrase), "i"), })).concat(FORBIDDEN_PATTERNS); +const entranceForbiddenPatterns = ENTRANCE_FORBIDDEN_PHRASES.map((phrase) => ({ + phrase: `${phrase} (entrance docs)`, + pattern: new RegExp(escapeRegExp(phrase), "i"), +})); + const violations = []; for (const root of ROOTS) { @@ -105,8 +133,11 @@ for (const root of ROOTS) { if (EXCLUDED_PATHS.has(file)) continue; const content = readFileSync(file, "utf8"); const lines = content.split("\n"); + const patterns = ENTRANCE_DOCS.has(file) + ? forbiddenPatterns.concat(entranceForbiddenPatterns) + : forbiddenPatterns; lines.forEach((line, index) => { - for (const { phrase, pattern } of forbiddenPatterns) { + for (const { phrase, pattern } of patterns) { if (!pattern.test(line)) continue; if (isAllowedTerminologyUse(line, phrase)) continue; violations.push({