Skip to content

feat(mcp): run a bootstrap flight when no flight exists to select - #83

Merged
jlrickert merged 4 commits into
mainfrom
feat/mcp-bootstrap-mode
Aug 6, 2026
Merged

feat(mcp): run a bootstrap flight when no flight exists to select#83
jlrickert merged 4 commits into
mainfrom
feat/mcp-bootstrap-mode

Conversation

@jlrickert

Copy link
Copy Markdown
Owner

Second of four. Targets #82; retargets to main once that merges.

A session that can reach no flights at all had nothing to offer: the KEG tools
were locked and the recovery text asked the user to select a flight that did not
exist. Sessions now run on a synthetic bootstrap flight whose cover is empty —
every KEG operation stays denied — but which grants manage_flights and
manage_kegs, so the agent can create the first flight and the first KEG and
then be selected into real authority.

The provider decides whether to synthesize it, because only it knows how to
count its transport's flights; the gate reads that decision off the manifest.
Bootstrap sessions expose an allowlist rather than the full tool set, so the
agent does not spend the session discovering the same refusal one tool at a
time. Recovery instructions ride in the manifest because the local and hosted
surfaces nudge toward different places.

The payload never calls this an "active flight": a reader who believes a flight
was selected will not go set one up, which is the entire point of the mode.

keg_create joins the agent surface for this, gated on manage_kegs and
re-checked inside the tool so an embedded surface without the session gate
cannot reach creation through a flight that never granted it. A new KEG is not
readable until a flight's cover names it.

Also here

  • fix(keg): node 0 is the placeholder landing node and carries no type by
    design, so requiring one made every schema-bearing KEG permanently invalid —
    and the standing error told agents to "fix" node 0 by destroying it. Scoped to
    that one rule; a node 0 that does declare a type is still validated.
  • feat(cli): contextWindow and args per launch agent. Harnesses express a
    context cap differently, so the launcher translates per harness and reports
    rather than drops it where there is no equivalent.
  • docs(mcp): orientation, node 0, and attachment paths move into the rules
    block, which is what survives a context reset. The plural assets/ and
    images/ spelling is asserted, since a singular path yields links that upload
    fine and then resolve to nothing.

Testing

Every commit builds, passes go test ./..., and is gofmt-clean on its own
(verified with git rebase --exec).

Node 0 is the keg's placeholder landing node and carries no type by
design — Init writes it with empty meta. Requiring one made every
schema-bearing keg permanently invalid, and the standing error told
agents to fix node 0 the only way the message suggests: by giving it a
type and content, destroying the placeholder.

A node the schema contract cannot describe must not be reported as
violating it. The exemption is scoped to this one rule: a node 0 that
does declare a type is still validated against it, and doctor's other
node-0 checks are untouched.
Harnesses express a context cap differently — Codex as model metadata,
Claude Code as an auto-compact threshold — so the launcher translates
contextWindow per harness rather than passing a raw flag. Where a
harness has no equivalent it reports the setting instead of dropping it:
quietly ignoring a context cap is how you discover it never applied.

Setting it also silences Codex's "model metadata not found" warning for
a local tag it does not know. Agent args are appended before the
invocation's own so a one-off can still override them.
A session that can reach no flights at all had nothing to offer: the KEG
tools were locked and the recovery text asked the user to select a
flight that did not exist. Sessions now run on a synthetic bootstrap
flight whose cover is empty — every KEG operation stays denied — but
which grants manage_flights and manage_kegs, so the agent can create the
first flight and the first keg and then be selected into real authority.

The provider decides whether to synthesize it, because only it knows how
to count its transport's flights; the gate reads that decision off the
manifest. Bootstrap sessions expose an allowlist rather than the full
tool set, so the agent does not spend the session discovering the same
refusal one tool at a time. Recovery instructions ride in the manifest
because the local and hosted surfaces nudge toward different places.

The payload never calls this an "active flight": a reader who believes a
flight was selected will not go set one up, which is the entire point of
the mode.

keg_create is added to the agent surface for this, gated on manage_kegs
and re-checked inside the tool so an embedded surface without the
session gate cannot reach creation through a flight that never granted
it. A new keg is not readable until a flight's cover names it.
The rules block is what survives a context reset, so guidance that only
lived in prose the agent may never re-read was not doing any work. Four
things move into it: orient before anything else, orient again after a
clear or compact, treat this payload as superseding every earlier copy
of itself, and leave node 0 alone as the placeholder landing node.

Attachment links are stated too, relative to the node's own directory
with plural directory names. The plural spelling is asserted rather than
trusted: a singular path produces links that upload fine and then
silently resolve to nothing, which is the kind of failure nobody reports
because it looks like it worked.
@jlrickert
jlrickert force-pushed the feat/mcp-bootstrap-mode branch from d2fbb03 to 06a9bdc Compare August 6, 2026 22:43
@jlrickert
jlrickert changed the base branch from refactor/mcp-transport-providers to main August 6, 2026 22:43
@jlrickert
jlrickert merged commit b1a4a42 into main Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant