Ghost stack 1/6 — Layer-2 design reset & surface-model spec (docs)#189
Draft
nahiyankhan wants to merge 9 commits into
Draft
Ghost stack 1/6 — Layer-2 design reset & surface-model spec (docs)#189nahiyankhan wants to merge 9 commits into
nahiyankhan wants to merge 9 commits into
Conversation
Stop circling. Three notes (purposes, ghost-layers, contract-and-binding) shared one diagnosis: the descriptive core is clean; selection/routing/merge leaked into the artifact's shape. reset.md fixes purpose, goals, layers, and separation of concerns, and schedules a single first cut. coordinate-space.md is the clean-room Layer 2 design: a surface is an author-named group with an optional description; topology is a strict containment tree plus cascade-from-ancestors plus rare explicit shared-edges; resolution is BYOA (Ghost emits a described menu, the agent matches); delete list covers inventory.topology, smeared applies_to, and ghost.map/v1. Focus pass: delete pre-redesign docs (fingerprint-format, generation-loop, host-adapters, ghost-fleet, language-fingerprints, relay-configs-and-context, prompt-first-relay-prd) that described the dead Relay-routing and topology/applies_to model. Port the one durable thesis (language maps onto the four facets) inline into the voice skill reference and fix its stale coordinate guidance. Update README and ideas/README to the reset arc.
A real non-UI composition case showed the topology conflated two axes. Containment (where a node lives, who owns it) is a Layer 2 strict tree with cascade-from-ancestors. Composition (what combines to serve a request) is a Layer 3 typed reference graph laid over the tree. The explicit edges are not a rare exception; in composition-heavy, pathless cases they are the primary structure. The original 'tree + rare edges' framing over-fit the in-repo UI case and under-served the no-repo composition case. Amends the topology section, the layer-asks, decision 3, the surface shape, read-back, and the ideas README.
First concrete cut from coordinate-space.md. Proposes a new surfaces.yml facet (ghost.surfaces/v1) anchored by the existing manifest, expressing both axes: parent (the containment tree) and typed edges over edge_kinds (the composition graph). Specifies a field-by-field migration off inventory.topology, smeared applies_to, and exemplar surface_type/scope to a single surface: placement pointer, keeping Layer 1 prose constant and the flat facet files intact for the first cut. Includes a worked example from this repo's own dogfood .ghost/, lint obligations, and open forks (closed vs open edge_kinds, dotted ids, default placement, where path->surface mapping lives). Additive and backward compatible: absent surfaces.yml keeps single-core behavior.
Resolve two open forks into decisions. edge_kinds is a fixed, Ghost-owned, closed set referenced (never defined) per package: opening it would make Ghost a general-purpose graph database and lose the interface-composition focus; richer consumers extend edges consumer-side, not by opening Ghost's set. IDs are flat, unique slugs with no structural meaning; dotted-id-as-hierarchy is banned (lint error) so the tree lives only in parent, one source of truth (kills Leak C). Updates the example, field rules, lint obligations, and forks list; two forks remain (surface default, path->surface binding).
…coped ownership Resolve the remaining forks. Placement is explicit: defaulting un-placed nodes to core would rebuild global-fallback (the brand-mixing failure the redesign cures), so authoring drafts placement, lint warns-and-teaches on the gap, and un-placed never silently means core (warning not error, matching the derivation- ref convention). Reframe the path->surface fork as scoped ownership: in a repo, surfaces are owned by location (the checkout surface is realized under apps/checkout), which is ordinary nested-package/CODEOWNERS-shaped binding, not a new subsystem. The portable contract (surfaces.yml) carries no paths; paths live on the binding. One sub-fork remains for its own note: nested-package-as-binding vs explicit path declaration vs both.
Second concrete extraction. The contract (surfaces.yml) carries no paths; the binding owns all path matching. Directory location is the default binding (a scoped .ghost/ binds surfaces to its subtree, reframing nested-package resolution from data-merge to binding); an explicit .ghost.bind.yml is the escape hatch when ownership does not match the tree, and is the real home for the deleted topology.scopes[].paths. One resolver serves prompt, path, and diff roads, meeting at a surface id; no-repo cases need no binding. Reframes nesting-as-ownership to retire Leak E (no silent merge override, no silently disabled inherited critical check). Records open forks (external contract references, core fallback, bind-vs-redeclare) and the honest caution that this is the least proof-validated layer, so it ships smallest-first.
Plan the breaking change as eight dependency-ordered phases, each a green, committed cut: (0) freeze/baseline, (1) ghost.surfaces/v1 schema, (2) surfaces lint, (3) placement on nodes — the breaking line, removing topology/applies_to/ surface_type/scope, (4) delete ghost.map/v1, (5) slice resolver + menu (prompt road), (6) one-shot migration command + migrate this repo's .ghost/, (7) ghost.binding/v1 path/diff roads + retire child-wins-by-id (Leak E), (8) command/ skill/docs reconciliation. Measured blast radius (~38 src, ~16 map, ~20 test files). Additive phases 1-2 land first to de-risk; least-validated binding lands last. Records open planning decisions (relay survival, migrator permanence, delete-list commands).
…s test A command's desire survives if the new model serves it; its implementation survives only if it already is that. Relay's desire (right narrow context, right time, traceable) is realized by the Phase 5 resolver; relay's implementation (relay-config, request_resolvers, sources, ghost.relay-request/v1) is the second routing system on the delete list. So relay/stack/survey/diff/describe are deleted: relay and stack absorbed into a new gather/select command shipped in Phase 5, the rest dead. Phase 5 ships the new context command on the resolver (not old relay plumbing); Phase 8 deletes the dead commands as execution, not decision. Collapses three open planning decisions into one.
…odule First implementation cut, purely additive. Specs a new ghost-core/surfaces/ module mirroring fingerprint/ (types, schema, index) plus a schema test and one re-export in ghost-core/index.ts. Schema bans dotted ids via a dot-excluding slug regex (the tree lives only in parent); single parent falls out of parent being scalar; edge kinds restricted to the fixed Ghost-owned set. Draws an explicit schema/lint boundary: graph-level checks (cycles, dangling parent/edge refs, near-miss, reserved core) are deferred to Phase 2 lint, documented in a test case so they are not fixed in the wrong layer. Out-of-scope and acceptance criteria are enumerated; one commit, no changeset (no user-visible behavior).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked PR 1 of 6 · base: `main`
Design reset and the surface-model contract that the rest of the stack builds on. Docs/spec only — no runtime code.
Contents
Stack order
Merge bottom-up. Each PR targets the branch below it.