8000 docs(specs): add the mesh and remote forward spec (MRF) by norrietaylor · Pull Request #1420 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

docs(specs): add the mesh and remote forward spec (MRF) - #1420

Closed
norrietaylor wants to merge 3 commits into
mainfrom
docs/spec-mesh-remote-forward
Closed

norrietaylor wants to merge 3 commits into
mainfrom
docs/spec-mesh-remote-forward

Conversation

@norrietaylor
@norrietaylor norrietaylor commented Sep 17, 2026 •
Copy link
Copy Markdown
Member

Summary

  • Adds docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md, prefix MRF, cut from the box networking spec NET (#1380) under the local-first ordering of 2026-09-15. Same epic, gominimal/inbox#646.
  • 9 requirements, text and tier unchanged from NET, former IDs recorded beside each: MRF-001 (NET-106: min net forward against a remote session); MRF-002 to MRF-009 (NET-112 to NET-119: mesh join under the signed-in identity, signed peer documents, remote box by name, status, leave within the revocation window, the peer-document mirror, binding admission, tenant-zone resolution on the laptop).
  • Stories S13, S14. S14 (box-to-box across hosts by named-network grant) carries no requirement; it is a non-goal blocked on an architecture ruling. MRF-001 implements the remote clause of NET's forward story (S12), which stays in NET.
  • Tiers: T0 throughout.
  • Prerequisite: NET. The local forward (NET-104, NET-105) is what MRF-001 serves remotely; the local names and box-zone resolution (NET-011 to NET-013, NET-072) are what MRF-009 extends.
  • Siblings: EHE #1418, GWI #1419; MMI #1356 (the daemon as a mesh-reachable session host and the relay), MCC #1355 (client core), CRA #1374 (the remote session MRF-001 forwards over), NPOL (gominimal/gatehouse#7) for bindings and peer documents.
  • Architecture: Gatehouse §6.9 (v1.19), design §4.1 and §4.5, architecture D7.

Open questions

HIGH: MRF-007 and MRF-008 overlap MMI's daemon-side peer-document and binding requirements, MMI's first open question expects its relay leg to fold into the networking spec, and since design v0.7 §4.1 the host-side helper, not the VM's daemon, terminates the endpoint on a laptop; which component and which document own the daemon's half. MEDIUM: the grant model for box-to-box reach across hosts; which channel serves the remote forward (direct-tcpip on the certificate connection, or the mesh).

Lint

spec_lint.py --repo-root: 9 P004 (one per requirement, pre-implementation). Nothing else.

🤖 Generated with Claude Code

Cut from the box networking spec (NET, #1380) under the local-first
ordering of 2026-09-15: mesh join under the signed-in identity, peer
documents, remote box names, status, leave, the peer-document mirror,
binding admission, tenant-zone resolution, and the remote form of
`min net forward`. Nine requirements, text and tiers unchanged, former
NET IDs recorded beside each.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai
coderabbitai Bot commented Sep 17, 2026
Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

@github-actions
github-actions Bot commented Sep 17, 2026 •
Copy link
Copy Markdown
Contributor

Spec lint

docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md — 9 finding(s)

docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:66: P004 MRF-001 names test 'net_forward_remote_host', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:71: P004 MRF-002 names test 'mesh_join_uses_signed_in_identity', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:76: P004 MRF-003 names test 'mesh_join_receives_peer_documents', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:81: P004 MRF-004 names test 'mesh_reaches_remote_box_by_name', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:86: P004 MRF-005 names test 'net_status_shows_peers_handshake', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:91: P004 MRF-006 names test 'mesh_leave_within_revocation_window', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:96: P004 MRF-007 names test 'mesh_from_peer_document_mirror', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:101: P004 MRF-008 names test 'peer_admitted_only_with_valid_binding', which was not found in the repository
docs/specs/23-spec-mesh-remote-forward/23-spec-mesh-remote-forward.md:106: P004 MRF-009 names test 'laptop_resolves_tenant_zone_locally', which was not found in the repository

Advisory. None of this blocks the merge; the review decides.

Advisory, and never a merge gate. Linter: gominimal/foundry@1bd959c2, spec format: How Minimal Writes Specs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
norrietaylor added a commit that referenced this pull request Sep 17, 2026
Local-first ordering, 2026-09-15: NET now binds only what a box host does
with no identity plane, on a laptop with VM-backed boxes or a co-resident
Linux host. Thirty-six requirements whose precondition is enrolment, a
gateway association, a mesh, or a remote session move, unchanged in text
and tier, to three sibling specs from the same epic: EHE (#1418), GWI
(#1419), MRF (#1420). Surviving IDs are unchanged; 83 remain, with all
seven failure sub-bullets, nine Kani harnesses, and the T1 parity
property.

Context, Success, First slice, Non-goals, Design reasoning, Security
considerations, and Open questions are rewritten for the local scope.
The Context names the local Box Egress Proxy's dependencies on this
document (box-zone resolution, DNS-pinned admission, proxy parity, UDP
dropped unless declared). The host-OS resolution question is answered by
design §7.1 v0.5 and folded in; NET-018 and NET-019 take their WHERE from
its supersession condition; the macOS per-box-address mechanism stays
open per design §12 item 13; the association-contract question moves out
with EHE. NET-037 now calls the hyphenated spellings legacy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On a host with a VM the node side of any association is the VM together
with its host-side helper (design §4.1 v0.7), so the HIGH open question
on who owns the laptop's peer-document mirror and binding admission now
names the helper as a candidate. Attach to bare-metal fleet hosts through
the gated host-side forwarder and mesh through the gateway's forwarding
role are non-goals with destinations. No requirement changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
norrietaylor added a commit that referenced this pull request Sep 18, 2026
* docs(specs): add the box networking spec (NET)

Spec 12 binds the box host's side of the networking design from the
epic gominimal/inbox#646: names through the hostname proxy and native
resolution, network posture on the CLI, bounded egress enforced outside
the VM, gateway-attached and enrolled-host obligations, mesh join, and
the reverse-proxy retirement. 119 EARS requirements at T0 with named
tests, eleven T2 Kani cores, and one T1 property. Its identity-plane
sibling is NPOL in gominimal/gatehouse.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): renumber box-networking to 18

12 and 13 are taken by the GitHub sessions and min client core specs; 14–16
by other open spec PRs. Directory, file and in-document references move
together; content is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(specs): re-scope NET to the un-enrolled local host

Local-first ordering, 2026-09-15: NET now binds only what a box host does
with no identity plane, on a laptop with VM-backed boxes or a co-resident
Linux host. Thirty-six requirements whose precondition is enrolment, a
gateway association, a mesh, or a remote session move, unchanged in text
and tier, to three sibling specs from the same epic: EHE (#1418), GWI
(#1419), MRF (#1420). Surviving IDs are unchanged; 83 remain, with all
seven failure sub-bullets, nine Kani harnesses, and the T1 parity
property.

Context, Success, First slice, Non-goals, Design reasoning, Security
considerations, and Open questions are rewritten for the local scope.
The Context names the local Box Egress Proxy's dependencies on this
document (box-zone resolution, DNS-pinned admission, proxy parity, UDP
dropped unless declared). The host-OS resolution question is answered by
design §7.1 v0.5 and folded in; NET-018 and NET-019 take their WHERE from
its supersession condition; the macOS per-box-address mechanism stays
open per design §12 item 13; the association-contract question moves out
with EHE. NET-037 now calls the hyphenated spellings legacy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): correct NET's Linux baseline and NET-037's legacy spellings

Two review findings on the re-scope. The Context claimed Linux installs
lack the VM stack; the release manifests have shipped minvmd, the switch,
and the guest payload for linux/amd64 and linux/arm64 since #1070, so the
gap NET-049 and NET-051 bind is a fresh KVM host activating a VM-backed
box, and NET-048 and NET-050 guard shipped behaviour. NET-037 now
enumerates `no-net` beside `host-net` and `own-ip`: it is the CLI's third
kebab-case spelling and the one a saved config would otherwise fail on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): align NET with arch #67 (design v0.7, Gatehouse v1.19)

The local default path carries no WireGuard (design §7.1, §11). The Box
Egress Proxy NET's Context anticipates is now the node-local BEP of
Gatehouse §6.10 v1.19; its dependency list gains NET-084, the relay's
source-address check that lets the proxy attribute a box by switch
source. Store references and [secret-store-rules] consent are routed to
the local BEP document; the hosted BEP stays with the broker epic.
BareMetalVM, the sixth style, is named as EHE's with NET-081 to NET-085
as what a metal host reuses per VM. No requirement changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): answer the NET review findings and the BEP field asks

- NET-060 accepts `egress.allow_dns_hosts`; NET-072 spells the field the
  same way (one spelling; design §7.1's `egress_allow_dns` is a §5.4
  placeholder).
- NET-003 resolves `host.min.internal` to an address; reach over it is
  local reach under the box's egress rules, so deny-all wins (NET-079).
- NET-010 allocates from the host-global allocation; its property and
  harness range over every daemon on the host (NET-027, NET-059).
- NET-045 gains a failure case: `ask` with no client attached is refused
  with a typed error, recorded by NET-046.
- NET-120 accepts an `egress` section on a host-address box, superseding
  03-spec R2.1's HostNet parse-time error; NET-065 keeps `none`.
- NET-043 notes `dynamic_ingress` supersedes `dynamic_allowed_ports`.
- NET-085 and the escape invariant cite design §5.1 for the baseline set.
- Context limits the switch-source attribution to VM-backed hosts; the
  host-address cohort is attributed as one cohort (NET-078).
- S17 is a split story: its text is transcribed, NET-102 keeps the
  un-enrolled clause, EHE holds the enrolled ones.
- Design reasoning records each choice and the alternative rejected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): follow the arch#69 ruling on un-enrolled GitHub minting in NET's Context

The un-enrolled node-local Box Egress Proxy may redeem GitHub-module
members the min client minted from its own sign-in; only
Gatehouse-brokered grants are absent un-enrolled (owner ruling
2026-09-17, proposed in gominimal/arch#71). One clause in the Context;
no requirement changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): revise NET after review, binding §7.1's answerer and bind rules

Answers the open review threads on #1380 and the arch tip (design v0.7.1,
Gatehouse v1.20.1, command tree after gominimal/arch#72).

- NET-121 to NET-130: declared ports bound before the name; resolver
  advisory at session start; reserved-range bind probe with the 127.0.0.1
  interim; answerer semantics (NODATA, NXDOMAIN, TTL, answer confinement,
  stopped shared-address box); host-address namespace-mirror rule with
  collision reporting; un-enrolled node-plane baseline set.
- NET-060 accepts `egress.deny_subnets`; NET-067 names the denied range.
- NET-074/075 gain the in-force WHERE; NET-077 keeps the shipped allow-all
  default; three shipped rules superseded, precedence stated.
- NET-079 states its enforcement locus; NET-068 conditioned on the hosts it
  needs; NET-003 resolves to the host-reach address; NET-002 names the
  zone's general form; NET-010 scoped to own-address and `none` boxes;
  NET-016 to permit-range ports; NET-109 retires the surface, not the verb.
- NET-108 retired; NET-107 names the lane's per-mode tests.
- Design reasoning: command-tree binding, bind discipline, field-name
  attribution, precision-versus-floor split; harness stated once; links
  reference-style; provenance narration removed; roles deduplicated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): restore NET's lists and close the revision-2 review gaps

