feat: ScenarioBranch facade + LF integration mapping v1#265
Conversation
…enario-world agent
Three additive changes that compose existing pieces (Pearl Rung 3
intervention, Lance versioning, archetype meta-state, WorldModelDto)
into a first-class explicit scenario branching surface.
contract/scenario.rs (NEW, ~340 LOC including tests):
ScenarioBranch — named handle with parent_tag, fork_seed,
archetype_prior, intervention list, default NARS inference mode.
ScenarioDiff — three-resolution gestalt diff (graph / fingerprint /
world-model). Composes VersionedGraph::diff + worlds_differ +
WorldModelDto.field_state.dissonance.
ScenarioWorld trait — fork / simulate_forward / forecast_palette /
diff_branches / replay. Zero-dep; concrete impls live downstream.
7 unit tests, all pass.
archetype/world.rs (WIRE, was Unimplemented):
fork(branch) — appends ?branch=<name> URI suffix, resets tick.
Empty branch name → InvalidBranch.
at_tick(tick) — clones with rewound tick, validates tick <= current,
InvalidTick if requested > current.
Archetype crate stays lance-free per ADR-0001; downstream resolver
translates URI suffix → VersionedGraph::tag_version + new dataset
path.
6 new tests, 16 total pass.
archetype/error.rs (EXTEND):
+ InvalidBranch
+ InvalidTick { requested, current }
.claude/agents/scenario-world.md (NEW):
Specialist agent with the full decision tree:
- Time travel vs branching vs intervention (three operations,
not one).
- Why scenario_id column was rejected (5 reasons including
I-VSA-IDENTITIES violation).
- Why a separate scenarios crate was rejected.
- Why URI-suffix branching (keeps archetype lance-free).
- Why CounterfactualSynthesis as default inference mode.
- Why fork_seed (Apache-Temporal-extracted determinism).
- Why palette compose-chain forecast (Chronos-extracted method).
- Why three-resolution diff (gestalt structure preservation).
LF-80/81 reframing: marketplace = portable auditable counterfactuals,
not speculative bundle distribution. Becomes enterprise anchor
product when ScenarioBundle = Ontology + ScenarioBranch set +
ModelBinding + AuditEntry chain + spider-rs evidence URLs.
docs/ScenarioWorldCounterfactual.md (NEW):
Cross-cutting design doc with TL;DR, decision summary table, tools
considered (NARS / Archetype / ONNX / Chronos / Apache Temporal)
and what each contributed, three-resolution diff explanation, and
the LF-80/81 reframing for regulated industries.
240 contract + 16 archetype tests pass. Workspace cargo check clean.
https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
Comprehensive map of all 41 LF + 4 W chunks shipped or queued across
the lance-graph workspace. Producer-side mirror of SMB session's
foundry-parity-checklist.md; lives in lance-graph so future producer
sessions see the state at a glance.
Status totals:
17 DONE (Tier 1 LF-1..8 + W-1..4 + LF-21/22/90/91/92)
2 IN-PR (LF-70, LF-72 on this branch via ScenarioBranch facade)
22 QUEUED (Stage 1 connectors, Stage 2 ontology adds, Stage 3 storage,
Stage 4 search, Stage 5 models, Stage 6 decisions,
Stage 7 LF-73/74/75 forward-sim wiring)
2 DEFERRED (LF-32 sharded writes, LF-53 AIP Logic UI)
2 FUTURE (LF-80/81 marketplace bundles)
Stage 7 redesign documented:
LF-71 (scenario_id column) DROPPED — would widen SIMD sweep + duplicate
Lance versioning. Replaced with role-bind + dataset-path branch identity.
LF-73 simulate_forward — wires existing dormant CounterfactualSynthesis
NARS inference type into ScenarioWorld trait.
LF-74 forecast_palette — Chronos-extracted method (compose-chain over
existing 256-archetype palette + ComposeTable). Adopt the idea,
don't pull in the model.
LF-75 replay — Apache-Temporal-extracted method (deterministic replay
via captured fork_seed). Adopt the idea, don't adopt durable-execution
workflow runtime.
Sequencing recommendation for next 10 chunks ordered by leverage:
1. Merge this branch (Stage 7 + scenario-world agent)
2. LF-12 Pipeline DAG (unblocks Stage 1 connector tier)
3. LF-50/52 ModelRegistry + LlmProvider (xAI/OpenAI/Anthropic/Ollama)
4. LF-20 FunctionSpec
5. LF-23 NotificationSpec
6. LF-31 scan_as_of (almost-free trait expose of existing VersionedGraph)
7. LF-10 Connector registry
8. LF-61 NARS-revision-on-correction
9. LF-73 simulate_forward
10. LF-40 Tantivy full-text search
INTEGRATION_PLANS.md prepended with new v1 entry per board hygiene rule.
https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0289567a11
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let separator = if self.dataset_uri.contains('?') { "&" } else { "?" }; | ||
| Ok(World { | ||
| tick: 0, | ||
| dataset_uri: format!("{}{}branch={}", self.dataset_uri, separator, branch), |
There was a problem hiding this comment.
Percent-encode branch names in forked dataset URI
The branch name is interpolated directly into the query string, so names containing reserved characters (for example &, #, or spaces) produce an ambiguous or malformed URI and can resolve to the wrong branch downstream (e.g., branch=a&b is parsed as branch=a). Since fork accepts arbitrary non-empty branch names, this can silently misroute scenario writes/reads in real workloads where names come from user-defined scenario labels; the branch value should be URL-encoded (or stored separately from URI text) before concatenation.
Useful? React with 👍 / 👎.
Summary
contract::scenario(~340 LOC, 7 tests) — named handle composing Pearl Rung 3 intervention, Lance versioning, archetype meta-state, and WorldModelDto gestalt into explicit counterfactual branchingarchetype::World::fork/at_tickfromUnimplementedstubs to working implementations (URI-suffix branching + tick rewind validation)Stage 7 redesign (LF-70/71/72)
World::forkfull implarchetype::World::fork+ScenarioBranch::newwith fork_seed, archetype_prior, interventionsscenario_idcolumn on every BindSpace SoA rowdiff(base, fork)ScenarioDiffcomposing three resolutions: graph-node + fingerprint-Hamming + gestalt-dissonanceNew chunks added (LF-73/74/75 — queued, not implemented)
simulate_forward— wires dormantNarsInference::CounterfactualSynthesisforecast_palette— Chronos-extracted compose-chain method over existing 256-archetype palettereplay— Apache-Temporal-extracted deterministic replay via fork_seedTest plan
cargo test -p lance-graph-contract --lib scenario— 7 passedcargo test --manifest-path crates/lance-graph-archetype/Cargo.toml --lib— 16 passedcargo clippy -p lance-graph-contract -p lance-graph-archetype— clean on new filescargo check— full workspace cleanhttps://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
Generated by Claude Code