diff --git a/docs/BEARING.md b/docs/BEARING.md index 791daa29..ce239209 100644 --- a/docs/BEARING.md +++ b/docs/BEARING.md @@ -1,6 +1,6 @@ # BEARING -Updated at cycle boundaries. Not mid-cycle. +Updated at cycle boundaries and before the final commit of each v18 slice. Scope note: @@ -12,64 +12,73 @@ Scope note: - For later-major horizon planning, use [release-horizon-v20-v21.md](design/release-horizon-v20-v21.md). +## Continuum Optic Admission Posture + +For cross-repo optic admission, git-warp is a complete Continuum participant, +not an Echo runtime surrogate. Continuum is the protocol for exchanging +witnessed causal history. Wesley compiles artifacts and descriptors, Echo +admits Echo-local runtime invocations, git-warp admits git-warp-local causal +history and readings, authority layers issue grants, and applications hide +handles and basis references behind product adapters. + ## Where are we -`git-warp` is executing the v17 release-blocker DAG. The current work is -not a broad RuntimeHost rewrite; it is one bounded release blocker at a -time, with the DAG status and SVG kept current after each completed -cycle. +`git-warp` has shipped `v17.0.0`. The release work is now behind us in +repo history, npm, and JSR; the active direction is `v18.0.0`. + +The v18 hill is not generic graph-model cleanup. It is Continuum +compatibility: + +> Make `git-warp` a Continuum-compatible sibling WARP runtime: consume +> Wesley-generated artifacts for Continuum-owned contract families, map +> git-warp's append-only Git-backed causal history into honest WARP Optic +> evidence, and +> give `warp-ttd` generated-family facts instead of handwritten adapter +> folklore. + +The long-term compatibility target is the WARP Optic shape described in +`~/git/blog/aion-paper-07/dist/aion-paper-07.txt`, plus the Continuum +contract families authored in `~/git/continuum/schemas/` and compiled by +Wesley. Echo and `git-warp` are sibling runtime implementations. `git-warp` +has its own Continuum role, and it must not emit Continuum-shaped values as +native Continuum witnesses until that witnesshood is actually proven. + +Backlog fold-in: the repo-visible v18 lane is +`WL-4A-v18-graph-substrate-convergence` in +[WORKLOADS.md](method/backlog/WORKLOADS.md), backed by the eight notes in +[method/backlog/v18.0.0](method/backlog/v18.0.0/). Treat that lane as the +graph-model track inside this compatibility campaign: node and edge record +identity, attachment slots, graph-op algebra, content cutover, legacy property +projection, migration tooling, and genesis replay equivalence. Existing +`echo-shaped` backlog identities are historical shorthand for graph-model +pressure already exercised by Echo, not a claim that Echo owns `git-warp`'s +Continuum role. Current branch state at this boundary: -- Branch: `release/v17.0.0` -- Push state: local branch remains ahead of `origin/release/v17.0.0`; - push only after explicit approval. -- DAG map: - [0124-v17-release-blocker-dag.md](design/0124-v17-release-blocker-dag.md) +- Branch: `codex/v18-continuum-opening` +- Release tag: `v17.0.0` +- Latest remote head inspected: `origin/main` at `5afdd3eb` +- Latest package version: `17.0.0` - Latest closed cycle: - `0144-release-preflight-and-rc` -- Latest full unit gate shape: - `npm run test:local` is green with `438` files and `6771` tests. -- Latest validation shape: - lint, anti-sludge shell checks, source/test typecheck, consumer - typecheck, markdown lint, markdown code-sample lint, high-level npm - audit, release preflight, and whitespace diff checks are green at this - boundary. - -The current release ladder remains: - -- `v17.0.0`: TypeScript migration, public API honesty, - materialization-frontdoor deletion, readings/optics direction, and - query read-model groundwork -- `v18.0.0`: graph substrate convergence + `0145-push-pr-review-merge` + +The release ladder is now: + +- `v17.0.0`: shipped TypeScript migration, public API honesty, + materialization-frontdoor deletion, readings/optics direction, and query + read-model groundwork. +- `v18.0.0`: Continuum/WARP Optic compatibility for git-warp as an independent + Continuum participant, through Wesley-generated contract-family artifacts and + honest evidence posture. - `v19.0.0`: observation, doctrine, and slice-first runtime convergence - `v20.0.0`: slice-first read execution - `v21.0.0`: distributed observer geometry and admission reality -Recent work narrowed v17 honestly, removed public materialization -frontdoor docs, fixed runtime read guidance, made checkpoint schema `5` -the single runtime checkpoint contract, removed the checkpoint, patch, -subscription, and sync controller private materialization dependencies, -retired stale materialize-spy expectations, pinned default observer -readings, and aligned remaining checkpoint/materialize unit tests with -the current checkpoint contract, and replaced plain sync HMAC credential -flow with an opaque `SyncSecret`. The sync server now fails closed for -non-local unauthenticated serving and requires an explicit unsafe option -for unauthenticated localhost serving. It also applies per-key token-bucket -rate limiting for configured sync auth and requires an explicit rate-limit -budget for non-local enforced sync auth. The package upgrade command now has -a real checkpoint upgrade path for retired checkpoint envelopes. Unexpected -HTTP sync `500` responses are now sanitized to `E_SYNC_INTERNAL`, with -internal details kept in structured logs. - -The runtime is still partially state-first in important places. The -important current truth is narrow: the non-security `test:local` blockers -from the v17 materialization cleanup and the direct sync security hardening -nodes are closed. File-level anti-sludge quarantines are also graduated, and -the full gate matrix is green, and the release cut/version/changelog node is -closed. Final local release preflight is also green. The remaining blocker is -release coordination: push, PR, review, green CI, and an explicit merge -decision. +The v18 compatibility work is bigger than ten slices. The first ten slices are +the opening campaign. Slice 11 is an explicit re-plan point after the repo has +real evidence from generated artifact ingestion, evidence posture, and the +first receipt-family projection. ## Invariants @@ -109,80 +118,71 @@ mapping, and concrete checks live in `docs/invariants/`. ## What just shipped -Cycles `0132-subscription-controller-reading-basis` through -`0144-release-preflight-and-rc`: - -- Removed `_materializeGraph()` from subscription/watch and sync - controller read paths. -- Made default sync metadata-only unless callers explicitly request - `materialize: true`. -- Rewrote stale auto-materialize and materialize-spy tests around the v17 - reading-basis contract. -- Pinned default `graph.observer()` reads to the caller's fresh reading - basis. -- Aligned remaining checkpoint/materialize tests with schema `5` or - explicit retired-schema upgrade rejection. -- Added `SyncSecret` so sync auth secrets redact in string, JSON, and - inspect output while still signing HMAC requests. -- Hardened sync serve defaults: non-local bind hosts require enforced - auth, and local unauthenticated serving must opt into unsafe localhost - mode. -- Added per-key token-bucket sync auth rate limiting and required explicit - `auth.rateLimit` for non-local enforced sync hosts. -- Sanitized unexpected HTTP sync `500` responses and routed internal error - detail through `LoggerPort`. -- Graduated the anti-sludge file-level quarantine manifests to empty - `files` lists and narrowed remaining legacy hits to owning-cycle inline - suppressions. -- Recorded the full gate matrix green after quarantine graduation. -- Cut the v17.0.0 changelog section for May 5 and aligned the release note with - the honest 0123 bounded-query scope. -- Cleared the local release preflight from a clean commit. The hard preflight - repairs landed in `bdafca51`, and the final preflight reports all hard checks - passed. -- Brought `npm run test:local` back to green. -- Marked `PORT_subscription-controller-reading-basis`, - `PORT_sync-controller-reading-basis`, - `SPEC_materialize-spy-test-clusters`, - `SPEC_observer-coordinate-pinning`, and - `SPEC_checkpoint-materialize-test-drift` complete in the DAG, then - marked `HEX_sync-secret-plain-string` and - `HEX_sync-production-auth-defaults` complete, then marked - `HEX_sync-no-rate-limiting`, `HEX_sync-500-sanitization`, and - `REL_quarantine-graduate-clean`, then - `REL_full-gate-matrix-green`, then - `REL_release-cut-version-changelog`, then - `REL_release-preflight-and-rc` complete. +`v17.0.0` shipped and was followed by release hardening: + +- The v17 release branch landed through PR #84. +- Follow-up repair and package migration work landed through PR #85. +- Release hardening landed through PR #86. +- The final v17 coverage ratchet landed through PR #87; the signed + `v17.0.0` tag points at that merge. +- npm publish recovery landed through PR #88. +- PR #89 simplified the README model sentence after the release line. + +The shipped v17 scope remains: TypeScript migration, public API honesty, +materialization-frontdoor deletion, readings/optics direction, query +read-model groundwork, sync hardening, release gates, and package publishing. ## What feels wrong -- v17 is still not releasable until the branch is pushed, reviewed, green in - CI, and explicitly approved for merge. -- `REL_push-pr-review-merge` is now the open node. - The release preflight fix lowered the coverage ratchet to the measured full-suite v17 line baseline `91.74%`; this is tracked as v19 bad-code debt in `SPEC_coverage-ratchet-baseline-drop.md`. -- Broader historical version-suffixed substrate names still exist in - `src/`; the checkpoint upgrade slice removed the touched checkpoint and - migration names only. -- The branch remains local-only relative to origin; pushing is a separate - release/coordination decision. +- v18 can easily turn into adapter folklore if `git-warp` hand-authors local + mirrors of Continuum-owned families instead of consuming Wesley-generated + artifacts. +- v18 can also lie in the other direction: Continuum-shaped values are not + Continuum-native witnesses unless the runtime has actually proven native + witnesshood. Initial git-warp compatibility evidence should be treated as + translated git-warp evidence until stronger proof exists. +- The v18 backlog already names a graph-model convergence lane. The plan must + fold that lane into Continuum compatibility instead of replacing it with a + parallel cross-repo adapter plan. +- `warp-ttd` needs git-warp facts as generated-family nouns, but the existing + ecosystem still contains handwritten adapter and protocol residue. ## What comes next -Continue executing the DAG one open node at a time. - -Recommended next pull: - -- `REL_push-pr-review-merge` - -Why: - -- It is open. -- The full gate matrix, release cut, and local preflight are green. -- The branch is still local-only relative to origin. -- Merge must remain gated on review, green CI, and explicit human approval. - -Keep the loop strict: write the cycle doc, capture RED, green the slice, -update changelog/DAG/SVG/retro, validate, commit, then pull the next open -node. +Run the v18 opening campaign. Update this task list at the end of each slice, +before the final commit for that slice, and mark completed items with `- [x]`. + +## Running Task List + +- [x] 1. Sync and clean the repo runway: fast-forward `main`, clear fsmonitor + noise, close stale v17/0145 bookkeeping, and record the v18 starting point. +- [x] 2. Create the v18 Continuum compatibility charter: WARP Optic + compatibility, Continuum contract-family compatibility, Wesley-generated + artifact consumption, and `warp-ttd` acceptance. +- [x] 3. Build the cross-repo contract matrix: Continuum family to Wesley + generated artifact to git-warp source fact to `warp-ttd` consumer need, + with `WL-4A-v18-graph-substrate-convergence` folded in as the graph-model + track. +- [x] 4. Define git-warp's WARP Optic realization map: observer plan, bounded + slice, lowering surface, admissibility law, and retention contract. +- [x] 5. Add a generated-artifact ingestion path for Continuum families, with a + guard against handwritten local mirrors becoming contract authority. +- [ ] 6. Make evidence posture explicit: translated git-warp evidence first, + native Continuum evidence only after native witnesshood is proven. +- [ ] 7. Prove the patch commit visibility contract: success means canonical + writer-tip advancement and visible graph truth, not just object creation. +- [ ] 8. Add the same-writer concurrent patch race witness with final-frontier + and visible-state assertions. +- [ ] 9. Project git-warp receipt facts into the generated Continuum + receipt-family shape with conformance tests. +- [ ] 10. Add the first `warp-ttd` smoke over generated-family git-warp receipt + facts instead of handwritten adapter-local receipt folklore. +- [ ] 11. Re-plan with evidence in hand before expanding into reading-envelope, + suffix/runtime-boundary, neighborhood-core, and settlement-family slices. + +The loop stays strict: write or update the cycle doc, capture RED, green the +slice, update this BEARING task list before the final commit, validate, then +commit only the files touched in that slice. diff --git a/docs/VISION.md b/docs/VISION.md index dc41296c..8b4bf682 100644 --- a/docs/VISION.md +++ b/docs/VISION.md @@ -60,13 +60,14 @@ The read-side correction now matters just as much as the admission-side one: - Observer-first read surfaces through worldlines and apertures - Decentralized sync through Git transport -In other words: `git-warp` owns the cold causal substrate and the lawful -read/folding surfaces over it. It should not have to pretend that a giant -in-memory graph is the ontology. +In other words: `git-warp` is a complete Continuum participant for witnessed +causal history, append-only Git-backed persistence, and lawful read/folding +surfaces. It should not have to pretend that a giant in-memory graph is the +ontology. ## What git-warp does not own -- Hot deterministic execution → Echo +- Echo's runtime-local deterministic execution → Echo - Time-travel debugging UI → warp-ttd - Shared schemas and contract surfaces → Wesley - Application domain semantics → yours @@ -87,10 +88,11 @@ Sync is just `git push` / `git fetch` of WARP refs. ## The Continuum horizon -When used in the wider stack, `git-warp` is the cold causal substrate. -The Continuum vision (Paper VII §5) reframes processes as strands -whose live realization is a shadow working set over shared machine -history: +When used in the wider stack, `git-warp` and Echo are sibling Continuum +participants. Continuum is the protocol for exchanging witnessed causal +history, not a runtime hierarchy. The Continuum vision (Paper VII §5) reframes +processes as strands whose live realization is a shadow working set over +shared machine history: - **Ephemeral scratch** — local, weakly retained, disposable - **Author-only speculative lane** — durable, replayable, sealed diff --git a/docs/design/0124-v17-release-blocker-dag.dot b/docs/design/0124-v17-release-blocker-dag.dot index 8cf1b28b..db782657 100644 --- a/docs/design/0124-v17-release-blocker-dag.dot +++ b/docs/design/0124-v17-release-blocker-dag.dot @@ -150,8 +150,10 @@ digraph V17ReleaseBlockers { penwidth=2.4 ]; "REL_push-pr-review-merge" [ - fillcolor="#fee2e2", - label="OPEN\nREL_push / PR\nreview / merge" + color="#15803d", + fillcolor="#bbf7d0", + label="DONE\nREL_push / PR\nreview / merge", + penwidth=2.4 ]; "SPEC_docs-materialize-frontdoor-drift" -> "SPEC_runtime-error-reading-basis-guidance"; diff --git a/docs/design/0124-v17-release-blocker-dag.md b/docs/design/0124-v17-release-blocker-dag.md index 2ae27f38..e081b0c2 100644 --- a/docs/design/0124-v17-release-blocker-dag.md +++ b/docs/design/0124-v17-release-blocker-dag.md @@ -164,8 +164,9 @@ closure. A blank cell means "not directly blocked by that task," not documented runbook warning. `REL_push-pr-review-merge` -: Open. Push the branch, open or update the release PR, get review and green - CI, and merge only after explicit approval. +: Closed in cycle 0145. The release branch was pushed, reviewed, repaired, + merged, tagged, and published. Follow-up hardening and npm publish recovery + also landed on `main`. ## Excluded From v17 Blockers @@ -180,9 +181,9 @@ substrate convergence are also excluded from this release-blocker graph. ## Current Open Front -The tasks with no direct blockers are: +There are no open v17 release-blocker nodes. -- `REL_push-pr-review-merge` +The v17 DAG is closed. `SPEC_consumer-typecheck-materialize-residue` closed in cycle 0125. `SPEC_docs-materialize-frontdoor-drift` closed in cycle 0126 and unlocks @@ -208,7 +209,8 @@ quarantine graduation. Quarantine graduation closed in cycle 0141, opening the full gate matrix. The full gate matrix closed in cycle 0142, opening release cut/version/changelog. Release cut/version/changelog closed in cycle 0143, opening release preflight and RC. Release preflight and RC closed in -cycle 0144, opening push, PR, review, and merge. +cycle 0144, opening push, PR, review, and merge. Push, PR, review, merge, tag, +and publish closed in cycle 0145. ## Regeneration diff --git a/docs/design/0124-v17-release-blocker-dag.svg b/docs/design/0124-v17-release-blocker-dag.svg index b49b6865..a87a246f 100644 --- a/docs/design/0124-v17-release-blocker-dag.svg +++ b/docs/design/0124-v17-release-blocker-dag.svg @@ -419,16 +419,16 @@ REL_push-pr-review-merge - -OPEN + +DONE REL_push / PR review / merge REL_release-preflight-and-rc->REL_push-pr-review-merge - - + + diff --git a/docs/design/0124-v17-release-blocker-status.csv b/docs/design/0124-v17-release-blocker-status.csv index da7f0a0a..29afca4b 100644 --- a/docs/design/0124-v17-release-blocker-status.csv +++ b/docs/design/0124-v17-release-blocker-status.csv @@ -19,4 +19,4 @@ REL_quarantine-graduate-clean,complete,BND_checkpoint-schema-contract-drift;PORT REL_full-gate-matrix-green,complete,SPEC_consumer-typecheck-materialize-residue;SPEC_docs-materialize-frontdoor-drift;SPEC_runtime-error-reading-basis-guidance;BND_checkpoint-schema-contract-drift;PORT_patch-controller-reading-basis;PORT_checkpoint-controller-reading-basis;PORT_subscription-controller-reading-basis;PORT_sync-controller-reading-basis;SPEC_materialize-spy-test-clusters;SPEC_observer-coordinate-pinning;SPEC_checkpoint-materialize-test-drift;SPEC_uniform-git-cas-upgrade-contract-drift;HEX_sync-no-rate-limiting;HEX_sync-500-sanitization;REL_quarantine-graduate-clean,,no,Closed by 0142 full gate matrix. REL_release-cut-version-changelog,complete,REL_full-gate-matrix-green,,no,Closed by 0143 release cut/version/changelog. REL_release-preflight-and-rc,complete,REL_release-cut-version-changelog,,no,Closed by 0144 release preflight and RC readiness. -REL_push-pr-review-merge,incomplete,REL_release-preflight-and-rc,,yes,Open node; release preflight is green. +REL_push-pr-review-merge,complete,REL_release-preflight-and-rc,,no,Closed by 0145 push PR review merge; v17 merged tagged and published. diff --git a/docs/design/0145-push-pr-review-merge/push-pr-review-merge.md b/docs/design/0145-push-pr-review-merge/push-pr-review-merge.md index efd3106e..b4f3b3db 100644 --- a/docs/design/0145-push-pr-review-merge/push-pr-review-merge.md +++ b/docs/design/0145-push-pr-review-merge/push-pr-review-merge.md @@ -1,11 +1,12 @@ --- cycle: 0145 task_id: REL_push-pr-review-merge -status: Draft +status: Complete sponsors: human: James agent: Codex started_at: 2026-05-05 +completed_at: 2026-05-21 release_home: v17.0.0 --- @@ -24,6 +25,21 @@ unless James explicitly says `YES`. The release branch is visible on GitHub, represented by a PR against `main`, and blocked only by external review, CI, or the explicit merge approval gate. +## Closeout + +The coordination hill is closed in repo-visible history: + +- PR #84 merged the `release/v17.0.0` branch to `main`. +- PR #85 landed v17 follow-up repair and package migration work. +- PR #86 landed release publish hardening. +- PR #87 finalized the v17 coverage ratchet and produced the signed + `v17.0.0` tag. +- PR #88 recovered npm release publishing. +- PR #89 landed the post-release README wording cleanup. + +The release branches have been pruned from `origin`, `origin/main` is at +`5afdd3eb`, and `v17.0.0` is visible on npm and JSR. + ## Playback Questions 1. Is `release/v17.0.0` pushed to `origin` at the current local commit? @@ -139,11 +155,10 @@ Current evidence before implementation: ### Goldens -- Local and remote branch tips match. -- The PR body records the v17 scope, validation evidence, and the explicit - non-merge gate. -- The final release decision remains outside automation until James says - `YES`. +- `main` contains the release merge and follow-up release hardening. +- The signed `v17.0.0` tag points at the final coverage-ratchet release merge. +- npm and JSR both expose `17.0.0` as the latest package version. +- The final release branches are no longer open remote work. ### Known Fails diff --git a/docs/design/0146-v18-continuum-compatibility-charter/v18-continuum-compatibility-charter.md b/docs/design/0146-v18-continuum-compatibility-charter/v18-continuum-compatibility-charter.md new file mode 100644 index 00000000..aa2a3993 --- /dev/null +++ b/docs/design/0146-v18-continuum-compatibility-charter/v18-continuum-compatibility-charter.md @@ -0,0 +1,152 @@ +--- +cycle: 0146 +task_id: V18_continuum_compatibility_charter +status: Complete +sponsors: + human: James + agent: Codex +started_at: 2026-05-21 +completed_at: 2026-05-21 +release_home: v18.0.0 +--- + +# V18 Continuum Compatibility Charter + +## Pull + +v17 made the current engine shippable. v18 must make `git-warp` compatible +with the shared Continuum/WARP Optic stack as a complete sibling Continuum +participant without collapsing it into Echo, Wesley, or `warp-ttd`. + +## Hill + +`git-warp` becomes a Continuum-compatible sibling WARP runtime: + +- it consumes Wesley-generated artifacts for Continuum-owned contract families; +- it maps append-only Git history into honest WARP Optic evidence; +- it exposes generated-family facts to `warp-ttd`; +- it separates translated git-warp evidence from native Continuum witnesshood. + +## Source Artifacts + +- `~/git/blog/aion-paper-07/dist/aion-paper-07.txt` +- `~/git/continuum/schemas/` +- `~/git/continuum/docs/contract-family-registry.md` +- `~/git/wesley/README.md` +- `~/git/echo/docs/BEARING.md` +- `~/git/warp-ttd/docs/BEARING.md` +- [VISION.md](../../VISION.md) +- [BEARING.md](../../BEARING.md) +- [backlog/WORKLOADS.md](../../method/backlog/WORKLOADS.md) +- [backlog/v18.0.0/README.md](../../method/backlog/v18.0.0/README.md) + +## Compatibility Law + +The target WARP Optic shape is: + +```text +Psi = (Omega, chi, rho, Pi, Lambda) +Lower_Psi(F*, P) = (R, W, theta) +``` + +For v18, `git-warp` should interpret that shape as a compatibility boundary: + +- `Omega`: observer/read discipline, basis, and emission posture; +- `chi`: bounded frontier-relative support slice; +- `rho`: append-only Git/CRDT lowering surface over patch chains; +- `Pi`: admission law producing derived, plural, conflict, or obstruction + outcomes; +- `Lambda`: retained replay, audit, transport, revelation, and reliance + obligations. + +This charter does not require one generic optic engine. It requires each +published compatibility surface to say which part of the optic shape it +implements and which evidence supports that claim. + +## Contract Families + +The first v18 compatibility families are the Continuum-authored families: + +- `receipt-family` +- `settlement-family` +- `neighborhood-core-family` +- `runtime-boundary-family` + +Wesley is the compiler and artifact authority for these shared families. +`git-warp` must consume generated artifacts or documented generated fixtures. +Handwritten mirrors may exist only as temporary local adapters with explicit +non-authority status. + +## Backlog Integration + +The repo-visible v18 backlog already names +`WL-4A-v18-graph-substrate-convergence` as the first major workload. This +charter folds that work into the Continuum campaign rather than replacing it. + +That workload contributes the graph-model track: + +- node and edge record identity; +- attachment-plane substrate work; +- graph-op algebra convergence; +- content migration out of legacy property conventions; +- property-bag reads reduced to projections; +- graph-model migration tooling; +- replay equivalence from genesis. + +The existing `PROTO_echo-shaped-*` task identities are retained as backlog +history. In this charter, `echo-shaped` means graph-model pressure already +exercised by Echo. It does not mean Echo owns `git-warp`'s Continuum role or +defines `git-warp`'s participant obligations. + +## Evidence Posture + +The default posture for existing git-warp facts mapped into Continuum-family +shapes is translated evidence. A value may be Continuum-shaped without being +Continuum-native. + +`git-warp` may claim native Continuum witnesshood only after a runtime witness +proves the value was produced through the corresponding Continuum family +contract and not merely mapped from local git-warp facts. + +## Non-Goals + +- Do not make Echo the owner or authority for `git-warp`'s Continuum role. +- Do not make `git-warp` a semantic owner for Continuum contract families. +- Do not make `warp-ttd` hand-normalize git-warp facts into substitute shared + contracts. +- Do not build a generic WARP Optic runtime before repeated concrete + compatibility cuts justify it. +- Do not claim native Continuum witnesshood for translated git-warp evidence. + +## Acceptance + +The v18 opening campaign is on track when: + +- [ ] `BEARING.md` tracks the running v18 task list. +- [x] A cross-repo contract matrix names each family, generated artifact, local + source fact, consumer, and missing witness. +- [x] A WARP Optic realization map exists for `git-warp`. +- [x] The repo can ingest at least one generated Continuum family artifact or + generated fixture. +- [x] A guard prevents generated-family local mirrors from becoming hidden + authority. +- [ ] The first receipt-family projection reaches `warp-ttd` without adapter + folklore. + +## SSJS Scorecard + +- Runtime-backed forms: green for this documentation slice; no runtime forms + introduced. +- Boundary validation: green; the charter names generated artifacts as the + boundary authority. +- Behavior ownership: green; Continuum owns shared semantics, Wesley compiles, + `git-warp` emits git-warp-local facts, and `warp-ttd` observes. +- Message parsing: green; no behavior branches are introduced. +- Ambient time or entropy: green; no runtime code introduced. +- Fake shape trust or cast-cosplay: green; the charter explicitly rejects fake + native witnesshood. + +## Closeout + +This charter closes BEARING task 2 and defines the standard later v18 slices +must satisfy before making stronger compatibility claims. diff --git a/docs/design/0147-v18-continuum-contract-matrix/v18-continuum-contract-matrix.md b/docs/design/0147-v18-continuum-contract-matrix/v18-continuum-contract-matrix.md new file mode 100644 index 00000000..5f68a4f7 --- /dev/null +++ b/docs/design/0147-v18-continuum-contract-matrix/v18-continuum-contract-matrix.md @@ -0,0 +1,110 @@ +--- +cycle: 0147 +task_id: V18_continuum_contract_matrix +status: Complete +sponsors: + human: James + agent: Codex +started_at: 2026-05-21 +completed_at: 2026-05-21 +release_home: v18.0.0 +--- + +# V18 Continuum Contract Matrix + +## Pull + +The v18 charter names the compatibility target. This slice names the actual +contract families and the current proof gap for each one. + +## Hill + +`git-warp` can now point at a concrete matrix: + +- Continuum owns the shared family semantics. +- Wesley compiles and witnesses generated family artifacts. +- Echo and `git-warp` are sibling runtimes that may emit or consume conforming + values. +- `warp-ttd` is the structured debugger/read-model consumer. +- Existing `git-warp` facts are translated evidence until native Continuum + witnesshood is proven. + +## Evidence Snapshot + +The matrix below is based on these inspected local sources: + +| Repo | Head | Evidence | +| --- | --- | --- | +| Continuum | `01e0735` | `docs/contract-family-registry.md`, `schemas/*.graphql`, `wesley/profile/scopes.mjs` | +| Wesley | `19b2c1c9` | `README.md`, `docs/architecture/continuum-minimum-shared-contract-surface.md` | +| Echo | `b1d979d` | `docs/BEARING.md` | +| `warp-ttd` | `0491be6` | `docs/BEARING.md`, `schemas/warp-ttd-protocol.graphql` | +| `git-warp` | this branch | `docs/BEARING.md`, `src/domain/types/TickReceipt.ts`, `src/domain/types/DeliveryObservation.ts`, read/materialize capabilities | + +## Family Matrix + +| Family | Authored home | Wesley status | `git-warp` source facts | Primary `warp-ttd` need | Missing witness | +| --- | --- | --- | --- | --- | --- | +| `receipt-family` | `~/git/continuum/schemas/continuum-receipt-family.graphql` | `profiled`, `fixture-witnessed`; scope `receipt-family` checks cross-leg schema hash, TTD fixture shape, Echo fixture shape, boundary fixture, roundtrip vectors, and receipt/witness separation | `TickReceipt`, op outcomes, `DeliveryObservation`, audit receipt chains, materialize/provenance receipt collection | Receipt and delivery facts as generated-family nouns, not adapter-local summaries | Live `git-warp` receipt publication mapped through generated artifacts with translated evidence posture, then witnessed as native only after a Continuum runtime witness exists | +| `settlement-family` | `~/git/continuum/schemas/continuum-settlement-family.graphql` | `profiled`, `fixture-witnessed`; scope `settlement-family` checks cross-leg coherence and settlement boundary fixtures | Patch diffs, conflict traces, merge/conflict analysis, strand/braid conflict artifacts, writer frontier state | Import/settlement explanation for cross-runtime history and merge inspection | Live settlement values from `git-warp` suffix/import or merge flows, plus generated-artifact conformance | +| `neighborhood-core-family` | `~/git/continuum/schemas/continuum-neighborhood-core-family.graphql` | `authored`; not yet profiled in the current Continuum Wesley scope list | Graph name, writer refs, worldline/frontier facts, local site-like participation facts still unnamed as a stable family | Neighborhood focus, participant catalog, and site navigation across Echo and `git-warp` targets | Wesley profile and fixture witness first; then `git-warp` participant values with explicit translated/native evidence status | +| `runtime-boundary-family` | `~/git/continuum/schemas/continuum-runtime-boundary-family.graphql` | `authored`; not yet profiled in the current Continuum Wesley scope list | Materialize/read requests, observer/read basis, patch suffixes, frontiers, provenance refs, receipt collections, import outcomes still split across local APIs | Admission-chain read model: observer plans, reading envelopes, evidence posture, suffix shells, causal suffix bundles, import outcomes | Wesley profile, generated fixtures, and a live witnessed suffix exchange/admission proof between sibling runtimes | + +## Source-Fact Map + +| Continuum noun | Current `git-warp` anchor | Current posture | +| --- | --- | --- | +| `Receipt` | `TickReceipt`, audit receipts, receipt shards | Translated evidence; shape is not yet generated-family native | +| `DeliveryObservation` | `DeliveryObservation` and effect sink observations | Local fact with strong name overlap; not yet Continuum family output | +| `Witness` | checkpoint-tail witnesses, conflict witnesses, audit chain proofs | Local witness forms; no shared generated family surface yet | +| `SettlementDelta` / `ConflictArtifact` | `PatchDiff`, conflict traces, merge/conflict services | Candidate source facts; missing shared generated settlement adapter | +| `NeighborhoodCore` / `NeighborhoodParticipant` | graph name, writers, frontiers, worldline metadata | Candidate source facts; missing stable local site/participant object | +| `ObserverPlan` / `ObservationRequest` | query/read basis, materialize options, traversal context | Candidate source facts; missing generated runtime-boundary profile | +| `ReadingEnvelope` | materialize/query/read results plus provenance/receipt options | Candidate source facts; missing explicit evidence status wrapper | +| `TranslatedSubstrateEvidence` | append-only Git-backed causal history, patch SHAs, writer refs, receipts | Correct initial evidence posture for compatibility outputs | +| `WitnessedSuffixShell` / `CausalSuffixBundle` | writer patch chains, frontier maps, transport/sync suffixes | Candidate source facts; missing compact generated shell and admission witness | +| `ImportOutcome` | sync/import/materialization outcomes and conflict posture | Candidate source facts; missing runtime-boundary family emission | + +## `warp-ttd` Consumer Matrix + +`warp-ttd`'s active bearing pressures these generated-family facts first: + +| `warp-ttd` target | Needed from `git-warp` | Contract-family lane | +| --- | --- | --- | +| Dual live app debugging | Read-only posture for a live `git-warp` target without host mutation | runtime-boundary-family | +| Admission-chain read model | Artifact registration, evidence posture, receipts, witnesses, and reading envelopes as distinct facts | runtime-boundary-family, receipt-family | +| Neighborhood and site catalog | Participant/site summaries that can compare Echo and `git-warp` targets | neighborhood-core-family | +| Receipt shell summary | Generated-family receipt facts and delivery observations | receipt-family | +| Merge and import inspection | Conflict artifacts, import candidates, settlement plans, and outcomes | settlement-family | + +## First Implementation Pressure + +The first implementation slice should not try to ingest every family. It should +build a generated-artifact ingestion seam around one generated fixture family, +then guard against hidden handwritten mirrors. + +Recommended order: + +1. Ingest or locally fixture the `receipt-family` generated artifact manifest. +2. Reject local `git-warp` files that claim to be authoritative mirrors of + Continuum-owned families. +3. Map `TickReceipt` and `DeliveryObservation` into a translated + `receipt-family` projection without claiming native Continuum witnesshood. +4. Let `warp-ttd` consume that projection as generated-family-shaped input. + +## SSJS Scorecard + +- Runtime-backed forms: green for this documentation slice; no runtime forms + introduced. +- Boundary validation: green; the matrix keeps authored schemas and Wesley + generated artifacts as authority. +- Behavior ownership: green; each row separates authored home, compiler, + runtime source fact, consumer, and missing witness. +- Message parsing: green; no behavior branches introduced. +- Ambient time or entropy: green; no runtime code introduced. +- Fake shape trust or cast-cosplay: green; every current `git-warp` mapping is + marked as translated evidence until a stronger witness exists. + +## Closeout + +This closes BEARING task 3 and supplies the evidence table for slices 4 and 5. diff --git a/docs/design/0148-v18-warp-optic-realization-map/v18-warp-optic-realization-map.md b/docs/design/0148-v18-warp-optic-realization-map/v18-warp-optic-realization-map.md new file mode 100644 index 00000000..6c859f4b --- /dev/null +++ b/docs/design/0148-v18-warp-optic-realization-map/v18-warp-optic-realization-map.md @@ -0,0 +1,113 @@ +--- +cycle: 0148 +task_id: V18_warp_optic_realization_map +status: Complete +sponsors: + human: James + agent: Codex +started_at: 2026-05-21 +completed_at: 2026-05-21 +release_home: v18.0.0 +--- + +# V18 WARP Optic Realization Map + +## Pull + +The contract matrix names the cross-repo families. This slice maps +`git-warp`'s current runtime facts onto the WARP optic tuple without claiming a +generic optic engine. + +## Hill + +For v18, `git-warp` interprets: + +```text +Psi = (Omega, chi, rho, Pi, Lambda) +Lower_Psi(F*, P) = (R, W, theta) +``` + +as a compatibility map over existing repo facts. + +## Component Map + +| Optic component | WARP role | Current `git-warp` anchors | v18 compatibility gap | +| --- | --- | --- | --- | +| `Omega` | Observer discipline: projection, basis, observer state, update discipline, and emission | `WorldlineOptic`, `NodeOptic`, `NodePropertyOptic`, `ReadIdentity`, `Observer`, `QueryRunner`, `QueryReadModelProvider`, `ExternalizationPolicy` | Generated `ObserverPlan`, `ObservationRequest`, and `ReadingEnvelope` family shapes | +| `chi` | Bounded frontier-relative optic slice | `CheckpointTailWitnessLocator`, `CheckpointTailBasisLoader`, `CheckpointTailOpticSource`, `CheckpointTailReadIdentityBuilder`, `ProvenanceController.materializeSlice` | Shared vocabulary for slice support, tail budget, and graph-model attachment plane | +| `rho` | Set-side lowering surface that presents comparable claims over `chi` | `reduceV5`, `applyWithReceipt`, `JoinReducerSession`, op classes, `PatchDiff`, `syncDelta`, materialize-coordinate paths | Generated lowering inputs for receipt, settlement, and runtime-boundary families | +| `Pi` | Admission law for derived, plural, conflict, or obstruction outcomes | `OpStrategies`, `ReceiptBuilder`, `TickReceipt` outcomes, `ConflictAnalyzerService`, `SyncTrustGate`, `OpticReadFailureCause` | First-class outcome algebra aligned with Continuum `AdmissionOutcomeKind` and runtime-boundary admission nouns | +| `Lambda` | Retention contract for replay, audit, transport, revelation, and reliance obligations | append-only Git commits, writer refs, patch SHAs, checkpoints, `ReceiptShard`, `AuditReceiptService`, `ReadIdentity`, sync suffixes | Generated evidence-status wrappers, suffix shells, and explicit retention obligations for `warp-ttd` | + +## Lowering Scales + +| Scale | Weave `P` | Frontier `F*` | Result `R` | Witness `W` | Retained shell `theta` | Current posture | +| --- | --- | --- | --- | --- | --- | --- | +| Tick / patch | One patch or ordered patch sequence | Writer and graph frontier | State transition, `PatchDiff`, or op outcomes | `TickReceipt`, op outcome details | Patch commit, receipt, optional audit receipt | Real local runtime fact; not native Continuum receipt-family output yet | +| Read / optic | Observer/read target plus basis | Live, coordinate, or strand source | Node/property/traversal/materialized reading | `ReadIdentity`, checkpoint-tail witnesses, failure cause | Read identity plus checkpoint/tail anchors | Real local read fact; missing generated `ReadingEnvelope` | +| Provenance slice | Backward cone for a target | Patch graph reachable from target | Bounded reconstructed state and patch count | Causal patch list, optional receipts | Provenance payload and source SHAs | Real local source fact; missing Continuum evidence wrapper | +| Strand / braid | Strand overlay or braided strand set | Parent frontier plus overlay heads | Materialized strand state or conflict trace | conflict receipts, conflict anchors, participant traces | strand descriptor, overlay patches, conflict analysis | Candidate settlement-family source facts | +| Replica / sync | Remote suffix family or frontier delta | Local and remote writer frontiers | Needed patch ranges, trust posture, import/sync result | writer trust gate result, ancestry checks | transferred patch commits and refs | Candidate runtime-boundary suffix/import facts | + +## Outcome Algebra Posture + +The WARP paper's outcome space is: + +```text +O(X) = Derived(X) + Plural(X) + Conflict + Obstruction +``` + +Current `git-warp` facts map into it conservatively: + +| Outcome | Local anchors | Current limitation | +| --- | --- | --- | +| `Derived` | successful reducer outcomes, materialized readings, query results | Not wrapped as a generated Continuum outcome | +| `Plural` | strand/braid coexistence and multi-writer frontier facts | Plurality is represented structurally, not as a named outcome | +| `Conflict` | conflict traces, diagnostics, conflict receipt refs | Settlement-family projection is still missing | +| `Obstruction` | optic read failures, sync trust rejection, validation errors | Obstruction is not yet one shared runtime-boundary noun | + +## Evidence Posture + +The first v18 compatibility layer must mark `git-warp` outputs as translated +evidence unless a native Continuum runtime witness exists. + +That means: + +- a `TickReceipt` can be mapped toward `receipt-family`; +- a conflict trace can be mapped toward `settlement-family`; +- a read result can be mapped toward `runtime-boundary-family`; +- a sync suffix can be mapped toward `WitnessedSuffixShell`; +- none of those mappings may claim native Continuum witnesshood by shape alone. + +## Next Engineering Cut + +Slice 5 should create a generated-artifact ingestion seam that can load one +Continuum family artifact descriptor or fixture and reject hidden handwritten +authority. The first useful family is `receipt-family` because `git-warp` +already has strong local source facts: `TickReceipt`, op outcomes, +`DeliveryObservation`, receipt shards, and audit receipts. + +The seam should not: + +- parse arbitrary GraphQL in the domain; +- generate types at runtime; +- make `git-warp` the owner of Continuum family semantics; +- equate translated `git-warp` evidence with native Continuum witnesshood. + +## SSJS Scorecard + +- Runtime-backed forms: green for this documentation slice; no runtime forms + introduced. +- Boundary validation: green; the map treats generated artifacts as later + boundary inputs. +- Behavior ownership: green; optic components are mapped to owning local + modules and their gaps are named. +- Message parsing: green; no behavior branches introduced. +- Ambient time or entropy: green; no runtime code introduced. +- Fake shape trust or cast-cosplay: green; translated evidence is explicit. + +## Closeout + +This closes BEARING task 4 and gives slice 5 a narrow implementation target: +ingest a generated-family artifact descriptor or fixture and guard against +shadow authority. diff --git a/docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md b/docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md new file mode 100644 index 00000000..e7f8d79d --- /dev/null +++ b/docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md @@ -0,0 +1,100 @@ +--- +cycle: 0149 +task_id: V18_continuum_artifact_ingestion +status: Complete +sponsors: + human: James + agent: Codex +started_at: 2026-05-21 +completed_at: 2026-05-21 +release_home: v18.0.0 +--- + +# V18 Continuum Artifact Ingestion + +## Pull + +The contract matrix and optic map both point at the same first implementation +pressure: `git-warp` needs a generated-family artifact seam before it can map +local facts into Continuum-family shapes. + +## Hill + +Add a narrow ingestion path for generated Continuum family artifact descriptors +and reject local mirrors before they can become hidden family authority. + +## Implementation + +This slice adds: + +- `ContinuumFamilyId` for the four Continuum-owned family ids; +- `ContinuumArtifactAuthority` for generated artifacts, generated fixtures, + local mirrors, and handwritten mirrors; +- `ContinuumArtifactDescriptor` as the runtime-backed descriptor object; +- `ContinuumArtifactIngestionPolicy` as the authority guard; +- `ContinuumArtifactJsonFileAdapter` as the infrastructure-edge JSON loader; +- `test/fixtures/continuum/receipt-family-generated-artifact.json` as the first + generated-family fixture descriptor. + +The guard accepts only: + +- `generated-artifact` +- `generated-fixture` + +It rejects: + +- `local-mirror` +- `handwritten-mirror` + +## Boundary Law + +JSON parsing stays in `src/infrastructure/adapters/`. Domain code receives +validated constructor fields and runtime-backed objects. + +The descriptor does not parse GraphQL, generate TypeScript, or claim family +semantics. It only records which generated-family artifact or fixture is being +admitted and whether that admission posture is allowed. + +## Verification + +Focused checks: + +```text +npx eslint src/domain/continuum/ContinuumFamilyId.ts \ + src/domain/continuum/ContinuumArtifactAuthority.ts \ + src/domain/continuum/ContinuumArtifactDescriptor.ts \ + src/domain/continuum/ContinuumArtifactIngestionPolicy.ts \ + src/domain/errors/ContinuumArtifactAuthorityError.ts \ + src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts +npm run typecheck:src +npm run typecheck:test +npm run typecheck:surface +npx vitest run \ + test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts \ + test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts +``` + +Observed focused test result: + +```text +Test Files 2 passed (2) +Tests 9 passed (9) +``` + +## SSJS Scorecard + +- Runtime-backed forms: green; new Continuum concepts are classes with + constructor validation and frozen instances. +- Boundary validation: green; untrusted JSON is parsed only in the + infrastructure adapter. +- Behavior ownership: green; the descriptor owns descriptor invariants and the + ingestion policy owns authority decisions. +- Message parsing: green; no behavior branches parse free-form messages. +- Ambient time or entropy: green; no ambient time or entropy introduced. +- Fake shape trust or cast-cosplay: green; mirror descriptors are rejected + before ingestion. + +## Closeout + +This closes BEARING task 5 and gives later receipt-family projection work a +safe generated-artifact entry point. diff --git a/docs/design/continuum-categories.pdf b/docs/design/continuum-categories.pdf index a218496f..82c7fc81 100644 Binary files a/docs/design/continuum-categories.pdf and b/docs/design/continuum-categories.pdf differ diff --git a/docs/design/continuum-categories.tex b/docs/design/continuum-categories.tex index e4d5d1ef..66d3e7ed 100644 --- a/docs/design/continuum-categories.tex +++ b/docs/design/continuum-categories.tex @@ -53,13 +53,17 @@ \section{Context} The intended runtime family is the present Continuum surface: \begin{itemize}[leftmargin=2em] -\item \Echo{} as the hot runtime, -\item \GitWarp{} as the cold causal runtime, +\item \Echo{} as a Continuum participant, +\item \GitWarp{} as a Continuum participant, \item \TTD{} as the host-neutral debugger protocol surface, \item \Fuse{}-style materializations as host adapters over worldlines, strands, or braids. \end{itemize} +Continuum is the protocol for exchanging witnessed causal history. It is not a +runtime hierarchy, and it does not make \Echo{} the owner of \GitWarp{}'s +participant role. + \section{Design Claim} \begin{principle}[Continuum split] @@ -272,7 +276,7 @@ \section{Host-Indexed Optic Interpretations} \toprule Host or realization context & Interpreted role \\ \midrule -\Echo{} & execute hot-side rewrites \\ +\Echo{} & execute Echo-local rewrites \\ \GitWarp{} & admit and materialize causal patches \\ \TTD{} & expose debugger playback and explanation surfaces \\ \Fuse{} & materialize editable filesystem projections \\ diff --git a/docs/method/backlog/README.md b/docs/method/backlog/README.md index caa37341..74e38a7f 100644 --- a/docs/method/backlog/README.md +++ b/docs/method/backlog/README.md @@ -127,7 +127,7 @@ lanes. | `B1` | backlog root | Unlaned maintenance and reference work. Needs classification or direct pull before it should block committed work. | `B0` or direct human pull. | | `B2` | `bad-code/` | Foundational debt and invariant repair. This lane can legitimately block release or execution work. | `B0`, `B1`, or lower-level debt in `B2`. | | `B3` | `v17.0.0/` | Current committed release work. Explicit per-note edges win here. | `B2`, same-band work, or explicit edges. | -| `B4` | `v18.0.0/`, `up-next/` | Next-major substrate work plus unslotted near-term feature overflow after the active release. | `B2`, `B3`, or explicit same-band edges. | +| `B4` | `v18.0.0/`, `up-next/` | Next-major graph-model work plus unslotted near-term feature overflow after the active release. | `B2`, `B3`, or explicit same-band edges. | | `B5` | `v19.0.0/` | Doctrine/runtime follow-through after the substrate cut. | `B2`, `B3`, `B4`, or explicit same-band edges. | | `B6` | `v20.0.0/`, `v21.0.0/`, `cool-ideas/` | Far-horizon slice-first/runtime and distributed/plural follow-through plus speculative orbit. | Promotion into another lane or completion of lower numbered bands. | @@ -139,8 +139,8 @@ lanes. | backlog root | `B1` | These notes are real work, but still need lane assignment or an explicit pull decision. When `feature:` is present, treat that as the subsystem home while release-home remains undecided. | | `bad-code/` | `B2` | Invariant debt can block `v17.0.0`, `v18.0.0`, and `up-next`. | | `v17.0.0/` | `B3` | This is the active release graph for TypeScript migration and streaming ORSets. | -| `v18.0.0/` | `B4` | This is the next-major graph-substrate convergence lane. | -| `up-next/` | `B4` | Feature-overflow queue behind the active release and next-major substrate work unless explicitly promoted into a numbered lane. | +| `v18.0.0/` | `B4` | This is the next-major graph-model convergence lane. | +| `up-next/` | `B4` | Feature-overflow queue behind the active release and next-major graph-model work unless explicitly promoted into a numbered lane. | | `v19.0.0/` | `B5` | Doctrine, observer, and admission convergence after the substrate cut. | | `v20.0.0/` | `B6` | Slice-first runtime realization after `v19.0.0/` hardens the noun and support law. | | `v21.0.0/` | `B6` | Common-basis, braid, and fuller distributed observer geometry after `v20.0.0/`. | @@ -296,13 +296,14 @@ Prefix counts: | `SLUDGE` | 1 | | `TS` | 11 | -### `v18.0.0/` — `B4` Graph-Substrate Convergence +### `v18.0.0/` — `B4` Graph-Model Convergence Dependency posture: - downstream of `v17.0.0/` - explicit frontmatter edges carry the actual substrate cut order -- this lane is the Echo-shaped graph-model cut, not full repo parity +- this lane is the Continuum-compatible graph-model cut pressure-tested against + Echo, not full repo parity or runtime hierarchy Canonical lane readme: diff --git a/docs/method/backlog/WORKLOADS.md b/docs/method/backlog/WORKLOADS.md index be8715b3..30502d45 100644 --- a/docs/method/backlog/WORKLOADS.md +++ b/docs/method/backlog/WORKLOADS.md @@ -42,7 +42,7 @@ dependency graph and likely write-surface overlap. | `3.0` | `B3` | 5 | 25 | Ready-now v17 foundations and independent release hygiene | | `3.1` | `B3` | 2 | 7 | Downstream v17 runtime split work | | `3.x` parked | `B3` | 1 | 6 | Launch-prep proof and package tail | -| `4` | `B4` | 9 | 43 | v18 substrate cut plus current `up-next/` queue | +| `4` | `B4` | 9 | 43 | v18 graph-model cut plus current `up-next/` queue | | `5` | `B5` | 3 | 11 | v19 observer/admission/runtime convergence | | `6` | `B6` | 10 | 100 | v20/v21 horizon plus speculative orbit | | Grand total | all | 44 | 371 | Full live backlog | @@ -114,12 +114,12 @@ engineering trunks. ## Wave 4 — `B4` -This wave contains the next-major graph-substrate lane and the current -`up-next/` queue. +This wave contains the next-major graph-model lane and the current `up-next/` +queue. | Workload | Count | Items | Agent surface | Preconditions | |----------|------:|-------|---------------|---------------| -| `WL-4A-v18-graph-substrate-convergence` | 8 | `PROTO_echo-shaped-node-records`, `PROTO_echo-shaped-edge-records`, `PROTO_attachment-plane-substrate`, `PROTO_graph-op-algebra-convergence`, `PROTO_content-attachment-plane-cutover`, `PROTO_legacy-props-as-projection`, `INFRA_graph-model-migration-tool`, `TRUST_genesis-replay-equivalence` | Echo-shaped graph model cut, migration tooling, and replay proof | v17 core release work complete | +| `WL-4A-v18-graph-substrate-convergence` | 8 | `PROTO_echo-shaped-node-records`, `PROTO_echo-shaped-edge-records`, `PROTO_attachment-plane-substrate`, `PROTO_graph-op-algebra-convergence`, `PROTO_content-attachment-plane-cutover`, `PROTO_legacy-props-as-projection`, `INFRA_graph-model-migration-tool`, `TRUST_genesis-replay-equivalence` | Continuum-compatible graph model cut pressure-tested against Echo, migration tooling, and replay proof | v17 core release work complete | | `WL-40-upnext-api-capability-contracts` | 4 | `DX_modular-type-declarations`, `DX_plumbing-to-gitplumbing-rename`, `PROTO_controller-capability-interfaces`, `PROTO_patch-commit-visibility-contract` | API capability and declaration-contract cleanup | none | | `WL-41-upnext-runtime-boundaries` | 9 | `DX_max-file-size-policy`, `DX_trailer-codec-dts`, `NDNM_delete-vv-orset-shims`, `PROTO_cbor-op-hydration`, `PROTO_drop-v5-runtime-nouns`, `PROTO_op-consumer-instanceof-migration`, `PROTO_warpkernel-port-cleanup`, `PROTO_warpruntime-open-options-class`, `PROTO_wire-format-migration-edgepropset` | Runtime boundary cleanup and noun drift removal | none | | `WL-42-upnext-streaming-read-chain` | 5 | `NDNM_defaultcodec-to-infrastructure`, `PERF_stream-read-migration`, `PERF_stream-cleanup`, `PERF_async-generator-traversal`, `PERF_stream-memory-tests` | Streaming read migration and memory witnesses | root `PERF_out-of-core-materialization` | @@ -132,7 +132,7 @@ This wave contains the next-major graph-substrate lane and the current ## Wave 5 — `B5` This wave is `v19.0.0`: observer, admission, and doctrine convergence -after the graph-substrate cut. +after the graph-model cut. | Workload | Count | Items | Agent surface | Preconditions | |----------|------:|-------|---------------|---------------| @@ -189,7 +189,7 @@ If you want to staff agents immediately, start here: 3. Pull Wave `3.1` only after the named `v17` prerequisites are true. 4. Run Wave `2` in parallel when a release slice hits the same invariant family. -5. Use Wave `4` for `v18.0.0` planning or selective substrate prep +5. Use Wave `4` for `v18.0.0` planning or selective graph-model prep without starving active `B3` work. 6. Keep Waves `5` and `6` parked unless deliberately working doctrine, horizon, or speculative follow-through. diff --git a/docs/method/backlog/bad-code/RELEASE_TRIAGE.md b/docs/method/backlog/bad-code/RELEASE_TRIAGE.md index 3e95a3f0..0ff84d70 100644 --- a/docs/method/backlog/bad-code/RELEASE_TRIAGE.md +++ b/docs/method/backlog/bad-code/RELEASE_TRIAGE.md @@ -28,8 +28,8 @@ Use the release theme, not the filename prefix, as the slotting rule: | Release | Bad-Code That Belongs Here | |---------|----------------------------| | `v17.0.0` | Current engine cleanup: TypeScript migration fallout, capability/API honesty, `WarpRuntime` deletion fallout, current sync/security hardening, current trie/checkpoint/index correctness, and test/doc debt that blocks the v17 package from being honest. | -| `v18.0.0` | Echo-shaped graph substrate convergence: node/edge record identity, attachment plane, typed payload model, graph-op algebra, graph-model migration, and replay equivalence from genesis. | -| `v19.0.0` | Observer/admission/doctrine convergence: audit/admission seams, observer-readable receipts, patch/session admission semantics, trust/admission boundary models, and doctrine cleanup that should not be mixed into graph-substrate migration. | +| `v18.0.0` | Continuum-compatible graph-model convergence pressure-tested against Echo: node/edge record identity, attachment plane, typed payload model, graph-op algebra, graph-model migration, and replay equivalence from genesis. | +| `v19.0.0` | Observer/admission/doctrine convergence: audit/admission seams, observer-readable receipts, patch/session admission semantics, trust/admission boundary models, and doctrine cleanup that should not be mixed into graph-model migration. | | `v20.0.0` | Slice-first runtime realization: bounded-support reads, streaming/page-shaped APIs, causal indexes, query/index cost surfaces, external-memory global operators, and materialization paths that must stop assuming whole-graph residency. | | `v21.0.0` | Distributed observer geometry and admission reality: strand/braid/common-basis/local-site semantics, merge runtime nouns, witnessed admission, conflict witnesses, wormhole/plurality surfaces, and public noun cleanup for those later semantics. | @@ -70,10 +70,10 @@ Other v17 recheck candidates: ## `v18.0.0` Fit -The first metadata pass promoted only graph-substrate bad-code into +The first metadata pass promoted only graph-model bad-code into `v18.0.0`. This should stay narrow. -Cards now pinned to v18 for the Echo-shaped graph substrate cycle: +Cards now pinned to v18 for the graph-model convergence cycle: - `CAST_warpstate-prop-unknown-value`: property value truth belongs with typed attachment/payload substrate decisions. - `MODEL_neighbor-edge-typedef`: neighbor edge shape should line up with stable edge identity and edge-record nouns. @@ -199,7 +199,7 @@ The first metadata pass did this: 3. Pulled the direct `WarpRuntime`/Worldline escape-hatch cards forward into v17 or graveyard them if the current runtime-deletion line already removed the smell. -4. Promoted only graph-substrate cards into v18. Do not move generic +4. Promoted only graph-model cards into v18. Do not move generic typedef cleanup there just because v18 has room. 5. Recomputed bad-code release counts from frontmatter and updated `bad-code/README.md`. @@ -212,7 +212,7 @@ Use feature/release overlap: 1. During the v17 burndown, pay down or graveyard bad-code cards that sit in the files already touched by the active v17 task. -2. At the v18 pull, move only the graph-substrate candidates listed +2. At the v18 pull, move only the graph-model candidates listed above into the v18 lane and leave unrelated cleanup behind. 3. At the v19 pull, resolve admission/trust/audit cards as part of the observer/admission surface work. diff --git a/docs/method/backlog/v18.0.0/PROTO_echo-shaped-edge-records.md b/docs/method/backlog/v18.0.0/PROTO_echo-shaped-edge-records.md index 2d8101f2..16f92bb4 100644 --- a/docs/method/backlog/v18.0.0/PROTO_echo-shaped-edge-records.md +++ b/docs/method/backlog/v18.0.0/PROTO_echo-shaped-edge-records.md @@ -8,13 +8,17 @@ blocks: feature: graph-model-substrate --- -# Echo-shaped edge records +# Shared graph-model edge records + +Identity note: the backlog id keeps the older `echo-shaped` shorthand for +continuity. The target is graph-model alignment pressure-tested by Echo, not +Echo ownership of `git-warp`. ## Why `git-warp` still identifies edges by the `(from, to, label)` triple -and derived key encodings. Echo's substrate gives edges first-class -identity and treats edge type as part of the record, not the identity +and derived key encodings. Echo has already pressure-tested edges as +first-class records where edge type is part of the record, not the identity carrier. Shared graph shape requires stable edge records. diff --git a/docs/method/backlog/v18.0.0/PROTO_echo-shaped-node-records.md b/docs/method/backlog/v18.0.0/PROTO_echo-shaped-node-records.md index fcf1152c..7861ce70 100644 --- a/docs/method/backlog/v18.0.0/PROTO_echo-shaped-node-records.md +++ b/docs/method/backlog/v18.0.0/PROTO_echo-shaped-node-records.md @@ -8,12 +8,16 @@ blocks: feature: graph-model-substrate --- -# Echo-shaped node records +# Shared graph-model node records + +Identity note: the backlog id keeps the older `echo-shaped` shorthand for +continuity. The target is graph-model alignment pressure-tested by Echo, not +Echo ownership of `git-warp`. ## Why `git-warp` still treats node identity as a bare string plus property -bag fallout. Echo's substrate treats nodes as skeleton records with +bag fallout. Echo has already pressure-tested nodes as skeleton records with stable identity and explicit type. If the repos are going to share the same graph model, node records diff --git a/docs/method/backlog/v18.0.0/README.md b/docs/method/backlog/v18.0.0/README.md index 77e76e32..82dd5327 100644 --- a/docs/method/backlog/v18.0.0/README.md +++ b/docs/method/backlog/v18.0.0/README.md @@ -1,10 +1,16 @@ -# v18.0.0 — Echo-Shaped Graph Substrate Convergence +# v18.0.0 — Continuum-Compatible Graph Model Convergence -The hill: make `git-warp` and Echo share the same graph substrate -shape without pretending they must immediately share the same public -API, admission model, or runtime shell. +The hill: make `git-warp`'s graph model compatible with the concrete +shape Echo has already exercised while keeping both engines as equal +Continuum participants. They do not need to share the same public API, +admission model, or runtime shell. -This release cuts the graph layer to the Echo-shaped two-plane model: +Doctrine note: `PROTO_echo-shaped-*` task identities are historical +backlog shorthand for graph-model alignment pressure from Echo. They do +not mean Echo owns `git-warp`, and they do not make Continuum a runtime +hierarchy. + +This release cuts the graph layer toward the shared two-plane model: - skeleton-only node records - skeleton-only edge records with stable edge identity @@ -55,10 +61,9 @@ LAYER 2 (migration and proof): ## Practical rule -`v18.0.0` is graph-substrate convergence, not "make git-warp become -Echo." Keep the `git-warp` causal envelope if it can faithfully carry -the shared graph model. Change the envelope only if replay honesty -requires it. +`v18.0.0` is graph-model convergence, not "make git-warp become Echo." +Keep the `git-warp` causal envelope if it can faithfully carry the shared +graph model. Change the envelope only if replay honesty requires it. ## Status key diff --git a/docs/method/retro/0145-push-pr-review-merge/push-pr-review-merge.md b/docs/method/retro/0145-push-pr-review-merge/push-pr-review-merge.md new file mode 100644 index 00000000..30e8df71 --- /dev/null +++ b/docs/method/retro/0145-push-pr-review-merge/push-pr-review-merge.md @@ -0,0 +1,38 @@ +# 0145 Push PR Review Merge Retro + +## Outcome + +`REL_push-pr-review-merge` is closed. The v17 release branch was merged to +`main`, the signed `v17.0.0` tag was created, npm and JSR publish recovery +completed, and the short-lived release branches were pruned from `origin`. + +## What Went Well + +- The final release coordination happened through visible PR history instead of + local-only release state. +- Follow-up repair PRs kept publication and CI hardening close to the release + merge, which makes the release story auditable from `main`. +- Registry checks confirmed that both npm and JSR expose `17.0.0` as the + current package version. + +## What Was Messy + +- `BEARING.md` and the 0145 design doc drifted behind reality after the + package published. +- The v17 DAG still showed the final coordination node as open after the branch + had landed. +- Local git fsmonitor was producing noisy status/diff warnings during the + closeout inspection. + +## Follow-Up + +Start v18 from a truthful signpost: Continuum/WARP Optic compatibility through +Wesley-generated artifacts, explicit evidence posture, and `warp-ttd` +acceptance over generated-family facts. + +## Battle Report + +The release train made it into the station, then the station sign kept saying +"boarding soon." This retro fixes the sign. The next mess is bigger: teach +`git-warp` to speak Continuum contract families without dressing adapter +folklore up as native witnesshood. diff --git a/index.ts b/index.ts index e4719aed..ce8b8572 100644 --- a/index.ts +++ b/index.ts @@ -46,6 +46,7 @@ import NoOpLogger from './src/infrastructure/adapters/NoOpLogger.ts'; import ConsoleLogger, { LogLevel } from './src/infrastructure/adapters/ConsoleLogger.ts'; import { AuditError, + ContinuumArtifactAuthorityError, EncryptionError, ForkError, IndexError, @@ -207,6 +208,14 @@ import { exportCoordinateComparisonFact, exportCoordinateTransferPlanFact, } from './src/domain/services/CoordinateFactExport.ts'; +import ContinuumArtifactAuthority from './src/domain/continuum/ContinuumArtifactAuthority.ts'; +import ContinuumArtifactDescriptor from './src/domain/continuum/ContinuumArtifactDescriptor.ts'; +import ContinuumArtifactIngestionPolicy from './src/domain/continuum/ContinuumArtifactIngestionPolicy.ts'; +import ContinuumFamilyId from './src/domain/continuum/ContinuumFamilyId.ts'; +import ContinuumArtifactJsonFileAdapter from './src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts'; +import type { ContinuumArtifactAuthorityValue } from './src/domain/continuum/ContinuumArtifactAuthority.ts'; +import type { ContinuumArtifactDescriptorFields } from './src/domain/continuum/ContinuumArtifactDescriptor.ts'; +import type { ContinuumFamilyIdValue } from './src/domain/continuum/ContinuumFamilyId.ts'; export { GitGraphAdapter, @@ -247,6 +256,7 @@ export { // Error types for integrity failure handling AuditError, + ContinuumArtifactAuthorityError, EncryptionError, PatchError, ForkError, @@ -318,6 +328,13 @@ export { exportCoordinateComparisonFact, exportCoordinateTransferPlanFact, + // Continuum compatibility artifacts + ContinuumArtifactAuthority, + ContinuumArtifactDescriptor, + ContinuumArtifactIngestionPolicy, + ContinuumFamilyId, + ContinuumArtifactJsonFileAdapter, + // Tick receipts (LIGHTHOUSE) createTickReceipt, tickReceiptCanonicalJson, @@ -360,7 +377,14 @@ export { SyncSecret, }; -export type { PropValue, SnapshotPropValue, SyncRateLimitConfig }; +export type { + PropValue, + SnapshotPropValue, + SyncRateLimitConfig, + ContinuumArtifactAuthorityValue, + ContinuumArtifactDescriptorFields, + ContinuumFamilyIdValue, +}; // WarpApp is the primary product-facing API for v15. export default WarpApp; diff --git a/src/domain/continuum/ContinuumArtifactAuthority.ts b/src/domain/continuum/ContinuumArtifactAuthority.ts new file mode 100644 index 00000000..589b1a7a --- /dev/null +++ b/src/domain/continuum/ContinuumArtifactAuthority.ts @@ -0,0 +1,61 @@ +import WarpError from '../errors/WarpError.ts'; + +const GENERATED_ARTIFACT_AUTHORITY = 'generated-artifact'; +const GENERATED_FIXTURE_AUTHORITY = 'generated-fixture'; +const LOCAL_MIRROR_AUTHORITY = 'local-mirror'; +const HANDWRITTEN_MIRROR_AUTHORITY = 'handwritten-mirror'; + +export type ContinuumArtifactAuthorityValue = + | typeof GENERATED_ARTIFACT_AUTHORITY + | typeof GENERATED_FIXTURE_AUTHORITY + | typeof LOCAL_MIRROR_AUTHORITY + | typeof HANDWRITTEN_MIRROR_AUTHORITY; + +export const CONTINUUM_ARTIFACT_AUTHORITIES: readonly ContinuumArtifactAuthorityValue[] = Object.freeze([ + GENERATED_ARTIFACT_AUTHORITY, + GENERATED_FIXTURE_AUTHORITY, + LOCAL_MIRROR_AUTHORITY, + HANDWRITTEN_MIRROR_AUTHORITY, +]); + +/** Runtime-backed authority posture for an ingested Continuum artifact. */ +export default class ContinuumArtifactAuthority { + readonly value: ContinuumArtifactAuthorityValue; + + constructor(value: string) { + this.value = requireContinuumArtifactAuthority(value); + Object.freeze(this); + } + + /** Returns true for Wesley-generated artifacts and documented fixtures. */ + isGeneratedAuthority(): boolean { + return ( + this.value === GENERATED_ARTIFACT_AUTHORITY || + this.value === GENERATED_FIXTURE_AUTHORITY + ); + } + + /** Returns the stable authority string. */ + toString(): string { + return this.value; + } +} + +/** Validates a raw authority posture string. */ +export function requireContinuumArtifactAuthority(value: string): ContinuumArtifactAuthorityValue { + switch (value) { + case GENERATED_ARTIFACT_AUTHORITY: + return GENERATED_ARTIFACT_AUTHORITY; + case GENERATED_FIXTURE_AUTHORITY: + return GENERATED_FIXTURE_AUTHORITY; + case LOCAL_MIRROR_AUTHORITY: + return LOCAL_MIRROR_AUTHORITY; + case HANDWRITTEN_MIRROR_AUTHORITY: + return HANDWRITTEN_MIRROR_AUTHORITY; + default: + throw new WarpError( + `Continuum artifact authority must be one of: ${CONTINUUM_ARTIFACT_AUTHORITIES.join(', ')}`, + 'E_VALIDATION', + ); + } +} diff --git a/src/domain/continuum/ContinuumArtifactDescriptor.ts b/src/domain/continuum/ContinuumArtifactDescriptor.ts new file mode 100644 index 00000000..d474b8b1 --- /dev/null +++ b/src/domain/continuum/ContinuumArtifactDescriptor.ts @@ -0,0 +1,96 @@ +import ContinuumArtifactAuthority from './ContinuumArtifactAuthority.ts'; +import ContinuumFamilyId from './ContinuumFamilyId.ts'; +import WarpError from '../errors/WarpError.ts'; + +export type ContinuumArtifactDescriptorFields = { + readonly familyId: string | ContinuumFamilyId; + readonly version: string; + readonly sourceSchemaPath: string; + readonly generatedBy: string; + readonly artifactKind: string; + readonly authority: string | ContinuumArtifactAuthority; + readonly targets: readonly string[]; + readonly witnessScope?: string; + readonly artifactDigest?: string; +}; + +/** Runtime-backed descriptor for a generated Continuum family artifact. */ +export default class ContinuumArtifactDescriptor { + readonly familyId: ContinuumFamilyId; + readonly version: string; + readonly sourceSchemaPath: string; + readonly generatedBy: string; + readonly artifactKind: string; + readonly authority: ContinuumArtifactAuthority; + readonly targets: readonly string[]; + readonly witnessScope: string | undefined; + readonly artifactDigest: string | undefined; + + constructor(fields: ContinuumArtifactDescriptorFields) { + const { familyId, version, sourceSchemaPath, generatedBy, artifactKind, authority, targets } = fields; + this.familyId = normalizeFamilyId(familyId); + this.version = requireNonEmptyString(version, 'version'); + this.sourceSchemaPath = requireNonEmptyString(sourceSchemaPath, 'sourceSchemaPath'); + this.generatedBy = requireNonEmptyString(generatedBy, 'generatedBy'); + this.artifactKind = requireNonEmptyString(artifactKind, 'artifactKind'); + this.authority = normalizeAuthority(authority); + this.targets = freezeTargets(targets); + this.witnessScope = optionalNonEmptyString(fields.witnessScope, 'witnessScope'); + this.artifactDigest = optionalNonEmptyString(fields.artifactDigest, 'artifactDigest'); + Object.freeze(this); + } + + /** Returns true when the descriptor includes the requested generation target. */ + hasTarget(target: string): boolean { + return this.targets.includes(target); + } + + /** Returns true when the artifact may be used as generated authority. */ + hasGeneratedAuthority(): boolean { + return this.authority.isGeneratedAuthority(); + } +} + +/** Normalizes a family id carrier. */ +function normalizeFamilyId(value: string | ContinuumFamilyId): ContinuumFamilyId { + if (value instanceof ContinuumFamilyId) { + return value; + } + return new ContinuumFamilyId(value); +} + +/** Normalizes an authority carrier. */ +function normalizeAuthority(value: string | ContinuumArtifactAuthority): ContinuumArtifactAuthority { + if (value instanceof ContinuumArtifactAuthority) { + return value; + } + return new ContinuumArtifactAuthority(value); +} + +/** Validates a required non-empty string. */ +function requireNonEmptyString(value: string, name: string): string { + if (value.length === 0) { + throw new WarpError(`${name} must be a non-empty string`, 'E_VALIDATION'); + } + return value; +} + +/** Validates an optional non-empty string. */ +function optionalNonEmptyString(value: string | undefined, name: string): string | undefined { + if (value === undefined) { + return undefined; + } + return requireNonEmptyString(value, name); +} + +/** Freezes and validates a generated target list. */ +function freezeTargets(targets: readonly string[]): readonly string[] { + if (targets.length === 0) { + throw new WarpError('targets must contain at least one generated target', 'E_VALIDATION'); + } + const normalized: string[] = []; + for (const target of targets) { + normalized.push(requireNonEmptyString(target, 'targets[]')); + } + return Object.freeze(normalized); +} diff --git a/src/domain/continuum/ContinuumArtifactIngestionPolicy.ts b/src/domain/continuum/ContinuumArtifactIngestionPolicy.ts new file mode 100644 index 00000000..bd0fad1b --- /dev/null +++ b/src/domain/continuum/ContinuumArtifactIngestionPolicy.ts @@ -0,0 +1,21 @@ +import ContinuumArtifactAuthorityError from '../errors/ContinuumArtifactAuthorityError.ts'; +import type ContinuumArtifactDescriptor from './ContinuumArtifactDescriptor.ts'; + +/** Policy gate for admitting generated Continuum family artifacts. */ +export default class ContinuumArtifactIngestionPolicy { + /** Accepts generated artifacts and documented fixtures, rejecting mirrors. */ + ingest(descriptor: ContinuumArtifactDescriptor): ContinuumArtifactDescriptor { + this.assertGeneratedAuthority(descriptor); + return descriptor; + } + + /** Rejects descriptors whose authority would make local mirrors canonical. */ + assertGeneratedAuthority(descriptor: ContinuumArtifactDescriptor): void { + if (descriptor.hasGeneratedAuthority()) { + return; + } + throw new ContinuumArtifactAuthorityError( + `Continuum family ${descriptor.familyId.toString()} must be loaded from a generated artifact or fixture, not ${descriptor.authority.toString()}`, + ); + } +} diff --git a/src/domain/continuum/ContinuumFamilyId.ts b/src/domain/continuum/ContinuumFamilyId.ts new file mode 100644 index 00000000..7c15288e --- /dev/null +++ b/src/domain/continuum/ContinuumFamilyId.ts @@ -0,0 +1,58 @@ +import WarpError from '../errors/WarpError.ts'; + +const RECEIPT_FAMILY_ID = 'receipt-family'; +const SETTLEMENT_FAMILY_ID = 'settlement-family'; +const NEIGHBORHOOD_CORE_FAMILY_ID = 'neighborhood-core-family'; +const RUNTIME_BOUNDARY_FAMILY_ID = 'runtime-boundary-family'; + +export type ContinuumFamilyIdValue = + | typeof RECEIPT_FAMILY_ID + | typeof SETTLEMENT_FAMILY_ID + | typeof NEIGHBORHOOD_CORE_FAMILY_ID + | typeof RUNTIME_BOUNDARY_FAMILY_ID; + +export const CONTINUUM_FAMILY_IDS: readonly ContinuumFamilyIdValue[] = Object.freeze([ + RECEIPT_FAMILY_ID, + SETTLEMENT_FAMILY_ID, + NEIGHBORHOOD_CORE_FAMILY_ID, + RUNTIME_BOUNDARY_FAMILY_ID, +]); + +/** Runtime-backed identifier for a Continuum-owned contract family. */ +export default class ContinuumFamilyId { + readonly value: ContinuumFamilyIdValue; + + constructor(value: string) { + this.value = requireContinuumFamilyId(value); + Object.freeze(this); + } + + /** Returns true when both ids name the same Continuum family. */ + equals(other: ContinuumFamilyId): boolean { + return this.value === other.value; + } + + /** Returns the stable family id string. */ + toString(): string { + return this.value; + } +} + +/** Validates a raw family id string. */ +export function requireContinuumFamilyId(value: string): ContinuumFamilyIdValue { + switch (value) { + case RECEIPT_FAMILY_ID: + return RECEIPT_FAMILY_ID; + case SETTLEMENT_FAMILY_ID: + return SETTLEMENT_FAMILY_ID; + case NEIGHBORHOOD_CORE_FAMILY_ID: + return NEIGHBORHOOD_CORE_FAMILY_ID; + case RUNTIME_BOUNDARY_FAMILY_ID: + return RUNTIME_BOUNDARY_FAMILY_ID; + default: + throw new WarpError( + `Continuum family id must be one of: ${CONTINUUM_FAMILY_IDS.join(', ')}`, + 'E_VALIDATION', + ); + } +} diff --git a/src/domain/errors/ContinuumArtifactAuthorityError.ts b/src/domain/errors/ContinuumArtifactAuthorityError.ts new file mode 100644 index 00000000..4734cd51 --- /dev/null +++ b/src/domain/errors/ContinuumArtifactAuthorityError.ts @@ -0,0 +1,8 @@ +import WarpError, { type WarpErrorOptions } from './WarpError.ts'; + +/** Error thrown when a Continuum artifact would create shadow authority. */ +export default class ContinuumArtifactAuthorityError extends WarpError { + constructor(message: string, options: WarpErrorOptions = {}) { + super(message, 'E_CONTINUUM_ARTIFACT_AUTHORITY', options); + } +} diff --git a/src/domain/errors/index.ts b/src/domain/errors/index.ts index 2dd7cb41..f087fcc3 100644 --- a/src/domain/errors/index.ts +++ b/src/domain/errors/index.ts @@ -1,6 +1,7 @@ /** Custom error classes for domain operations. */ export { default as AuditError } from './AuditError.ts'; +export { default as ContinuumArtifactAuthorityError } from './ContinuumArtifactAuthorityError.ts'; export { default as EncryptionError } from './EncryptionError.ts'; export { default as ForkError } from './ForkError.ts'; export { default as IndexError } from './IndexError.ts'; diff --git a/src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts b/src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts new file mode 100644 index 00000000..60042a9e --- /dev/null +++ b/src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts @@ -0,0 +1,115 @@ +import { readFile } from 'node:fs/promises'; + +import ContinuumArtifactDescriptor, { + type ContinuumArtifactDescriptorFields, +} from '../../domain/continuum/ContinuumArtifactDescriptor.ts'; +import ContinuumArtifactIngestionPolicy from '../../domain/continuum/ContinuumArtifactIngestionPolicy.ts'; +import AdapterValidationError from '../../domain/errors/AdapterValidationError.ts'; + +type JsonObject = Readonly>; + +/** Loads Continuum artifact descriptors from JSON files at the adapter edge. */ +export default class ContinuumArtifactJsonFileAdapter { + private readonly policy: ContinuumArtifactIngestionPolicy; + + constructor(policy: ContinuumArtifactIngestionPolicy = new ContinuumArtifactIngestionPolicy()) { + this.policy = policy; + } + + /** Reads and ingests a generated artifact descriptor from disk. */ + async loadFile(path: string): Promise { + const raw = await readFile(path, 'utf8'); + return this.loadString(raw); + } + + /** Ingests a generated artifact descriptor from JSON text. */ + loadString(raw: string): ContinuumArtifactDescriptor { + const parsed: unknown = JSON.parse(raw); + const fields = parseDescriptorFields(parsed); + return this.policy.ingest(new ContinuumArtifactDescriptor(fields)); + } +} + +/** Converts untrusted JSON into descriptor fields. */ +function parseDescriptorFields(value: unknown): ContinuumArtifactDescriptorFields { + const source = requireJsonObject(value); + const base = { + familyId: readRequiredString(source, 'familyId'), + version: readRequiredString(source, 'version'), + sourceSchemaPath: readRequiredString(source, 'sourceSchemaPath'), + generatedBy: readRequiredString(source, 'generatedBy'), + artifactKind: readRequiredString(source, 'artifactKind'), + authority: readRequiredString(source, 'authority'), + targets: readStringArray(source, 'targets'), + }; + return withOptionalFields(base, source); +} + +/** Adds optional descriptor fields when present. */ +function withOptionalFields( + base: ContinuumArtifactDescriptorFields, + source: JsonObject, +): ContinuumArtifactDescriptorFields { + const witnessScope = readOptionalString(source, 'witnessScope'); + const artifactDigest = readOptionalString(source, 'artifactDigest'); + return { + ...base, + ...(witnessScope !== undefined ? { witnessScope } : {}), + ...(artifactDigest !== undefined ? { artifactDigest } : {}), + }; +} + +/** Requires a non-array JSON object. */ +function requireJsonObject(value: unknown): JsonObject { + if (!isJsonObject(value)) { + throw new AdapterValidationError('Continuum artifact descriptor JSON must be an object'); + } + return value; +} + +/** Returns true when a value is a non-array JSON object. */ +function isJsonObject(value: unknown): value is JsonObject { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} + +/** Reads a required string field. */ +function readRequiredString(source: JsonObject, key: string): string { + const value = source[key]; + if (typeof value !== 'string' || value.length === 0) { + throw new AdapterValidationError(`Continuum artifact descriptor field "${key}" must be a non-empty string`); + } + return value; +} + +/** Reads an optional string field. */ +function readOptionalString(source: JsonObject, key: string): string | undefined { + const value = source[key]; + if (value === undefined) { + return undefined; + } + if (typeof value !== 'string' || value.length === 0) { + throw new AdapterValidationError(`Continuum artifact descriptor field "${key}" must be a non-empty string when present`); + } + return value; +} + +/** Reads a required string array field. */ +function readStringArray(source: JsonObject, key: string): readonly string[] { + const value = source[key]; + if (!Array.isArray(value) || value.length === 0) { + throw new AdapterValidationError(`Continuum artifact descriptor field "${key}" must be a non-empty string array`); + } + const strings: string[] = []; + for (const entry of value) { + strings.push(readStringArrayEntry(entry, key)); + } + return Object.freeze(strings); +} + +/** Reads one string array entry. */ +function readStringArrayEntry(value: unknown, key: string): string { + if (typeof value !== 'string' || value.length === 0) { + throw new AdapterValidationError(`Continuum artifact descriptor field "${key}" must contain only non-empty strings`); + } + return value; +} diff --git a/test/fixtures/continuum/receipt-family-generated-artifact.json b/test/fixtures/continuum/receipt-family-generated-artifact.json new file mode 100644 index 00000000..cc6c9029 --- /dev/null +++ b/test/fixtures/continuum/receipt-family-generated-artifact.json @@ -0,0 +1,11 @@ +{ + "familyId": "receipt-family", + "version": "0.1.0", + "sourceSchemaPath": "~/git/continuum/schemas/continuum-receipt-family.graphql", + "generatedBy": "wesley witness-continuum --scope receipt-family", + "artifactKind": "continuum.family.fixture", + "authority": "generated-fixture", + "targets": ["typescript", "echo"], + "witnessScope": "receipt-family", + "artifactDigest": "sha256:receipt-fixture" +} diff --git a/test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts b/test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts new file mode 100644 index 00000000..b8b86bf2 --- /dev/null +++ b/test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts @@ -0,0 +1,57 @@ +import { describe, expect, it } from 'vitest'; + +import ContinuumArtifactAuthorityError from '../../../../src/domain/errors/ContinuumArtifactAuthorityError.ts'; +import ContinuumArtifactDescriptor from '../../../../src/domain/continuum/ContinuumArtifactDescriptor.ts'; +import ContinuumArtifactIngestionPolicy from '../../../../src/domain/continuum/ContinuumArtifactIngestionPolicy.ts'; +import ContinuumFamilyId from '../../../../src/domain/continuum/ContinuumFamilyId.ts'; + +/** Builds a receipt-family descriptor for policy tests. */ +function makeDescriptor(authority: string): ContinuumArtifactDescriptor { + return new ContinuumArtifactDescriptor({ + familyId: 'receipt-family', + version: '0.1.0', + sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql', + generatedBy: 'wesley witness-continuum --scope receipt-family', + artifactKind: 'continuum.family.fixture', + authority, + targets: ['typescript', 'echo'], + witnessScope: 'receipt-family', + }); +} + +describe('ContinuumArtifactIngestionPolicy', () => { + it('accepts documented generated fixtures', () => { + const descriptor = makeDescriptor('generated-fixture'); + const policy = new ContinuumArtifactIngestionPolicy(); + + expect(policy.ingest(descriptor)).toBe(descriptor); + }); + + it('accepts generated artifacts', () => { + const descriptor = makeDescriptor('generated-artifact'); + const policy = new ContinuumArtifactIngestionPolicy(); + + expect(policy.ingest(descriptor)).toBe(descriptor); + }); + + it('rejects local mirrors as family authority', () => { + const descriptor = makeDescriptor('local-mirror'); + const policy = new ContinuumArtifactIngestionPolicy(); + + expect(() => policy.ingest(descriptor)).toThrow(ContinuumArtifactAuthorityError); + }); + + it('rejects handwritten mirrors as family authority', () => { + const descriptor = makeDescriptor('handwritten-mirror'); + const policy = new ContinuumArtifactIngestionPolicy(); + + expect(() => policy.ingest(descriptor)).toThrow(ContinuumArtifactAuthorityError); + }); + + it('keeps family ids runtime-backed', () => { + const descriptor = makeDescriptor('generated-fixture'); + + expect(descriptor.familyId).toBeInstanceOf(ContinuumFamilyId); + expect(descriptor.familyId.toString()).toBe('receipt-family'); + }); +}); diff --git a/test/unit/domain/errors/index.test.ts b/test/unit/domain/errors/index.test.ts index 30fc4cf7..59c75c57 100644 --- a/test/unit/domain/errors/index.test.ts +++ b/test/unit/domain/errors/index.test.ts @@ -6,6 +6,7 @@ describe('domain/errors index barrel', () => { expect(Object.keys(errors).sort()).toEqual([ 'AuditError', + 'ContinuumArtifactAuthorityError', 'EncryptionError', 'ForkError', 'IndexError', diff --git a/test/unit/domain/index.exports.test.ts b/test/unit/domain/index.exports.test.ts index 9e768ac7..c96d5be5 100644 --- a/test/unit/domain/index.exports.test.ts +++ b/test/unit/domain/index.exports.test.ts @@ -40,6 +40,7 @@ import WarpAppDefault, { TraversalError, OperationAbortedError, Observer, + ContinuumArtifactAuthorityError, // Cancellation utilities checkAborted, @@ -57,6 +58,11 @@ import WarpAppDefault, { compareVisibleState, normalizeVisibleStateScope, scopeMaterializedState, + ContinuumArtifactAuthority, + ContinuumArtifactDescriptor, + ContinuumArtifactIngestionPolicy, + ContinuumFamilyId, + ContinuumArtifactJsonFileAdapter, } from '../../../index.ts'; const { WarpGraph, WarpRuntime, Worldline, ObserverView } = (await import('../../../index.ts') as any); @@ -244,6 +250,36 @@ describe('index.ts exports', () => { expect(OperationAbortedError).toBeDefined(); expect(typeof OperationAbortedError).toBe('function'); }); + + it('exports ContinuumArtifactAuthorityError', () => { + expect(ContinuumArtifactAuthorityError).toBeDefined(); + expect(typeof ContinuumArtifactAuthorityError).toBe('function'); + }); + }); + + describe('Continuum compatibility artifacts', () => { + it('exports the artifact descriptor classes', () => { + expect(ContinuumArtifactAuthority).toBeDefined(); + expect(ContinuumArtifactDescriptor).toBeDefined(); + expect(ContinuumArtifactIngestionPolicy).toBeDefined(); + expect(ContinuumFamilyId).toBeDefined(); + expect(ContinuumArtifactJsonFileAdapter).toBeDefined(); + }); + + it('constructs a generated receipt-family descriptor from public exports', () => { + const descriptor = new ContinuumArtifactDescriptor({ + familyId: 'receipt-family', + version: '0.1.0', + sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql', + generatedBy: 'wesley witness-continuum --scope receipt-family', + artifactKind: 'continuum.family.fixture', + authority: 'generated-fixture', + targets: ['typescript'], + }); + + expect(descriptor.familyId).toBeInstanceOf(ContinuumFamilyId); + expect(descriptor.hasGeneratedAuthority()).toBe(true); + }); }); describe('cancellation utilities', () => { diff --git a/test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts b/test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts new file mode 100644 index 00000000..e1a08079 --- /dev/null +++ b/test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; +import { fileURLToPath } from 'node:url'; + +import ContinuumArtifactJsonFileAdapter from '../../../../src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts'; +import ContinuumArtifactAuthorityError from '../../../../src/domain/errors/ContinuumArtifactAuthorityError.ts'; +import AdapterValidationError from '../../../../src/domain/errors/AdapterValidationError.ts'; + +const generatedFixtureJson = `{ + "familyId": "receipt-family", + "version": "0.1.0", + "sourceSchemaPath": "~/git/continuum/schemas/continuum-receipt-family.graphql", + "generatedBy": "wesley witness-continuum --scope receipt-family", + "artifactKind": "continuum.family.fixture", + "authority": "generated-fixture", + "targets": ["typescript", "echo"], + "witnessScope": "receipt-family", + "artifactDigest": "sha256:receipt-fixture" +}`; + +const localMirrorJson = `{ + "familyId": "receipt-family", + "version": "0.1.0", + "sourceSchemaPath": "src/domain/continuum/local-receipt.ts", + "generatedBy": "git-warp", + "artifactKind": "continuum.family.fixture", + "authority": "local-mirror", + "targets": ["typescript"] +}`; + +const generatedFixturePath = fileURLToPath( + new URL('../../../fixtures/continuum/receipt-family-generated-artifact.json', import.meta.url), +); + +describe('ContinuumArtifactJsonFileAdapter', () => { + it('loads generated fixture descriptors', () => { + const adapter = new ContinuumArtifactJsonFileAdapter(); + const descriptor = adapter.loadString(generatedFixtureJson); + + expect(descriptor.familyId.toString()).toBe('receipt-family'); + expect(descriptor.hasTarget('typescript')).toBe(true); + expect(descriptor.hasGeneratedAuthority()).toBe(true); + expect(descriptor.artifactDigest).toBe('sha256:receipt-fixture'); + }); + + it('loads generated fixture descriptor files', async () => { + const adapter = new ContinuumArtifactJsonFileAdapter(); + const descriptor = await adapter.loadFile(generatedFixturePath); + + expect(descriptor.familyId.toString()).toBe('receipt-family'); + expect(descriptor.witnessScope).toBe('receipt-family'); + }); + + it('rejects local mirrors before they become authority', () => { + const adapter = new ContinuumArtifactJsonFileAdapter(); + + expect(() => adapter.loadString(localMirrorJson)).toThrow(ContinuumArtifactAuthorityError); + }); + + it('rejects malformed descriptor JSON', () => { + const adapter = new ContinuumArtifactJsonFileAdapter(); + + expect(() => adapter.loadString('{ "familyId": "receipt-family" }')).toThrow(AdapterValidationError); + }); +});