Skip to content

Latest commit

 

History

History
280 lines (212 loc) · 8.57 KB

File metadata and controls

280 lines (212 loc) · 8.57 KB

Migrating to v18.0.0

v18.0.0 makes Worldlines and Optics the first-use public API story for application code.

This is not a removal guide. The lower-level graph capability bag, WarpApp, WarpCore, and materialize-named diagnostic surfaces remain available for compatibility, migrations, substrate tooling, and operator evidence. The migration goal is to stop teaching application code to open a graph and fold state as the normal read path.

What Changes

Area v17 habit v18 preferred shape
Entry point openWarpGraph({ graphName }) openWarpWorldline({ worldlineName })
App writes graph.patches.patch(...) worldline.commit(...)
Live reads graph.query.worldline() worldline.live()
Historical reads graph.query.worldline({ source }) await worldline.seek({ source })
Filtered reads graph.query.observer(...) or worldline.observer(...) worldline.observer(...)
Optic reads graph.query.worldline().optic() Verify existing basis with worldline.prepareOpticBasis(), then use worldline.coordinate().optic()
Whole-state replay graph.materialize() Diagnostic only; use worldline reads for apps
Advanced substrate work WarpApp / WarpCore escape hatches openWarpGraph() capability namespaces

Before And After

Opening

Before:

import { GitGraphAdapter, openWarpGraph } from '@git-stunts/git-warp';
import GitPlumbing from '@git-stunts/plumbing';

const plumbing = new GitPlumbing({ cwd: './team-repo' });
const persistence = new GitGraphAdapter({ plumbing });

const graph = await openWarpGraph({
  persistence,
  graphName: 'events',
  writerId: 'agent-1',
});

After:

import { GitGraphAdapter, openWarpWorldline } from '@git-stunts/git-warp';
import GitPlumbing from '@git-stunts/plumbing';

const plumbing = new GitPlumbing({ cwd: './team-repo' });
const persistence = new GitGraphAdapter({ plumbing });

const events = await openWarpWorldline({
  persistence,
  worldlineName: 'events',
  writerId: 'agent-1',
});

The value previously passed as graphName becomes worldlineName. The underlying storage layout still uses graph refs; the public application noun is now the admitted worldline.

Writing

Before:

const patchSha = await graph.patches.patch((patch) => {
  patch.addNode('task:auth')
    .setProperty('task:auth', 'status', 'open');
});

After:

const patchSha = await events.commit((patch) => {
  patch.addNode('task:auth')
    .setProperty('task:auth', 'status', 'open');
});

Both forms commit one atomic WARP patch and return the patch commit SHA. The v18 form keeps application code on the Worldline-first handle.

Reading Current Truth

Before:

const live = graph.query.worldline();
const props = await live.getNodeProps('task:auth');

After:

const live = events.live();
const props = await live.getNodeProps('task:auth');

events.live() does not expose graphName, materialize(), checkpoint, provenance, sync, strands, or raw core access.

Reading Earlier Truth

Before:

const beforeReview = graph.query.worldline({
  source: {
    kind: 'coordinate',
    frontier: { alice: 'abc123...' },
    ceiling: 12,
  },
});

After:

const beforeReview = await events.seek({
  source: {
    kind: 'coordinate',
    frontier: { alice: 'abc123...' },
    ceiling: 12,
  },
});

Historical reads stay in the read model. Application code should not rebuild old state by manually replaying patches.

Filtered Reads

Before:

const live = graph.query.worldline();
const publicView = await live.observer('public', {
  match: ['task:*', 'service:*'],
  redact: ['internalNotes'],
});

After:

const publicView = await events.observer('public', {
  match: ['task:*', 'service:*'],
  redact: ['internalNotes'],
});

Use observers for product boundaries such as redaction, tenant scoping, and role-specific views.

Optic Reads

Before:

const status = await graph.query.worldline()
  .optic()
  .node('task:auth')
  .prop('status')
  .read();