Revision 2's reference-link reflow collapsed the Non-goals and Open
questions lists into paragraphs; both are lists again. NET-010 and its
injectivity property are scoped WHERE the reserved local range is
present, so NET-123's 127.0.0.1 interim composes with it. NET-121's
failure cases carry the whole design §7.1 bind discipline: revocation
unbinds and terminates established connections, and a failed forwarder
bind is reported, never substituted. Design reasoning states that
egress.deny_subnets has no crate counterpart, that min ls is the tree's
own alias, and NET-072's comment cites box.toml for the canonical
spelling. Bare issue references are links.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): scope NET-127 to the host answerer and close the owner's nits

NET-127 is the host answerer's confinement rule per design §7.1, so it
now triggers on lookups originating on the host OS; in-guest the node's
DNS layer answers with switch addresses, which NET-003 and NET-072/073
rely on. The sixth invariant's enforced-by says the same. NET-124's
NODATA rule covers held names only, leaving unknown names to NET-125.
NET-130 keeps the daemon's registry and cache endpoints in the baseline
enumeration, which is what NET-080's package fetch rests on. NET-003
says "inside boxes" without qualification, NET-123's comment records
that Linux always carries the range on lo, and the retirement non-goal
names the general zone form.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@norrietaylor
norrietaylor deleted the docs/spec-mesh-remote-forward branch October 18, 2026 03:31
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

0