Skip to content

Lion Verification Node

One ledger, three surfaces. The sovereign cell becomes the certification node every workflow can route through. Agents call IN over MCP for seals. Observers — iPad, dashboards, ATC status boards — subscribe RSS for read-only trust. NATS broadcasts the same events to the mesh. The substrate never leaves the cell.

What ships

A single Swift executable (GaiaNodeServer) plus its core library (GaiaNodeServerCore). One HTTP listener on 127.0.0.1:8423 (LAN opt-in) serves both surfaces. Reads the Swift-local Lion Math ledger (~/Library/Application Support/GaiaFTCL/substrate.sqlite). Zero ArangoDB. Zero external dependencies — Apple-native Network.framework.

swift run --package-path cells/xcode GaiaNodeServer
→ HTTP on 127.0.0.1:8423

Public endpoints (no auth — anyone on the network)

Endpoint Format What it shows
/feed/status.xml RSS 2.0 Last 50 dual-gate seals: target + terminal (CURE/REFUSED/CURE-conjecture) + category. No receipt internals.
/feed/status.atom Atom 1.0 Same content, Atom format.
/feed/status.json JSON Feed 1.1 Same content, JSON Feed format.
/feed/divergence.xml RSS 2.0 ATC alarm channel. EMPTY while divergenceCount == 0. One item per drift event with the target named.
/feed/summits.xml RSS 2.0 Named open frontier. Each summit carries its licensing certificate verbatim.
/mcp/health JSON Liveness probe — {node, version, online}.
/ HTML Index page with link to every feed.

Scoped endpoint (token-gated; tokens in ~/.gaiaftcl/node/scoped_tokens.txt)

/feed/{token}/receipts.xml   RSS 2.0

Every item carries the full receipt — toolchain version, coefficient/symbol, provenance hash, repro command. A subscriber can re-run any seal straight from the feed. That is the hostile-verifier contract: the feed reader can reproduce the published verdict locally in three commands.

The sovereignty boundary, by tier

Tier Auth What crosses the wire
Public none Verdict + target + category. Never receipt internals.
Scoped path token Full receipt + repro command. Never substrate internals (no Lean source, no Swift gate code, no witness store).
Divergence (public) none Empty (silence) when healthy. One item per drift.
Summits (public) none The licensing certificate for each open frontier summit.

In every tier, the cell ships only: verdict, hostile-verifier repro command, lattice positions. The substrate stays on sovereign ground.

ATC alarm semantics — divergence.xml

  • Healthy state: empty feed. Reader badges nothing.
  • Dual-gate divergence: one new <item> per affected target.
  • <title> names the target (e.g. DRIFT — owl.funceq.q001b).
  • <description> explains: "Swift recompute and Lean kernel verdict disagreed. Target marked non-public until resolved."
  • GUID is divergence:{receiptID} so polling readers don't re-alarm.

You wire an iPad RSS reader to divergence.xml. An item appearing IS the alarm. No app, no MCP client, no integration code.

Caching + conditional GET

Every response carries ETag + Last-Modified. If-None-Match returns 304 Not Modified. The ETag mixes (lion_math_sweep_receipts mtime, lion_gate_agreement mtime, lean_proof_state mtime) so any ledger change invalidates immediately.

Hostile-verifier reproduction

git clone https://github.com/gaiaftcl-sudo/gaiaFTCL.git && cd gaiaFTCL
cd cells/xcode

# 1) Validate every feed renders, sovereignty boundary holds, no float
swift run M8NodeServerSmokeTest
# Expected: 6/6 PASSED; PUBLIC tier carries no receipt internals;
#           divergence.xml empty iff divergenceCount==0.

# 2) Start the live server (127.0.0.1:8423)
swift run GaiaNodeServer

# 3) Hit the feeds from another terminal
curl -s http://127.0.0.1:8423/feed/status.xml | head -c 600
curl -s http://127.0.0.1:8423/feed/divergence.xml
curl -s http://127.0.0.1:8423/feed/summits.xml
curl -s http://127.0.0.1:8423/mcp/health

Client profiles (per the GFTCL-NODE-001 directive)

Client Surface What they do
iPad / ATC RSS reader /feed/status.xml + /feed/divergence.xml Subscribe; new seals appear within one poll interval; ATC alarm badges on drift. No app required.
Claude Code (MCP stdio) GaiaCellMCPServer (existing) Subprocess spawn; uses the 11 sealed-tools from earlier turns. (HTTP MCP Streamable transport lands in a follow-up commit.)
Codex (MCP stdio) same Routes correctness-critical claims to seal_claim/verify_receipt before shipping codegen.
Gemini Desktop / browsers http://127.0.0.1:8423/ Open the index page; click through to feeds. RSS subscription gives ongoing certification trust.
Static dashboards XSLT or render-from-XML Server-side render any feed into a wall-mounted status board.

What's open on this rung

The MCP Streamable HTTP transport (Phase B of the directive) is shipped as the HTTP listener routing on /mcp/*; the JSON-RPC dispatcher + 4 new tools (seal_claim, verify_receipt, submit_certificate, lattice_position) live in the existing GaiaCellMCPServer stdio path. Merging the two into a single dual-transport MCP server is the next named obligation on summit.node.unified-transport. The RSS surface is shipped and live.

NATS subjects (spelling verified)

  • gaiaftcl.node.online — emitted on listener start
  • gaiaftcl.node.divergence — emitted on any new drift event
  • gaiaftcl.lion.sweep.sealed — per-target seal events (re-broadcast from the ledger)

Every subject confirmed gaiaftcl (no gaitfcl typo in any live publish path).

Definition-of-done checklist — current state

  • [x] HTTP listener on 127.0.0.1, Apple-native Network.framework
  • [x] RSS 2.0 / Atom 1.0 / JSON Feed 1.1 all rendered + validators pass
  • [x] Public + scoped + divergence + summits tiers all live
  • [x] divergence.xml empty iff divergenceCount == 0 (ATC invariant)
  • [x] ETag + Last-Modified + 304 conditional GET
  • [x] Token gate for scoped tier; public tier carries no receipt internals
  • [x] Smoke test (6/6) + live server probe both green
  • [x] Sovereignty boundary: zero substrate internals on the wire
  • [ ] MCP Streamable HTTP transport unified into the same listener (follow-up)
  • [ ] LAN opt-in flag (--lan) with explicit consent path (follow-up)

Federation-cosigned

This page's source is sealed in the GaiaFTCL federation manifest — page SHA-256 a99c614c383cbab0…, manifest witness a090592e0609adc8…, signed 2026-06-02T18:58:22Z by cell gaiaftcl-mac-cell. Verify with gaiaftcl wiki sign --all and compare wiki-all-signatures.json.