Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .changeset/ghost-check-json-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@anarchitecture/ghost": minor
---

Add `ghost check --format json` for detector-backed markdown checks, producing `ghost.check-report/v1` findings that review orchestrators can convert into PR comments.
40 changes: 40 additions & 0 deletions apps/docs/src/content/docs/cli-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,46 @@ A mixed pull partially succeeds: known ids are emitted, unknown ids warn with cl

</DocSection>

<DocSection title="Govern Changes">

### Run deterministic checks: `check`

Run detector-backed `ghost.check/v1` checks against a unified diff and emit a
stable report. Checks without `detector:` remain agent-evaluated and are
surfaced by `ghost review`, not run by `ghost check`.

<CliHelp tool="ghost" command="check" hideDescription />

```bash
ghost check --diff change.patch --format json
ghost check --base origin/main --format json
```

The JSON report is intended for review orchestrators that own PR posting
identity:

```json
{
"schema": "ghost.check-report/v1",
"result": "fail",
"findings": [
{
"check_id": "no-palette-utilities",
"title": "No raw palette utilities",
"severity": "high",
"path": "src/features/chat/ui/GhostReviewDemo.tsx",
"line": 20,
"detector": "forbidden-regex",
"message": "Added UI code matched a forbidden pattern.",
"match": "bg-gray-100",
"repair": "Use semantic token utilities."
}
]
}
```

</DocSection>

<DocSection title="Skill And Inspection">

### Install the skill: `skill`
Expand Down
89 changes: 89 additions & 0 deletions apps/docs/src/content/docs/integrations-enterprise-review.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Enterprise review integration
slug: integrations/enterprise-review
description: How Ghost deterministic findings flow into enterprise PR review systems.
section: guide
order: 50
---

<DocSection title="Ownership Boundary">

Ghost is not a PR bot. Ghost emits deterministic design findings; your review
orchestrator owns PR discovery, diff-line mapping, status updates, and the
GitHub posting identity.

A typical enterprise lane is:

```text
PR opened or updated
Enterprise code-review routine
ghost check --package <trusted-package-dir> --diff <patch> --format json
Ghost emits deterministic findings
Review orchestrator maps findings to inline PR comments
The organization's approved review bot posts comments
```

Repo-local scripts should not call `gh pr comment` directly for Ghost review
findings when a first-party review system owns comment identity, auditability,
and branch-protection behavior.

</DocSection>

<DocSection title="Ghost Contract">

An enterprise review lane can invoke Ghost as a deterministic check engine:

```bash
ghost check --package <trusted-package-dir> --diff <patch> --format json
```

For environments that do not have `ghost` preinstalled, use a pinned npm
invocation:

```bash
npx --yes @anarchitecture/ghost@0.18.1 check \
--package <trusted-package-dir> \
--diff <patch> \
--format json
```

The JSON shape is stable for consumers:

```json
{
"schema": "ghost.check-report/v1",
"result": "fail",
"findings": [
{
"check_id": "no-palette-utilities",
"title": "No raw palette utilities",
"severity": "high",
"path": "src/features/chat/ui/GhostReviewDemo.tsx",
"line": 20,
"detector": "forbidden-regex",
"message": "Added UI code matched a forbidden pattern.",
"match": "bg-gray-100",
"repair": "Use semantic token utilities."
}
]
}
```

</DocSection>

<DocSection title="Trust Model">

Use the base branch Ghost package as trusted review policy and the PR diff as
reviewed input. A PR should not be able to change the policy that evaluates
itself by default.

For demos where a PR introduces its first Ghost package, make any head-branch
policy mode explicit in the host review system and clearly label findings as
demo-grounded. Production review lanes should use the base-branch package.

</DocSection>
46 changes: 45 additions & 1 deletion apps/docs/src/generated/cli-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"generatedAt": "2026-07-03T05:32:38.719Z",
"generatedAt": "2026-07-06T18:55:13.135Z",
"tools": [
{
"tool": "ghost",
Expand Down Expand Up @@ -76,6 +76,50 @@
}
]
},
{
"tool": "ghost",
"name": "check",
"rawName": "check",
"description": "Run deterministic ghost.check/v1 gates with detectors against a git diff.",
"group": "core",
"defaultHelp": true,
"compactName": "check",
"summary": "Run deterministic detector-backed checks against a diff.",
"options": [
{
"rawName": "--base <ref>",
"name": "base",
"description": "Git ref to diff against (default: HEAD)",
"default": null,
"takesValue": true,
"negated": false
},
{
"rawName": "--diff <patch>",
"name": "diff",
"description": "Unified diff file to check instead of running git diff. Use '-' for stdin.",
"default": null,
"takesValue": true,
"negated": false
},
{
"rawName": "--package <dir>",
"name": "package",
"description": "Use this fingerprint package directory (default: ./.ghost)",
"default": null,
"takesValue": true,
"negated": false
},
{
"rawName": "--format <fmt>",
"name": "format",
"description": "Output format: markdown or json",
"default": "markdown",
"takesValue": true,
"negated": false
}
]
},
{
"tool": "ghost",
"name": "gather",
Expand Down
2 changes: 2 additions & 0 deletions packages/ghost/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { cac } from "cac";
import { registerCheckCommand } from "./commands/check-command.js";
import { formatGhostHelp } from "./commands/command-discovery.js";
import { registerFingerprintCommands } from "./commands/fingerprint-commands.js";
import { registerGatherCommand } from "./commands/gather-command.js";
Expand All @@ -21,6 +22,7 @@ export function buildCli(): ReturnType<typeof cac> {
const cli = cac("ghost");

registerFingerprintCommands(cli);
registerCheckCommand(cli);
registerGatherCommand(cli);
registerPullCommand(cli);
registerPulseCommand(cli);
Expand Down
Loading