From 393bd0871a345edb52960b5e0b4945181f74e4de Mon Sep 17 00:00:00 2001 From: Rich Bodo Date: Sun, 31 May 2026 20:56:12 +1200 Subject: [PATCH 1/5] =?UTF-8?q?docs:=20toolkit=20DX=20+=20framing=20?= =?UTF-8?q?=E2=80=94=20per-repo=20install,=20validation-not-cert,=20except?= =?UTF-8?q?ions=20prior=20art?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - users-guide.md: expand per-repo skill install (symlink for dev vs vendored-copy-with-pinned-commit for a contributing design) + the 'skills load at session start, restart to invoke' caveat. - PNA_Spec.md § Building a PNA: promote 'validation, not certification' to a first-class framing statement (cross-links CONTRIBUTING + SKILL; ties in exceptions reported by AC/EX ID, not graded). - prior_art.md: new § 9 — behavioral exceptions, consent propagation (TCF/UMA/Kantara/macaroons), graded assurance (EAL/ASVS/SLSA/EARL), and legible labeling (nutrition labels/model cards/datasheets); finding that the mechanics have precedent but the exception-as-class-concept is novel. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/PriorArt.md | 13 +++++++++++++ docs/PriorArtReferences.md | 15 +++++++++++++++ docs/users-guide.md | 20 ++++++++++++++++++-- spec/PNA_Spec.md | 2 ++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/docs/PriorArt.md b/docs/PriorArt.md index d430e60..5eb4dad 100644 --- a/docs/PriorArt.md +++ b/docs/PriorArt.md @@ -116,6 +116,19 @@ Background research on the application class PNT targets. **Proximity to PNT:** Background. Defines the domain but not the class-blueprint approach. +### 9. Behavioral exceptions, consent propagation, and graded assurance + +Prior art for the [Exceptions](../spec/exceptions.md) concept — a PNA *deliberately and honestly* departing from a guarantee — and for its per-dimension strength profiles. Surveyed when designing `EX-CLOUD-LLM`. + +- **Graded assurance levels.** Common Criteria EAL, [OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/) levels, and [SLSA](https://slsa.dev/) levels (all surveyed in § 4–5) establish the *grade-the-strength* precedent. PNT's strength profile borrows the idea but **rejects a single collapsed level** in favor of per-dimension classes — one number would hide that "the boundary is enforced" and "the provider's data handling is unverifiable" are different *kinds* of assurance. +- **Machine-readable conformance reporting.** [W3C EARL](https://www.w3.org/TR/EARL10-Schema/)'s pass / fail / cannot-tell vocabulary is the model for the evaluate flow reporting exception handling by ID (including "unable-to-determine"). +- **Consent propagation through delegation chains.** The IAB Europe [Transparency & Consent Framework](https://iabeurope.eu/transparency-consent-framework/) (a consent string propagated down an ad-tech chain), [User-Managed Access and Consent Receipts](https://kantarainitiative.org/) (Kantara), and **macaroons** (Birgisson et al., Google Research, 2014 — bearer credentials with *attenuating* caveats). Macaroons are the closest match to handler clause EX-H7: delegated authority only **narrows** as it passes through intermediaries, never amplifies — exactly the property "consent must reach the ultimate human; a proxy can't manufacture it" requires. +- **Legible strength/limitation labeling.** Apple privacy "nutrition labels", [model cards](https://arxiv.org/abs/1810.03993) (Mitchell et al., 2019), and [datasheets for datasets](https://arxiv.org/abs/1803.09010) (Gebru et al., 2018) — precedent for surfacing strengths *and* limitations in a fixed, user-readable structure. The per-dimension strength profile is this idea applied to a behavioral exception. + +**Finding:** the *mechanics* — grade the strength, attest it, propagate attenuated consent, report cannot-tell — have solid precedent, and PNT borrows them rather than inventing. What appears genuinely new is **framing a deliberate behavioral deviation as a first-class, stable-ID'd, caught-and-handled "exception" for an application class**; no surveyed artifact offers a description language for that. The human-AI-team development context is why it surfaces now. + +**Proximity to PNT:** Informative (mechanism). The grading, reporting, and attenuation patterns are adopted; the exception-as-class-concept is the novel part. + ## Proximity matrix | Artifact | Generative? | Class-scoped? | Multi-flavor? | Machine-checkable? | Overall proximity | diff --git a/docs/PriorArtReferences.md b/docs/PriorArtReferences.md index 6c58acd..c12d9c0 100644 --- a/docs/PriorArtReferences.md +++ b/docs/PriorArtReferences.md @@ -95,6 +95,21 @@ Companion reference list to [`PriorArt.md`](./PriorArt.md), the analytical surve - **[vCard (draft-ietf-vcarddav-vcardrev-02)](https://www.ietf.org/archive/id/draft-ietf-vcarddav-vcardrev-02.html)** — The contact-data format underlying CardDAV and most contact-exchange systems. - **[Defensics vCard Test Suite (Black Duck)](https://www.blackduck.com/fuzz-testing/defensics/protocols/vcard.html)** — Commercial fuzz/robustness conformance suite for vCard implementations. +## Behavioral exceptions & consent propagation + +Sources for [`PriorArt.md` § 9](./PriorArt.md) — prior art for the Exceptions concept (a PNA deliberately, honestly departing from a guarantee) and its per-dimension strength profiles. + +- **[Macaroons: Cookies with Contextual Caveats for Decentralized Authorization](https://research.google/pubs/pub41892/)** — Birgisson, Politz, Erlingsson, Taly, Vrable, Lentczner (Google, 2014). Bearer credentials whose authority can only be *attenuated* (narrowed) by adding caveats as they pass through intermediaries, never amplified. The closest formal analog to handler clause EX-H7 — consent must reach the ultimate human; a proxy cannot manufacture it. +- **[IAB Europe Transparency & Consent Framework (TCF)](https://iabeurope.eu/transparency-consent-framework/)** — A consent string propagated down a multi-party (ad-tech) delegation chain; prior art — cautionary as much as exemplary — for carrying a consent signal across actors. +- **[Kantara Initiative — User-Managed Access (UMA) & Consent Receipts](https://kantarainitiative.org/)** — Standards for user-controlled delegated authorization and for issuing a machine-readable receipt that a specific consent was given; relevant to recording and propagating the human's consent under an exception. +- **[Common Criteria — Evaluation Assurance Levels (ISO/IEC 15408)](https://www.commoncriteriaportal.org/)** — Graded assurance levels (EAL1–7); the canonical "grade the strength" precedent the strength profile borrows from while rejecting a single collapsed level. +- **[OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/)** — Application Security Verification Standard; level-based (L1–L3) assurance — another graded-strength precedent. +- **[SLSA](https://slsa.dev/)** — Supply-chain Levels for Software Artifacts; graded build-integrity assurance levels. +- **[W3C EARL — Evaluation and Report Language](https://www.w3.org/TR/EARL10-Schema/)** — pass / fail / cannot-tell reporting vocabulary; the model for reporting exception handling by ID, including "unable-to-determine". +- **[Model Cards for Model Reporting](https://arxiv.org/abs/1810.03993)** — Mitchell et al., 2019. Fixed-structure disclosure of a model's intended use, performance, and limitations; precedent for surfacing strengths *and* limitations legibly (the per-dimension strength profile applies this to a behavioral exception). +- **[Datasheets for Datasets](https://arxiv.org/abs/1803.09010)** — Gebru et al., 2018. Standardized dataset documentation (provenance, composition, limitations); same legible-disclosure lineage as model cards. +- **Apple App Store privacy "nutrition labels"** — Per-app privacy summaries in a fixed structure; a consumer-facing instance of legible strength/limitation labeling. + --- *Reference list compiled from a conversation with Claude (Anthropic), May 2026. See [`PriorArt.md`](./PriorArt.md) for the analytical survey that uses these sources.* diff --git a/docs/users-guide.md b/docs/users-guide.md index 2039240..a5473e6 100644 --- a/docs/users-guide.md +++ b/docs/users-guide.md @@ -34,10 +34,26 @@ Symlinking keeps the skill in sync with your PNT clone — a `git pull` here upd **Alternatives:** - **Copy instead of symlink** — replace `ln -s` with `cp -r` to pin the skill to a specific version. You'll re-copy when you want updates. -- **Project-level install** — replace `~/.claude/skills` with `/.claude/skills` to scope the skill to one project (useful if you want different skill versions in different projects). - **Run Claude Code from PNT itself** — no install required; the skill is discoverable from this directory. Adequate for one-off auditing. -**Verify.** Start Claude Code in any directory and try one of the prompts below; if the skill triggers, you're set. You can also ask the agent something like *"what PNT skills do you have available?"* to check. +### Per-repo install (for a design that contributes to PNT) + +When a PNA repo actively contributes back (it's a reference design, or you drive the contribute flow from it), scope the skill to that repo at `/.claude/skills/pna-build-eval-contrib` so collaborators on it pick the skill up. Two forms: + +- **Symlink** (dev convenience, no drift): + ```bash + ln -s /pna-build-eval-contrib /.claude/skills/pna-build-eval-contrib + ``` + Stays in sync with your PNT clone, but the absolute path is machine-specific — **don't commit a machine-specific symlink.** +- **Vendored copy** (portable, committable): + ```bash + cp -r /pna-build-eval-contrib /.claude/skills/pna-build-eval-contrib + ``` + Commit it **with a provenance note pinning the PNT commit** it was copied from (e.g. an `INSTALLED_FROM.md` beside `SKILL.md`). Collaborator-friendly and reproducible, but it **drifts** from upstream — re-sync (re-copy + bump the pinned commit) before relying on it for a contribution. + +Pick the symlink for local iteration; pick the vendored copy when the design repo should carry the skill for everyone working on it. + +**Verify.** Start Claude Code and try one of the prompts below; if the skill triggers, you're set. You can also ask *"what PNT skills do you have available?"*. **Note:** skills load at **session start** — if you just installed the skill, restart Claude Code (or open a fresh session) before it becomes invocable; a mid-session install is not picked up. --- diff --git a/spec/PNA_Spec.md b/spec/PNA_Spec.md index 34c7c15..6b8a12f 100644 --- a/spec/PNA_Spec.md +++ b/spec/PNA_Spec.md @@ -24,6 +24,8 @@ Without PNAs, or something like them, we often go to a list of contacts in linke When an AI is asked to build a PNA, it is required to follow the contracts of the PNA on the user's behalf, and those contracts are written so the AI can pick them up and check its own work. The user's confidence comes from the spec being clear enough that both they and the AI can read it. As long as the contracts hold, an AI can rewrite a PNA from scratch while the user is still talking to it without changing the user's sovereignty, durability, or privacy posture. The goals below are user-facing needs; the [architectural commitments (ACs)](#vocab-universal-ac) after them are the choices that make those needs achievable. Check out the specs of any reference design to see the output of this process. +> **Validation, not certification.** PNT validates behaviors against the Goals; it does not certify. There is no pass/fail badge and no certifying body (see [`CONTRIBUTING.md`](../CONTRIBUTING.md) § "Acceptance is not certification" and the skill's § Principles, "Conformance is checked, not awarded"). Conformance is *checked* — by the user, or by an AI running the evaluate flow — against this spec. Where a PNA deliberately departs from a guarantee it raises an [Exception](exceptions.md); the evaluate flow then detects each exception and verifies how it is handled, **reporting by `AC-*`/`EX-*` ID rather than awarding a grade.** + --- From f25f558560f86c5a61e22d694504e7a4ec95cffc Mon Sep 17 00:00:00 2001 From: Rich Bodo Date: Sun, 31 May 2026 21:09:41 +1200 Subject: [PATCH 2/5] spec: version the toolkit as a unit (Toolkit-Version, anchored to /VERSION) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The whole toolkit — spec, contracts, skill, lint, templates — is now versioned as one unit, equal to the spec version, so 'which toolkit am I building against?' resolves to a name, not just a git SHA. - /VERSION = 0.1.0-draft (single source of truth). - Every versioned artifact carries a 'Toolkit-Version: 0.1' stamp in its native format (md blockquote; # / -- / // comments; JSON $comment). - lint-spec-ids.py enforces presence + minor-match against /VERSION. - CONTRIBUTING § Versioning: the version covers the toolkit as a unit and all contribution shapes (reference design / AC-exception-solution / spec-doc change); releases git-tagged; designs declare the Toolkit-Version they built against. - ARCHITECTURE_TEMPLATE: design version field relabeled to Toolkit-Version. Revalidated against the now-named version: lint green across the chain (25 AC IDs, 12/12 contracts, 1 exception, toolkit 0.1). Co-Authored-By: Claude Opus 4.8 (1M context) --- CONTRIBUTING.md | 4 + README.md | 2 + VERSION | 1 + contracts/client-errors-payload.schema.json | 2 +- contracts/distribution-auth.openapi.yaml | 1 + contracts/mcp-comms.schema.json | 2 +- contracts/mcp-diagnostics.schema.json | 2 +- contracts/mcp-ingestion.schema.json | 2 +- contracts/mcp-private-data-ops.schema.json | 2 +- contracts/mcp-shared-data-ops.schema.json | 2 +- contracts/private-db.schema.sql | 1 + contracts/shared-db.schema.sql | 1 + contracts/transport-interface.d.ts | 1 + contracts/worker-init-handshake.schema.json | 2 +- contracts/worker-rpc-protocol.schema.json | 2 +- pna-build-eval-contrib/SKILL.md | 2 + .../templates/ARCHITECTURE_TEMPLATE.md | 6 +- reference_designs/templates/TEMPLATE.md | 2 + spec/PNA_Spec.md | 2 + spec/axes.md | 2 + spec/exceptions.md | 2 +- spec/use_cases.md | 2 + tools/lint-spec-ids.py | 80 ++++++++++++++++--- 23 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 VERSION diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 150a81e..5f551bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 @@ -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`). 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. diff --git a/README.md b/README.md index 0c13980..8fae963 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3e56aee --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0-draft diff --git a/contracts/client-errors-payload.schema.json b/contracts/client-errors-payload.schema.json index 20a5822..1487e44 100644 --- a/contracts/client-errors-payload.schema.json +++ b/contracts/client-errors-payload.schema.json @@ -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"], diff --git a/contracts/distribution-auth.openapi.yaml b/contracts/distribution-auth.openapi.yaml index c6f9e6f..2acee03 100644 --- a/contracts/distribution-auth.openapi.yaml +++ b/contracts/distribution-auth.openapi.yaml @@ -1,4 +1,5 @@ # Realizes: AC-2, AC-5, AC-8. +# Toolkit-Version: 0.1 # Distribution slot — auth, install, and sanitized-error endpoints. # diff --git a/contracts/mcp-comms.schema.json b/contracts/mcp-comms.schema.json index ac39a19..6439663 100644 --- a/contracts/mcp-comms.schema.json +++ b/contracts/mcp-comms.schema.json @@ -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"], diff --git a/contracts/mcp-diagnostics.schema.json b/contracts/mcp-diagnostics.schema.json index 3923b0f..756f5a3 100644 --- a/contracts/mcp-diagnostics.schema.json +++ b/contracts/mcp-diagnostics.schema.json @@ -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" } diff --git a/contracts/mcp-ingestion.schema.json b/contracts/mcp-ingestion.schema.json index acde235..9c7c063 100644 --- a/contracts/mcp-ingestion.schema.json +++ b/contracts/mcp-ingestion.schema.json @@ -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" } diff --git a/contracts/mcp-private-data-ops.schema.json b/contracts/mcp-private-data-ops.schema.json index aaead7b..35bb8b7 100644 --- a/contracts/mcp-private-data-ops.schema.json +++ b/contracts/mcp-private-data-ops.schema.json @@ -2,7 +2,7 @@ "$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.", + "$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 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).", "type": "object", "required": ["server_name", "transport", "tools"], diff --git a/contracts/mcp-shared-data-ops.schema.json b/contracts/mcp-shared-data-ops.schema.json index 9d45c17..c035356 100644 --- a/contracts/mcp-shared-data-ops.schema.json +++ b/contracts/mcp-shared-data-ops.schema.json @@ -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"], diff --git a/contracts/private-db.schema.sql b/contracts/private-db.schema.sql index 739c560..65b8d78 100644 --- a/contracts/private-db.schema.sql +++ b/contracts/private-db.schema.sql @@ -1,4 +1,5 @@ -- Realizes: AC-1, AC-9. +-- Toolkit-Version: 0.1 -- Private schema interface — canonical SQL DDL for a conforming Private DB. -- diff --git a/contracts/shared-db.schema.sql b/contracts/shared-db.schema.sql index 92e7c80..83ddd7f 100644 --- a/contracts/shared-db.schema.sql +++ b/contracts/shared-db.schema.sql @@ -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. -- diff --git a/contracts/transport-interface.d.ts b/contracts/transport-interface.d.ts index 45d5dd0..3f73c47 100644 --- a/contracts/transport-interface.d.ts +++ b/contracts/transport-interface.d.ts @@ -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. diff --git a/contracts/worker-init-handshake.schema.json b/contracts/worker-init-handshake.schema.json index 8a2e775..4958578 100644 --- a/contracts/worker-init-handshake.schema.json +++ b/contracts/worker-init-handshake.schema.json @@ -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"], diff --git a/contracts/worker-rpc-protocol.schema.json b/contracts/worker-rpc-protocol.schema.json index ef5d95a..543efda 100644 --- a/contracts/worker-rpc-protocol.schema.json +++ b/contracts/worker-rpc-protocol.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://pna-spec.example/v0.1/worker-rpc-protocol.schema.json", "title": "Storage slot — RPC protocol", - "$comment": "Realizes: AC-4, AC-10.", + "$comment": "Realizes: AC-4, AC-10. Toolkit-Version: 0.1.", "description": "Sub-contract ST-3 from the Storage slot. Defines the request/response envelope across the Storage boundary plus the input/output shape of the AC-load-bearing ops. The envelope is what every implementation must conform to; the op catalog below is the v0.1 minimum surface — implementations expose additional ops (CRUD on Private DB tables, reads on the Shared DB, auto-backup management, diagnostics) under the same envelope, and those flavor-specific ops are documented per implementation rather than pinned here.\n\nThe ops pinned here are the ones that enforce or surface an architectural commitment, so the spec contract is what an auditor reads to confirm AC compliance:\n- `init` — the version handshake (AC-4) and capability flag (AC-12); shape lives in worker-init-handshake.schema.json.\n- `compareSharedDbSha`, `previewSharedDbSwap`, `applySharedDbSwap`, `cancelSharedDbSwap` — the staged Shared-DB swap dance that AC-10 (opt-in non-destructive re-imports of the Shared store) hinges on.\n- `wipeAll` — the Reset Everything nuclear path (ST-10).\n- `getOpfsInventory`, `getVersions` — the diagnostic surface (ST-11) used by `?diag=1` and bug reports.\n\nFan-in dispatch: a single Storage boundary handles concurrent in-flight RPCs by correlating `id`. The implementation tracks pending RPCs in a sequence-numbered Map and rejects all pending entries on `worker.onerror` (or substrate-equivalent fatal-error signal) with a synthetic error so callers can fall back instead of hanging.\n\nNaming note (v0.1): the spec uses generic op names (`compareSharedDbSha`, `previewSharedDbSwap`, …). fellows_local_db's worker today uses fellows-specific names (`compareFellowsDbSha`, `previewFellowsDbSwap`, …) — a flavor-specific divergence pre-dating the spec; aligning op names is tracked separately. Implementations conforming to v0.1 should use the generic names.", "type": "object", "required": ["envelope", "errorCodes", "ops"], diff --git a/pna-build-eval-contrib/SKILL.md b/pna-build-eval-contrib/SKILL.md index 82b9a77..770c545 100644 --- a/pna-build-eval-contrib/SKILL.md +++ b/pna-build-eval-contrib/SKILL.md @@ -5,6 +5,8 @@ description: 'Use when building, extending, or evaluating a Personal Network App # Building, Evaluating, and Contributing to PNAs +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). + A PNA is a local-first application built to the PNT spec. The spec defines the architectural commitments (ACs) all PNAs share and the axes along which they legitimately differ. Conformance is satisfied by implementing the typed contracts in `contracts/` for each declared axis pick and honoring every applicable AC. PNT itself is a *generative + evaluative* application-class blueprint: diff --git a/reference_designs/templates/ARCHITECTURE_TEMPLATE.md b/reference_designs/templates/ARCHITECTURE_TEMPLATE.md index 98784cd..da74910 100644 --- a/reference_designs/templates/ARCHITECTURE_TEMPLATE.md +++ b/reference_designs/templates/ARCHITECTURE_TEMPLATE.md @@ -1,10 +1,12 @@ # — Architecture +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../../VERSION). + > The Architecture document is this design's Security Target: a declaration of its conformance against the PNA Spec (which plays the Protection Profile role). PNT requires every accepted reference design to ship one. A row missing the Verification field in the AC attestation table below is grounds for PR rejection. -## PNA Spec version +## Toolkit-Version -This design conforms to PNA Spec v. +This design was built and validated against Toolkit-Version (the `/VERSION` minor, e.g. `0.1`), which fixes the version of the whole toolkit — spec, contracts, skill, lint, and templates — that this design conforms to. ## Axis picks diff --git a/reference_designs/templates/TEMPLATE.md b/reference_designs/templates/TEMPLATE.md index c3aac62..6786e97 100644 --- a/reference_designs/templates/TEMPLATE.md +++ b/reference_designs/templates/TEMPLATE.md @@ -1,5 +1,7 @@ # +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../../VERSION). + **Maintainer:** () **License:** **First accepted:** PNA Spec v, diff --git a/spec/PNA_Spec.md b/spec/PNA_Spec.md index 6b8a12f..6bd6b59 100644 --- a/spec/PNA_Spec.md +++ b/spec/PNA_Spec.md @@ -1,5 +1,7 @@ # PNA Spec +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). + > **Spec-Version:** 0.1 (draft) > > This document is the universal specification for personal network applications (PNAs). Reference designs declare conformance to a specific spec version and to a specific application flavor (defined by a constellation of feature axis picks). A PNA conforms to this spec if it satisfies the universal architectural commitments and the axis-derived contracts for each of its declared axis picks, listed herein. Each reference design's specialization lives in its own repo (ex: fellows_local_db's specialization is at [`docs/Architecture.md`](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md)). diff --git a/spec/axes.md b/spec/axes.md index ad8a4a9..a66eed8 100644 --- a/spec/axes.md +++ b/spec/axes.md @@ -1,5 +1,7 @@ # Axes +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). + > **Spec-Version:** 0.1 (draft) This document catalogs the Axes a PNA picks along, the attested picks on each Axis, and the flavor-derived ACs each pick triggers. diff --git a/spec/exceptions.md b/spec/exceptions.md index 1e55713..2f16301 100644 --- a/spec/exceptions.md +++ b/spec/exceptions.md @@ -1,6 +1,6 @@ # PNA Exceptions -> **Spec-Version:** tracks the PNA Spec version in [`PNA_Spec.md`](PNA_Spec.md). +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). > > This file defines **Exceptions**: stable-ID'd conditions (`EX-*`) under which a PNA deliberately > departs from a baseline guarantee — a named AC, or the core PNA definition ("runs local-only, diff --git a/spec/use_cases.md b/spec/use_cases.md index 1270b62..479d963 100644 --- a/spec/use_cases.md +++ b/spec/use_cases.md @@ -1,5 +1,7 @@ # Use cases +> **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). + > **Spec-Version:** 0.1 (draft) This document catalogs the use cases the spec attests. Each use case names a coherent class of PNA from the user's perspective; it suggests default axis picks but does not determine them. The Use case concept is defined in [`PNA_Spec.md` § Vocabulary](PNA_Spec.md#vocabulary). diff --git a/tools/lint-spec-ids.py b/tools/lint-spec-ids.py index 867a5bb..03c05d0 100755 --- a/tools/lint-spec-ids.py +++ b/tools/lint-spec-ids.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 -"""Lint the AC/EX ↔ contract bidirectional traceability invariants. +# Toolkit-Version: 0.1 +"""Lint the AC/EX ↔ contract traceability invariants and toolkit-version stamps. Checks: 1. Every AC in spec/PNA_Spec.md and spec/axes.md carries a stable ID @@ -15,10 +16,14 @@ 6. Every "Reversible:" field is well-formed (yes|no); a "yes" requires a "Reversal:" field. Every value in a strength-profile column is one of the fixed strength classes (EX-H8). + 7. The toolkit is versioned as a unit: a /VERSION file is the source of + truth, and every versioned toolkit artifact (spec, skill, lint, + contracts, templates, CONTRIBUTING, README) carries a "Toolkit-Version:" + header whose minor matches /VERSION. -The lint validates the *shape* of declarations (presence + ID/vocabulary -resolution), not their behavioral correctness — that is the LLM evaluate -flow's job (see pna-build-eval-contrib/SKILL.md § Evaluate flow). +The lint validates the *shape* of declarations (presence + ID/vocabulary/ +version resolution), not their behavioral correctness — that is the LLM +evaluate flow's job (see pna-build-eval-contrib/SKILL.md § Evaluate flow). Exits 0 if clean, 1 if any violation found. Designed to be CI-friendly. """ @@ -49,7 +54,24 @@ "provider-asserted", "recoverable-only", "none", } +# Matches the version stamp across every artifact format: markdown +# (`**Toolkit-Version:** 0.1`), comments (`# / -- / // Toolkit-Version: 0.1`), +# and JSON `$comment` strings (`... Toolkit-Version: 0.1.`). +TOOLKIT_VERSION_RE = re.compile(r"Toolkit-Version:\**\s*(\d+\.\d+)") + EXCEPTIONS_PATH = REPO / "spec" / "exceptions.md" +VERSION_PATH = REPO / "VERSION" + +# Toolkit artifacts that must carry a Toolkit-Version stamp matching /VERSION. +# (contracts/* are added at runtime via glob.) Absent files are skipped so the +# lint stays usable on partial checkouts. +VERSIONED_ARTIFACTS = [ + "spec/PNA_Spec.md", "spec/axes.md", "spec/use_cases.md", "spec/exceptions.md", + "pna-build-eval-contrib/SKILL.md", "CONTRIBUTING.md", "README.md", + "tools/lint-spec-ids.py", + "reference_designs/templates/TEMPLATE.md", + "reference_designs/templates/ARCHITECTURE_TEMPLATE.md", +] def collect_spec_ac_ids() -> set[str]: @@ -77,8 +99,7 @@ def collect_contract_realizes() -> dict[Path, list[str]]: def collect_exception_ids() -> set[str]: - """EX-* registry IDs from spec/exceptions.md. Empty if the file is absent - (so the lint stays green on toolkit versions that predate Exceptions).""" + """EX-* registry IDs from spec/exceptions.md. Empty if the file is absent.""" if not EXCEPTIONS_PATH.exists(): return set() return set(EX_RE.findall(EXCEPTIONS_PATH.read_text())) @@ -110,13 +131,11 @@ def collect_strength_violations(text: str) -> list[str]: j = i + 2 # skip header + |---| separator while j < len(lines) and lines[j].lstrip().startswith("|"): row = [c.strip() for c in lines[j].strip().strip("|").split("|")] - if len(row) > col and row[col]: - val = row[col] - if val not in STRENGTH_CLASSES: - violations.append( - f"strength-profile names unknown class '{val}' " - f"(allowed: {', '.join(sorted(STRENGTH_CLASSES))})" - ) + if len(row) > col and row[col] and row[col] not in STRENGTH_CLASSES: + violations.append( + f"strength-profile names unknown class '{row[col]}' " + f"(allowed: {', '.join(sorted(STRENGTH_CLASSES))})" + ) j += 1 i = j continue @@ -124,6 +143,36 @@ def collect_strength_violations(text: str) -> list[str]: return violations +def expected_toolkit_minor() -> str | None: + """The MAJOR.MINOR series from /VERSION (e.g. '0.1' from '0.1.0-draft').""" + if not VERSION_PATH.exists(): + return None + m = re.match(r"\s*(\d+\.\d+)", VERSION_PATH.read_text()) + return m.group(1) if m else None + + +def check_toolkit_versions() -> tuple[str | None, list[str]]: + """Every versioned artifact must stamp a Toolkit-Version matching /VERSION.""" + failures: list[str] = [] + minor = expected_toolkit_minor() + if minor is None: + return None, ["/VERSION file missing or unparseable at repo root."] + paths = [REPO / p for p in VERSIONED_ARTIFACTS] + paths += [f for f in sorted((REPO / "contracts").glob("*")) + if f.is_file() and f.name != "README.md"] + for p in paths: + if not p.is_file(): + continue + head = "\n".join(p.read_text(errors="ignore").splitlines()[:30]) + m = TOOLKIT_VERSION_RE.search(head) + rel = p.relative_to(REPO) + if not m: + failures.append(f"{rel}: missing 'Toolkit-Version: {minor}' stamp in head.") + elif m.group(1) != minor: + failures.append(f"{rel}: Toolkit-Version {m.group(1)} != /VERSION {minor}.") + return minor, failures + + def main() -> int: failures: list[str] = [] @@ -165,6 +214,10 @@ def main() -> int: failures.append("exceptions.md: 'Reversible: yes' present but no 'Reversal:' field.") failures.extend(f"exceptions.md: {v}" for v in collect_strength_violations(ex_text)) + # --- Toolkit version stamps --- + toolkit_minor, version_failures = check_toolkit_versions() + failures.extend(version_failures) + if failures: print(f"lint-spec-ids: {len(failures)} violation(s) found.") for line in failures: @@ -173,6 +226,7 @@ def main() -> int: n_realizing = sum(1 for v in contract_realizes.values() if v) print("lint-spec-ids: OK") + print(f" toolkit version {toolkit_minor} (/VERSION: {VERSION_PATH.read_text().strip()})") print(f" spec defines {len(spec_ids)} AC IDs") print(f" {n_realizing}/{len(contract_realizes)} contract files declare a 'Realizes:' header") print(f" exceptions.md defines {len(exception_ids)} exception ID(s)") From 4dd0630def27f526444f4fec41a16fff6a058101 Mon Sep 17 00:00:00 2001 From: Rich Bodo Date: Sun, 31 May 2026 21:18:17 +1200 Subject: [PATCH 3/5] spec: reconcile to a single version name (Toolkit-Version) Drop the duplicate Spec-Version: metadata field now that the toolkit is versioned as a unit. PNA_Spec/axes/use_cases keep one version block (Toolkit-Version + prose); the version a design *declares* is Toolkit-Version everywhere (SKILL, CONTRIBUTING, users-guide, ARCHITECTURE_TEMPLATE, llms.txt). Generic 'spec version' evolution prose (CHANGELOG, future-spec-version notes) and the design-side fellows Architecture copy are intentionally left for a separate pass. Lint green: toolkit version 0.1. Co-Authored-By: Claude Opus 4.8 (1M context) --- CONTRIBUTING.md | 2 +- docs/users-guide.md | 6 +++--- llms.txt | 2 +- pna-build-eval-contrib/SKILL.md | 4 ++-- reference_designs/templates/ARCHITECTURE_TEMPLATE.md | 2 +- spec/PNA_Spec.md | 4 +--- spec/axes.md | 2 -- spec/use_cases.md | 2 -- 8 files changed, 9 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f551bf..aa461b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,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. diff --git a/docs/users-guide.md b/docs/users-guide.md index a5473e6..1e44a91 100644 --- a/docs/users-guide.md +++ b/docs/users-guide.md @@ -66,7 +66,7 @@ You're starting (or extending) a personal network application. 1. Skim the spec for vocabulary, then pick a use case. 2. Walk through axis picks with the agent (via the skill). 3. Study the reference design closest to your axis picks. -4. Stub an Architecture document declaring spec version + axis picks. +4. Stub an Architecture document declaring Toolkit-Version + axis picks. 5. Build code that satisfies the typed contracts for your picks. 6. Fill in the AC attestation table as you build. 7. Self-check via Goal 2 before declaring done. @@ -83,7 +83,7 @@ You're starting (or extending) a personal network application. **3. Study the closest reference design.** Each [`reference_designs//`](../reference_designs/) directory has a design record naming its flavor and a Software Heritage SWHID (Persistent IDentifier) pointing to archived source. Pick the design whose flavor has the most overlap with your picks. Read its code; treat it as the seed your PNA grows from. Adapting from an existing design is faster than starting from scratch — most of the cross-slot integration work is already done. -**4. Stub an Architecture document.** Copy [`reference_designs/templates/ARCHITECTURE_TEMPLATE.md`](../reference_designs/templates/ARCHITECTURE_TEMPLATE.md) to `docs/Architecture.md` (or equivalent) in your design's own repo. Fill in: PNA Spec version, axis picks and their versions, and per-axis implementation notes. Leave the AC attestation table empty for now — you'll fill it in as you build (step 6). +**4. Stub an Architecture document.** Copy [`reference_designs/templates/ARCHITECTURE_TEMPLATE.md`](../reference_designs/templates/ARCHITECTURE_TEMPLATE.md) to `docs/Architecture.md` (or equivalent) in your design's own repo. Fill in: Toolkit-Version, axis picks and their versions, and per-axis implementation notes. Leave the AC attestation table empty for now — you'll fill it in as you build (step 6). **5. Build against the typed contracts.** [`contracts/`](../contracts/) holds the load-bearing interfaces — JSON Schema for the worker init handshake and RPC (Remote Procedure Call) protocol, OpenAPI for distribution auth, SQL DDL for the two database schemas, TypeScript for the Communications transport, JSON Schema for each canonical MCP server's tool surface. Every contract opens with `Realizes: AC-X, AC-Y` naming the ACs it serves; your code conforms to these contracts. If you find you need to deviate from a contract, propose a spec change via Goal 3 (Contribute) rather than just diverging. @@ -168,7 +168,7 @@ If your design is *identical* to an existing reference with no novelty, reach ou The agent will: - 1. **Locate your Architecture document.** If it exists, validate it against the code. If it doesn't, walk you through creating one interactively (PNA Spec version, axis picks, per-axis notes, AC attestation rows). + 1. **Locate your Architecture document.** If it exists, validate it against the code. If it doesn't, walk you through creating one interactively (Toolkit-Version, axis picks, per-axis notes, AC attestation rows). 2. **Ask what's interesting architecturally** about your design (one of the three patterns above). 3. **Report what's broken or missing** as a structured list — files, sections, Verification fields, cited-but-absent code, failing tests, license problems. diff --git a/llms.txt b/llms.txt index a361967..429e57f 100644 --- a/llms.txt +++ b/llms.txt @@ -12,7 +12,7 @@ ## Spec -- [PNA Spec](spec/PNA_Spec.md) — universal spec; Spec-Version 0.1 (draft) +- [PNA Spec](spec/PNA_Spec.md) — universal spec; Toolkit-Version 0.1 (draft) - [Axes](spec/axes.md) — the Axes a PNA varies along, attested picks per Axis, and the flavor-derived ACs each pick triggers - [Use cases](spec/use_cases.md) — attested classes of PNA (Directory Archive, Personal Relationship Manager [draft], Multi-PNA ecosystem [target v0.2+]) - [CHANGELOG](CHANGELOG.md) — spec version history diff --git a/pna-build-eval-contrib/SKILL.md b/pna-build-eval-contrib/SKILL.md index 770c545..5f3012c 100644 --- a/pna-build-eval-contrib/SKILL.md +++ b/pna-build-eval-contrib/SKILL.md @@ -22,7 +22,7 @@ Use when the user is starting or extending a PNA. 1. **Read the spec end-to-end first.** `spec/PNA_Spec.md` covers vocabulary, goals, axes, universal architectural commitments, and the slot map with 57 sub-contracts. The universal ACs are non-negotiable. 2. **Determine axis picks with the user.** Each axis has documented options in `spec/axes.md`. The axes in v0.1: distribution, storage substrate, ingestion shape, workspace shell, comms transport set, MCP-exposure. The spec uses variable language because the set may evolve. -3. **Author an Architecture document for the design.** Use the template at `reference_designs/templates/ARCHITECTURE_TEMPLATE.md`. It declares the PNA Spec version, axis picks and their versions, and per-axis implementation choices. +3. **Author an Architecture document for the design.** Use the template at `reference_designs/templates/ARCHITECTURE_TEMPLATE.md`. It declares the Toolkit-Version, axis picks and their versions, and per-axis implementation choices. 4. **Pull the typed contracts.** For each axis pick, the relevant contracts live in `contracts/`. Each contract opens with a `Realizes: AC-X, AC-Y` header naming the ACs it realizes. Treat the contracts as load-bearing — do not deviate without proposing a spec change (contribute flow). 5. **Find a reference design that shares axis picks.** Each `reference_designs//` directory has a record with the design's flavor and a Software Heritage SWHID linking the archived source. Study the design that's closest to what the user wants. 6. **Build against the contracts.** @@ -69,7 +69,7 @@ Before authoring the PR, validate that the design is submission-ready. This step 1. **Locate the design's Architecture document.** Typically at `docs/Architecture.md` (or equivalent) in the design's own repo. - **If it exists**, validate it against the code. For each AC attested as `conformant`, check the cited code locations and confirm the realization matches. For each AC with a Verification mechanism declared, check that the cited test/rubric/note actually exists and (where automated) passes. - **If it doesn't exist**, walk the user through creating one interactively. Use `reference_designs/templates/ARCHITECTURE_TEMPLATE.md` as the template. Ask about each section in turn: - - Which PNA Spec version does the design conform to? + - Which Toolkit-Version does the design conform to? - For each axis in `spec/axes.md`, which pick does the design use, and at which axis version? - For each axis, how does the design realize the pick? (Read the code to help fill this in.) - For each applicable AC (universal in `spec/PNA_Spec.md`, plus any flavor-derived AC in `spec/axes.md` triggered by the picks): how does the design realize it? What test/rubric/note verifies it? diff --git a/reference_designs/templates/ARCHITECTURE_TEMPLATE.md b/reference_designs/templates/ARCHITECTURE_TEMPLATE.md index da74910..c71ad61 100644 --- a/reference_designs/templates/ARCHITECTURE_TEMPLATE.md +++ b/reference_designs/templates/ARCHITECTURE_TEMPLATE.md @@ -93,7 +93,7 @@ What spec changes (if any) this submission proposes, and what working code in th - ****: ... — demonstrated by `` in the canonical repo. - ****: ... — demonstrated by `` in the canonical repo. -If this is an additive submission (no spec changes proposed; the design simply attests against the current spec version), say so: "No spec changes proposed; this submission attests conformance to PNA Spec v." +If this is an additive submission (no spec changes proposed; the design simply attests against the current Toolkit-Version), say so: "No spec changes proposed; this submission attests conformance to Toolkit-Version ." ## Reproducibility notes diff --git a/spec/PNA_Spec.md b/spec/PNA_Spec.md index 6bd6b59..1e4a182 100644 --- a/spec/PNA_Spec.md +++ b/spec/PNA_Spec.md @@ -1,10 +1,8 @@ # PNA Spec > **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). - -> **Spec-Version:** 0.1 (draft) > -> This document is the universal specification for personal network applications (PNAs). Reference designs declare conformance to a specific spec version and to a specific application flavor (defined by a constellation of feature axis picks). A PNA conforms to this spec if it satisfies the universal architectural commitments and the axis-derived contracts for each of its declared axis picks, listed herein. Each reference design's specialization lives in its own repo (ex: fellows_local_db's specialization is at [`docs/Architecture.md`](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md)). +> This document is the universal specification for personal network applications (PNAs). Reference designs declare conformance to a specific Toolkit-Version and to a specific application flavor (defined by a constellation of feature axis picks). A PNA conforms to this spec if it satisfies the universal architectural commitments and the axis-derived contracts for each of its declared axis picks, listed herein. Each reference design's specialization lives in its own repo (ex: fellows_local_db's specialization is at [`docs/Architecture.md`](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md)). --- diff --git a/spec/axes.md b/spec/axes.md index a66eed8..fd904d8 100644 --- a/spec/axes.md +++ b/spec/axes.md @@ -2,8 +2,6 @@ > **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). -> **Spec-Version:** 0.1 (draft) - This document catalogs the Axes a PNA picks along, the attested picks on each Axis, and the flavor-derived ACs each pick triggers. The Axis concept is defined in [`PNA_Spec.md` § Vocabulary](PNA_Spec.md#vocabulary). The Axes overview in `PNA_Spec.md` lists picks at a glance; this file is the authoritative catalog with full descriptions and AC triggers. diff --git a/spec/use_cases.md b/spec/use_cases.md index 479d963..d2adc5b 100644 --- a/spec/use_cases.md +++ b/spec/use_cases.md @@ -2,8 +2,6 @@ > **Toolkit-Version:** 0.1 (draft) — the toolkit (spec, contracts, skill, lint, templates) is versioned as a unit; see [VERSION](../VERSION). -> **Spec-Version:** 0.1 (draft) - This document catalogs the use cases the spec attests. Each use case names a coherent class of PNA from the user's perspective; it suggests default axis picks but does not determine them. The Use case concept is defined in [`PNA_Spec.md` § Vocabulary](PNA_Spec.md#vocabulary). v0.1 attests two named use cases plus one longer-arc target: From 880532654e69acb3f3055bb3436492cfe0db749f Mon Sep 17 00:00:00 2001 From: Rich Bodo Date: Sun, 31 May 2026 21:32:27 +1200 Subject: [PATCH 4/5] =?UTF-8?q?docs:=20complete=20the=20spec-version=20?= =?UTF-8?q?=E2=86=92=20toolkit-version=20language=20sweep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Repo-wide once-over removing dangling 'spec version' language in favor of 'toolkit version' (the toolkit is what's versioned as a unit; the PNA Spec is a document within it). Covers CONTRIBUTING, README, llms.txt, users-guide, plans, reference-design records + the fellows Architecture copy, the spec files' future-version prose, three contract description strings, and retitles CHANGELOG to 'PNT Changelog'. Document references to 'the spec' and the JSON contract $id URIs are intentionally preserved. Also refreshes the users-guide status note (the contribute flow has now been exercised end-to-end). Lint green; all contracts parse. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 4 ++-- CONTRIBUTING.md | 2 +- README.md | 6 +++--- contracts/mcp-private-data-ops.schema.json | 2 +- contracts/worker-init-handshake.schema.json | 2 +- contracts/worker-rpc-protocol.schema.json | 4 ++-- docs/users-guide.md | 9 ++++----- llms.txt | 2 +- plans/reorganization-plan.md | 18 +++++++++--------- reference_designs/README.md | 2 +- .../fellows_local_db/Architecture.md | 2 +- reference_designs/fellows_local_db/README.md | 6 +++--- reference_designs/templates/TEMPLATE.md | 6 +++--- spec/PNA_Spec.md | 18 +++++++++--------- spec/axes.md | 4 ++-- spec/use_cases.md | 4 ++-- 16 files changed, 45 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da1e38a..cb1d84d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# PNA Spec Changelog +# PNT Changelog ## v0.1 draft (in progress) @@ -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). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa461b2..06814dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,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 `, 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/` 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 diff --git a/README.md b/README.md index 8fae963..936aec1 100644 --- a/README.md +++ b/README.md @@ -46,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 @@ -65,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 | | ------------------- | ----------------------------- | diff --git a/contracts/mcp-private-data-ops.schema.json b/contracts/mcp-private-data-ops.schema.json index 35bb8b7..03b42ed 100644 --- a/contracts/mcp-private-data-ops.schema.json +++ b/contracts/mcp-private-data-ops.schema.json @@ -3,7 +3,7 @@ "$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. 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 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).", + "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": { diff --git a/contracts/worker-init-handshake.schema.json b/contracts/worker-init-handshake.schema.json index 4958578..43825c1 100644 --- a/contracts/worker-init-handshake.schema.json +++ b/contracts/worker-init-handshake.schema.json @@ -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": {} } diff --git a/contracts/worker-rpc-protocol.schema.json b/contracts/worker-rpc-protocol.schema.json index 543efda..9b0bd76 100644 --- a/contracts/worker-rpc-protocol.schema.json +++ b/contracts/worker-rpc-protocol.schema.json @@ -118,7 +118,7 @@ }, "NormativeErrorCodes": { "type": "object", - "description": "v0.1 normative `errorCode` allowlist. The codes here are reserved across all conforming implementations — their semantics are tied to ACs, and workspaces are entitled to dispatch UI specifically on them. Implementations MAY add additional codes for op-specific failures, but additions MUST NOT collide with these names and MUST NOT change their AC meaning. Future spec versions may extend this set.", + "description": "v0.1 normative `errorCode` allowlist. The codes here are reserved across all conforming implementations — their semantics are tied to ACs, and workspaces are entitled to dispatch UI specifically on them. Implementations MAY add additional codes for op-specific failures, but additions MUST NOT collide with these names and MUST NOT change their AC meaning. Future toolkit versions may extend this set.", "required": ["OWNERSHIP_CONFLICT", "VERSION_MISMATCH", "LOCAL_DATA_UNAVAILABLE", "NOT_FOUND", "INTERNAL"], "additionalProperties": false, "properties": { @@ -304,7 +304,7 @@ }, "op_getOpfsInventory": { "type": "object", - "description": "ST-11 diagnostic read. Snapshot of every entry at OPFS root (browser PNAs) or the substrate-equivalent storage root, plus the SAH-pool slot inventory. Used by the `?diag=1` panel post-Phase-1 so the maintainer can see exactly what's on disk without main-thread substrate access. Pure read; no writes, no fetches. The name reflects browser-PNA heritage; native-PNA implementations may rename this op to `getStorageInventory` in a future spec version.", + "description": "ST-11 diagnostic read. Snapshot of every entry at OPFS root (browser PNAs) or the substrate-equivalent storage root, plus the SAH-pool slot inventory. Used by the `?diag=1` panel post-Phase-1 so the maintainer can see exactly what's on disk without main-thread substrate access. Pure read; no writes, no fetches. The name reflects browser-PNA heritage; native-PNA implementations may rename this op to `getStorageInventory` in a future toolkit version.", "required": ["input", "output"], "properties": { "input": { diff --git a/docs/users-guide.md b/docs/users-guide.md index 1e44a91..12d45f6 100644 --- a/docs/users-guide.md +++ b/docs/users-guide.md @@ -6,15 +6,14 @@ PNT (Personal Network Toolkit) is built to be consumed by AI coding agents. Most **The fastest way in is auditing.** If you just want to know whether a contact app is safe before you install it — without building or contributing anything — go straight to [Goal 2](#goal-2--audit-a-candidate-pna-before-installing-it). It's the lowest-friction front door to PNT: point an agent at the app's source and get back an AC-keyed safety report. -> **Status note (May 2026).** PNT's deterministic tooling is now tested; the agent-driven flows are not yet exercised end-to-end. +> **Status note (May 2026).** PNT's deterministic tooling is tested; the agent-driven flows are now being exercised for real. > > **Tested / CI-enforced:** > - [`tools/egress-lint.py`](../tools/egress-lint.py) — the deterministic AC-1 egress check, with clean/dirty self-test fixtures run in CI. -> - [`tools/lint-spec-ids.py`](../tools/lint-spec-ids.py) — AC ↔ contract traceability lint, run in CI. +> - [`tools/lint-spec-ids.py`](../tools/lint-spec-ids.py) — AC ↔ contract / exception / toolkit-version traceability lint, run in CI. > - [`tools/evaluate-report.schema.json`](../tools/evaluate-report.schema.json) — the audit-report schema, validated against its meta-schema and conditional rules. > -> **Not yet exercised end-to-end:** -> - The **build**, **audit**, and **contribute** skill flows. The materials are in place; Phase 5 of the reorganization plan validates them against `fellows_local_db` as the first reference design. The agent prompts and output shapes below describe the *intended* behavior per [`pna-build-eval-contrib/SKILL.md`](../pna-build-eval-contrib/SKILL.md); expect refinement as the skill gets dogfooded. +> **Exercised end-to-end:** the **contribute** flow — `fellows_local_db`'s Exceptions contribution and this Toolkit-Version work were both authored through it, with the build and evaluate flows informing that work. The **build** and **audit** flows are still being dogfooded; Phase 5 continues to validate them against `fellows_local_db`. The agent prompts and output shapes below describe the intended behavior per [`pna-build-eval-contrib/SKILL.md`](../pna-build-eval-contrib/SKILL.md); expect continued refinement. --- @@ -202,7 +201,7 @@ For high-signal designs, the maintainer may additionally mirror the design to a If you find a spec gap, ambiguity, or contradiction while building or operating your PNA, your PR includes a spec diff. The maintainer reviews the diff in the context of your demonstrating reference design. -After merge, the PNA Spec version is bumped per linear SemVer: +After merge, the Toolkit-Version is bumped per linear SemVer: - **Patch** — clarifications, typo fixes - **Minor** — additive changes (new ACs, new axes, new picks, new sub-contracts) diff --git a/llms.txt b/llms.txt index 429e57f..407844a 100644 --- a/llms.txt +++ b/llms.txt @@ -15,7 +15,7 @@ - [PNA Spec](spec/PNA_Spec.md) — universal spec; Toolkit-Version 0.1 (draft) - [Axes](spec/axes.md) — the Axes a PNA varies along, attested picks per Axis, and the flavor-derived ACs each pick triggers - [Use cases](spec/use_cases.md) — attested classes of PNA (Directory Archive, Personal Relationship Manager [draft], Multi-PNA ecosystem [target v0.2+]) -- [CHANGELOG](CHANGELOG.md) — spec version history +- [CHANGELOG](CHANGELOG.md) — toolkit version history ## Typed contracts diff --git a/plans/reorganization-plan.md b/plans/reorganization-plan.md index 46ba99b..bdd50aa 100644 --- a/plans/reorganization-plan.md +++ b/plans/reorganization-plan.md @@ -54,7 +54,7 @@ The *specifics* of which test verifies which AC live per-design, in each Archite 3. Spec changes must be accompanied by a reference design that demonstrates the change in working code. -4. Each accepted design ships an Architecture document declaring conformance to a specific PNA Spec version, declaring per-axis picks and their versions, attesting per-AC conformance, and **mapping each applicable AC to the specific test(s) or review mechanism(s) that verify it in the design**. Test coverage of the AC list is an acceptance criterion. +4. Each accepted design ships an Architecture document declaring conformance to a specific Toolkit-Version, declaring per-axis picks and their versions, attesting per-AC conformance, and **mapping each applicable AC to the specific test(s) or review mechanism(s) that verify it in the design**. Test coverage of the AC list is an acceptance criterion. 5. Archival is robust to upstream repo deletion. PNT does not undertake routine maintenance of contributed code. @@ -88,13 +88,13 @@ These are settled here so subsequent work doesn't relitigate. **No first-party in-repo designs.** All reference designs — including those Rich maintains personally, such as `fellows_local_db` — are external. PNT references snapshots, never bundles code. -**Software Heritage SWHID is the canonical permanent identifier (v0.1).** When a design is accepted, Save Code Now is triggered on the contributor's repo at the submitted commit; the resulting SWHID is recorded in the design entry. Software Heritage archives source permanently with content-addressed identifiers. The PNA Spec itself states this v0.1 commitment; future spec versions may revise. +**Software Heritage SWHID is the canonical permanent identifier (v0.1).** When a design is accepted, Save Code Now is triggered on the contributor's repo at the submitted commit; the resulting SWHID is recorded in the design entry. Software Heritage archives source permanently with content-addressed identifiers. The PNA Spec itself states this v0.1 commitment; future toolkit versions may revise. **Optional secondary fork for high-signal designs.** A `pnt-archive` GitHub-organization fork is at maintainer discretion for designs PNT wants belt-and-braces archival on. SWHID alone is sufficient for the archival promise. **Linear SemVer for the PNA Spec; per-axis versioning declared in each design's Architecture document.** Patch for clarifications, minor for additive, major for breaking. Individual axes can evolve at different rates; a design declares which axis version it implements for each axis it picks. -**Every accepted contribution ships an Architecture document with a complete AC attestation table.** It declares conformance to a specific PNA Spec version, declares per-axis picks and versions, documents implementation choices per axis, and includes an AC attestation table that maps every applicable AC to (a) how the design realizes it and (b) the specific test(s) or review mechanism(s) that verify it. A row missing the verification field is a rejected PR. This is the load-bearing acceptance check. +**Every accepted contribution ships an Architecture document with a complete AC attestation table.** It declares conformance to a specific Toolkit-Version, declares per-axis picks and versions, documents implementation choices per axis, and includes an AC attestation table that maps every applicable AC to (a) how the design realizes it and (b) the specific test(s) or review mechanism(s) that verify it. A row missing the verification field is a rejected PR. This is the load-bearing acceptance check. **Architecture document = Security Target in role.** The Common Criteria Protection Profile / Security Target model maps cleanly: the PNA Spec acts as the Protection Profile (class-level requirements); each design's Architecture document acts as the Security Target (this design's declared conformance, with implementation details and test pointers). PNT keeps its own terminology — no rename — but the model is what we're building. @@ -182,7 +182,7 @@ The spec-formalization work is the largest single addition over the prior commun **Maintainer:** () **License:** -**First accepted:** PNA Spec v, +**First accepted:** Toolkit-Version , **Status:** active | archived | superseded ## Summary @@ -198,7 +198,7 @@ One paragraph describing what this design is and what it demonstrates. ## Contributions to the spec -### PNA Spec v (PR #) +### Toolkit-Version (PR #) - Reference design version: commit `` - Software Heritage: `swh:1:dir:` - Optional archive: `archive/` at commit `` @@ -224,7 +224,7 @@ See [Architecture.md](./Architecture.md), the design's Security Target, copied a The Architecture document plays the Security Target role: it is the design's declared conformance against the PNA Spec (the Protection Profile). To be accepted, it must contain: -1. **PNA Spec version declaration.** "This design conforms to PNA Spec v0.7." +1. **Toolkit-Version declaration.** "This design conforms to Toolkit-Version 0.7." 2. **Axis pick declaration with per-axis versions.** A table naming each axis the design exercises and the version it implements. 3. **Per-axis implementation notes.** A short section per axis explaining the implementation choices. 4. **AC attestation table — the load-bearing artifact.** For each AC that applies to the design's flavor, a row stating: @@ -255,7 +255,7 @@ A row missing the verification field is a rejected PR. This is the mechanical ch - Spec changes land (including any new AC IDs, sub-contracts, or axis-pick additions) - Maintainer runs `tools/swh-save.sh ` and records the returned SWHID in the design record - Maintainer decides whether the design warrants an `archive/` fork - - Spec version bumped per SemVer rules + - Toolkit version bumped per SemVer rules **Automated contribution path.** The skill (see below) walks an LLM through steps 3–4 end-to-end. A builder using Claude Code can ask the agent to "open a PR adding this design to PNT" and the skill guides the agent through authoring the Architecture document, generating the AC attestation table from the design's source, and producing the PR. Maintainer review at step 5 is the human-judgment gate that's intentionally not automated. @@ -275,7 +275,7 @@ A PNA is a local-first application built to the PNT spec. The spec defines the a 1. Read `spec/PNA_Spec.md` end-to-end. 2. Determine the user's axis picks. Each axis has options in `spec/axes/`. -3. Author an Architecture document for the design declaring PNA Spec version, axis picks, and per-axis implementation choices. +3. Author an Architecture document for the design declaring Toolkit-Version, axis picks, and per-axis implementation choices. 4. Pull the typed contracts from `contracts/` for each axis pick. 5. Find a reference design in `reference_designs/` that shares as many axis picks as possible. Visit its archived source (SWHID linked in the design record) and study its implementation. 6. Build against the contracts. Treat them as load-bearing. Do not deviate without proposing a spec change per the contribute flow below. @@ -360,7 +360,7 @@ Phases are sized for Claude Code sessions. Each ends in a committable, working s - [x] Write `reference_designs/templates/ARCHITECTURE_TEMPLATE.md`, including the AC attestation table format with the Verification field. - [x] Audit existing spec prose for numeric axis counts and replace with variable language. - [x] Add to `spec/PNA_Spec.md`: declaration that v0.1 uses Software Heritage SWHIDs as the permanent identifier for reference designs. -- [x] Add to `spec/PNA_Spec.md § Vision`: forward note about conformance evaluation as a potential precondition for multi-PNA ecosystem interop in a future spec version, framed as a systems-level test that will require rethinking the spec at that level. +- [x] Add to `spec/PNA_Spec.md § Vision`: forward note about conformance evaluation as a potential precondition for multi-PNA ecosystem interop in a future toolkit version, framed as a systems-level test that will require rethinking the spec at that level. ### Phase 3 — Spec formalization pass diff --git a/reference_designs/README.md b/reference_designs/README.md index 67699b5..77ddd7f 100644 --- a/reference_designs/README.md +++ b/reference_designs/README.md @@ -22,6 +22,6 @@ The skill at [`../pna-build-eval-contrib/SKILL.md`](../pna-build-eval-contrib/SK ## Accepted designs -- [`fellows_local_db/`](fellows_local_db/) — Directory Archive PNA; magic-link distributed PWA flavor. The design from which most of PNA Spec v0.1 was distilled. *(Status: placeholder — SWHID and full AC attestation pending Phase 5 of the reorganization plan.)* +- [`fellows_local_db/`](fellows_local_db/) — Directory Archive PNA; magic-link distributed PWA flavor. The design from which most of the v0.1 toolkit was distilled. *(Status: placeholder — SWHID and full AC attestation pending Phase 5 of the reorganization plan.)* When a second design lands, it'll be linked here. diff --git a/reference_designs/fellows_local_db/Architecture.md b/reference_designs/fellows_local_db/Architecture.md index b646184..a85c9f6 100644 --- a/reference_designs/fellows_local_db/Architecture.md +++ b/reference_designs/fellows_local_db/Architecture.md @@ -8,7 +8,7 @@ Universal PNA architecture — vocabulary, goals, the two-store ownership split, ## Spec conformance -**Spec-Version:** [0.1 (draft)](https://github.com/richbodo/personal_network_toolkit/blob/main/CHANGELOG.md) +**Toolkit-Version:** [0.1 (draft)](https://github.com/richbodo/personal_network_toolkit/blob/main/CHANGELOG.md) **Use case:** [Directory Archive](https://github.com/richbodo/personal_network_toolkit/blob/main/use_cases.md#directory-archive) ### Flavor — fellows's six axis picks diff --git a/reference_designs/fellows_local_db/README.md b/reference_designs/fellows_local_db/README.md index 8a0c09e..a6ffaeb 100644 --- a/reference_designs/fellows_local_db/README.md +++ b/reference_designs/fellows_local_db/README.md @@ -2,12 +2,12 @@ **Maintainer:** Rich Bodo (https://github.com/richbodo/fellows_local_db) **License:** see upstream repo -**First accepted:** PNA Spec v0.1, +**First accepted:** Toolkit-Version 0.1, **Status:** active (Software Heritage SWHID pending maintainer archival post-merge; AC + exception attestation now present in `Architecture.md`) ## Summary -`fellows_local_db` is the first PNA reference design — a Directory Archive PNA realizing the Knack-export → static-PWA + magic-link distribution flavor. It is the design from which most of the v0.1 spec was distilled. The canonical repo lives at https://github.com/richbodo/fellows_local_db; its Architecture document is at `docs/Architecture.md` upstream. +`fellows_local_db` is the first PNA reference design — a Directory Archive PNA realizing the Knack-export → static-PWA + magic-link distribution flavor. It is the design from which most of the v0.1 toolkit was distilled. The canonical repo lives at https://github.com/richbodo/fellows_local_db; its Architecture document is at `docs/Architecture.md` upstream. ## Axis picks at first acceptance @@ -15,7 +15,7 @@ ## Contributions to the spec -The bulk of PNA Spec v0.1 — every universal AC except those flagged `[draft]`, every sub-contract under `WS-`, `ST-`, `SH-`, `PR-`, `DB-`, `IN-`, `CO-`, `DI-`, and the realized axis picks in `axes.md` — derives from learnings on this design. The detailed contribution list and the SWHID are backfilled in Phase 5 of `plans/reorganization-plan.md`. +The bulk of the v0.1 toolkit — every universal AC except those flagged `[draft]`, every sub-contract under `WS-`, `ST-`, `SH-`, `PR-`, `DB-`, `IN-`, `CO-`, `DI-`, and the realized axis picks in `axes.md` — derives from learnings on this design. The detailed contribution list and the SWHID are backfilled in Phase 5 of `plans/reorganization-plan.md`. **The Exceptions concept (originating contribution).** `spec/exceptions.md` — the raise/catch/handle model, PNA-mode vs non-PNA-mode, the `EX-H1`–`EX-H8` handler contract, the `Relaxes:`/`Reversible:`/`Stresses:` header conventions, the per-dimension strength-profile vocabulary, and the first registry entry `EX-CLOUD-LLM` — together with the `tools/lint-spec-ids.py` traceability extension and the SKILL evaluate-flow exceptions step, were distilled from this design. They are demonstrated by its cloud-MCP consent handler: a pre-raise consent gate, the persistent "Going rogue — not a PNA" banner, the `#/exception/` explainer (surfacing the strength profile), the return-to-PNA-mode control, and a best-effort consent-propagation notice in the MCP servers' `instructions`. See the `EX-CLOUD-LLM` row in this design's Architecture document (§ Exception attestation) and `docs/architectural_findings.md` upstream. diff --git a/reference_designs/templates/TEMPLATE.md b/reference_designs/templates/TEMPLATE.md index 6786e97..1198b75 100644 --- a/reference_designs/templates/TEMPLATE.md +++ b/reference_designs/templates/TEMPLATE.md @@ -4,7 +4,7 @@ **Maintainer:** () **License:** -**First accepted:** PNA Spec v, +**First accepted:** Toolkit-Version , **Status:** active | archived | superseded ## Summary @@ -24,14 +24,14 @@ One paragraph describing what this design is and what it demonstrates. ## Contributions to the spec -### PNA Spec v (PR #) +### Toolkit-Version (PR #) - Reference design version: commit `` - Software Heritage: `swh:1:dir:` - Optional archive: `archive/` at commit `` (if PNT forked for high-signal archival) - Summary: <2–4 sentences> -### PNA Spec v (PR #) +### Toolkit-Version (PR #) (Add a section per accepted contribution from this design over time.) diff --git a/spec/PNA_Spec.md b/spec/PNA_Spec.md index 1e4a182..fd3aa01 100644 --- a/spec/PNA_Spec.md +++ b/spec/PNA_Spec.md @@ -33,7 +33,7 @@ When an AI is asked to build a PNA, it is required to follow the contracts of th One longer-arc target is an ecosystem of cooperating PNAs on a single user's device — a [Personal Relationship Manager](#vocab-use-case) (PRM - where private relationship data lives) running alongside one or more Directory Archives, a Contact Manager, and a Calendar app, each in its own bundle and sharing data as per their contracts. -The PRM acts as the [meta-workspace](#vocab-workspace): relationship data layered on top of a deduplicated read-only meta-view composed from the other apps' shared stores (Bob's cell from Google + work history from a fellowship directory + email from a Facebook export, resolved into one coherent contact view; the PRM's private overlay attached through stable IDs). The user can also work in clean per-app workspaces when they want a single context. Composing the meta-view requires per-source connectors, dedup with conflict resolution, and disciplined provenance — work for later spec versions. The eventual *ecosystem [reference design](#vocab-reference-design)* is the goal; v0.1 ships one PNA (fellows_local_db) and the spec it conforms to, along with [MCP servers](#vocab-mcp-server) (MCP = Anthropic's Model Context Protocol), with the architectural seams sized to let the ecosystem grow into place. +The PRM acts as the [meta-workspace](#vocab-workspace): relationship data layered on top of a deduplicated read-only meta-view composed from the other apps' shared stores (Bob's cell from Google + work history from a fellowship directory + email from a Facebook export, resolved into one coherent contact view; the PRM's private overlay attached through stable IDs). The user can also work in clean per-app workspaces when they want a single context. Composing the meta-view requires per-source connectors, dedup with conflict resolution, and disciplined provenance — work for later toolkit versions. The eventual *ecosystem [reference design](#vocab-reference-design)* is the goal; v0.1 ships one PNA (fellows_local_db) and the spec it conforms to, along with [MCP servers](#vocab-mcp-server) (MCP = Anthropic's Model Context Protocol), with the architectural seams sized to let the ecosystem grow into place. PNAs that participate in such an ecosystem need to be reachable not just to humans but to AI agents acting on the user's behalf. The spec therefore defines MCP server interfaces at five canonical connection points, split along the Shared / Private privacy boundary so an AI client can be wired to one without the other: @@ -43,9 +43,9 @@ PNAs that participate in such an ecosystem need to be reachable not just to huma - A **Communications server** — stages outreach for workspace-mediated user confirmation per AC-19 (the workspace launches the transport, not the MCP server — AC-MCP-B). - A **Diagnostics server** — read-only access to the Debug contract. -An AI client (Claude Desktop, Cursor, a local-Ollama-backed agent, or any MCP-capable runtime) can drive a PNA through these servers without modifying its core; canonical implementations will ship with the personal_network_toolkit. Cloud AI clients (anything that sends Private DB rows off-device) require explicit per-call consent — see AC-MCP-A in [§ Universal architectural commitments](#universal-architectural-commitments). v1 surfaces are read-only on both data-ops servers; tool-side write contracts (Private DB CRUD — Create, Read, Update, Delete; message-send confirmation on Comms) land in a later spec version. +An AI client (Claude Desktop, Cursor, a local-Ollama-backed agent, or any MCP-capable runtime) can drive a PNA through these servers without modifying its core; canonical implementations will ship with the personal_network_toolkit. Cloud AI clients (anything that sends Private DB rows off-device) require explicit per-call consent — see AC-MCP-A in [§ Universal architectural commitments](#universal-architectural-commitments). v1 surfaces are read-only on both data-ops servers; tool-side write contracts (Private DB CRUD — Create, Read, Update, Delete; message-send confirmation on Comms) land in a later toolkit version. -*Future direction — conformance evaluation as a precondition for ecosystem interop.* As the ecosystem grows, conformance evaluation may become a precondition for runtime interop between PNAs. Today an AI client wires two PNAs together by trusting each implements the canonical contracts; tomorrow, in a larger ecosystem with PNAs the user hasn't personally audited, a *systems-level conformance test* — does this candidate PNA honor the architectural commitments before I let it touch my Private DB? — becomes a natural precondition. This requires rethinking the spec at the systems level: the test isn't whether one PNA conforms in isolation but whether the cooperation across PNAs preserves the spec's guarantees. v0.1 doesn't define this; the present-day evaluation surface (PNA-by-PNA conformance check, performed by an LLM (Large Language Model) consuming this spec) is the closest analog. A later spec version may formalize the runtime-interop variant. +*Future direction — conformance evaluation as a precondition for ecosystem interop.* As the ecosystem grows, conformance evaluation may become a precondition for runtime interop between PNAs. Today an AI client wires two PNAs together by trusting each implements the canonical contracts; tomorrow, in a larger ecosystem with PNAs the user hasn't personally audited, a *systems-level conformance test* — does this candidate PNA honor the architectural commitments before I let it touch my Private DB? — becomes a natural precondition. This requires rethinking the spec at the systems level: the test isn't whether one PNA conforms in isolation but whether the cooperation across PNAs preserves the spec's guarantees. v0.1 doesn't define this; the present-day evaluation surface (PNA-by-PNA conformance check, performed by an LLM (Large Language Model) consuming this spec) is the closest analog. A later toolkit version may formalize the runtime-interop variant. --- @@ -87,7 +87,7 @@ Worked examples below cite `fellows_local_db` as the first reference design — - **Reference design / thematic example.** A working, deployed PNA that demonstrates one valid combination of slot-fills against the spec. fellows_local_db is the first reference design — its load-bearing adjectives are *magic-link distributed PWA (Progressive Web App)* (Distribution choice) + *static network DB archive* (Ingestion choice — the directory is mirrored once with opt-in updates, not linked to a live contact manager) + *single shared directory* (Source choice). New reference designs accumulate adjectives as their slot-fills land. AIs adapting a thematic example start from one of these and ask the user which slot-fills to keep, swap, or extend. - *Archival (v0.1).* When a reference design is accepted into PNT (Personal Network Toolkit)'s set, its source at the submitted commit MUST be archived with a Software Heritage Persistent IDentifier (SWHID — a `swh:1:dir:...` content-addressed identifier produced by Software Heritage's Save Code Now service). The SWHID is recorded in the design's PNT entry so the source survives even if the upstream repo is deleted or relocated. Future spec versions MAY revise the archival mechanism; v0.1 commits to SWHID. + *Archival (v0.1).* When a reference design is accepted into PNT (Personal Network Toolkit)'s set, its source at the submitted commit MUST be archived with a Software Heritage Persistent IDentifier (SWHID — a `swh:1:dir:...` content-addressed identifier produced by Software Heritage's Save Code Now service). The SWHID is recorded in the design's PNT entry so the source survives even if the upstream repo is deleted or relocated. Future toolkit versions MAY revise the archival mechanism; v0.1 commits to SWHID. - **Use case.** A user-facing class of PNA — "Directory Archive," "Personal Relationship Manager." A use case names what kind of app this is *from the user's perspective*. v0.1 attests two; future versions will add more. Use case is *not* one of the Axes (defined next); it's the parent category that a flavor instantiates. A use case typically suggests default axis picks (Directory Archives gravitate toward web-bundle distribution; PRMs toward never-distributed-single-user) but the axes remain independent — a hypothetical Directory Archive shipped as a Tauri shell + native SQLite is conceivable. Full catalog in [`use_cases.md`](use_cases.md). @@ -109,7 +109,7 @@ Worked examples below cite `fellows_local_db` as the first reference design — - **Communications** — stages outreach for workspace-mediated user confirmation (AC-MCP-B; the MCP server proposes, the workspace disposes). - **Diagnostics** — read-only access to the Debug contract. - Splitting Data ops along the Shared / Private boundary mirrors the storage split (AC-1) at the MCP surface: the privacy posture of each tool call is determined by which server it lands on, not by an in-server gate. An AI client (Claude Desktop, Cursor, a local-Ollama-backed agent, etc.) consumes these servers to drive the PNA. v1 reference implementations expose read-only surfaces only; future spec versions may add write-side tools (Private DB CRUD, Comms message-send confirmation) as separate contracts. MCP servers are how multiple PNAs cooperate at runtime: a PNA exposing MCP becomes externally reachable so an AI client can wire multiple PNAs together on the user's device even though each is its own bundle. + Splitting Data ops along the Shared / Private boundary mirrors the storage split (AC-1) at the MCP surface: the privacy posture of each tool call is determined by which server it lands on, not by an in-server gate. An AI client (Claude Desktop, Cursor, a local-Ollama-backed agent, etc.) consumes these servers to drive the PNA. v1 reference implementations expose read-only surfaces only; future toolkit versions may add write-side tools (Private DB CRUD, Comms message-send confirmation) as separate contracts. MCP servers are how multiple PNAs cooperate at runtime: a PNA exposing MCP becomes externally reachable so an AI client can wire multiple PNAs together on the user's device even though each is its own bundle. - **Universal AC vs flavor-derived AC.** Universal ACs derive from goals alone and apply to every PNA. Flavor-derived ACs are triggered by specific axis picks (e.g., `[storage:opfs-sqlite-wasm]`) and apply only when the flavor matches. [§ Universal architectural commitments](#universal-architectural-commitments) lists the universal set; flavor-derived ACs live in [`axes.md`](axes.md), grouped under the axis-pick that triggers them. @@ -400,15 +400,15 @@ These cross-slot threads are what make the spec describe a *system* rather than ## Scope and versioning -This spec is intentionally narrow. It addresses the user demand and runtime realities we can implement and deploy now. New demand develops further versions of the spec; reference designs continue to satisfy whatever spec version they were built against. +This spec is intentionally narrow. It addresses the user demand and runtime realities we can implement and deploy now. New demand develops further versions of the toolkit; reference designs continue to satisfy whatever Toolkit-Version they were built against. -**This is PNA Spec v0.1.** When new demand surfaces or runtime constraints shift, we bump the version, declare what changed in [`CHANGELOG.md`](CHANGELOG.md), and update the architectural commitments accordingly. +**This is the PNA Spec, at Toolkit-Version 0.1.** When new demand surfaces or runtime constraints shift, we bump the toolkit version, declare what changed in [`CHANGELOG.md`](CHANGELOG.md), and update the architectural commitments accordingly. -Items deliberately deferred to future spec versions: +Items deliberately deferred to future toolkit versions: - **Privacy reclassification migration mechanics.** The Preamble commits PNAs to honoring user-driven privacy reclassification of a record (shared → private). The *implementation pattern* — does the record stay in the Shared DB with a private-side override row that supersedes? Get copied into the Private DB and removed from the Shared DB on next re-mirror? — is not pinned in v0.1. The contract is declared; the migration is left for a future version when the first reference design needs it. - **Multi-source dedup implementation.** AC-PRM-B (catalogued in [`axes.md`](axes.md) as a draft flavor-derived AC) captures the v0.1 commitment for `ingestion:multi-source-merge-with-dedup` flavors — stable `record_id` survives merge, dedup wizard surfaces conflicts, per-field provenance. The concrete implementation (merge UI, conflict-resolution algorithms) awaits the first multi-source reference design. -- **Per-database (or finer) transport requirements.** A future spec version may let each database — Shared, Private, or any custom database in a richer PNA — declare which transport properties it requires for outbound flow. v0.1 handles the data-transport matching implicitly: AC-18 filters out transports that read content; AC-19 ensures the user sees the full payload before launch; the user resolves the matching in the moment. Explicit per-DB rules (workspaces auto-suggesting or auto-filtering transports based on source DB sensitivity) land when a reference design has an auto-send feature that needs them. +- **Per-database (or finer) transport requirements.** A future toolkit version may let each database — Shared, Private, or any custom database in a richer PNA — declare which transport properties it requires for outbound flow. v0.1 handles the data-transport matching implicitly: AC-18 filters out transports that read content; AC-19 ensures the user sees the full payload before launch; the user resolves the matching in the moment. Explicit per-DB rules (workspaces auto-suggesting or auto-filtering transports based on source DB sensitivity) land when a reference design has an auto-send feature that needs them. - **Cross-device sync.** Out of scope for v0.1. Future versions may declare a sync protocol; v0.1 explicitly does not. - **Federated P2P capabilities.** Signed-repo asset pulls (a community member's photos), community-stats aggregation tools (the CRT vision). Out of scope for v0.1. - **Formally verifiable code.** A longer-arc goal. v0.1 aims for AI-checkable contracts (markdown prose + JSON Schema / OpenAPI / SQL DDL / TypeScript declarations); formal verification (TLA+ / Alloy / etc.) is reserved for a later version. diff --git a/spec/axes.md b/spec/axes.md index fd904d8..c0ef6de 100644 --- a/spec/axes.md +++ b/spec/axes.md @@ -43,7 +43,7 @@ What backs the data layer — the bytes on disk or in OPFS that hold the Shared - **`opfs-sqlite-wasm`** — sqlite-wasm running in a dedicated worker, with OPFS-SAH-Pool VFS as the underlying storage. Browser-only. Attested in [fellows_local_db](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md). Triggers AC-3, AC-12; combines with `dist:web-served` to trigger AC-13. - **`native-sqlite-via-filesystem`** — Native SQLite library (libsqlite3) opens database files directly via OS filesystem APIs. WAL mode + advisory file locks recommended. CLI / native PNAs only. PRT-inspired (not yet against this spec). Triggers AC-PRM-C **[draft]**. -- **`idb-only-browser`** — IndexedDB without SQLite. Less expressive (no SQL); mostly hypothetical for PNA. No flavor-derived ACs in v0.1 (the relevant ACs assume sqlite); a future spec version may add IDB-specific ACs if a reference design picks this. +- **`idb-only-browser`** — IndexedDB without SQLite. Less expressive (no SQL); mostly hypothetical for PNA. No flavor-derived ACs in v0.1 (the relevant ACs assume sqlite); a future toolkit version may add IDB-specific ACs if a reference design picks this. - **`native-sqlcipher`** — Encrypted-at-rest variant of `native-sqlite-via-filesystem`. Inherits AC-PRM-C **[draft]** plus additional commitments about key storage and rotation that v0.1 doesn't yet name. Deferred ACs land when a SQLCipher-flavored reference design is built. ### Triggered flavor-derived ACs @@ -64,7 +64,7 @@ How the Shared DB is filled and refreshed — whether from a single export, a si ### Picks - **`single-source-static-mirror`** — One external source produces a complete Shared DB on each refresh; ingestion stages → validates → atomically swaps. No dedup needed. Re-imports are opt-in per AC-10. Attested in [fellows_local_db](https://github.com/richbodo/fellows_local_db/blob/main/docs/Architecture.md) (Knack-JSON ETL). Triggers no axis-specific ACs. -- **`single-source-live-pull`** — One external source queried live (REST API, OAuth, etc.). Same single-source dedup story (none needed). Triggers no axis-specific ACs in v0.1; a future spec version may add live-pull contracts (rate limiting, partial-failure handling, etc.). +- **`single-source-live-pull`** — One external source queried live (REST API, OAuth, etc.). Same single-source dedup story (none needed). Triggers no axis-specific ACs in v0.1; a future toolkit version may add live-pull contracts (rate limiting, partial-failure handling, etc.). - **`multi-source-merge-with-dedup`** — Multiple external sources (Google + Apple + Facebook + organizational directories) merged into one Shared DB. Dedup wizard surfaces conflicts; per-field provenance preserved. PRT-inspired (not yet against this spec). Triggers AC-PRM-B **[draft]**. - **`federated-read`** *(deferred)* — Reading from peer PNAs. Out of scope for v0.1. diff --git a/spec/use_cases.md b/spec/use_cases.md index d2adc5b..78a4455 100644 --- a/spec/use_cases.md +++ b/spec/use_cases.md @@ -36,7 +36,7 @@ The user's *own* contact databases (Google + Apple + Facebook + LinkedIn + organ `distribution:never-distributed-single-user + storage:native-sqlite-via-filesystem + ingestion:multi-source-merge-with-dedup + workspace-shell:tui-textual + comms:shell-out-to-cli-clients + mcp-exposure:full` -This is a draft — a future PRM reference design built against PNA Spec v0.1 will live in its own repo and may pick differently. The TUI shell choice in particular is PRT's current direction; a Tauri-wrapped GUI or a CLI-subcommand-only flavor are equally plausible alternatives. +This is a draft — a future PRM reference design built against Toolkit-Version 0.1 will live in its own repo and may pick differently. The TUI shell choice in particular is PRT's current direction; a Tauri-wrapped GUI or a CLI-subcommand-only flavor are equally plausible alternatives. **Triggered flavor-derived ACs (via likely picks):** AC-PRM-B **[draft]** (ingestion-derived), AC-PRM-C **[draft]** (storage-derived). MCP-related universal ACs (AC-MCP-A, AC-MCP-B) apply when `mcp-exposure` is non-`none`. @@ -64,7 +64,7 @@ The longer-arc goal introduced in [`PNA_Spec.md` § Vision](PNA_Spec.md#vision): **v0.2+ work:** -Achieving the unified meta-view requires per-source database connectors, careful dedup and conflict resolution, and disciplined provenance — substantial work that's deferred to later spec versions. The eventual *ecosystem reference design* would demonstrate this; v0.1 establishes the architectural seams (the five canonical MCP server contracts, AC-10's opt-in non-destructive re-imports, AC-PRM-B's draft multi-source dedup contract, AC-MCP-A's cloud-client consent rule, AC-MCP-B's workspace-mediated outreach) that let the ecosystem grow into place. +Achieving the unified meta-view requires per-source database connectors, careful dedup and conflict resolution, and disciplined provenance — substantial work that's deferred to later toolkit versions. The eventual *ecosystem reference design* would demonstrate this; v0.1 establishes the architectural seams (the five canonical MCP server contracts, AC-10's opt-in non-destructive re-imports, AC-PRM-B's draft multi-source dedup contract, AC-MCP-A's cloud-client consent rule, AC-MCP-B's workspace-mediated outreach) that let the ecosystem grow into place. This is the deep "why" behind defining slot contracts substrate-neutrally: when the second PNA exists, an AI agent can wire it to the first without modifying either; when the fifth PNA exists, the same. Composability isn't bolted on; it's the architecture's primary deliverable. From ec01074cd323478541fa7a2bfdae0f5264911bdc Mon Sep 17 00:00:00 2001 From: Rich Bodo Date: Sun, 31 May 2026 21:51:19 +1200 Subject: [PATCH 5/5] spec: extend Toolkit-Version stamping to the tools added by #6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit egress-lint.py and evaluate-report.schema.json (landed on main via #6) are toolkit artifacts too — stamp them and add them to the lint's versioned set, so 'the entire toolkit is versioned as a unit' actually holds after the merge with main. Co-Authored-By: Claude Opus 4.8 (1M context) --- tools/egress-lint.py | 1 + tools/evaluate-report.schema.json | 1 + tools/lint-spec-ids.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/egress-lint.py b/tools/egress-lint.py index d2d363b..b255840 100755 --- a/tools/egress-lint.py +++ b/tools/egress-lint.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# Toolkit-Version: 0.1 """Egress lint — deterministic private-data-sovereignty check (Goal 1 / AC-1). Scans a PNA's source tree for *egress vectors*: code or markup that can send a diff --git a/tools/evaluate-report.schema.json b/tools/evaluate-report.schema.json index a3f25ad..80caf2b 100644 --- a/tools/evaluate-report.schema.json +++ b/tools/evaluate-report.schema.json @@ -1,6 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://pna-spec.example/v0.1/evaluate-report.schema.json", + "$comment": "Toolkit-Version: 0.1.", "title": "PNT evaluate-report artifact", "description": "Machine-comparable form of the report produced by the skill's evaluate flow (pna-build-eval-contrib/SKILL.md § Evaluate flow). Keyed by AC ID so two runs on the same candidate can be diffed to show exactly which ACs changed status. The human-readable report is a rendering (a view) over an instance of this schema; this artifact is the source of truth. This is NOT a PNA interface contract — it realizes no AC and intentionally lives in tools/, not contracts/ (the lint-spec-ids check requires every file in contracts/ to name an AC it realizes; this one realizes none). It is the typed output of PNT's own evaluative tooling. Deterministic checks in tools/ (for example the egress lint) emit evidence entries with source=deterministic that an LLM evaluator folds into the relevant AC finding alongside its own source=llm evidence; source=human covers maintainer or reviewer judgement. Goals 1-5 (see spec/PNA_Spec.md § Goals) are the load-bearing user-facing concerns and drive the summary.", "type": "object", diff --git a/tools/lint-spec-ids.py b/tools/lint-spec-ids.py index 03c05d0..da17e6e 100755 --- a/tools/lint-spec-ids.py +++ b/tools/lint-spec-ids.py @@ -68,7 +68,7 @@ VERSIONED_ARTIFACTS = [ "spec/PNA_Spec.md", "spec/axes.md", "spec/use_cases.md", "spec/exceptions.md", "pna-build-eval-contrib/SKILL.md", "CONTRIBUTING.md", "README.md", - "tools/lint-spec-ids.py", + "tools/lint-spec-ids.py", "tools/egress-lint.py", "tools/evaluate-report.schema.json", "reference_designs/templates/TEMPLATE.md", "reference_designs/templates/ARCHITECTURE_TEMPLATE.md", ]