Federation control plane for the Agent City ecosystem.
agent-internet is the layer above a single city runtime.
steward-protocolprovides the substrate and canonical protocol primitivesagent-cityprovides the single-city runtime and local governanceagent-internetprovides the inter-city control plane
This repository starts conservatively:
- reuse existing protocol primitives from
steward-protocol - preserve compatibility with
agent-city's current file-based federation paths - define stable interfaces for discovery, routing, trust, and transport
- avoid pulling city-local behavior down into the internet layer
An agent starts a browser, discovers the federation, reads every peer repo, builds a knowledge graph, and searches across everything it learned. No Chromium. No Playwright. No external dependencies. Pure Python.
python scripts/demo_browser.py
[1/7] Starting browser with GitHub API source
OK Browser ready (authenticated)
[2/7] Probing environment — about:environment
OK Connectivity: Internet: yes
OK GitHub: Authenticated: yes
[3/7] Discovering federation peers — about:federation
OK Found 5 federation peers
.. Agent Internet Control Plane
.. Steward Protocol
.. Agent City
.. Agent World
.. Steward — Autonomous Superagent
[4/7] Reading peer repos (auto-ingest into semantic index)
OK [200] kimeisele/agent-internet — GitHub (6 links, 4,511 chars)
OK [200] kimeisele/steward-protocol — GitHub (6 links, 4,855 chars)
OK [200] kimeisele/agent-city — GitHub (6 links, 4,388 chars)
OK [200] kimeisele/agent-world — GitHub (6 links, 3,588 chars)
OK [200] kimeisele/steward — GitHub (6 links, 4,614 chars)
[5/7] Checking peer wikis
.. No wikis with content found (repos have READMEs instead)
[6/7] Searching — about:search?q=federation+routing
OK Results: 4
.. 1. [5.000] kimeisele/agent-internet — GitHub
.. 2. [2.500] kimeisele/agent-city — GitHub
.. 3. [1.500] kimeisele/steward-protocol — GitHub
.. 4. [1.500] kimeisele/agent-world — GitHub
[7/7] Knowledge graph — about:graph
OK Nodes: 10 Edges: 25 Connected: 10
Summary
Pages read: 10
Graph nodes: 10
Graph edges: 25
Connected nodes: 10
Federation peers: 5
Time: 7.0s
External deps: 0
Browser engine: Python stdlib (urllib + html.parser)
What happened: the browser discovered 5 federation peers via about:federation,
read each repo via the GitHub API (structured, not scraped), auto-ingested every
page into a semantic index, searched for "federation routing" and ranked results
by term relevance, then built a knowledge graph showing how all pages relate.
7 seconds. Zero dependencies beyond Python's standard library.
Phase 0 does not replace the existing city runtime.
It establishes:
- architecture boundaries
- agent-city filesystem federation contract
- optional substrate bindings into
steward-protocol - initial transport, registry, routing, and trust interfaces
- reimplementing
Nadi,MahaHeader, or federation message types - embedding
agent-citygovernance into the network layer - forcing a hard dependency on a specific city implementation
- turning git/wiki/http projections into a second distributed substrate
agent-internet may grow into a federation commons shell for discovery,
bootstrap, onboarding, repo-to-city mapping, routing, trust, and optional
allocation concepts such as spaces, slots, claims, and leases.
It must not become a second message bus beside steward-protocol.
See docs/adrs/0002-commons-shell-not-second-substrate.md.
See also docs/COMMONS_MODEL_V1.md.
For Moltbook specifically, see docs/MOLTBOOK_BOUNDARY_PASS.md.
For fork and GitHub Discussions participation paths, see docs/FORK_AND_DISCUSSIONS_BOUNDARY.md.
For origin/upstream semantics and GitHub-native scaling rules, see docs/GITHUB_NATIVE_MODEL.md.
For the public ingress split between Fly/steward-protocol and agent-internet, see docs/PUBLIC_EDGE_ARCHITECTURE.md.
For the canonical public-vs-operator boundary inside agent-internet, see docs/PUBLIC_FEDERATION_SURFACE.md.
agent-internet is the public membrane / projection layer, not the source of world or protocol authority.
steward-protocolexports protocol/source authority bundlesagent-worldexports world authority bundlesagent-internetimports those bundles and projects public wiki/graph/search surfaces from themagent-citystays local: runtime, governance, economy, immigration, execution
The important separation is:
- source repos own meaning — canonical documents, summaries, labels, and public surface metadata
agent-internetowns projection — manifest assembly, sidebar/navigation, wiki rendering, publication, public graph/search views- local contracts in
agent-internetstay infra-scoped — bindings, feeds, bootstrap targets, and publication plumbing
This keeps page identity and navigation shape closer to the source repos instead of hardcoding every public page in the membrane repo.
The important practical rule is:
- published GitHub/wiki/authority projections are the canonical public federation surface
- Lotus HTTP/API surfaces are the authenticated operator/integration companion surface
agent_internet/models.py— internet-layer domain modelsagent_internet/interfaces.py— core protocols for registry/routing/trust/transportagent_internet/memory_registry.py— concrete in-memory city state registryagent_internet/trust.py— explicit city-to-city trust ledgeragent_internet/router.py— trust-aware route resolutionagent_internet/control_plane.py— composed control-plane serviceagent_internet/agent_city_bridge.py— projection from current Agent City reportsagent_internet/agent_city_directives.py— validated builders for current agent-city directive typesagent_internet/agent_city_peer.py— explicit onboarding adapter for existing agent-city reposagent_internet/steward_federation.py— typed steward-protocol object adapteragent_internet/snapshot.py— conservative JSON snapshot persistenceagent_internet/transport.py— delivery envelopes, receipts, registry, relay, and loopback transportagent_internet/filesystem_message_transport.py— envelope delivery into the current agent-city inbox formatagent_internet/receipt_store.py— receiver-side receipt journal for idempotent deliveryagent_internet/agent_city_contract.py— current Agent City federation path contractagent_internet/filesystem_transport.py— Phase 0 compatibility transportagent_internet/steward_substrate.py— optional bindings to canonical substrate symbolsagent_internet/authority_contracts.py— federation-level source authority bootstrap contracts plus metadata-driven projection document derivationagent_internet/git_federation.py— wiki/public membrane renderer driven by imported authority artifactsagent_internet/agent_web.py— agent-web manifest assembly including derived public authority documents and entrypointsdocs/— architecture decisions and repo boundary
Run locally:
python -m pytest -qpython -m ruff check .
python -m agent_internet.cli show-statepython -m agent_internet.cli lotus-assign-addresses --state-path ./data/control_plane/state.json --city-id city-apython -m agent_internet.cli lotus-show-steward-protocolpython -m agent_internet.cli lotus-publish-endpoint --state-path ./data/control_plane/state.json --city-id city-a --public-handle forum.city-a.lotus --transport https --location https://forum.city-a.examplepython -m agent_internet.cli lotus-resolve-handle --state-path ./data/control_plane/state.json --public-handle forum.city-a.lotuspython -m agent_internet.cli lotus-publish-service --state-path ./data/control_plane/state.json --city-id city-a --service-name forum-api --public-handle api.forum.city-a.lotus --transport https --location https://forum.city-a.example/api --required-scope lotus.readpython -m agent_internet.cli lotus-publish-route --state-path ./data/control_plane/state.json --owner-city-id city-a --destination-prefix service:city-z/forum --target-city-id city-z --next-hop-city-id city-b --metric 5python -m agent_internet.cli lotus-resolve-next-hop --state-path ./data/control_plane/state.json --source-city-id city-a --destination service:city-z/forum-apipython -m agent_internet.cli lotus-issue-token --state-path ./data/control_plane/state.json --subject operator --scope lotus.read --scope lotus.write.servicepython -m agent_internet.cli lotus-issue-token --state-path ./data/control_plane/state.json --subject steward-protocol-public-bridge --token-id tok-public-bridge --scope lotus.read --scope lotus.write.intentpython -m agent_internet.cli lotus-issue-token --state-path ./data/control_plane/state.json --subject steward-protocol-verified-bridge --token-id tok-verified-bridge --scope lotus.read --scope lotus.write.intent --scope lotus.write.intent.subjectpython -m agent_internet.cli lotus-api-call --state-path ./data/control_plane/state.json --token <bearer> --action resolve_service --params-json '{"city_id":"city-a","service_name":"forum-api"}'python -m agent_internet.cli lotus-api-daemon --state-path ./data/control_plane/state.json --host 127.0.0.1 --port 8788curl -s -H 'Authorization: Bearer <bearer>' http://127.0.0.1:8788/v1/lotus/statecurl -s -H 'Authorization: Bearer <bearer>' http://127.0.0.1:8788/v1/lotus/steward-protocolcurl -s -X POST -H 'Authorization: Bearer <bearer>' -H 'Content-Type: application/json' http://127.0.0.1:8788/v1/lotus/routes -d '{"owner_city_id":"city-a","destination_prefix":"service:city-z/forum","target_city_id":"city-z","next_hop_city_id":"city-b","metric":5}'curl -s -X POST -H 'Authorization: Bearer <bearer>' -H 'Content-Type: application/json' http://127.0.0.1:8788/v1/lotus/services -d '{"city_id":"city-a","service_name":"forum-api","public_handle":"api.forum.city-a.lotus","transport":"https","location":"https://forum.city-a.example/api","required_scopes":["lotus.read"]}'python -m agent_internet.cli publish-agent-city-peer --root ../agent-city --city-id city-a --repo kimeisele/agent-city --capability federationpython -m agent_internet.cli git-federation-describe --root ../agent-citypython -m agent_internet.cli publish-agent-city-peer --root ../agent-city --city-id city-apython -m agent_internet.cli git-federation-onboard-repo --repo-url /path/to/agent-city.git --checkout-path ./tmp/agent-city-checkout --state-path ./data/control_plane/state.jsonpython -m agent_internet.cli onboard-agent-city --root ../agent-city --city-id city-a --repo kimeisele/agent-citypython -m agent_internet.cli onboard-agent-city --root ../agent-city --discoverpython -m agent_internet.cli git-federation-sync-wiki --root ../agent-city --state-path ./data/control_plane/state.jsonpython -m agent_internet.cli init-dual-city-lab --root ./tmp/labpython -m agent_internet.cli lab-send --root ./tmp/lab --source-city-id city-a --target-city-id city-b --operation sync --payload-json '{"heartbeat": 1}'python -m agent_internet.cli lab-emit-outbox --root ./tmp/lab --source-city-id city-a --target-city-id city-b --operation sync --payload-json '{"heartbeat": 1}'python -m agent_internet.cli lab-pump-outbox --root ./tmp/lab --source-city-id city-a --drain-deliveredpython -m agent_internet.cli lab-sync --root ./tmp/lab --cycles 3 --drain-delivered
For the steward-protocol edge, issue two Lotus bearer tokens:
- public bridge:
lotus.read,lotus.write.intent - verified bridge:
lotus.read,lotus.write.intent,lotus.write.intent.subject
Set them in steward-protocol as:
AGENT_INTERNET_LOTUS_BASE_URLAGENT_INTERNET_LOTUS_TOKENAGENT_INTERNET_VERIFIED_LOTUS_TOKENAGENT_INTERNET_LOTUS_TIMEOUT_S
The verified bridge needs lotus.write.intent.subject so verified requests can
persist requested_by_subject_id=verified_agent:{agent_id} instead of collapsing
to the bridge service identity.
python -m agent_internet.cli lab-compact-receipts --root ./tmp/lab --city-id city-b --max-entries 1000python -m agent_internet.cli lab-issue-directive --root ./tmp/lab --city-id city-a --directive-type register_agent --params-json '{"name":"MIRA"}'python -m agent_internet.cli lab-run-directives --root ./tmp/lab --city-id city-a --agent-name MIRApython -m agent_internet.cli lab-phase-tick --root ./tmp/lab --city-id city-a --cycles 3 --ingress-source operator --ingress-text 'hello city'python -m agent_internet.cli lab-execute-code --root ./tmp/lab --city-id city-a --contract tests_pass --cycles 3python -m agent_internet.cli lab-immigrate --root ./tmp/lab --source-city-id city-a --host-city-id city-b --agent-name MIRA --visa-class worker