Context Lab
Context Lab is the editor for a deterministic context compiler. Files in a git repository are the source of truth. A model is optional; context resolution, regression, tests, sweeps and Builds work without one.
Workspace
Open a project from the home screen or pass --project <folder> to the native app.
Use --context <folder> to open the same project's Context engineering workspace instead. Home's New context project opens Context engineering; Open the Lab → New project creates files and opens the Lab. The top bar shows the repository, its git branch and change count (or not a git repository), and the engine verbs: Resolve (⌘R/Ctrl+R), Test (⌘T/Ctrl+T), Sweep and Build. They run the same engine commands as bin/seif. The selector row chooses agent, objective, profile and environment, and states what is deployed there (UNKNOWN when no Build binding exists) and that no model is called.
The activity rail switches the Explorer between Files, Search, Git (changed files only), Tests and Experiments, and opens Traces, Releases and the Living Studio graph. Clicking Files again, or ⌘B, collapses the Explorer. Badges count git changes and failing tests.
The Explorer is the real project tree. Folders collapse. Each file carries its role from the engine (agent, context, objective, knowledge, policy, internal, tool, test, guard, experiment, binding, manifest), estimated tokens, a selection bar when retained traces exist, and its git state (M, A, D, U). After a test run, test files show ✓/✕/?. When seif.yaml exists, context-project.json is marked legacy: it is not authoritative. Build lineage and locally retained traces sit beneath it.
Creating, renaming and deleting files
+ in the Explorer (or ⌘N, or New file here… on a folder's context menu) opens a composer instead of writing anything:
- Choose what it is: Knowledge, Policy, Check (a Context Test for the current question and inputs) or Experiment (a budget sweep over your checks).
- Give it a name. The file name is derived from it (
Refund exceptions→knowledge/refund-exceptions.md). Existing files are never overwritten; a suffix is added. - For knowledge and policy, pick the area (layer). The composer states, before anything is written, how that area reaches the agent under the current profile: always given, given when it matches the question, behind a door, never shared, or not used by this task yet.
- + New area… starts out of view. Tick Let the agent use it when relevant to also add a retrieve rule to the current profile's
context.yaml. Without it, no rule changes.
The new file opens with its placeholder selected, so typing replaces it. A legacy JSON project is converted to files first, keeping its JSON.
Right-click a file for Rename… or Move to trash…. Renaming keeps the extension and refuses to overwrite. Deleting moves the file into .seif/trash/<time>/, so it can be restored from the file system. Both warn when checks mention the file. seif.yaml, context-project.json and everything under agents/ define the project; they can be edited but not renamed or deleted here.
Tabs work like VS Code's preview tabs. A single click in the Explorer, Problems or Tests opens the file in one italic preview tab, which the next single click replaces. Editing a file or double-clicking it (in the Explorer or on its tab) keeps it open. The tab strip scrolls with the wheel or trackpad without an overlay scrollbar. ⌄ lists every open editor and can close the others. File tooltips open beside the row after a pause, never over the name.
Zoom and text size
- Interface zoom scales everything in the window, from 80% to 160%, and stays clickable. Use ⌘+ / ⌘− / ⌘0 (Ctrl on Windows and Linux), the − 100% + control in the status bar, or View › Zoom In / Zoom Out / Actual Size in the macOS menu bar.
- Reading text changes only the editor, the Console and the section lenses, from 10 to 24 px. Use ⌥⌘+ / ⌥⌘− / ⌥⌘0, the A− 13 A+ control in the status bar, or View › Bigger Text / Smaller Text.
Both settings are also in the command palette. They are saved per user and apply to the Lab, the World and the home screen.
Editor
Markdown and YAML open in AvaloniaEdit with TextMate highlighting and tabs. Engine facts are drawn in place; the view computes none of them:
- Selection gutter between line numbers and text: solid green = selected, dashed amber = eligible but cut by a rule, red = excluded, grey = not applicable, violet = UNKNOWN.
- Section lenses at the end of each heading: state, the engine's reason (for example 682 days old; rule allows 45), estimated tokens, referring tests and usage among retained traces (UNKNOWN without traces, never 0%).
- Diagnostics are wavy underlines (amber warning, red error) with codes listed in seif-ls.
- Hover on a section or diagnostic shows the reason, layer, locator and digest, plus quick fixes (Add forbid test, Pin as required) and why?, which runs
whyin the Console. Quick fixes open a reviewable diff; nothing is written until you accept it.
Out-of-date files. A knowledge file is judged by its own updated: (or date:) line against the strictest freshness rule (currentness.maxAgeDays) of the areas it feeds. When it is too old (SEIF-W146) or has no date under a rule that needs one (SEIF-W147), a banner above the editor says when it was updated, how long the area trusts it and what that costs, with Mark as reviewed today (the content stays, the date line moves) and Change how long it is trusted… (a reviewed change to the rule). Saving new content moves the date to today by itself: editing a file is updating it. A section with its own date (<!-- seif: updated=… -->) moves only when that section changed, and a date you typed is kept. A file that is due soon says by when.
Files read from Git. A Git source pins the committed content (Builds and the agent use it), so a saved change says Saved, not in use yet (SEIF-I148) with Commit this change, and freshness is judged on the committed version. Marking such a file as reviewed commits that one file.
The breadcrumb follows the caret to the current ## section. Chips show its layers, file tokens, how many sections are selected and a link to the file's problems. Save with ⌘S; file conflicts refuse to overwrite an external edit. The watcher invalidates facts and reloads clean buffers. Dirty buffers remain available for review.
Context Window
Shows the query and inputs, the estimated budget (used, limit, free), a stacked bar with one stable colour per layer, the layer table (state, tokens, reason), the independently counted stages, and a diff against the selected environment's Build binding. Consumption is UNKNOWN during design-time resolution. No deployment, runtime connection, trace history or model execution is invented. Panels are resizable; the bottom panel shrinks on small windows. The command palette (⌘K) restores collapsed panels.
Console, Tests, Plots, Traces, Problems
The Console uses the human CLI parser, including quoted paths, and prints the same readable output as bin/seif (resolve tables, test failures, why reasons, diffs, sweep summaries, Build results). Its measured experiment plot sits beside it. Tests lists each test with its failing assertions and opens the test file. Problems lists every diagnostic. Selecting one opens the file at the line with the hover visible.
Experiments and drafts
An experiment declares id, profile, axes, corpus and optionally at:
id: budget
profile: support-answer
at: 2026-10-08T12:00:00Z
axes:
budget.maxTokens: [1000, 2000, 3000, 4000]
rules.pricing.maxItems: [1, 2, 3]
corpus: tests/**
seif sweep experiments/budget.exp.yaml freezes observations, evaluates up to four workers, and caches by project/material/configuration/date digest. Results live at .seif/experiments/<id>/results.json. Axes support integer lists or "1000..6000 step 500". Sweeps are bounded to 500 configurations. They report required-context coverage, forbidden leaks, average estimated tokens, materials per layer and a test × layer matrix. No required assertions means coverage UNKNOWN. Missing fixtures stay UNKNOWN. The Pareto set excludes leaks and unknown tests. The result also records the profile's current values for each axis.
Two points are marked, with different purposes:
- recommended (★) is the cheapest measured configuration in which every Context Test passes with no forbidden leak and no UNKNOWN. Ties prefer the earlier configuration. It is the only point a draft proposes by default, so applying it never trades away a passing test. If no configuration passes, nothing is proposed (
NO_PASSING_CONFIGURATION). - knee (◆) maximizes normalized coverage minus normalized token cost, with cheaper points winning ties. It is an explicit trade-off heuristic, not a universal optimum, and can sit below 100% required coverage. It is shown for analysis only.
The plot draws each series, the current value as a dashed line, failing configurations as hollow red points, and both marked points. Plots also lists every configuration. Apply recommended configuration as draft opens a reviewable context.yaml proposal. It never saves automatically; Accept reviewed diff checks the original file again. Quick fixes follow the same flow. Model response metrics are outside this deterministic surface; ask reports UNKNOWN when no proposal model is configured.
Trace documents
Import a retained trace with seif trace import incident.json; open it with seif trace open <id> or the native Traces panel. Documents are read-only and show ordered records. Replay uses the exact retained Build through historical.mjs; missing or expired input/material remains UNKNOWN. Diff compares retained input against the working tree. trace guard <id> --forbid <locator> --reviewed creates tests/incident-<id>.guard.md. The expectation is user supplied; an incident never proves what the correct behavior should be. Guard review is bound to its scenario digest. Expired content is not resurrected and secrets are redacted before display.
Proof
Run bash scripts/prove-context-lab.sh. It runs the file-native engine tests (migration, CLI/REPL, seif-ls facts, sweeps, trace documents), then drives the real native Lab headlessly: external file edits, section facts, a sweep whose recommended draft keeps every test green, a forbid quick fix, the hover, and save conflicts. It writes evidence/context-lab/context-lab-1280x720.png and context-lab-1920x1200.png. bash scripts/verify.sh checks existing engine/runtime, Build portability, .NET behavior and UI regressions as well as the new paths.