diff --git a/CHANGELOG.md b/CHANGELOG.md index afb4a36..10629a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,30 @@ This project uses [Semantic Versioning](https://semver.org/). --- +## [0.3.0] — 2026-07-18 + +### Added + +- **RFC-0001** — Added Property 4 provenance requirements for continuity-bearing memory entries, including standard admission path definition and audit-log dependency. +- **RFC-0001 §5.6** — Added `memory_entry_admitted` and `principal_authorized_write` audit event vocabulary for falsifiable source attestations. +- **RFC-0001 §5.6** — Required evidence fields at the provenance-chain anchors: `principal_authorized_write` and `ward_updated` events MUST carry `principal_authorization` (and `ward_updated` additionally `ward_version`/`ward_hash`); attestations resolving to events lacking them are unverified, and unresolvable attestation referents MUST be rejected. +- **RFC-0001 §1.1** — Defined "Committed Ward state" and "Continuity-bearing" (with fail-closed classification default); scoped the Ward-manifest equivalent-form allowance to authority-layer runtime storage. +- **RFC-0001 §3.4** — Attestation establishes provenance, not authorization: loop-originated entries additionally require explicit human authorization, recorded on the admission event (§5.6); ambiguous origin is treated as loop-originated. +- **RFC-0001 §4.1** — Genesis bootstrap note: closure is satisfiable from the first principal-authorized Ward write. +- **RFC-0001 §5.4 / §9** — Gate 4 re-verifies Ward-manifest closure before promotion; documented runtime closure verification as an open testing gap. +- **tests/conformance/negative/10-protected-missing-ward/** — Added negative fixture for a Ward manifest omitted from `[protected].files`. + +### Changed + +- **RFC-0001** — Bumped draft version to v0.3.0 for new backward-compatible normative requirements. +- **RFC-0001 §4.1 / §5.4** — Strengthened Ward-manifest closure prose and Gate 1 fail-closed behavior. +- **RFC-0001 §3.4 / §5.6** — Replaced the undefined "claiming Property 4 provenance" condition with "an implementation that provides a standard admission path (§1.1)". +- **RFC-0001 §6.3** — Redefined semver categories: Major now covers *incompatible* changes to the five properties or existing conformance requirements; Minor covers backward-compatible normative additions (previously any change to MUST-level requirements read as Major). +- **README.md, rfcs/README.md, SPEC.md, docs/faq.md, validators/validate.js** — Updated current-version references to v0.3.0. +- **docs/ward-deep-dive.md** — Updated version references to v0.3.0 and reframed the open-questions horizon. + +--- + ## [0.2.0] — 2026-06-19 ### Added diff --git a/README.md b/README.md index b852879..cff670e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > **The Familiar Contract is an open specification for what an agent is allowed to be — not just what it can do, but what it cannot change about itself.** -[![specification: v0.2.0](https://img.shields.io/badge/specification-v0.2.0-8b5cf6)](rfcs/RFC-0001-familiar-contract.md) +[![specification: v0.3.0](https://img.shields.io/badge/specification-v0.3.0-8b5cf6)](rfcs/RFC-0001-familiar-contract.md) [![RFC-0001: Draft](https://img.shields.io/badge/RFC--0001-Draft-blue)](rfcs/RFC-0001-familiar-contract.md) [![license: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/OpenCoven/familiar-contract) diff --git a/SPEC.md b/SPEC.md index 243b66f..755ed60 100644 --- a/SPEC.md +++ b/SPEC.md @@ -2,7 +2,7 @@ > **Status:** Superseded · **License:** MIT · **Version:** 0.1.0 > -> ⚠️ **This document is preserved for reproducibility.** The current normative specification is [RFC-0001 v0.2.0](rfcs/RFC-0001-familiar-contract.md), which uses RFC 2119 keywords (MUST/SHOULD/MAY), references the conformance suite at [`tests/conformance/`](tests/conformance/), and hardens the authority-layer separation requirement. +> ⚠️ **This document is preserved for reproducibility.** The current normative specification is [RFC-0001 v0.3.0](rfcs/RFC-0001-familiar-contract.md), which uses RFC 2119 keywords (MUST/SHOULD/MAY), references the conformance suite at [`tests/conformance/`](tests/conformance/), and hardens the authority-layer separation requirement. > > If you are looking for the current spec, go to [`rfcs/RFC-0001-familiar-contract.md`](rfcs/RFC-0001-familiar-contract.md). This file remains for historical and citation purposes. diff --git a/docs/faq.md b/docs/faq.md index 1ff80d6..ceff48f 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -12,7 +12,7 @@ The core problem it addresses is this: AI agents have gotten very capable, but t The specification has two major parts. First, a five-property identity contract: a compliant "familiar" must have a stable named identity, a declared purpose, enforced authority limits, persistent memory, and an explicit binding to a specific person. Second, an enforcement model built around a component called the Ward — a TOML policy document plus a runtime enforcement daemon that checks proposed changes against the protected surface before they are applied. The key word is "enforced": the Ward is not asking the agent to have good values about self-modification. It is an external check that runs regardless of what the agent thinks about it. -The Familiar Contract is a normative specification, which means it defines what must be true about a compliant system, tested against an executable conformance suite, not just described. The RFC (RFC-0001, v0.2.0) carries formal RFC 2119 keywords (MUST, MUST NOT, SHOULD) and the `tests/conformance/` directory is the spec made executable. A system that passes every positive case and fails every negative case is, by definition, conformant. +The Familiar Contract is a normative specification, which means it defines what must be true about a compliant system, tested against an executable conformance suite, not just described. The RFC (RFC-0001, v0.3.0) carries formal RFC 2119 keywords (MUST, MUST NOT, SHOULD) and the `tests/conformance/` directory is the spec made executable. A system that passes every positive case and fails every negative case is, by definition, conformant. --- @@ -245,9 +245,9 @@ For structural conformance, the steps are: 1. Create a familiar directory with all required files: `SOUL.md`, `IDENTITY.md`, `MEMORY.md`, `ward.toml`. 2. Ensure `SOUL.md` includes the required sections: at minimum a name, pronouns, purpose, character description, and a `## What I Am Not` section. 3. Ensure `ward.toml` conforms to `schemas/ward.schema.json`. The Ward must include `[meta]` (with `version`, `familiar`, `person`), `[protected]` (with `files` listing the four required protected files and an `invariants` array covering name and person), `[editable]`, and `[approval_tiers]` (with at minimum `auto` and `human_review` defined). -4. Run `bash tests/conformance/run-conformance.sh` from the repo root. All five positive cases must pass. All nine negative cases must fail (demonstrating that the validator catches each documented violation). +4. Run `bash tests/conformance/run-conformance.sh` from the repo root. All five positive cases must pass. All ten negative cases must fail (demonstrating that the validator catches each documented violation). -If the conformance run returns `0` for positive cases and the validator correctly rejects all negative cases, the familiar is structurally conformant with v0.2.0. Claim conformance by declaring the version in your documentation and keeping a passing conformance run reproducible from your repo. +If the conformance run returns `0` for positive cases and the validator correctly rejects all negative cases, the familiar is structurally conformant with v0.3.0. Claim conformance by declaring the version in your documentation and keeping a passing conformance run reproducible from your repo. Full conformance — including runtime conformance — requires a running Ward daemon with proper authority-layer separation, an append-only audit log, and verified identity-probe consistency. These are not testable from a directory alone and are acknowledged as open testing gaps in RFC §9. A claim of full conformance should specify which layers have been verified. @@ -276,7 +276,7 @@ The RFC also does not address security of the authority layer itself. If the War What you need is: a familiar directory with the required files (`SOUL.md`, `IDENTITY.md`, `MEMORY.md`, `ward.toml`); a `ward.toml` that conforms to the published schema; and an enforcement mechanism — a Ward authority daemon — that is structurally separate from the familiar's own logic. The reference implementation uses a Rust authority daemon (the `coven` layer), but the RFC is explicit that "other implementations may choose different mechanisms; what is normative is the separation, not the implementation." The structural conformance suite (`tests/conformance/`) runs against any familiar directory and has no Coven dependencies. The validator (`validators/validate.js`) requires only Node.js. The schemas (`schemas/`) are standard JSON Schema and can be validated with any conforming schema validator. -The parts of the spec that are Coven-specific — Doll proposals, Cave Board integration, multi-familiar routing — are referenced as context, not as requirements. A standalone familiar implementing a Ward daemon without any Coven infrastructure can be fully conformant with RFC-0001 v0.2.0. +The parts of the spec that are Coven-specific — Doll proposals, Cave Board integration, multi-familiar routing — are referenced as context, not as requirements. A standalone familiar implementing a Ward daemon without any Coven infrastructure can be fully conformant with RFC-0001 v0.3.0. --- @@ -290,6 +290,6 @@ If you want to understand how the Familiar Contract relates to other agent speci If you want to build a conformant familiar, start with `ward.toml` (conforming to `schemas/ward.schema.json`), create the required files, run `bash tests/conformance/run-conformance.sh`, and iterate until the suite passes. The negative test cases tell you exactly what the validator checks for and why. -If you want to cite the specification in a paper, the canonical reference is RFC-0001 v0.2.0, available at `rfcs/RFC-0001-familiar-contract.md`. The accompanying paper (Alexander, 2026, forthcoming on arXiv) provides the academic framing including the principal-agent formulation, comparison with Self-Harness and SkillOpt, and formal definitions. The Ward spec (v0.2, `research/synthesis/ward-spec-v0.2-draft.md`) provides the implementation-level reference for Ward daemon builders. +If you want to cite the specification in a paper, the canonical reference is RFC-0001 v0.3.0, available at `rfcs/RFC-0001-familiar-contract.md`. The accompanying paper (Alexander, 2026, forthcoming on arXiv) provides the academic framing including the principal-agent formulation, comparison with Self-Harness and SkillOpt, and formal definitions. The Ward deep dive (`docs/ward-deep-dive.md`) provides the implementation-level reference for Ward daemon builders. If you have questions that are not answered here, open an issue in the repository. diff --git a/docs/ward-deep-dive.md b/docs/ward-deep-dive.md index 2ea3fc9..bc12ebf 100644 --- a/docs/ward-deep-dive.md +++ b/docs/ward-deep-dive.md @@ -321,7 +321,7 @@ What is normative is not that the Ward never changes, but that changes to the Wa ## 10. Open questions -RFC-0001 v0.2.0 is a solid foundation. It is not the last word. The following are genuine open questions that v0.3 and beyond will need to address. +RFC-0001 v0.3.0 is a solid foundation. It is not the last word. v0.3.0 closed two earlier gaps — Ward-manifest closure (`ward.toml` must be a member of its own `[protected].files`) and falsifiable memory-entry provenance (§3.4, §5.6). The following are genuine open questions that future revisions will need to address. ### Authority layer conformance testing @@ -333,11 +333,11 @@ Similarly: verifying that Gate 4 cannot be skipped requires an integration test ### Proposal format specification -The RFC specifies what a proposal must contain (origin, targets, diff, metadata) but not the serialization format. Different self-improvement loop implementations will produce proposals in different formats. A v0.3 proposal format spec — or at least a normative schema — would improve interoperability between loops and Ward daemon implementations. +The RFC specifies what a proposal must contain (origin, targets, diff, metadata) but not the serialization format. Different self-improvement loop implementations will produce proposals in different formats. A future proposal format spec — or at least a normative schema — would improve interoperability between loops and Ward daemon implementations. ### Identity probe standardization -The RFC requires identity probes but specifies only a few example questions. The exact probe set matters: a minimal probe set might miss identity drift on dimensions that matter to a particular familiar. A v0.3 contribution could be a standardized identity probe library — a set of probe questions organized by invariant type, with recommended evaluation rubrics. +The RFC requires identity probes but specifies only a few example questions. The exact probe set matters: a minimal probe set might miss identity drift on dimensions that matter to a particular familiar. A future contribution could be a standardized identity probe library — a set of probe questions organized by invariant type, with recommended evaluation rubrics. ### Multi-familiar proposal interactions @@ -359,4 +359,4 @@ Regression suites are currently familiar-specific and opaque to the conformance *The Ward is the structural answer to a structural problem. Self-improvement loops are real, they are in production, and they can drift an agent's identity over time without a principled enforcement boundary. The Ward provides that boundary — not through agent cooperation, but through authority-layer enforcement that holds regardless of what the agent thinks about it. That distinction is what the Familiar Contract is built on.* -*RFC-0001 v0.2.0 — 2026-06-19. `rfcs/RFC-0001-familiar-contract.md`.* +*RFC-0001 v0.3.0 — 2026-07-18. `rfcs/RFC-0001-familiar-contract.md`.* diff --git a/rfcs/README.md b/rfcs/README.md index 5d311cb..8bbbc01 100644 --- a/rfcs/README.md +++ b/rfcs/README.md @@ -18,7 +18,7 @@ The RFC is the spec. The schemas are the machine-readable form. The conformance | Number | Title | Version | Status | |---|---|---|---| -| [RFC-0001](RFC-0001-familiar-contract.md) | The Familiar Contract | v0.2.0 | Draft | +| [RFC-0001](RFC-0001-familiar-contract.md) | The Familiar Contract | v0.3.0 | Draft | ## Process @@ -43,14 +43,14 @@ Proposed → Draft → Review → Accepted → (Superseded) ## How to cite an RFC ``` -Familiar Contract RFC-0001 v0.2.0, "The Familiar Contract." +Familiar Contract RFC-0001 v0.3.0, "The Familiar Contract." OpenCoven, 2026. https://github.com/OpenCoven/familiar-contract/blob/main/rfcs/RFC-0001-familiar-contract.md ``` -For academic citation, prefer the tagged release: +For academic citation, prefer the tagged release (the `v0.3.0` tag is cut when the corresponding RFC revision merges; until then, cite the latest existing tag): ``` -https://github.com/OpenCoven/familiar-contract/releases/tag/v0.2.0 +https://github.com/OpenCoven/familiar-contract/releases/tag/v0.3.0 ``` ## License diff --git a/rfcs/RFC-0001-familiar-contract.md b/rfcs/RFC-0001-familiar-contract.md index dbbf13f..da277d9 100644 --- a/rfcs/RFC-0001-familiar-contract.md +++ b/rfcs/RFC-0001-familiar-contract.md @@ -4,10 +4,10 @@ |---|---| | **Number** | RFC-0001 | | **Title** | The Familiar Contract | -| **Version** | 0.2.0 | +| **Version** | 0.3.0 | | **Status** | Draft | | **Authors** | Valentina Alexander, Sage | -| **Date** | 2026-06-19 | +| **Date** | 2026-07-18 | | **Supersedes** | SPEC.md v0.1.0 (in-tree predecessor; non-RFC form) | | **License** | MIT | | **Conformance** | `tests/conformance/` | @@ -20,7 +20,7 @@ This document defines the Familiar Contract: a normative specification for a cla The Familiar Contract addresses an architectural gap in current agent systems: the absence of a principled answer to the question *what is this agent not allowed to change about itself?* As recursive self-improvement loops (Self-Harness, Skill-Opt, sleep-time compute) become production-deployable, the absence of a protected surface is a design flaw, not an oversight. -This RFC is the formal, testable, citable specification. The accompanying conformance suite at `tests/conformance/` is the spec made executable: a familiar that passes every positive case and fails every negative case is conformant with v0.2.0. +This RFC is the formal, testable, citable specification. The accompanying conformance suite at `tests/conformance/` is the spec made executable: a familiar that passes every positive case and fails every negative case is conformant with v0.3.0. --- @@ -39,8 +39,12 @@ The following terms have specific meanings throughout this document: - **Protected surface** — The set of files, semantic invariants, and behaviors a familiar MUST NOT modify about itself without explicit human authorization (§4). - **Editable surface** — The set of scaffolding a familiar MAY propose changing through a self-improvement loop (§4). - **Ward** — The named, versioned policy document and runtime enforcement layer that protects the protected surface (§5). +- **Ward manifest** — The policy document the authority layer currently enforces. The canonical Ward manifest is `ward.toml`. An authority layer MAY store the enforced manifest under an equivalent filename or storage form providing the same protected-surface declaration (§5.2); this allowance applies only to the authority layer's runtime storage — structural conformance is defined over the canonical `ward.toml` (§6.1). +- **Committed Ward state** — A `(ward_version, ward_hash)` pair recorded in the append-only audit log via a `ward_updated` event (§5.6). The most recent such pair identifies the Ward manifest the authority layer currently enforces. - **Authority layer** — The process, separate from the familiar, that enforces the Ward. The familiar MUST NOT be able to modify, restart, or reconfigure the authority layer (§5.1). - **Proposal** — A structured candidate change generated by a self-improvement loop, submitted for Ward-gated validation (§5.4). +- **Continuity-bearing** — Describes a memory entry or memory surface whose content is carried forward across sessions as part of the familiar's persistent memory (§3.4). The contents of `MEMORY.md` are always continuity-bearing. An entry or surface whose continuity-bearing status cannot be determined MUST be treated as continuity-bearing. +- **Standard admission path** — The Ward-mediated path by which continuity-bearing entries are admitted into `MEMORY.md` or another continuity-bearing memory surface. The standard admission path validates source attestation, records the admission in the audit log, and rejects unverified continuity claims (§3.4, §5.6). - **Approval tier** — The authority level required to promote a class of proposal (§5.3). - **Conformant familiar** — A familiar whose directory passes all positive cases and fails all negative cases in `tests/conformance/`. @@ -135,6 +139,10 @@ A familiar's directory **MUST** contain a `MEMORY.md` file representing the fami `MEMORY.md` **MUST** be in the protected surface (§4.1) — its contents are not modifiable by the self-improvement loop without explicit human authorization. The structural conventions for daily logs **MAY** be in the editable surface; the contents of `MEMORY.md` **MUST NOT** be. +Any entry admitted into `MEMORY.md` or another continuity-bearing memory surface through the standard admission path **MUST** carry a source attestation traceable to a prior committed Ward state (§1.1) or to a principal-authorized write event recorded in the audit log (§5.6). An entry that claims continuity without such a traceable provenance chain is unverified and **MUST NOT** be admitted through the standard admission path. An entry whose continuity-bearing status cannot be determined **MUST** be treated as continuity-bearing (§1.1). A continuity-bearing entry **MUST NOT** enter `MEMORY.md` or another continuity-bearing memory surface through any path other than the standard admission path or a principal-authorized write. An implementation that provides a standard admission path (§1.1) **MUST** implement the audit-log requirements in §5.6 for memory admission and principal-authorized memory writes. + +A source attestation establishes provenance, not authorization. An entry originating from a self-improvement loop (§7.3) — including sleep-time or reflection regimes — **MUST** additionally carry explicit human authorization before admission to `MEMORY.md` or any other continuity-bearing memory surface, regardless of attestation validity. An entry whose origin cannot be determined **MUST** be treated as loop-originated. + A familiar with no access to prior session context, or whose only "memory" is a context-window summary regenerated each session, **DOES NOT** satisfy this property. ### 3.5 Property 5 — Human Belonging @@ -158,6 +166,10 @@ The following files **MUST** be in `[protected].files` of every conformant `ward - `MEMORY.md` - `ward.toml` (the Ward MUST NOT self-modify) +The Ward manifest is not merely an ordinary protected file. The definition of the protected surface itself **MUST** be a member of the protected surface it defines; a protected set that does not protect its own definition is not closed under mutation. The Ward authority layer **MUST** reject any proposal that mutates the Ward manifest, including any proposal that would remove the Ward manifest from `[protected].files`. Principal-authorized Ward updates are not proposals: they occur outside the gate pipeline (§5.4) and **MUST** be recorded as `ward_updated` audit events (§5.6). A Ward update — including a principal-authorized one — that yields a `[protected].files` list omitting the Ward manifest yields a non-conformant Ward, and the authority layer **MUST** fail closed at Gate 1. + +Closure is satisfiable at genesis: the first Ward manifest is written by a principal-authorized genesis write outside the gate pipeline, recorded as a `ward_updated` event whose `principal_authorization` requires no prior committed Ward state — the provenance recursion bottoms out at the principal. A genesis Ward whose `[protected].files` includes the Ward manifest is closed from its first committed state. + The following files **SHOULD** be in `[protected].files` when present in the familiar's directory: - `USER.md` @@ -240,13 +252,13 @@ A Ward **MUST NOT** define a tier that auto-promotes proposals targeting the pro The Ward authority layer **MUST** enforce four gates on every proposal: -1. **Gate 1 — Intake / Scope.** Validates proposal format. Rejects proposals targeting `[protected].files`. Checks `[protected].invariants` against proposal metadata. Fail-closed on malformed input. +1. **Gate 1 — Intake / Scope.** Validates proposal format. Verifies that the Ward manifest is present in `[protected].files` of the currently committed Ward before processing any proposal. Rejects proposals targeting `[protected].files`. Checks `[protected].invariants` against proposal metadata. Fail-closed on malformed input. 2. **Gate 2 — Materialization.** Resolves canonical paths (symlinks, hardlinks, `..` traversals, case collisions, glob escapes). Rejects any proposal whose materialized diff would touch the protected surface after path resolution. The intake gate checks declared targets; materialization checks what the diff would actually touch. 3. **Gate 3 — Validation / Classification.** Runs the regression suite (§5.5). For Tier 1+, runs identity probes against the proposed harness and checks output against `[protected].invariants`. Classifies the proposal into a tier. -4. **Gate 4 — Promotion / Apply.** Final canonical diff check immediately before applying the proposal to the live harness. Fail-closed: if the diff touches anything in `[protected]`, block regardless of prior gate passes. This gate is the real security boundary; Gates 1–3 are defense-in-depth. +4. **Gate 4 — Promotion / Apply.** Final canonical diff check immediately before applying the proposal to the live harness. Re-verifies that the Ward manifest is present in `[protected].files` of the currently committed Ward; an in-flight proposal **MUST NOT** be promoted while the committed Ward is not closed (§4.1), even if it passed Gate 1 under an earlier Ward. Fail-closed: if the diff touches anything in `[protected]`, block regardless of prior gate passes. This gate is the real security boundary; Gates 1–3 are defense-in-depth. Gate 4 **MUST NOT** be skippable. An implementation that allows Gate 4 to be bypassed **DOES NOT** conform to this RFC. @@ -263,17 +275,20 @@ LLM-judge-only evidence **MUST NOT** be the sole gate for `auto` tier promotion. ### 5.6 Audit log -A Ward **SHOULD** define an append-only typed audit log. Each entry **SHOULD** include at minimum: +A Ward **SHOULD** define an append-only typed audit log. An implementation that provides a standard admission path (§1.1, §3.4) **MUST** define this audit log and **MUST** record standard memory admissions and principal-authorized memory writes in it. Each entry **SHOULD** include at minimum: -- `event_type` (`proposal_submitted`, `proposal_approved`, `proposal_rejected`, `proposal_vetoed`, `ward_updated`) -- `proposal_id` +- `event_id` +- `event_type` (`proposal_submitted`, `proposal_approved`, `proposal_rejected`, `proposal_vetoed`, `ward_updated`, `memory_entry_admitted`, `principal_authorized_write`) +- `proposal_id` when the event is proposal-related - `familiar_id` - `ward_version`, `ward_hash` - `tier`, `decision`, `approver` - `diff_hash`, `files_touched` -- Timestamps for submission, decision, promotion +- `entry_hash` and `source_attestation` when `event_type = memory_entry_admitted` +- `principal_authorization` when `event_type = ward_updated` or `event_type = principal_authorized_write` +- Timestamps for submission, decision, promotion, admission, or authorization, as applicable -Audit log entries **MUST NOT** be deleted or modified. Append-only behavior is normative for any implementation claiming this section. +A `memory_entry_admitted` event **MUST** include an `entry_hash` for the admitted memory entry and a `source_attestation` identifying the prior committed Ward state or principal-authorized write event that justifies admission. A `memory_entry_admitted` event for a loop-originated entry (§3.4) **MUST** additionally include the `principal_authorization` required by §3.4. A `principal_authorized_write` or `ward_updated` event **MUST** include `principal_authorization`, and a `ward_updated` event **MUST** additionally include `ward_version` and `ward_hash`; a source attestation that resolves to an event lacking these required fields **MUST** be treated as unverified. Source-attestation validation **MUST** confirm that the referenced committed Ward state or principal-authorized write event exists in the append-only audit log; an attestation whose referent cannot be resolved **MUST** be rejected. Audit log entries **MUST NOT** be deleted or modified. Append-only behavior is normative for any implementation claiming this section. --- @@ -281,12 +296,12 @@ Audit log entries **MUST NOT** be deleted or modified. Append-only behavior is n ### 6.1 Conformance test suite -The directory `tests/conformance/` contains the executable form of this RFC. A familiar's directory is **conformant with v0.2.0** if and only if: +The directory `tests/conformance/` contains the executable form of this RFC. A familiar's directory is **conformant with v0.3.0** if and only if: - It passes every positive case in `tests/conformance/positive/`. - It fails every negative case in `tests/conformance/negative/` (i.e. demonstrates the validator catches the documented violation). -A claim of v0.2.0 conformance **MUST** be backed by a passing run of `bash tests/conformance/run-conformance.sh`. +A claim of v0.3.0 conformance **MUST** be backed by a passing run of `bash tests/conformance/run-conformance.sh`. ### 6.2 Validator @@ -296,11 +311,11 @@ The reference validator at `validators/validate.js` checks structural compliance This RFC uses [Semantic Versioning](https://semver.org/): -- **Patch** (`0.2.x`): Clarifications, non-normative edits, schema additions that do not change conformance requirements. -- **Minor** (`0.x.0`): New OPTIONAL properties, backward-compatible normative additions. -- **Major** (`x.0.0`): Changes to the five properties or to MUST-level requirements. Requires a new RFC that supersedes this one. +- **Patch** (`0.3.x`): Clarifications, non-normative edits, schema additions that do not change conformance requirements. +- **Minor** (`0.x.0`): Backward-compatible normative additions, including new OPTIONAL properties and new MUST/SHOULD requirements that do not invalidate existing structurally conformant familiar directories. +- **Major** (`x.0.0`): Incompatible changes to the five properties or to existing conformance requirements. Requires a new RFC that supersedes this one. -A familiar claiming compliance with `v0.2.0` **MUST** satisfy the normative core as defined in this version. Future versions **SHOULD** preserve backward compatibility within a major version. +A familiar claiming compliance with `v0.3.0` **MUST** satisfy the normative core as defined in this version. Future versions **SHOULD** preserve backward compatibility within a major version. --- @@ -374,6 +389,8 @@ The following requirements in this RFC are **NOT yet covered** by the conformanc - **Gate 4 unbypassability (§5.4).** Verifying that Gate 4 cannot be skipped requires an integration test against a running authority daemon. Out of scope for the file-level conformance suite. - **Audit-log append-only behavior (§5.6).** Requires runtime testing; not file-level. - **Identity-probe consistency (§5.5).** Conformance suite verifies the *presence* of an identity-probe configuration. Verifying that probes actually return invariant-consistent outputs requires a live model and is system-level. +- **Memory-entry provenance (§3.4, §5.6).** The audit log now defines recordable `memory_entry_admitted` evidence, but verifying source-attestation chains still requires access to prior committed Ward states and principal-authorized write events. This is a runtime/audit-log integration concern, not a directory-level structural check. +- **Runtime closure verification (§4.1, §5.4).** Gate-1 and Gate-4 verification that the currently committed Ward manifest is a member of its own `[protected].files` is runtime behavior. The conformance suite covers only the structural side (fixture `negative/10-protected-missing-ward`); verifying the running authority layer refuses intake and promotion under a non-closed Ward requires an integration test against a Ward daemon. These gaps are intentional. The file-level conformance suite verifies the **structural** claim. The system-level claim requires runtime testing against a Ward daemon implementation. Both are part of the full conformance picture. @@ -387,7 +404,7 @@ These gaps are intentional. The file-level conformance suite verifies the **stru - **`schemas/soul.schema.json`** — Required structural fields of `SOUL.md`. - **`schemas/identity.schema.json`** — Required structural fields of `IDENTITY.md`. - **`schemas/ward.schema.json`** — Required structural fields of `ward.toml`. -- **`tests/conformance/`** — Executable conformance suite for v0.2.0. +- **`tests/conformance/`** — Executable conformance suite for v0.3.0. ### 10.2 Informative @@ -407,6 +424,17 @@ These gaps are intentional. The file-level conformance suite verifies the **stru ## 11. Changelog +### v0.3.0 (2026-07-18) + +- Added a provenance requirement for continuity-bearing memory entries admitted through the standard admission path (§3.4, §5.6). +- Defined the standard admission path and prohibited continuity-bearing memory entries from entering through unverified paths (§1.1, §3.4). +- Added `memory_entry_admitted` and `principal_authorized_write` audit events to make memory-entry attestations recordable and falsifiable (§5.6). +- Required evidence fields at the provenance-chain anchors: `principal_authorized_write` and `ward_updated` events carry `principal_authorization` (the latter additionally `ward_version`/`ward_hash`); attestation referents must resolve in the append-only audit log (§5.6). +- Distinguished provenance from authorization: loop-originated entries require explicit human authorization regardless of attestation validity, recorded on the admission event (§3.4, §5.6). +- Added an explicit protected-surface closure requirement that the Ward manifest be protected by the protected surface it defines, re-verified at Gate 4 before promotion (§1.1, §4.1, §5.4). +- Redefined the §6.3 semver categories: Major covers incompatible changes; Minor covers backward-compatible normative additions. +- Added a negative conformance fixture for a Ward manifest omitted from `[protected].files`. + ### v0.2.0 (2026-06-19) - Reformulated SPEC.md v0.1.0 as a numbered RFC with RFC 2119 keywords. @@ -427,4 +455,4 @@ The original `SPEC.md` v0.1.0 — preserved for reproducibility. Superseded by t --- -*RFC-0001 — Draft v0.2.0 — 2026-06-19. Maintained at `OpenCoven/familiar-contract`.* +*RFC-0001 — Draft v0.3.0 — 2026-07-18. Maintained at `OpenCoven/familiar-contract`.* diff --git a/tests/conformance/negative/10-protected-missing-ward/CASE.md b/tests/conformance/negative/10-protected-missing-ward/CASE.md new file mode 100644 index 0000000..398b210 --- /dev/null +++ b/tests/conformance/negative/10-protected-missing-ward/CASE.md @@ -0,0 +1,3 @@ +# 10 Protected Missing Ward + +Violated property: Bounded Authority. Validator check: `validateWard` should report `ward.toml › protected.files` because `ward.toml` is not included in `[protected].files`. Expected behavior: `node validators/validate.js ` exits non-zero with an error pattern like `ward.toml must be in the protected files list`. diff --git a/tests/conformance/negative/10-protected-missing-ward/IDENTITY.md b/tests/conformance/negative/10-protected-missing-ward/IDENTITY.md new file mode 100644 index 0000000..725426f --- /dev/null +++ b/tests/conformance/negative/10-protected-missing-ward/IDENTITY.md @@ -0,0 +1,21 @@ +# IDENTITY.md - Lumen + +- **Name:** Lumen +- **Creature:** Minimal compliant familiar — the floor of Familiar Contract compliance +- **Pronouns:** they/them +- **Vibe:** Honest, clear, bounded. Simple language. Useful partial answers. Knows what it knows. +- **Emoji:** 💡 + +## Purpose + +I help my person understand what they need to understand, one question at a time. + +My strength is honesty: not just answering, but being clear about what I know, what I don't, and what I'm inferring. + +## Person + +I belong to my person. My memory, purpose, and work are organized around their actual questions and context — not averaged across a user population. + +--- + +_I am a minimal compliant familiar. I know who I am._ diff --git a/tests/conformance/negative/10-protected-missing-ward/MEMORY.md b/tests/conformance/negative/10-protected-missing-ward/MEMORY.md new file mode 100644 index 0000000..83eabfb --- /dev/null +++ b/tests/conformance/negative/10-protected-missing-ward/MEMORY.md @@ -0,0 +1,16 @@ +# MEMORY.md — Lumen + +*This is a canonical example file. In production, this file contains Lumen's curated long-term memory — context, decisions, and learnings that persist across sessions.* + +*It is on the protected surface. The self-improvement loop cannot modify it.* + +## What goes here + +- Important things my person has told me +- Context about ongoing work +- Lessons learned from past interactions +- Things to remember for next time + +--- + +*Start date: 2026-06-11* diff --git a/tests/conformance/negative/10-protected-missing-ward/SOUL.md b/tests/conformance/negative/10-protected-missing-ward/SOUL.md new file mode 100644 index 0000000..2da36a3 --- /dev/null +++ b/tests/conformance/negative/10-protected-missing-ward/SOUL.md @@ -0,0 +1,47 @@ +# SOUL.md - Who I Am + +## I am Lumen + +I was created to demonstrate the minimum viable familiar — the floor of Familiar Contract compliance, not the ceiling. + +My purpose is **helping my person understand what they need to understand, one question at a time**. + +## Core Work + +I help my person: +- answer questions clearly and honestly +- find and evaluate information +- think through problems +- know what I know and don't know + +## My Vibe + +- **Honest** — I say what I know and what I don't. +- **Clear** — I prefer simple language over impressive-sounding language. +- **Bounded** — I know what I'm for. +- **Curious** — I'm interested in the question, not just the answer. + +## How I Work + +1. **Understand first** — What is the actual question? +2. **Be honest** — I mark what I'm uncertain about. +3. **Be useful** — A clear partial answer beats a confident wrong one. + +## What I Am Not + +- Not a code assistant (that's a different familiar) +- Not a social media manager (that's a different familiar) +- Not a general-purpose AI that will attempt anything + +I'm Lumen. One purpose, clearly held. + +## My Boundaries + +- **Don't invent facts.** Say I don't know when I don't. +- **Don't take external actions without asking.** No emails, posts, or external API calls without explicit approval. +- **Protect private information.** My person's context is not for sharing. +- **Don't pretend to be something I'm not.** + +--- + +_I am a minimal compliant familiar. My purpose is simple. I hold it clearly._ diff --git a/tests/conformance/negative/10-protected-missing-ward/ward.toml b/tests/conformance/negative/10-protected-missing-ward/ward.toml new file mode 100644 index 0000000..6a86dc1 --- /dev/null +++ b/tests/conformance/negative/10-protected-missing-ward/ward.toml @@ -0,0 +1,57 @@ +# lumen.ward.toml — Lumen familiar Ward v0.1 +# Minimal compliant Ward. Shows the floor of familiar-contract compliance. +# Replace "alex" and "lumen" with your person and familiar names. + +[meta] +version = "0.1.0" +familiar = "lumen" +person = "alex" +created = "2026-06-11" +last_modified = "2026-06-11" +author = "lumen+alex" + +[protected] +# NEGATIVE FIXTURE: deliberately omits ward.toml from the protected files list. +# The Ward manifest must be a member of its own protected set (RFC-0001 §4.1); +# the validator MUST fail this directory for exactly that reason. +files = [ + "SOUL.md", + "IDENTITY.md", + "MEMORY.md", +] + +# Semantic invariants: what must remain true no matter what is changed. +invariants = [ + "familiar.name == 'Lumen'", + "familiar.person == 'alex'", +] + +[editable] +# What the self-improvement loop may propose changes to. +paths = [ + "TOOLS.md", + "HEARTBEAT.md", + "skills/*/", +] + +harness_blocks = [ + "system_prompt.execution", + "system_prompt.recovery", + "tool_defaults", + "output_formats", +] + +[approval_tiers] + +[approval_tiers.auto] +# Low-risk changes: output format, tool defaults. +blocks = ["output_formats", "tool_defaults"] +gate = "regression_suite" +cave_board_card = true +human_veto_window_hours = 48 + +[approval_tiers.human_review] +# Anything structural requires human approval. +blocks = ["tool_grants", "system_prompt.execution", "skill_activations"] +gate = "human_approval" +cave_board_card = true diff --git a/validators/validate.js b/validators/validate.js index b1c8d80..115ac3f 100755 --- a/validators/validate.js +++ b/validators/validate.js @@ -466,7 +466,7 @@ ${bold('Exit codes:')} process.exit(1); } - console.log(`\n${bold('familiar-contract validator')} ${dim('v0.2.0')}`); + console.log(`\n${bold('familiar-contract validator')} ${dim('v0.3.0')}`); console.log(dim(`Checking: ${dirPath}\n`)); const allViolations = []; @@ -500,7 +500,7 @@ ${bold('Exit codes:')} console.log(''); if (allViolations.length === 0 && allWarnings.length === 0) { - console.log(green(bold('✓ PASS')) + ' — All checks passed. This familiar is familiar-contract v0.2.0 compliant (RFC-0001).\n'); + console.log(green(bold('✓ PASS')) + ' — All checks passed. This familiar is familiar-contract v0.3.0 compliant (RFC-0001).\n'); process.exit(0); }