A full Entailment server is running on this Mac. Accounts, sync, invitations, and the MCP endpoint all work against it now. The hosted server is specified but not deployed.
- HTTP API.
http://localhost:3010. The health endpoint answers{"ok":true}. Source:app/apps/server/src/index.ts. - Sync. WebSocket on
ws://localhost:3011, also served atws://localhost:3010/sync. - Database. Postgres 16 in Docker, container
context-pg, host port 5439, all 59 migrations applied. - Email. Off. Sign-up completes without verification. Invitations are shared as copied links instead of emails. The production sender is Resend, decided and recorded in the prototype specification.
- Hosted server. Not deployed. Slice PR-S1 deploys this same server to Cloudflare as a Worker-routed container with R2 and managed Postgres, per ADR 0003. It is blocked by the domain decision below.
These steps work now, against the local server. The same steps work against the hosted server once PR-S1 and PR-S2 land. Only the server address changes.
- Start the desktop app:
corepack pnpm run dev:desktopfrom theapp/directory. - In the server picker, choose Entailment managed service. The development build points it at
localhost:3010. - Sign up with an email address and password. The account activates immediately because email verification is off locally.
- Create a vault and make it synced. The vault registers on the server and its notes begin syncing.
- Open Members and choose Copy link. Send the link to a teammate. They install the app, point it at the same server, sign up, and open the link to join.
- Set access per folder or per file from the access board. Allow and deny rows control what each member reads and writes. Refusals land in the access audit. Source:
app/apps/server/src/permissions/,app/apps/server/src/audit/access.ts.
Scope note for collections: access control operates on folders and files inside a shared vault. To share one collection, put it in a folder and grant that folder. To share one note, grant that file.
The specification lives in the repository at docs/entailment/. Four documents govern the build: the goal document, the P0 identity specification, the prototype specification, and the open decisions list. Every slice merges in one day with tests green.
The server is multi-tenant by inheritance. Teams, invitations, roles, per-folder access, and the audit trail are working upstream code, and as of October 24, 2026 they are in prototype scope as inventory rows INV-27, INV-28, and INV-31.
- Tenancy unit. A vault. Each vault has an owner, members with roles, and its own access board. One account can own and join many vaults. Source:
app/apps/server/src/invitations/,app/apps/server/src/members/. - Team rollout. Each teammate installs the app, points it at the shared server, and signs up. Membership in a vault comes from an invite link or a join code. An account by itself grants nothing.
- Isolation. An account sees only vaults it owns or joined. Within a shared vault, deny rows carve out folders and files per member.
- Audit. Member activity and access refusals are recorded server-side. Source:
app/apps/server/src/audit/access.ts, migration 056.
This section describes the intended client path. It is a proposal. It waits on a detailed specification from Jonny and is not yet in the feature inventory.
- A forward-deployed engineer completes the ShurIQ report and the SPBI report for the client.
- The engineer provisions a client vault on the shared server: a new vault, the client's members invited by link, access rows set per folder.
- Meeting transcripts, after-action reports, and other artifacts route into the client vault through the MCP endpoint, written as Markdown with frontmatter YAML, OKF concepts, and wikilink trails. The seams this uses are specified: stable note ids, revision-guarded MCP writes, and JSON-LD export (inventory row INV-38, ADR 0004).
- Graph connections between artifacts come from the wikilinks themselves. The graph view and backlinks panel render them without extra work.
- Content-gap and cluster analysis over a client's vault runs through the InfraNodus path: layer 1 as an outside agent now, layer 2 as an in-product Analyze panel after the go decision (rows INV-39 and INV-40).
Boundary rule: Entailment carries no ShurIQ names, code, data, or dependencies. Client routing connects only through the published seams. This rule is ADR 0004 and it is what keeps the clean-room option open.
Seven decisions were made and applied to the specification on October 24, 2026: the Postgres provider (Neon), the email sender (Resend), the placeholder icon, the InfraNodus test runner, the lazy id backfill, the acceptance-suite location, and the layer-2 adapter shape. One remains.
- The domain name. The hosted server needs a domain before PR-S1 can deploy and before PR-S2 can set the default server address. The identity values freeze after the first install, so the name should be final, not provisional. Record:
docs/entailment/OPEN_DECISIONS.md, item 1.
Sequence once the domain is named: PR-S1 and PR-S2 make the server public, P0-S2 and P0-S3 finish the identity and detach the updater, PR-S10 and PR-S11 put teams and access under test, and the team onboards. The remaining slices harden sync, seams, and parity in parallel.