Skip to content

Ghost stack 5/6 — Node/graph model (unify-nodes, Phases 1–7)#193

Draft
nahiyankhan wants to merge 12 commits into
ghost/04-one-roadfrom
ghost/05-node-graph
Draft

Ghost stack 5/6 — Node/graph model (unify-nodes, Phases 1–7)#193
nahiyankhan wants to merge 12 commits into
ghost/04-one-roadfrom
ghost/05-node-graph

Conversation

@nahiyankhan

Copy link
Copy Markdown
Collaborator

Stacked PR 5 of 6 · base: `ghost/04-one-road`

The node/graph model. ⚠️ Most breaking PR in the stack — removes the facet model and several commands.

Contents

  • `ghost.node/v1` schema, parser, serializer (Phase 1)
  • In-memory node graph + loader fold (Phase 2)
  • gather-on-graph + `--as` incarnation filter (Phase 3)
  • checks/review routed + grounded on the graph (Phase 4)
  • Remove compare/drift/fleet + direct `fingerprint.md` machinery
  • Node-based init + migrate + skill (Phase 5)
  • Remove the facet model — the graph is the only model (Phase 6)
  • Cross-package `extends` — inherit nodes by identity (Phase 7)

Stack order

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

The node artifact — markdown + frontmatter, the unit a fingerprint graph is
made of. Permissive lowercase-slug ids (dashes are the emitted convention, not
a lint rule); the tree lives only in `under`; typed-and-optional `relates`
(reinforces/contrasts/variant); optional open-enum `medium`; cross-package
`package#id` refs parsed but not resolved. Reuses a shared markdown
frontmatter splitter (lifted from the check parser). Per-node validation only;
graph rules deferred. Nothing else changes.
assembleGraph folds authored nodes/*.md (ghost.node/v1) with a lossy
facet->node projection into one in-memory GhostGraph of pure-prose nodes
(Option A): tree (under, root=core) + nodes-by-id + relates links + medium +
body. Attached additively to LoadedFingerprintPackage.graph; authored nodes win
over same-id projections. The projection is transition scaffolding marked for
deletion in the facet-removal phase. Nothing reads the graph yet — facet
loader, gather, checks, compare untouched and green.
gather now composes its slice by traversing GhostGraph (resolveGraphSlice)
instead of reading facet sections: own + cascaded ancestors + one-hop relates,
emitted as nodes-by-provenance prose (Option A). New --as <incarnation> filters
to one output form; essence (untagged) nodes always pass. Renamed the node
field medium -> incarnation across the node/graph model. Edge contributions now
come from node relates only — legacy composes/governed-by surface-edge slice
contributions are intentionally not reproduced through the graph. checks,
compare, and the facet loader remain on the facet model and stay green.
selectChecksForSurfaces now walks graph ancestry (ancestorChain) instead of the
surfaces-doc parent map. Grounding is reconceived as the gather slice:
resolveGraphSlice's prose nodes by provenance replace the typed why/what
(principles/contracts/patterns/exemplars) — the why and what live in node prose,
ensured by authoring, not extracted by Ghost. checks/review drop groundSurface
and gain optional --as incarnation filtering of grounding. Exemplar path: gone
from grounding (flagged for removal with the facet model). Skill references
updated. groundSurface/resolveSurfaceSlice remain (compare still on facets) but
have no command consumers now; deleted in the facet-removal phase.
The concepts hold; the implementations did not. compare/drift/fleet rested on a
quantified visual-design-system model (13 fixed dimensions + decision
embeddings) abandoned by the context-graph reframe (Option A, prose nodes), and
operated on a parallel direct-fingerprint.md artifact, not the .ghost graph.

Removed: compare/drift/ack/track/diverge CLI verbs; compare.ts, drift-command,
evolution-commands, comparable-fingerprint; core/ (compare, gate, evolution,
reporters); ghost-core/embedding/; decision-vocabulary, perceptual-prior;
direct-fingerprint.md machinery (parser, writer, diff, body, compose, layout,
fingerprint-load, verify-fingerprint, frontmatter, legacy types,
target-resolver); ./compare + ./drift subpaths and root compare/drift exports;
their tests and skill references.

lint now validates .ghost/ packages + node/surface/check artifacts only;
nodes/*.md lints as ghost.node/v1. Concepts parked for graph-native rethink in
docs/ideas/compare-drift-fleet-rethink.md. All green: 211 tests, full check.
…grate, node-granularity rule

init is template-driven (registry seam now, default template only; no Q&A
wizard); --reference dropped; migrate is one-way facet->nodes (projection
becomes the writer); node granularity is purpose-coherent + frontmatter-uniform
(any body length; split only when under/incarnation/relates diverge). Granularity
rule also recorded in context-graph.md as a model-level clarification.
init is template-driven (registry seam, default template): scaffolds
manifest.yml + surfaces.yml spine + a seed nodes/*.md, not facet files.
--reference dropped. migrate is one-way facet->nodes: the Phase 2
projection becomes the persistent writer (migratedNodeFiles), emitting
nodes/*.md + surfaces.yml and removing the old facet files. Skill
(capture.md, SKILL.md) teaches node authoring with intent/inventory/
composition as authoring lenses (not fields). Old facet init templates
removed. Loader still reads facet packages until the facet-removal phase.
All green: 212 tests, full check.
The loader folds nodes/*.md + surfaces.yml directly into the graph; no facet
parsing. Deleted: ghost-core/fingerprint/ (intent/inventory/composition schemas,
GhostFingerprintDocument, facet lint), the facet->node projection
(project-facets), the dormant surfaces resolve/ground/cascade, verify-package,
emit + its context modules, fingerprint-yml/facet-layer file-kinds.

Commands: lint + verify collapse into one 'validate' verb (shape pass via the
artifact linters + graph pass via new lintGraph: links resolve, one root,
acyclic). 'emit' removed. 'scan' reconceived as node/surface contribution.
Legacy facet packages fail load with 'run ghost migrate' guidance. The package
manifest schema moved to ghost-core/package-manifest.ts.

Capability dropped (Option A): structured exemplar-path + evidence verification
— evidence lives in node prose. Skill bundle + tests updated; dead facet tests
removed. All green: 163 tests, full check.
A package extends others by identity: manifest 'extends: { <id>: <dir> }' maps a
contract id to where it lives. Refs reference inherited context by identity,
never path: '<package-id>:<node>' (e.g. brand:core-trust), replacing the
npm-style <pkg>#<id> grammar. The loader resolves each extended package, verifies
its manifest id matches the key, and folds its nodes in read-only as
origin:'inherited' (ids qualified, internal tree not re-rooted; one level deep).
lintGraph + resolveGraphSlice resolve qualified refs (no more skipping); inherited
nodes are exempt from the single-root rule. New validate errors: unresolved ref,
package-not-extended, identity mismatch, cross-package cycle. extends value is an
explicit relative dir for now; discovery (by-id match) is a future upgrade that
keeps refs unchanged. Skill SKILL.md documents extends. All green: 165 tests,
full check.
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