Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# PNA Spec Changelog
# PNT Changelog

## v0.1 draft (in progress)

Expand All @@ -13,7 +13,7 @@

### v0.1 baseline

Initial release of the PNA Spec. Establishes:
Initial release of the toolkit (PNA Spec + typed contracts). Establishes:

- Vocabulary (Use case, Axis, Axis pick, Flavor, Composition model, MCP server, Universal vs flavor-derived AC).
- Goals (1-5: private data sovereignty, mirror centralized sources locally, secure communication options, portable/durable/recoverable user data, locally diagnosable).
Expand Down
8 changes: 6 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Contributing to PNT

> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](VERSION).

PNT (the Personal Network Toolkit) evolves through reference-driven specification: spec changes are accompanied by a working reference design that demonstrates the change in code. This document describes how to contribute a reference design — and how a spec change rides along with it.

## Philosophy
Expand All @@ -17,7 +19,7 @@ The step-by-step procedure for a contribution — preflight your design via the
- Reference designs derived from working applications.
- Under any OSI-approved license.
- With an Architecture document (the design's "Security Target") that:
- declares the PNA Spec version the design conforms to,
- declares the Toolkit-Version the design conforms to,
- declares per-axis picks and their versions,
- documents per-axis implementation choices, and
- includes an **AC (Architectural Commitment) attestation table** mapping every applicable AC to (a) how the design realizes it, with code references, and (b) the specific test(s), LLM (Large Language Model) evaluation rubric, or human-review record(s) that verify it for this design. Rows without a Verification reference are not accepted.
Expand Down Expand Up @@ -55,7 +57,7 @@ On merge:
- Spec changes land (including any new AC IDs, sub-contracts, or axis-pick additions)
- Maintainer triggers Software Heritage archival (planned tooling: `tools/swh-save.sh <repo-url> <commit-sha>`, landing in Phase 5; until then, archival is performed manually via Software Heritage's Save Code Now) and records the returned SWHID (Software Heritage Persistent IDentifier) in the design record
- Maintainer decides whether the design warrants an additional `archive/<design-name>` fork in the `pnt-archive` GitHub organization (high-signal designs only; SWHID alone is sufficient for the archival promise)
- Spec version bumped per the versioning rules below
- Toolkit version bumped per the versioning rules below

## Versioning

Expand All @@ -67,6 +69,8 @@ The PNA Spec uses linear SemVer:

Individual axes carry their own version (declared per-axis in each design's Architecture document). A breaking change to an axis bumps that axis's version and the PNA Spec major.

**The toolkit is versioned as a unit.** The version in `/VERSION` covers the whole toolkit — spec, contracts, skill, lint, and templates — not just the prose spec; every toolkit artifact carries a matching `Toolkit-Version:` header, enforced by `tools/lint-spec-ids.py`. A contribution is a PR against that versioned toolkit, whatever its shape — (a) a reference design, (b) a new architectural commitment, exception, or solution, or (c) a modification to the spec documents. Releases are git-tagged (`v<MAJOR.MINOR.PATCH>`). A design declares the `Toolkit-Version` it was built and validated against in its Architecture document; that is how a reader knows which toolkit version a design conforms to.

## Archival

Software Heritage SWHIDs are the canonical permanent identifier for accepted reference designs (v0.1 — see `spec/PNA_Spec.md § Vocabulary` under "reference design"). PNT may additionally fork high-signal designs to a `pnt-archive` GitHub organization at maintainer discretion; these forks are frozen at the accepted commit and not maintained.
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Personal Network Toolkit

> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](VERSION).

The Personal Network Toolkit (PNT) is a [generative application-class blueprint](docs/PriorArt.md) for building and validating **[personal network applications (PNAs)](spec/PNA_Spec.md#goals)** — local-only apps for viewing contact data and working on relationship data over a firewalled private data layer. PNAs run on the user's device, never as SaaS, and bridge SaaS-held contact data into a private workspace. **[Why do this?](spec/PNA_Spec.md#preamble)**

When building a PNA, specs are foundational because users will increasingly compose software by prompting AI agents, and success is measured by adherence to them.
Expand Down Expand Up @@ -44,7 +46,7 @@ What we're working toward — success looks like:

Step-by-step instructions for each of those goals live in [`docs/users-guide.md`](docs/users-guide.md).

Substantive changes from v0.1 bump the spec version per [`CHANGELOG.md`](CHANGELOG.md).
Substantive changes from v0.1 bump the toolkit version per [`CHANGELOG.md`](CHANGELOG.md).

## Entry points

Expand All @@ -63,14 +65,14 @@ To dig into the spec more deeply:
- **[`spec/axes.md`](spec/axes.md)** — the Axes a PNA varies along, attested picks per Axis, and the flavor-derived ACs each pick triggers.
- **[`spec/use_cases.md`](spec/use_cases.md)** — attested classes of PNA (Directory Archive realized; Personal Relationship Manager draft; Multi-PNA ecosystem target).
- **[`contracts/`](contracts/)** — typed contracts for the load-bearing interfaces: JSON Schema for the worker init handshake + RPC (Remote Procedure Call) protocol, OpenAPI for distribution auth, SQL DDL (Data Definition Language) for the two database schemas, TypeScript for the Communications transport interface, JSON Schema for the five canonical MCP server tool surfaces.
- **[`CHANGELOG.md`](CHANGELOG.md)** — spec version history.
- **[`CHANGELOG.md`](CHANGELOG.md)** — toolkit version history.
- **[`llms.txt`](llms.txt)** — discovery file for the spec (humans + AI agents land here cold).

## Reference designs

A reference design is a working, deployed PNA that demonstrates one valid combination of axis picks against the spec. Each lives in its own repository so it can ship under its own release cadence.

- **[fellows_local_db](https://github.com/richbodo/fellows_local_db)** — first reference design. Directory Archive use case. Its [`docs/Architecture.md`](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md) declares spec-version conformance and the per-slot specializations. Flavor:
- **[fellows_local_db](https://github.com/richbodo/fellows_local_db)** — first reference design. Directory Archive use case. Its [`docs/Architecture.md`](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md) declares Toolkit-Version conformance and the per-slot specializations. Flavor:

| Axis | Pick |
| ------------------- | ----------------------------- |
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0-draft
2 changes: 1 addition & 1 deletion contracts/client-errors-payload.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/client-errors-payload.schema.json",
"title": "Debug contract — sanitized error sink payload",
"$comment": "Realizes: AC-7, AC-8.",
"$comment": "Realizes: AC-7, AC-8. Toolkit-Version: 0.1.",
"description": "Sub-contract DB-4 from spec/PNA_Spec.md § Slot map. Body schema for `POST /api/client-errors` (or the substrate-equivalent unauthenticated sink). The endpoint is unauthenticated by design — its job is to capture diagnostics from users who couldn't pass the auth gate — so the privacy boundary is load-bearing: only what's defined here is allowed to flow into the maintainer's structured log. Anything outside this schema MUST be silently dropped server-side (per DB-4 'always 204; events typed via a kind= enum allowlist; free-text fields sanitized server-side. Privacy boundary is *server-side*, not trusted to the client'). Adding new event kinds — and only new kinds — is the only widening lever (DB-5). For the full free-text sanitization rules (email redaction, slug/token redaction in hash routes, query-string drop, length caps), see the conforming implementation at `deploy/client_error_sanitizer.py` and `docs/email_gate.md` § Client error reporting.\n\nv0.1 size caps (operational, not strict spec): 16 KB body cap (enforced by the Distribution slot's POST handler — see DI-5); 20 events per POST; 500 chars per `msg`; 200 chars per `extra`; 240 chars each for `ua`, `route`; 64 chars for `build`.",
"type": "object",
"required": ["events"],
Expand Down
1 change: 1 addition & 0 deletions contracts/distribution-auth.openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Realizes: AC-2, AC-5, AC-8.
# Toolkit-Version: 0.1

# Distribution slot — auth, install, and sanitized-error endpoints.
#
Expand Down
2 changes: 1 addition & 1 deletion contracts/mcp-comms.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/mcp-comms.schema.json",
"title": "MCP server — Communications",
"$comment": "Realizes: AC-MCP-B, AC-18, AC-19.",
"$comment": "Realizes: AC-MCP-B, AC-18, AC-19. Toolkit-Version: 0.1.",
"description": "Tool surface for the canonical Communications MCP server. Stages outreach for workspace-mediated user confirmation; does NOT directly launch transports (AC-MCP-B). The server returns a mailto: URL plus a full payload preview; the user's mail client — acting as the workspace for this outreach — opens the URL with the composition pre-populated, and the user reviews and clicks send. AC-18 (transport eligibility): mailto: passes — the mechanism can't read message content, and the downstream mail client is the user's choice. AC-19 (user-visible payload before send): the `preview` field exposes recipients + subject + body explicitly so the AI client can show the full composition to the user before they open the link. State posture: staged compositions live in process memory only; nothing on disk, nothing across restarts. See spec/PNA_Spec.md § Universal architectural commitments (AC-MCP-B, AC-18, AC-19) and § Vision (canonical MCP servers).",
"type": "object",
"required": ["server_name", "transport", "tools"],
Expand Down
2 changes: 1 addition & 1 deletion contracts/mcp-diagnostics.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/mcp-diagnostics.schema.json",
"title": "MCP server — Diagnostics",
"$comment": "Realizes: AC-7.",
"$comment": "Realizes: AC-7. Toolkit-Version: 0.1.",
"description": "Tool surface for the canonical Diagnostics MCP server. Read-only access to the Debug contract: build label, OPFS inventory (or substrate-equivalent), recent error events, boot marks, version handshake. Placeholder — no reference implementation yet; tool surface to be drafted alongside the first Diagnostics-exposing PNA. See ../spec/PNA_Spec.md § Vocabulary (five canonical MCP servers) and § Slot map (DB-1 through DB-9 for the Debug contract sub-contracts).",
"type": "object"
}
2 changes: 1 addition & 1 deletion contracts/mcp-ingestion.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/mcp-ingestion.schema.json",
"title": "MCP server — Ingestion",
"$comment": "Realizes: AC-10, AC-17, AC-PRM-D.",
"$comment": "Realizes: AC-10, AC-17, AC-PRM-D. Toolkit-Version: 0.1.",
"description": "Tool surface for the canonical Ingestion MCP server. Drives source imports, dedup wizard interaction, orphan preview, conflict resolution. Placeholder — no reference implementation yet; tool surface to be drafted alongside the first Ingestion-exposing PNA. See ../spec/PNA_Spec.md § Vocabulary (five canonical MCP servers), AC-10 (opt-in non-destructive re-import), AC-PRM-B (multi-source dedup contract).",
"type": "object"
}
4 changes: 2 additions & 2 deletions contracts/mcp-private-data-ops.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/mcp-private-data-ops.schema.json",
"title": "MCP server — Private Data Ops",
"$comment": "Realizes: AC-MCP-A, AC-10.",
"description": "Tool surface for the canonical Private Data Ops MCP server. Exposes read-only access to Private DB rows (groups + their members joined to Shared DB display fields) so an AI client can answer 'who's in this group' and 'find my X group' questions. Members are returned with orphan-tolerant nulls when a member's record_id no longer resolves in the Shared DB after a re-mirror (per AC-10). AC-MCP-A applies: cloud AI clients require explicit per-call consent before invoking tools on this server. v1 scope is groups only; tag/note CRUD will appear in a later spec version once users are writing those at scale. See spec/PNA_Spec.md § Universal architectural commitments (AC-MCP-A, AC-10) and § Vision (canonical MCP servers).",
"$comment": "Realizes: AC-MCP-A, AC-10. Toolkit-Version: 0.1.",
"description": "Tool surface for the canonical Private Data Ops MCP server. Exposes read-only access to Private DB rows (groups + their members joined to Shared DB display fields) so an AI client can answer 'who's in this group' and 'find my X group' questions. Members are returned with orphan-tolerant nulls when a member's record_id no longer resolves in the Shared DB after a re-mirror (per AC-10). AC-MCP-A applies: cloud AI clients require explicit per-call consent before invoking tools on this server. v1 scope is groups only; tag/note CRUD will appear in a later toolkit version once users are writing those at scale. See spec/PNA_Spec.md § Universal architectural commitments (AC-MCP-A, AC-10) and § Vision (canonical MCP servers).",
"type": "object",
"required": ["server_name", "transport", "tools"],
"properties": {
Expand Down
2 changes: 1 addition & 1 deletion contracts/mcp-shared-data-ops.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/mcp-shared-data-ops.schema.json",
"title": "MCP server — Shared Data Ops",
"$comment": "Realizes: AC-17.",
"$comment": "Realizes: AC-17. Toolkit-Version: 0.1.",
"description": "Tool surface for the canonical Shared Data Ops MCP server. Exposes read-only access to the Shared DB so an AI client (Claude Desktop, Cursor, a local-Ollama-backed agent) can answer 'what's in this directory' questions and look up specific records. Conforming implementations expose exactly these four tools with the input/output shapes defined below. Does NOT return Private DB rows; AC-MCP-A (cloud-client consent) is not triggered by this server. See spec/PNA_Spec.md § Vision (canonical MCP servers) and AC-17 (mirrored data is sourced).",
"type": "object",
"required": ["server_name", "transport", "tools"],
Expand Down
1 change: 1 addition & 0 deletions contracts/private-db.schema.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-- Realizes: AC-1, AC-9.
-- Toolkit-Version: 0.1

-- Private schema interface — canonical SQL DDL for a conforming Private DB.
--
Expand Down
1 change: 1 addition & 0 deletions contracts/shared-db.schema.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-- Realizes: AC-1, AC-10, AC-17.
-- Toolkit-Version: 0.1

-- Shared schema interface — canonical SQL DDL for a conforming Shared DB.
--
Expand Down
1 change: 1 addition & 0 deletions contracts/transport-interface.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Realizes: AC-16, AC-18, AC-19.
// Toolkit-Version: 0.1

// Communications slot — the transport interface every comms transport
// implements. Sub-contracts CO-1 through CO-6 from `_pna_triage.md` Part 4.
Expand Down
4 changes: 2 additions & 2 deletions contracts/worker-init-handshake.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://pna-spec.example/v0.1/worker-init-handshake.schema.json",
"title": "Storage slot — init handshake",
"$comment": "Realizes: AC-4, AC-11, AC-12.",
"$comment": "Realizes: AC-4, AC-11, AC-12. Toolkit-Version: 0.1.",
"description": "Sub-contract ST-2 from the Storage slot. The first RPC across the Storage boundary must be `op='init'`, and the response carries the handshake blob defined here. Three things land in this single message: (1) the version pair that AC-4 enforces (workerRpcVersion + schemaVersion — page refuses mutating RPCs on mismatch, reads still work); (2) the capability flag AC-12 reads (opfsCapable — substrate-equivalent capability for non-browser PNAs); (3) the inventory the page needs to decide directory-mode vs distribution-gate (hasSharedDb, hasPrivateDb). Capability detection MUST happen inside this op, not on the page (AC-12 — browsers lie about main-thread support; the worker is the only context where the answer is reliable). The init response is wrapped by the standard RPC envelope from worker-rpc-protocol.schema.json — `ok` in the envelope indicates success/failure; the InitResult below is what the envelope's `result` field carries on success. Init failures surface via the envelope's error path, notably with `errorCode: 'OWNERSHIP_CONFLICT'` when AC-11 fires (multi-tab access conflict).\n\nNaming note (v0.1): the spec uses the generic field names `hasSharedDb` and `hasPrivateDb`, matching spec/PNA_Spec.md vocabulary. fellows_local_db's worker today emits `hasFellowsDb` and `hasRelationshipsDb` instead — a flavor-specific divergence pre-dating the spec. Implementations conforming to v0.1 should use the generic names; aligning fellows_local_db's field names is a clean-up task tracked separately.",
"type": "object",
"required": ["request", "response"],
Expand All @@ -20,7 +20,7 @@
"op": { "const": "init" },
"args": {
"type": "object",
"description": "v0.1: no init args. Future spec versions may add bootstrap flags (e.g. a 'skipAutoBackup' switch for test runners).",
"description": "v0.1: no init args. Future toolkit versions may add bootstrap flags (e.g. a 'skipAutoBackup' switch for test runners).",
"additionalProperties": false,
"properties": {}
}
Expand Down
Loading
Loading