After:

await events.prepareOpticBasis();
const coordinate = await events.coordinate();

const status = await coordinate
  .optic()
  .node('task:auth')
  .prop('status')
  .read();

Foundation optics require checkpoint-tail basis evidence. prepareOpticBasis() verifies existing basis evidence and fails closed when it is missing; it does not materialize the full graph to manufacture a basis. This path is transitional until gate 2 adds memory-budgeted basis and tail providers. If an optic reports E_OPTIC_NO_BOUNDED_BASIS, repair or build the checkpoint-tail evidence through operator tooling, or use events.live(), events.seek(...), or an observer read when you do not need Optic identity.

What Stays Compatible

Keep openWarpGraph() when you intentionally need:

  • graph.strands for speculative lanes, braid overlays, comparison, or transfer planning.
  • graph.provenance for patch-level explanation and evidence.
  • graph.checkpoint for operational checkpoint and GC work.
  • graph.sync for programmatic sync and serving.
  • graph.comparison for coordinate comparison and transfer facts.
  • graph.subscriptions for reactive push-style state notifications.
  • graph.materialize, materializeStrand, or materializeSlice for diagnostic replay, migration evidence, and tooling.

Keep WarpApp or WarpCore only when a compatibility dependency still expects that facade shape. New application code should not add new dependencies on those facades.

What v18 Does Not Claim

v18 does not claim:

  • full retirement of legacy content/property storage,
  • native Continuum witnesshood,
  • broader slice-first read execution beyond the bounded-memory public path, or
  • zero use of materialization inside the runtime.

The v18 public claim is narrower and stronger: application callers have a Worldline-first API, graph/materialize-first surfaces are compatibility, diagnostic, migration, or substrate tools, and public release is blocked until normal reads, writes, content lookup, and sync pass the bounded-memory large-graph product gate.

Migration Checklist

  • Replace app-facing openWarpGraph({ graphName }) calls with openWarpWorldline({ worldlineName }).
  • Replace app-facing graph.patches.patch(...) calls with worldline.commit(...).
  • Replace live graph.query.worldline() reads with worldline.live().
  • Replace historical graph.query.worldline({ source }) reads with await worldline.seek({ source }).
  • Replace app-facing observer creation with worldline.observer(...).
  • Keep openWarpGraph() only where a caller needs an advanced capability namespace.
  • Remove app-facing materialize() calls unless the caller is explicitly diagnostic, migratory, or operator tooling.
  • Run npm run typecheck, npm run test, or the equivalent consumer checks for your project.

Verification Plan

Use this plan after migrating a consumer:

Scenario Expected Result
openWarpWorldline({ worldlineName, writerId }) opens successfully Returned handle has worldlineName and writerId
openWarpWorldline({ graphName, writerId }) is attempted Typecheck rejects graphName
worldline.commit(...) writes a node worldline.live().getNodeProps(...) sees it
worldline.seek({ source }) pins a historical coordinate Later patches are hidden from the pinned read
worldline.observer(...) redacts properties Redacted keys are absent from observer reads
worldline.materialize is accessed Typecheck rejects the property
Existing diagnostic openWarpGraph() tooling remains in place Substrate commands still compile and run

Troubleshooting

graphName Is Not Accepted

WarpWorldlineOpenOptions uses worldlineName. Rename the option at the application boundary. Do not pass both names.

materialize Is Missing

That is intentional on WarpWorldline. Use live(), seek(...), observer(...), or optic() for app reads. Move diagnostic replay code to a small adapter that opens openWarpGraph() explicitly.

Optic Reads Reject With E_OPTIC_NO_BOUNDED_BASIS

The optic does not have checkpoint-tail basis evidence. Use a worldline or observer read for the same question, or repair/build the checkpoint-tail evidence required by the optic path.

I Need Strands

Strands remain an advanced graph capability. Open openWarpGraph() in the module that owns speculative-lane behavior, and keep the rest of the app on the Worldline-first surface.