Map A17 onto Outline's actual primitives, and record the MCP decision #23
@@ -622,6 +622,56 @@ rests on.
|
||||
**Deferred:** the operator-writable procedures collection. The interface is defined
|
||||
here; the content and the C2 binding list arrive with the policy taxonomy (Part H).
|
||||
|
||||
**Concrete mapping onto Outline.** Observed in the running instance: a **collection**
|
||||
carries per-user permissions with three tiers — visible-to (read), read-write, and
|
||||
manager. Permissions are collection-scoped, not per-document.
|
||||
- Therefore **one collection per writing principal**, with read membership granted to
|
||||
everyone else who needs it: `nisse-ops-world` (write: `nisse-ops`),
|
||||
`nisse-dev-world` (write: `nisse-dev`), `procedures` (write: operator).
|
||||
- **What this enforces, precisely:** no *other agent* can write a given agent's world
|
||||
model — the collision that would otherwise be silent and unattributable. It does not
|
||||
enforce operator-versus-agent exclusion, because the operator holds manager on their
|
||||
own wiki and can always grant themselves write. That half is procedural: the
|
||||
break-glass routine stops the agents first, so concurrent writers do not exist while
|
||||
editing.
|
||||
- **Assign per user, not per group.** Outline groups appear to be internal to Outline
|
||||
rather than federated with LLDAP (A8), so using them would put membership in a second
|
||||
place that nothing syncs. With three principals the manual mapping is trivial and
|
||||
obvious; revisit only if the cast grows.
|
||||
- **Each agent's API token must belong to that agent's own Outline user.** Outline API
|
||||
keys are per-user, so the token *is* the identity every permission above evaluates
|
||||
against. A token minted from the operator's account — or an admin's — silently voids
|
||||
the entire boundary while appearing to work.
|
||||
- **Identify collections and documents by ID, from config and state.** Collection IDs
|
||||
come from env (`NISSE_OUTLINE_*_COLLECTION`), never discovered from "whatever the
|
||||
token can write": a permission change must not silently redefine what an agent
|
||||
considers its own. Document IDs are recorded in the state store (A2) when created and
|
||||
used for updates, which also makes writing idempotent — a retry after a crash updates
|
||||
the document instead of creating a second one.
|
||||
- **Revision reads, not conditional writes.** Because break-glass stops the agents,
|
||||
compare-and-swap is unnecessary; what is needed is the ability to *observe* that a
|
||||
document changed since the agent last read it, feeding the A3 divergence check.
|
||||
Whether Outline exposes a revision identifier or only a modified timestamp is
|
||||
unverified — either satisfies this.
|
||||
|
||||
#### Considered and deferred: Outline's MCP server
|
||||
|
||||
Outline can expose search, read, create and edit over MCP (remote, Streamable HTTP,
|
||||
enabled workspace-wide). **Not adopted for the retrieval path**, because A17's
|
||||
enforcement depends on this library sitting *between* the model and the store: staleness
|
||||
marking, snapshotting into the canonical log, binding procedures to action classes, and
|
||||
gating a failed confirm-first read all happen to a retrieval before the model sees it.
|
||||
MCP's purpose is the opposite — direct model access — and a procedure the model may
|
||||
decline to fetch does not constrain it (A12).
|
||||
|
||||
It remains a reasonable candidate for the *discretionary* search tool later, and unlike
|
||||
the vendor agent SDKs A13 rejects, MCP is a neutral standard rather than lock-in: one
|
||||
client would serve many servers if others are ever added. Before adopting it, verify
|
||||
that it honours the key owner's **collection** permissions rather than mere workspace
|
||||
membership, and that the workspace-level toggle does not force broader exposure than
|
||||
intended.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## PART B — THE DEV AGENT / `nisse-dev` (build first)
|
||||
|
||||
Reference in new issue
Block a user