Add repo memory layer and agent governance

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Fable 5 committed 2026-08-12 20:57:00 -04:00
1 parent 08c56b37e1
commit 90d4290989
15 files changed
+245

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
# Repo Memory
Curated, reviewed knowledge for coding agents working in this repository.
Memory is an accelerator, not a second source of truth.
## Precedence (highest first)
1. Source code and tests
2. Executable configuration
3. Accepted design records / docs
4. `AGENTS.md`
5. This memory
If memory conflicts with anything above it, the memory is stale — propose a fix.
## Topics
- `memory/architecture.md` — durable architectural decisions and constraints
- `memory/conventions.md` — validated conventions not obvious from the code
- `memory/lessons.md` — hard-won lessons and recurring landmines
- `memory/decisions.jsonl` — structured decision records (one JSON object per line)
## Write policy
Agents MAY read everything here and MAY add candidates under `proposals/`
(one file per proposal, named `YYYY-MM-DD-<slug>.md`, with evidence links).
Agents MUST NOT edit `memory/` directly; trusted memory changes only through
reviewed commits that promote a proposal.
## Prohibited content
Credentials or secrets, personal data, raw transcripts or tool logs, session
TODOs, high-frequency agent state, unverified external claims.
+38
View File
@@ -0,0 +1,38 @@
# Architecture
Durable architectural decisions and constraints for BitGate.
## Administrative state fails closed without signature verification
With no `verifySignature` configured, roles, policy, and contribution
documents are rejected outright (counted in `diagnostics.rejectedUnverified`)
— `event.pubkey` is an unauthenticated claim until a signature is checked, so
an authorship check alone proves nothing. Verification runs inside
`ingestEvent` itself, not only in the loaders, because `ingestEvent` is
public API; an asynchronous verifier on that synchronous path is treated as
unverified ("I could not check this" reads as failure), and `ingestVerified()`
or the loaders must be used to await one. `trustUnsignedEvents: true` and the
widget's `verify="off"` exist for local development only and are made visible
on purpose. Trust signals (reports, mutes) are deliberately not gated this
way because they are bounded by the viewer's own follow graph — a weaker
guarantee, which is why verification still matters for them.
Authoritative source:
- docs/security.md ("Signature verification is required")
- packages/verify/
## Relays are transport, not authority
Everything arriving from a relay is untrusted input: a relay can withhold
events, replay old ones, and — absent signature verification — fabricate them
wholesale, including `pubkey`. Two independent checks therefore gate
administrative state: authorship (a roles document is accepted only from the
deployment's `configuredRoot`, compared against the constructor value and
never against current authority state, so a bad ingest cannot move the
goalposts) and authenticity (the signature check above). The hostile-input
table in the security doc enumerates the attacks this design is meant to
survive; consult it before touching ingest, authorship, or verification
paths.
Authoritative source:
- docs/security.md ("The trust boundary", "Hostile input BitGate is designed to survive")
+5
View File
@@ -0,0 +1,5 @@
# Conventions
Validated conventions not obvious from the code.
No entries yet.
+2
View File
@@ -0,0 +1,2 @@
{"kind":"constraint","subject":"security/fails-closed-verification","summary":"Administrative state (roles, policy, contributions) is rejected without a configured verifySignature; verification runs inside public ingestEvent, async verifiers on the sync path count as unverified, and trustUnsignedEvents/verify=off are development-only escape hatches made deliberately visible.","status":"active","evidence":[{"type":"repository","ref":"docs/security.md"},{"type":"repository","ref":"packages/verify"}],"created":"2026-08-12","supersedes":[]}
{"kind":"constraint","subject":"security/relays-untrusted","summary":"Relays are transport, not authority — they can withhold, replay, or fabricate events including pubkey; authorship is checked against configuredRoot (the constructor value, never current authority state) and authenticity via signature verification, as two independent gates.","status":"active","evidence":[{"type":"repository","ref":"docs/security.md"}],"created":"2026-08-12","supersedes":[]}
+5
View File
@@ -0,0 +1,5 @@
# Lessons
Hard-won lessons and recurring landmines.
No entries yet.
+8
View File
@@ -0,0 +1,8 @@
# Agent plans
Durable, multi-session execution plans only — the canonical backlog stays in
the repo's TODO file or GitHub Issues, and session-local checklists are never
committed. One plan per task, named `<ticket-or-slug>.md`, in `active/`;
move finished plans to `archive/`. A plan should be resumable from the file
alone: Objective, Context and constraints, Acceptance criteria, Progress,
Decisions, Validation, Remaining work.
View File
Whitespace-only changes.
View File
Whitespace-only changes.
+7
View File
@@ -0,0 +1,7 @@
# Memory proposals
Agents: drop candidate memories here, one file per proposal, named
`YYYY-MM-DD-<slug>.md`. State the claim, the evidence (file paths, commits,
test results), and why it is durable. A human reviews and either promotes it
into `../memory/` in a reviewed commit or deletes it. Nothing in this
directory is trusted context.
+29
View File
@@ -0,0 +1,29 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Repo Memory Decision Record",
"type": "object",
"additionalProperties": false,
"required": ["kind", "subject", "summary", "status", "evidence", "created"],
"properties": {
"kind": {"enum": ["decision", "constraint", "lesson", "observation", "workaround"]},
"subject": {"type": "string", "minLength": 1},
"summary": {"type": "string", "minLength": 1, "maxLength": 4096},
"status": {"enum": ["proposed", "active", "superseded", "expired"]},
"evidence": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["type", "ref"],
"properties": {
"type": {"enum": ["repository", "git", "issue", "test", "external"]},
"ref": {"type": "string", "minLength": 1}
}
}
},
"created": {"type": "string"},
"expires": {"type": ["string", "null"]},
"supersedes": {"type": "array", "items": {"type": "string"}}
}
}