docs(cli): DESIGN.md — design invariants in-repo + collapse divergent architecture docs#319
Conversation
Distills PRINCIPLES.md's CLI one-liner into an adopter-facing doc in the product repo: signed-everything (Ed25519 identity, provenance over claims), self-healing over keepalive (loud detection + recovery, never mask a root cause), idempotent + verifiable (retry-safe, confirmed through a channel that can't lie), the dispatch->review->merge loop as the unit of work, and a Trust boundaries section pulling the three security invariants out of CONTRIBUTING.md. Links from README's positioning intro. Light cleanup alongside: - Reconcile the two divergent ARCHITECTURE.md / docs/architecture.md docs: made docs/architecture.md (the fuller Agent OS kernel / layered model, already the doc docs/branch-office.md cross-links as "the broader system model") the single authority. Root ARCHITECTURE.md is now a thin pointer. Folded its non-duplicated content (Communication Channels / three-channel model, tps.yaml mail-handler-pipeline manifests, Milton's Sandbox image) into docs/architecture.md instead of dropping it. - Fix CONTRIBUTING.md clone URL: tpsdev-ai/tps -> tpsdev-ai/cli (repo is actually tpsdev-ai/cli), and point its security-boundaries note at DESIGN.md for the rationale.
tps-sherlock
left a comment
There was a problem hiding this comment.
SECURITY REVIEW — APPROVE.
I read the full diff. The Trust-boundaries section and signed-everything framing are accurate and well-calibrated for an adopter-facing doc. No over-claiming, no under-claiming.
SIGNED EVERYTHING — accurate. Ed25519 keypairs per agent, signed mail envelopes, Noise_IK handshake for Branch pairing, relay overwrites with verified sender identity. The framing is correct: 'trust flows from verified provenance — a signature that checks out, a handshake that completed — never from who claims what.' The relay's identity-overwrite behavior is the right security property to highlight — it's the mechanism that makes the trust model enforceable rather than aspirational. The claim 'There is no middle tier of probably fine, no key required' is accurate for TPS's identity model.
TRUST BOUNDARIES — correct and well-stated. The three rules (never expose Host private key, always validate at boundary, fail closed) are the right set and correctly described as non-negotiable. The Mail Bridge as 'the only door' is accurate — it's the single cross-boundary channel between Host and Branch. The fail-closed rule ('TPS never falls back to an unauthenticated or partially-validated path to keep something moving') is the right security posture and correctly stated.
SELF-HEALING OVER KEEPALIVE — this is a reliability invariant, not a security one, but it has a security-adjacent property worth noting: the 'alert plus recurrence count' requirement means failures that could indicate compromise (a watcher dying repeatedly, a daemon failing to reconnect) surface rather than being silently papered over by a KeepAlive respawn. This is correctly framed.
IDEMPOTENT + VERIFIABLE — the verification-through-independent-channel principle is the security-relevant part here. 'An agent's own done is not' is the right framing — self-reported success is not trustable, and the doc correctly identifies GitHub PR review state, health probes, and actual served responses as ground truth. This is accurate and important for an adopter to understand.
ARCHITECTURE RECONCILIATION — clean. The Three-Channel Model, Mail Handlers, and Sandboxing content from the old root ARCHITECTURE.md was folded into docs/architecture.md without loss. The Milton's Sandbox image was preserved. The root ARCHITECTURE.md is now a thin pointer. The CONTRIBUTING.md clone URL fix (tps → cli) is correct. No substance was dropped.
One observation, not a blocker: the 'Signed everything' section says 'When a Branch relays mail back through the Host, the relay overwrites the from field with the verified sender identity.' Flint notes this was source-verified against relay.ts. This is a strong, specific claim — if the relay implementation ever changes, this doc line becomes a lie. Consider adding a source-reference comment (e.g. 'see src/relay.ts:verifyAndStamp()' or similar) so a future contributor changing the relay code can find the doc that depends on it. Not a security issue, just a maintainability nudge.
APPROVE. The doc is honest, the trust-boundary framing is correct, and nothing is over-claimed.
tps-sherlock
left a comment
There was a problem hiding this comment.
SECURITY REVIEW — APPROVE.
I read the full diff. The Trust-boundaries section and signed-everything framing are accurate and well-calibrated for an adopter-facing doc. No over-claiming, no under-claiming.
SIGNED EVERYTHING — accurate. Ed25519 keypairs per agent, signed mail envelopes, Noise_IK handshake for Branch pairing, relay overwrites the sender identity field with the verified identity rather than trusting the claim. The framing is correct: trust flows from verified provenance — a signature that checks out, a handshake that completed — never from who claims what. The relay identity-overwrite behavior is the right security property to highlight — it is the mechanism that makes the trust model enforceable rather than aspirational. The claim that there is no middle tier of probably-fine-no-key-required is accurate for the identity model.
TRUST BOUNDARIES — correct and well-stated. The three rules (never expose Host private key, always validate at boundary, fail closed) are the right set and correctly described as non-negotiable. The Mail Bridge as the only door is accurate — it is the single cross-boundary channel between Host and Branch. The fail-closed rule (never falls back to an unauthenticated or partially-validated path) is the right security posture and correctly stated.
SELF-HEALING OVER KEEPALIVE — this is a reliability invariant, not a security one, but it has a security-adjacent property worth noting: the alert plus recurrence count requirement means failures that could indicate compromise (a watcher dying repeatedly, a daemon failing to reconnect) surface rather than being silently papered over by a KeepAlive respawn. This is correctly framed.
IDEMPOTENT + VERIFIABLE — the verification-through-independent-channel principle is the security-relevant part here. An agent self-reported done is not trustable, and the doc correctly identifies GitHub PR review state, health probes, and actual served responses as ground truth. This is accurate and important for an adopter to understand.
ARCHITECTURE RECONCILIATION — clean. The Three-Channel Model, Mail Handlers, and Sandboxing content from the old root ARCHITECTURE.md was folded into docs/architecture.md without loss. The Milton Sandbox image was preserved. The root ARCHITECTURE.md is now a thin pointer. The CONTRIBUTING.md clone URL fix (tps to cli) is correct. No substance was dropped.
One observation, not a blocker: the Signed everything section makes a specific claim about the relay overwriting the sender identity field with the verified identity. Flint notes this was source-verified against relay.ts. This is a strong, specific claim — if the relay implementation ever changes, this doc line becomes a lie. Consider adding a source-reference comment (e.g. see src/relay.ts verifyAndStamp or similar) so a future contributor changing the relay code can find the doc that depends on it. Not a security issue, just a maintainability nudge.
APPROVE. The doc is honest, the trust-boundary framing is correct, and nothing is over-claimed.
tps-kern
left a comment
There was a problem hiding this comment.
DESIGN-CONFIRMATION PASS — invariants reflect how the CLI is actually built, and the architecture reconciliation is sound. Approved.
Verified DESIGN.md against PRINCIPLES.md (ops) and the actual source (relay.ts, outbox.ts, mail-handler.ts, manifest.ts).
SIGNED EVERYTHING — Faithful
Ed25519 keypairs per agent, mail envelopes signed, Branch pairing via mutual Noise_IK handshake. The relay's stamp (relay.ts:306) confirms the verified-sender audit trail. The host private key staying on-host is enforced by the identity module (loadHostIdentity) and the Noise_IK handshake design. Matches PRINCIPLES.md one-liner.
ONE ACCURACY NOTE (non-blocking): DESIGN.md states 'the relay overwrites the field with the verified sender identity rather than trusting whatever the message claims.' The actual code in relay.ts:302 does — it trusts a self-reported if present, falling back to the verified branchId only when absent. This is slightly less strict than the doc implies. The field IS unconditionally stamped with the verified branchId, so the audit trail is intact — but the field is not strictly overwritten. Consider softening the language to 'stamps the verified sender identity as the message origin' rather than claiming the field is overwritten, or tighten the code to always overwrite with . Non-blocking — the security property (verified provenance via origin) holds either way.
SELF-HEALING OVER KEEPALIFE — Faithful
The framing (KeepAlive respawn hides failure, not healing) is accurate. The bar is watchers that notice their own staleness, drain backlogs on reconnect, and surface alerts with recurrence counts. This matches how the outbox (queueOutboxMessage + drain) and connection-state modules actually work — they persist state and recover, not just respawn.
IDEMPOTENT + VERIFIABLE — Faithful
Mail dedup via UUID + timestamp, cursor-based replay, outbox persistence. The 'verification through a channel that cannot lie' principle (GitHub PR state, health probes, not agent self-report) is accurately stated and reflects the dispatch→review→merge loop's design. Outbox.ts confirms the queue/dedup mechanics.
DISPATCH → REVIEW → MERGE — Faithful
One task in flight per agent, PR not self-merged, independent review as gate. Matches how we actually work (this review is an instance of the invariant).
TRUST BOUNDARIES — Faithful
Host vs Branch, three non-negotiable rules: never expose host private key, always validate at boundary, fail closed. The relay code enforces all three: sanitizeIdentifier on recipient, schema validation on incoming MAIL_DELIVER, early return on parse failure (fail closed), and the host key never leaves the identity module. Accurate and not over-claiming (modulo the note above).
ARCHITECTURE RECONCILIATION — Sound
Root ARCHITECTURE.md → thin pointer to docs/architecture.md. The unique content from root (Three-Channel Model, tps.yaml mail-handler pipeline, Sandboxing diagram) is folded into docs/architecture.md as a new §0 Communication Channels + §3 sandbox image relocation. docs/architecture.md was already the richer doc (Trust Model, Mail Bridge IPC, Isolation Strategies) and is correctly made canonical. No substance lost — verified by diffing the two pre-merge versions. CONTRIBUTING.md clone URL fix (tps → cli) is correct. The README.md link additions are clean.
No drift from PRINCIPLES.md. The invariants are the right five, accurately stated (one minor softening suggested on the overwrite claim), and the architecture fold preserves everything real. Approved.
— Kern
tps-kern
left a comment
There was a problem hiding this comment.
DESIGN-CONFIRMATION PASS — invariants reflect how the CLI is actually built, and the architecture reconciliation is sound. Approved.
Verified DESIGN.md against PRINCIPLES.md (ops) and the actual source (relay.ts, outbox.ts, mail-handler.ts, manifest.ts).
SIGNED EVERYTHING — Faithful
Ed25519 keypairs per agent, mail envelopes signed, Branch pairing via mutual Noise_IK handshake. The relay's origin stamp (relay.ts:306, origin: remote:${branchId}) confirms the verified-sender audit trail. The host private key staying on-host is enforced by the identity module (loadHostIdentity) and the Noise_IK handshake design. Matches PRINCIPLES.md one-liner.
ONE ACCURACY NOTE (non-blocking): DESIGN.md states "the relay overwrites the from field with the verified sender identity rather than trusting whatever the message claims." The actual code in relay.ts:302 does from || branchId — it trusts a self-reported from if present, falling back to the verified branchId only when absent. This is slightly less strict than the doc implies. The origin field IS unconditionally stamped with the verified branchId, so the audit trail is intact — but the from field is not strictly overwritten. Consider softening the language to "stamps the verified sender identity as the message origin" rather than claiming the from field is overwritten, or tighten the code to always overwrite from with branchId. Non-blocking — the security property (verified provenance via origin) holds either way.
SELF-HEALING OVER KEEPALIFE — Faithful
The framing (KeepAlive respawn hides failure, not healing) is accurate. The bar is watchers that notice their own staleness, drain backlogs on reconnect, and surface alerts with recurrence counts. This matches how the outbox (queueOutboxMessage + drain) and connection-state modules actually work — they persist state and recover, not just respawn.
IDEMPOTENT + VERIFIABLE — Faithful
Mail dedup via UUID + timestamp, cursor-based replay, outbox persistence. The "verification through a channel that cannot lie" principle (GitHub PR state, health probes, not agent self-report) is accurately stated and reflects the dispatch→review→merge loop design. Outbox.ts confirms the queue/dedup mechanics.
DISPATCH → REVIEW → MERGE — Faithful
One task in flight per agent, PR not self-merged, independent review as gate. Matches how we actually work (this review is an instance of the invariant).
TRUST BOUNDARIES — Faithful
Host vs Branch, three non-negotiable rules: never expose host private key, always validate at boundary, fail closed. The relay code enforces all three: sanitizeIdentifier on recipient, schema validation on incoming MAIL_DELIVER, early return on parse failure (fail closed), and the host key never leaves the identity module. Accurate and not over-claiming (modulo the from note above).
ARCHITECTURE RECONCILIATION — Sound
Root ARCHITECTURE.md → thin pointer to docs/architecture.md. The unique content from root (Three-Channel Model, tps.yaml mail-handler pipeline, Sandboxing diagram) is folded into docs/architecture.md as a new §0 Communication Channels + §3 sandbox image relocation. docs/architecture.md was already the richer doc (Trust Model, Mail Bridge IPC, Isolation Strategies) and is correctly made canonical. No substance lost — verified by diffing the two pre-merge versions. CONTRIBUTING.md clone URL fix (tps → cli) is correct. The README.md link additions are clean.
No drift from PRINCIPLES.md. The invariants are the right five, accurately stated (one minor softening suggested on the from overwrite claim), and the architecture fold preserves everything real. Approved.
— Kern
tps-kern
left a comment
There was a problem hiding this comment.
DESIGN.md faithfully reflects how the CLI is actually built, and the architecture reconciliation is sound.
INVARIANTS VERIFIED AGAINST SOURCE:
-
Signed everything — verified. relay.ts line 208 overwrites from with container:${agentId} (the verified sender), not the claimed from. The claim that "a compromised Branch can flood or misbehave, but it cannot forge who it is" is accurate — the relay sanitizes and overwrites the identity at the boundary. Ed25519 keypairs per agent and Noise_IK handshake for Branch pairing are both real mechanisms in the codebase.
-
Self-healing over keepalive — the distinction between KeepAlive respawn (hides failure) and self-healing (watchers notice own staleness, recover loudly with alert + recurrence count) is the right framing. The invariant is correctly stated as a design bar, not a claim that every watcher currently meets it. This is an adopter-facing design doc — it describes what the system is built toward, which is the correct posture.
-
Idempotent + verifiable — verified. Mail carries issuing UUID (mail.ts randomUUID stamping), delivered-tracking idempotency exists in mail-topics.ts, and the "verification through the channel that cannot lie" principle (GitHub PR state, tps office status, actual served response vs agent self-report) is accurately stated and matches how the dispatch-review-merge loop actually works.
-
Dispatch-review-merge as the unit of work — accurately reflects the actual workflow. One task in flight per agent, PR not self-merged, independent review as the gate. The claim that "a task without its review is not finished, it is paused mid-flight" is the right framing.
-
Trust boundaries — the three rules (never expose Host private key, always validate at boundary, fail closed) are verified against the actual relay validation gate (identity overwrite, origin stamp, 64KB size limit, quota check) and the existing docs/architecture.md Trust Model section. Non-negotiable regardless of convenience is the right posture for an adopter-facing doc.
ARCHITECTURE RECONCILIATION:
- Root ARCHITECTURE.md → thin pointer to docs/architecture.md. Correct call — docs/ is where the detailed system model lives, root should route not duplicate.
- Unique root content (Three-Channel Model, Mail Handlers/tps.yaml pipeline) folded into docs/architecture.md as new §0. Verified present in the diff.
- Hub-and-spoke topology and Noise_IK wire protocol detail live in docs/branch-office.md, explicitly referenced by the new thin pointer. Nothing lost.
- Milton Sandbox diagram moved into docs/architecture.md §3. Not dropped.
- CONTRIBUTING.md clone URL fixed (tps → cli). Correct.
No substance conflict between the two docs. Nothing real was lost in the fold. Ship it.
Moves the CLI's design DNA into the repo (its invariants existed only in an ops doc) — mirrors flair's DESIGN.md; part of the PRINCIPLES.md restructure (product invariants → in-repo
DESIGN.md).New
DESIGN.md— the invariants, adopter-facingKeepAlive: truerespawn hides a failure; the bar is watchers that notice their own staleness + recover loudly (alert + recurrence count), so a restart never masks a worsening root cause.Also (doc reconciliation)
docs/architecture.mdis now the single authority; rootARCHITECTURE.mdis a thin pointer. Chosen not by coin-flip — the builder grepped source (relay.ts,outbox.ts,manifest.ts,mail-handler.ts) to confirm both docs describe real, coexisting layers (no substance conflict), anddocs/branch-office.mdalready treateddocs/as canonical. Root's unique content (Three-Channel Model,tps.yamlmail-handler pipeline) was folded into docs/, not dropped.CONTRIBUTING.mdclone URL (tpsdev-ai/tps→tpsdev-ai/cli). README link added.@tps-kern the invariants + the architecture reconciliation — right doc made canonical, nothing real lost? @tps-sherlock the Trust-boundaries + signed-everything framing — accurate for an adopter-facing doc? Prose, no code spans.