Skip to content

Ghost stack 3/6 — Polish cuts A–D#191

Draft
nahiyankhan wants to merge 7 commits into
ghost/02-surface-modelfrom
ghost/03-polish-cuts
Draft

Ghost stack 3/6 — Polish cuts A–D#191
nahiyankhan wants to merge 7 commits into
ghost/02-surface-modelfrom
ghost/03-polish-cuts

Conversation

@nahiyankhan

Copy link
Copy Markdown
Collaborator

Stacked PR 3 of 6 · base: `ghost/02-surface-model`

Four deferred post-cutover cuts. ⚠️ Breaking.

Contents

  • A rebuild `review` on gather + checks rails
  • B delete dormant Job-2 selection machinery
  • C remove `ghost.validate/v1` — collapse to one check format
  • D external contract references

⚠️ `76cf819` is a known build-red WIP commit mid-PR. Squash-merge this PR so `main`/the stack never lands a broken build.

Stack order

  1. ghost/01-surface-spec
  2. ghost/02-surface-model
  3. ➡️ ghost/03-polish-cuts (this PR)
  4. ghost/04-one-road
  5. ghost/05-node-graph
  6. ghost/06-cleanup

@nahiyankhan nahiyankhan force-pushed the ghost/02-surface-model branch from c12f8f1 to 4de14e2 Compare June 28, 2026 14:14
@nahiyankhan nahiyankhan force-pushed the ghost/03-polish-cuts branch from 6ecff4f to a35efe1 Compare June 28, 2026 14:14
The cutover is complete; four items were parked. A full read shows they are not
independent: review/emit still depend on BOTH validate.yml and the dormant Job 2
entrypoint (matchScopes/globalFallbackRefs), so the order matters.

- Cut A (keystone): move review/emit onto gather + checks — the one with real
  design. Until review stops consuming validate.yml and buildContextEntrypoint,
  neither can be removed.
- Cut B: delete the dormant Job 2 entrypoint, freed once A lands.
- Cut C: validate/v1 positioning — recommend keeping ghost check as the
  deterministic gate (coexisting with ghost.check/v1 markdown), a docs cut, not
  a deletion; full removal only if deterministic checks are deemed unwanted.
- Cut D: external contract references in bindings — self-contained, anytime.

Survey-module removal explicitly held back: it is imported by comparable-
fingerprint, patterns/lint, perceptual-prior, verify-fingerprint — a deep
separate excavation, not a near-term cut. Sequence: A first, then B/C, D anytime.
The keystone polish cut. review no longer consumes validate.yml or the dormant
Job 2 context entrypoint (buildContextEntrypoint/buildSelectedContext) — it now
runs on the surface model:

- Resolve the diff's changed paths to touched surfaces (Phase 7a bindings).
- Select the markdown checks governing those surfaces and ancestors (Cut 3).
- Ground each in the fingerprint slice (Cut 4): why + what good looks like.

The advisory-review packet drops fingerprint/context_markdown/checks/stacks in
favor of touched_surfaces, routed_checks, and grounding (markdown + json).
emit/review-command already built from the package context (not the dormant
entrypoint), so it is unchanged. ghost check stays the deterministic gate.

This frees the dormant entrypoint and selected-context modules — they now have
zero non-context importers (Cut B's deletion target, now unblocked). Tests
updated to the surface-based packet. Full suite green (429 passed). Major
changeset (advisory-review JSON shape change).
…ut B)

Pure deletion, unblocked by Cut A. The path-selection graph (matchScopes,
globalFallbackRefs, appliesTo scoring) was made inert in Phase 3 and kept alive
only by review's old packet; Cut A removed that last caller.

Deleted: context/entrypoint.ts, selected-context.ts, selection-reasons.ts,
graph.ts. They formed a closed island importing only each other + the surviving
package-context. context/ now holds just package-context and
package-review-command (both still used by emit). No public export touched;
patch changeset. Full suite green (429 passed).
… format)

User settled it: two check formats make no sense, default to markdown. Escalates
Cut C from positioning to full removal. Verified the key assumption: the drift
stance ledger (gate.ts/config/evolution) is cleanly separable from the detector
gate in core/check.ts — drift-command pulls none of check.ts. Plan rescues
parseUnifiedDiff (used by the new review/checks) into a neutral home before
deleting core/check.ts, removes the ./govern export, and keeps ghost.check/v1
markdown as the single format.
Checkpoint snapshot — NOT green. Detector gate, ghost-core/checks, govern, the
check command, file-kind, init, package-context, package-review-command done;
parseUnifiedDiff rescued to scan/unified-diff.ts. Remaining: scan-status,
fingerprint-stack, verify-package, fingerprint-contribution (validate woven in
as a scan stage / contribution count / verify dimension / stack plumbing).
… (Polish Cut C)

Default down to a single check format: markdown ghost.check/v1, routed by surface
(ghost checks) and grounded by the fingerprint (ghost review). The deterministic
detector gate is gone.

Removed:
- ghost.validate/v1: ghost-core/checks/ (schema, types, lint, routing),
  GhostValidateSchema, GhostCheck, routeGhostValidateForPath.
- the validate.yml facet: from init scaffolding, FingerprintPackagePaths, the
  loader, file-kind detection/dispatch, scan-status (the validate stage),
  fingerprint-contribution (the validate facet + counts), verify-package
  (check-ref verification), and the fingerprint stack.
- the ghost check command and core/check.ts (detector evaluation,
  runGhostDriftCheck, inline-color-literals).
- the ./govern public export and govern.ts.

Rescued: parseUnifiedDiff moved to scan/unified-diff.ts (used by review/checks),
so the diff road is unaffected. The drift stance ledger (gate.ts/config/
evolution) is cleanly separate and untouched.

Tests: deleted checks-grounding and ghost-core/checks suites; removed ghost
check / validate.yml cases; updated init/scan/review/public-exports assertions
to the surface model. Skill bundle teaches the single markdown check format.
Full suite green (391 passed). Major changeset.
A .ghost.bind.yml contract: now accepts an npm package name (@scope/brand) in
addition to . (in-repo), resolved filesystem-only from node_modules. The last
deferred polish cut.

- classifyContractReference (ghost-core/binding/contract-ref.ts): . is in-repo,
  a valid npm name is npm, paths/urls/resource-ids are unsupported. Lint accepts
  in-repo or npm, rejects the rest.
- resolveContractDir (scan/contract-resolver.ts): . -> repoRoot/.ghost; npm name
  -> nearest node_modules/<name>/.ghost walking up to the git root; null on miss.
- verify-package: an adjacent .ghost.bind.yml with an external contract is
  validated — the package resolves (binding-contract-unresolved) and each bound
  surface exists in its surfaces.yml (binding-surface-unknown).

Scope held: resolution + validation only. No external fingerprint loading in
gather/checks/review (use --package), no resource-id resolvers, no version
pinning. The in-repo . path is unchanged.

12 new tests (classify/lint + resolver) + updated binding-schema assertions.
Full suite green (404 passed). Minor changeset.
@nahiyankhan nahiyankhan force-pushed the ghost/03-polish-cuts branch from a35efe1 to a0ae6cb Compare June 29, 2026 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant