Agent eligibility check · The decision corpus

Records

docs/RECORDS.md · no id · revision ? · /

This is the development record, published as it was written. It is amended by revision, including where the work went wrong. Nothing here has been rewritten for the web.

Records

The conventions for decision records in this project. They exist so the corpus stays readable when it is merged with the others and published, and so an agent can file a correct record without asking.

The rules are enforced where they can be. make records runs the Perspicuity checker and scripts/check_actors.py, and make ci runs it too. The actor check is ours, not the checker's: the checker validates front matter, and the naming rule lives in prose, so it needed something that reads prose. What each one covers is in What is checked, and what is not.

Where records live

RecordPathOwns
The project record[RECORD.md](../RECORD.md)The continuing account: current position, the inherited basis, the plan, the unit table, the review
Sub-decisionsdocs/records/YYYY-MM-DD-<slug>.mdOne consequential choice, its alternatives, its comparison and its review

The project record is the parent of every record in this repository. A sub-decision never replaces it; it hangs off it.

What is inside the checked set

make records reads RECORD.md, AGENTS.md, CONTEXT.md, docs/ACTORS.md, docs/RECORDS.md and docs/ARCHITECTURE.md, plus every file under docs/records/. In those files the actor naming rule is enforced on prose, not just on front matter. Outside that set:

Outside the setWhyConsequence
docs/RUBRIC.mdGenerated from the catalogue in eligibility/checks.py, and its subject is a site, not an actorEdited by make rubric, never by hand
docs/KICKOFF.md, TODO.md, README.md, docs/DEPLOY.md, docs/ADDING-A-CHECK.mdScaffolding and guides built *from* this document, kept in step by handBring them along when a rule here changes; they are not scanned
build/Generated outputNot a source

<!-- actor-naming: discusses-rule --> Named actors and the history of the Primary label are in ACTORS.md. <!-- actor-naming: end -->

Naming

File name: docs/records/YYYY-MM-DD-<slug>.md

Record id: ae- followed by the file name without its extension.

docs/records/2026-09-19-crawler-policy-stance.md
  ->  file stem: 2026-09-19-crawler-policy-stance
  ->  id:        ae-2026-09-19-crawler-policy-stance

That rule is mechanical on purpose: the id and the file can never disagree, and a script could check it. The project record keeps its original id, agent-eligibility-2026-09-19. Ids are stable. Never rename an id to match a later convention; supersede it with a new revision.

Title: a short intention phrase, sentence case — the decision, phrased as something done or chosen. Not a topic.

GoodBadWhy
Set the crawler policy stanceCrawler policyA topic is not a decision
Choose the report URL shapeURLsNames what was chosen
Refuse to audit domains we cannot verifySafety notesStates the position taken
2026-09-19-validation-fixes.mdnotes.md, updates.md, misc.mdAn activity log is not a record

Subject prefixes. Start the slug with one of these when one fits. It is a convenience for browsing, not a gate — if none fits, use a descriptive slug anyway.

PrefixCovers
rubric-Anything that changes a check, the weighting or the claim boundary
market-Payer, pricing, outreach, positioning
tech-Architecture, dependencies, storage, deployment
process-How we work: records, review, gates, delegation
data-Privacy, retention, what we store or fetch

Actors

<!-- actor-naming: discusses-rule --> **Name every actor. Never write "the agent", "the AI", a job title such as Primary or Coordinator, or a model name.** The reason is in ACTORS.md, which also holds the roster and the rules for choosing a name. <!-- actor-naming: end -->

name in ACTORS.md. It persists across every session it works in.

grant and appears in the return.

this record; the name says who they are.

This is not a request. scripts/check_actors.py fails the build on one of five listed role words — the retired label plus <!-- actor-naming: discusses-rule -->Coordinator, Assistant, Admin and Manager<!-- actor-naming: end --> — anywhere in the checked set, and it allows a page to quote them only inside a block opened by an HTML comment reading actor-naming: discusses-rule and closed by one reading actor-naming: end. A marked block is recognised only in ACTORS.md, this file, docs/records/ and RECORD.md — the places whose subject *is* the rule, or its history, and which cannot be written without naming what it forbids — and a marker may sit inline in a sentence, where it covers that line alone. Three guards keep the exception from swallowing the rule it serves:

cannot ride on a live one;

an actor is not stating the rule;

FORBIDDEN when it occurs; ACTORS.md says the same and records the known false positive on sentence-initial words.

When a record is required

Required when the choice:

  1. changes a published claim, the rubric, or a check's wording or weight;
  2. adds, removes or upgrades a dependency;
  3. changes what we fetch, store or publish — safety and privacy both live here;
  4. sets a precedent that later work will follow;
  5. changes authority, ownership, or creates a review obligation;
  6. selects among credible alternatives whose reason would otherwise be lost.

Not required, and better kept in the project record's action account: typo fixes, refactors with no behavioural change, formatting, and new tests that apply an existing rule.

The test is not "was this hard?" It is "would a stranger, later, need to know why?"

The skeleton

Copy this. Omit sections that carry nothing — a short honest record beats a padded one.

---
format: perspicuity-work/1
id: ae-YYYY-MM-DD-<slug>
revision: 1
skill_version: 0.4.0
updated: YYYY-MM-DD
created_at: "YYYY-MM-DDTHH:MM:SS-06:00"
updated_at: "YYYY-MM-DDTHH:MM:SS-06:00"
record_status: open
work_status: not_started
# next_check: YYYY-MM-DD   only when a timed obligation exists
---

# <Intention>

## Current position

Parent: [RECORD.md](../../RECORD.md), revision N.

Principal: David. Decider: <who>.
Work owner: <named actor>.
Decision: <pending | recommended | selected | inherited | none> — <one sentence, with the basis revision>.
Work scope: <the delivery this record owns>.
Work: <what has actually been done, with exact revisions>.
Outcome: <observed result, or explicitly unknown>.
Next: <named actor / action / trigger>.
Dependency: <the missing input and its owner, when work waits>.

## Frame and Decide

<The underlying problem, the adopted frame, and any reframe with its reason.>

| Fundamental objective | Source | Measure, direction and horizon |
| --- | --- | --- |

| Material condition | Type | Basis | Affects |
| --- | --- | --- | --- |

<Register this basis before evaluating alternatives.>

### Alternatives and consequences

<Credible complete courses of action, including the current course. A compact table.>

<The decisive tradeoff, the preference it rests on, and what would warrant reconsideration.>

### Selection

<`selected_at`, decider, basis revision, the choice and the reason. Or the pending question
and its owner.>

## Act

<The plan registered before implementation, with acceptance criteria. Actual evidence after.>

## Review

| Criterion | Evidence source | Owner, window or trigger | Finding | Response |
| --- | --- | --- | --- | --- |

<Delivery acceptance stays separate from evidence of later benefit.>

## Changes

<Revision, time, change, source, reason, affected work.>

Every label above is load-bearing. The checker reads Work scope, Next and Dependency out of ## Current position, and reads record_status and work_status from the front matter, so renaming one of them turns a clean record into a failing one. Parent: and the title are not read by any script; they are what makes the corpus navigable, and the first line of the skeleton is the one most often dropped.

Two things about the skeleton are easy to get wrong:

its parent is ../../RECORD.md and ACTORS.md is ../ACTORS.md. A link copied into RECORD.md itself needs one fewer ../, which is the mistake to check for first when a published page 404s.

a date invented to fill the field is worse than an empty one.

What is checked, and what is not

make records fails on any of these, so fix them before committing:

waits) Dependency: must appear inside it.

active, waiting, submitted, accepted, stopped.

work plus a closure explanation.

