Journey Specification
Guided walkthrough format using DAG-structured steps with block descriptors and narratives
Journey Specification
A Journey is a directed acyclic graph (DAG) of Steps that guides a user through a narrative experience. Each step combines prose (Markdown narrative) with a visual block descriptor, creating an agent-narrated interactive tour.
Journeys are the primary human interaction mode in WeftOS. While power users operate through the console, most users experience changes, reviews, and onboarding through guided journeys generated by the Weaver.
Key Properties
- DAG structure: Steps form a directed acyclic graph. No loops. Allows branching (user chooses path) but prevents infinite cycles.
- Each step is a BlockDescriptor: The visual content of every step is a standard block descriptor. All block types from the catalog are available.
- Narrative-first: Each step has a Markdown narrative explaining context before the visual content.
- Breakout support: Users can exit the guided flow at any step and enter free assembly mode on the Lego canvas.
Journey Format
Root Document
interface Journey {
/** Schema version */
version: "0.2.0";
/** Unique journey identifier */
id: string;
/** Journey metadata */
meta: JourneyMeta;
/** Starting step ID -- must be a key in the steps list */
start: string;
/** Ordered list of steps */
steps: JourneyStep[];
}
interface JourneyMeta {
/** Human-readable title */
title: string;
/** Description for catalog display */
description: string;
/** Creator identifier: "agent:<id>" or "user:<name>" */
creator: string;
/** ISO 8601 creation timestamp */
created_at: string;
/** Source material that generated this journey */
source?: string;
/** Tags for search and filtering */
tags?: string[];
}Step Format
interface JourneyStep {
/** Unique step ID within this journey */
id: string;
/** Human-readable step title (shown in progress bar) */
title: string;
/** Narrative text explaining this step (Markdown) */
narrative: string;
/** Block descriptor defining the visual content */
block: BlockDescriptor;
/** Transitions to possible next steps */
next: JourneyTransition[];
/** Whether the user can break out to free assembly mode */
allow_breakout?: boolean;
}The narrative field supports full Markdown including headings, code blocks with syntax highlighting, bold/italic emphasis, lists, and links.
The block field is a complete BlockDescriptor as defined in the Block Descriptor Schema. It can contain any combination of blocks, nested to the standard 6-level depth limit.
Transition Format
interface JourneyTransition {
/** Target step ID */
target: string;
/** Label for the transition button */
label: string;
/** Optional condition: transition only visible if condition evaluates true */
condition?: TransitionCondition;
}
interface TransitionCondition {
/** $state path to evaluate */
$state: string;
/** Comparison operator */
op: "eq" | "neq" | "gt" | "lt" | "exists";
/** Value to compare against (not needed for "exists") */
value?: unknown;
}Transitions define the edges of the DAG. When a step has multiple transitions, they render as labeled buttons. The user picks which path to follow.
Condition evaluation: If a transition has a condition, the renderer evaluates it against the current StateStore. The transition button is hidden (not disabled) if the condition is false. This enables contextual branching -- e.g., "Show security details" only appears if the project has security warnings.
DAG Structure Rules
- Acyclic: No step may be reachable from itself via transitions. The journey engine validates this at load time.
- Reachable: Every step must be reachable from
startvia at least one path. Unreachable steps are a validation error. - Terminal steps: Steps with an empty
nextarray are terminal. The journey shows a "Complete" indicator. - Max steps: A single journey may contain at most 50 steps. Longer narratives should be split into linked journeys.
- Max transitions per step: 5. More than 5 choices is cognitively overloading.
DAG with Branching
[Overview]
/ \
/ \
[Tool Signing] [WASM Shell]
\ /
\ /
[Summary]The user at "Overview" can choose either path. Both converge at "Summary".
Weaver Journey Generation
The Weaver generates journeys from structured inputs. The primary use case is git diff review.
Input Sources
| Source Type | Format | Description |
|---|---|---|
git-diff:<from>..<to> | Commit range | Generate a tour of code changes between two commits |
git-pr:<number> | PR number | Generate a review tour for a pull request |
manual | User-provided step outlines | Weaver fleshes out narratives and selects block types |
assessment:<path> | Project path | Generate an assessment tour of a codebase |
Generation Pipeline (git-diff)
Trigger generation with:
weaver.generate-journey --source git-diff:abc123..def456Step 1: Parse the diff -- The Weaver receives the raw diff and parses it into semantic chunks: files changed (grouped by directory/module), functions modified (AST-level analysis where possible), tests added or modified, configuration changes, documentation changes.
Step 2: Order by dependency -- If change B depends on change A (e.g., B calls a function introduced in A), A comes first in the DAG. The Weaver uses the CausalGraph to determine dependencies when available.
Step 3: Generate steps -- For each semantic chunk, the Weaver generates a JourneyStep:
| Chunk Type | Narrative Focus | Block Types Used |
|---|---|---|
| New module | What it does, why it exists | DiffViewer + CodeEditor (read-only) |
| Function change | Before/after behavior, why changed | DiffViewer |
| Test addition | What is being tested, coverage impact | DiffViewer + Metric (coverage) |
| Config change | What changed, impact | DataTable (before/after config) |
| Bug fix | Root cause, how the fix works | DiffViewer + CausalGraph (related ECC nodes) |
Each step's narrative is generated as concise, technical prose explaining the change in context. The Weaver avoids restating what the diff shows; instead it explains why.
Step 4: Add overview and summary steps -- Overview step: aggregate metrics (files changed, lines added/removed, tests added), high-level description. Summary step: overall assessment, what is left to do, link to next sprint.
Step 5: Validate -- Every generated BlockDescriptor is validated against the catalog schema. If validation fails, the Weaver falls back to a simpler block combination (e.g., Markdown only).
Step 6: Return the Journey document -- The complete Journey JSON is returned. It can be rendered immediately in the GUI, saved to IndexedDB for later, or committed to the ExoChain as a governed artifact.
Journey Rendering
Layout
The journey UI renders as a focused mode within the Lego canvas:
+------------------------------------------------------------------+
| Step 2 of 4: D9 Tool Signing [Free Mode] |
+------------------------------------------------------------------+
| |
| Tool signing ensures every WASM tool is cryptographically |
| verified before execution. Ed25519 signatures are checked |
| against a trust root anchored in the ExoChain genesis block. |
| |
+------------------------------------------------------------------+
| |
| +----------------------------+---------------------------+ |
| | BEFORE (validate.rs) | AFTER (validate.rs) | |
| | | | |
| | fn validate(tool: &Tool) | fn validate(tool: &Tool) | |
| | -> Result<()> { | -> Result<()> { | |
| | // no signature check | + verify_ed25519( | |
| | Ok(()) | + &tool.signature, | |
| | } | + &trust_root | |
| | | + )?; | |
| | | Ok(()) | |
| | | } | |
| +----------------------------+---------------------------+ |
| |
+------------------------------------------------------------------+
| [< Overview] [Next: WASM Shell >] |
+------------------------------------------------------------------+Components
- Step indicator: Breadcrumb or progress bar showing position in the DAG
- Narrative panel: Markdown rendered at the top of each step
- Content area: The step's
BlockDescriptorrendered below the narrative - Navigation buttons: "Next" / "Previous" plus any conditional transitions
- Free Mode button: If
allow_breakoutis true, detaches the block assembly to the main canvas
Breakout Mode
When the user clicks "Free Mode":
- The current step's block assembly is cloned onto the main Lego canvas
- The user can modify it freely (add blocks, remove blocks, rewire connections)
- A floating "Return to Journey" button remains visible
- Clicking "Return to Journey" discards modifications and resumes the journey at the same step
Multi-target Rendering
| Target | Journey Behavior |
|---|---|
| Web (React) | Full visual experience as described above |
| Terminal | Narrative printed as formatted text. Block descriptors rendered as ASCII. Navigation via numbered choices. |
| Mentra HUD | Narrative truncated to 3 lines. Block descriptor rendered per HUD constraints. Voice commands: "next", "back", "details". |
| Shell | Narrative printed. Blocks rendered as plain text tables. |
Persistence
| Storage | Format | Use Case |
|---|---|---|
| IndexedDB | JSON string keyed by journey ID | User's local journey history |
| ExoChain | ChainEvent with kind gui.journey.save | Governed journey storage, shared across users |
| File system | .weftos/journeys/<id>.json | Export/import for offline use |
Journeys committed to the ExoChain are immutable. Modifications create new journey versions with a source referencing the original.