checked set outside a marked block; no marked block that has gone stale or that covers an actor credit; and no marked block in a file outside ACTORS.md, this file, docs/records/ and RECORD.md. It is a denylist: it does not establish that every actor is named, only that the words which have been used instead of a name are absent.

A clean result establishes none of this: it does not check whether the reasoning is any good, whether the authority was real, or whether the work was done. It is a spell-checker, not a reviewer.

Two further limits are worth knowing before relying on a green run:

read; the path rule above is what keeps records inside the checked set.

/home/david/.codex/skills/perspicuity/scripts is absent, and says so in its output. A skip is not a pass: make records still exits 0, and the tell is the note plus the absence of the markdown_files: summary line. The actor check still runs, so a skip leaves part of the set unchecked rather than all of it.

which has no Perspicuity skill installed, so the front-matter check has never run there — only on David's machine, and only for as long as that path exists. Making it portable is a real choice with a real cost, recorded as pending in TODO.md rather than settled here. Nothing in the corpus is unchecked on the machine where records are filed; what is missing is the second pair of eyes.

Registration order

Save the basis before the work that depends on it, and the choice before dependent action. This is not a formality: a record written afterwards records what you decided, not what you knew, and the difference is the whole value of the corpus.

That creates a problem the rule alone does not solve, because a record is one file and the work it governs happens after it. The convention here is two moments in the life of the same file:

MomentWhat existsWhen
RegisteredThe record's identity, ## Current position, the frame, and the choice — everything the dependent work needs to be reviewable. Committed before that work starts.Before dependent action
FiledThe same file with ## Act evidence, ## Review findings and a ## Changes entry. Work status moves to submitted, or active while it runs.After the work

A registered record with work_status: active and an empty ## Act is a correct state, not an unfinished one. What is not correct is the reverse: creating the file at the end and writing the decision date from memory. When the documentation time differs from the decision time, say so in the record rather than letting the header imply otherwise — the project record's own "Registration order" note is the worked example.

When a later finding changes an earlier basis, do not edit the earlier revision into agreement. Add a revision, name what changed and why, and preserve the earlier one.

Lifecycle of a sub-record

Filing is not the end of the file's obligations. The parts that are easy to forget:

  1. The parent index is updated when the sub-record is registered, naming the record, its

owner and its state. An index that lists a record nobody filed, or omits one that exists, is the defect a reader notices first.

  1. The sub-record states who assesses it. Worker completion is not acceptance, and a record

whose author is also its only assessor says so and says why.

  1. **It stays open while an owed observation remains**, even after its delivery is accepted.

accepted work plus open record status is the normal state for anything with a later question attached.

  1. It closes only when every obligation is met, cancelled or transferred, with a Closure

naming the actor, date, reason and evidence, and with no next_check left in the header.

Publication hygiene

Assume every record may be published on perspicuity.ai. Never put in a record:

A record may name a public domain, a public source and a public price. It may name an internal path. When in doubt, describe the fact and leave the identifier out.

Review obligations

A record that promises later observation carries the question, the evidence source, the owner and a date or a trigger. next_check in the header is the earliest such date; the dashboard reads it, and a record with no timed obligation simply omits it.

Delivery acceptance is not benefit. "The check shipped" and "a supplier paid" are different findings, and the corpus is only honest if they stay separate.

Delegated work

A worker receives the parent basis, the objectives, the exact grant and the return destination, and a name for the assignment. It is the coordinator's job to assign that name, at the moment of the assignment, before the worker starts; an unnamed return is a defect in the grant, not in the return.

The return carries its own decision basis, or an explicit statement that it made no new choice, plus its output revision, its checks, its failures and anything unresolved. It is attributed to the worker's name, not to a model.

The assessor is named too, and is never the author. When the coordinator both commissioned the work and assesses it, the record says so, and an independent check is commissioned when the consequence warrants one. Worker completion is not acceptance.

How this record connects

It builds on or points to: RECORD, ACTORS.

It is referenced by: Agent instructions, Context, Actors, Make the record conventions followable and enforce the actor rule.