Records
The Records plugin tracks the kinds of thing your blueprints are made of: acceptance criteria and test cases for software, characters for a book, hypotheses for research, and the decisions a team settles along the way. The plugin knows only records; the root declares which kinds it has, as record types, and each type’s records are found, checked, numbered, and listed across the root. A record is not a blueprint: never a collection item, never in the index. The plugin changes only form (a label added, renumbered, or taken off, a list written into a region of its own), never a word you wrote. Off by default; eidos plugin enable records switches it on. With it off, records read as the plain lists they are and file-based ones stay in their folders.
In the browser
Section titled “In the browser”- Records, an activity in the Activity Bar: Overview (every type with its labels, where its records live, its fields, and its count, then the lists waiting for labels), Waiting with its count (while a type has statuses), each record type with its count, each type’s saved views, Waiting for labels, and Records settings at its foot. The + in its head makes a new record type.
- A type set to Show in the sidebar also gets its own entry in the Root view, under Records, with its count: a software root shows Acceptance criteria, a book root Characters.
- Each type has a table at
/p/records/<type>: the label, the text, the blueprint it is found in, the section, and a column per field, plus Status, Signed off, and Tasks where the type uses them. Every column sorts from its header; a search box leads the filters on the blueprint, the section, and each field, all kept in the page’s address, and Save as view keeps a filter as a shared or local view. A row opens its blueprint in a modal, scrolled to the record. A row’s menu offers Open, Open in its own page, Remove label, and Delete record (asked once), and for a type with statuses, Confirm and a Status submenu. - In the live editor, a list’s Turn into menu offers each type with a label pattern, which labels every item of the list, numbered after the labels already in the document, and Plain list (remove labels), which takes them off. Neither changes a word. The insert menu’s Link to a record finds a labelled record by its label or its words and writes the link.
- A link to a record is drawn as the blueprint’s title and the label, with the record’s words on hover. A link whose label is not there is drawn in the error tone.
- The settings page lists each record type as a card, with Edit and a remove button; New record type opens the same form from the settings page, the Overview, and the activity’s +.
Record types
Section titled “Record types”A record type is a name, a title, a label pattern, a few fields, and where its records live. The form asks for:
- Name: what the page calls it (Acceptance criteria). The command name is derived from it and shown (
criterion). - Label: how each record is numbered, with
{n}where the number goes:AC{n}labelsAC1,AC2, and so on, with a live example as you type. Leave it empty for records that are named rather than numbered, such as characters. - Where they live: In document lists, each record a list item inside a blueprint, or One file each, in a folder of the type’s. Once records of the type exist, this stays as it is.
- Show in the sidebar: an entry of its own in the Root view.
- Fields: details each record carries, each a name, a type (Text, Choice with its choices, Link, Number, or Yes or no), and whether it is Required.
The lifecycle settings below are in the same form. From the shell, configure:type writes the same settings the same way:
eidos records configure:type add criterion --title "Acceptance criteria" --label "AC{n}" --field "status:list:met|unmet" --sidebar--field "name:type[:options|…][:required]" takes text, list, link, number, or checkbox, and is repeated, replacing the fields. Removing a type whose records are written needs --force; its records stay as plain lists, or in their folder.
Records in a document
Section titled “Records in a document”An inline record is a list item that starts with its type’s label in bold, wherever it sits in a blueprint. Its fields are the indented line under it, name: value pairs separated by ·:
## Acceptance criteria
- **AC6:** A root with no collections checks clean. status: met · test: [check.test.ts](../../cli/test/check.test.ts)Every blueprint that already writes **AC1:** by hand reads as it is, and a label slotted between two (AC2b) is read too. A template can also mark a section for a type: in Framework Settings → Templates, a section’s Records choice writes <!-- records:section type=<type> --> into the template, and every item at the top of that section’s lists in a blueprint made from it is then a record of the type, labelled or not. That is how a named type, such as Characters, is found. The mark is the template’s alone; a blueprint never carries it. When a section is marked and an existing blueprint’s items there have no labels yet, the Overview offers Label n items, which changes nothing until you accept it.
Labels run in sequence within their blueprint, 1 to n with no gap. A new record takes the next number. Removing one (Remove label, Delete record, eidos records unlabel or remove) renumbers the ones after it, and every link to them, in any file of the root, follows. Labels out of sequence are reported, with a Renumber fix.
Records as files
Section titled “Records as files”A type set to One file each keeps one markdown file per record in a root folder declared as the type’s (owned_by: "@records/<type>", named for the type unless you give --folder). The frontmatter holds the label, the title (the words a list shows), the blueprints it serves by id, and the fields by name; the body is notes. Such a type’s labels run in sequence across its folder, each file renamed with its label, unless it is numbered by ids (below).
Linking to a record
Section titled “Linking to a record”Link to a record as to any part of a document: a standard markdown link to its blueprint’s file, with the label as the fragment.
See [Validate a Root AC6](../cli-core/check.md#ac6), and [Login AC1](#ac1) in this file.The link works anywhere markdown does, on GitHub too. The core check resolves the path, and moving the blueprint rewrites it as it does every link. The plugin checks the fragment, reports a label that is not there, and rewrites the fragment and the label in the link’s words when the record is renumbered. Write the link’s words as the blueprint’s title and the label; the editor’s Link to a record writes it for you. On the command line a record is named <blueprint>/<label> (B-SHS2/AC6, the blueprint by id or path) or <path>#<label>.
A record’s lifecycle
Section titled “A record’s lifecycle”A type can give its records a lifecycle. Each part is off until the type switches it on, in the record type form or with configure:type, so a type that uses none of them reads and behaves as a plain one.
-
Statuses: the stages a record moves through, each in one of three categories: waiting on whoever decides, confirmed, or closed (
--status Open:waiting --status Mitigated:confirmed --status Accepted:closed). New records start as names the first (--default-status). The records in a waiting status are the Waiting queue, in the Records activity and witheidos records --waiting. -
Sign-off (
--sign-off): confirming a record notes who confirmed it and when, asconfirmedandconfirmed_bybeside its status; leaving the confirmed category clears both. Only a person signs off. An agent proposes and leaves the record waiting, and confirms one only--asthe person who settled it in the conversation. -
List on documents (
--listed, file-based types): each blueprint a record serves shows the type’s records in a list, kept current in arecords:listregion the plugin writes, where the blueprint’s template puts it, or else under a heading named for the type at the foot of the body:<!-- records:list type=risk -->- [ ] [RSK-F36 The index drifts from the files](../risk/rsk-f36-the-index-drifts-from-the-files.md) · Open · @claude<!-- /records:list -->The plugin writes it after every change; never type into it.
-
Link to tasks (
--tasks, file-based types): a record names the tasks that carry it out (--task <id>), and each task’s page shows the records that name it. -
Numbering (file-based types): In order (
--numbering sequential, the default) labels records 1 to n and renumbers after a removal. Unique ids (--numbering ids) draws an id for each record as tasks draw theirs, with the letters you choose before the hyphen (--id-prefix RSKgivesRSK-F36). An id is never renumbered, and a changed one (eidos records set RSK-F36 --id RSK-DRIFT) keeps the old one as an alias that still finds it. Choose ids when several people add records on different branches, where two next numbers would collide on merge.
eidos records configure:type add risk --mode file --numbering ids --id-prefix RSK \ --status Open:waiting --status Mitigated:confirmed --status Accepted:closed \ --sign-off --listed --tasksKeeping decisions
Section titled “Keeping decisions”A decision log is the plainest use of everything above: a file-based record type with a lifecycle, one file per decision, waiting until a person confirms it, listed on the blueprints it was made for, and linked to the tasks it concerns.
eidos records configure:type add decision --mode file --numbering ids --id-prefix D \ --status Proposed:waiting --status Confirmed:confirmed --status Rejected:closed --status Superseded:closed \ --sign-off --listed --taskseidos records add B-SHS2 decision "Cache the index in memory" --task T-4KQ7 --notes "Why, and what else was weighed" --as claudeeidos records confirm D-7M2P --as grace--notes writes the record’s body: why, what else was weighed, what it rules out. An agent logs a decision it made on its own as itself and leaves it waiting for a person.
On disk
Section titled “On disk”.eidos/plugins/records/settings.yaml, shared:types, each withname,title,label,mode,sidebar,folderfor a file-based type, andfields(each aname,type,options, andrequired), plusstatuses,default_status,sign_off,listed,tasks,numbering, andid_prefixwhere the type uses them. The settings page andconfigure:typewrite it; never edit it by hand.- A file-based type’s folder at the root, declared
owned_by: "@records/<type>": one markdown file per record. The root → - Inline records live in the blueprints themselves, as your own list items. A
records:listregion in a blueprint is the plugin’s.
From the shell
Section titled “From the shell”eidos records # every record, by type; --type, --blueprint, --where field=value, --search, --waiting, --task, --jsoneidos records types # the types: labels, fields, mode, and counteidos records show B-SHS2/AC6 # one record; <path>#<label>, or a file-based record by its labeleidos records add B-SHS2 criterion "A root with no collections checks clean." --field status=meteidos records add B-SHS2 risk "The index drifts from the files" --task T-4KQ7 --as claude # a file-based record serving the blueprinteidos records set RSK-F36 --status Mitigated --as grace # --field name=value, --for, --task, --id; into a confirmed status signs it offeidos records confirm RSK-F36 --as grace # to the type's first confirmed status; a person signs offeidos records label B-SHS2 --section "Acceptance criteria" --type criterion --dry-run # the labels it would add; no word changeseidos records unlabel B-SHS2/AC6 # a plain list item again; the labels after it renumbered, links followingeidos records remove B-SHS2/AC6 # the record taken out; the labels after it renumbered, links followingeidos records renumber --dry-run # labels back in sequence, in one blueprint or every oneeidos records project # write every records:list region that drifted again; or one blueprinteidos records configure:type set criterion --no-sidebar # add|set|remove; --dry-run, --jsonEvery command takes --json. A write is signed with --as <alias>, else EIDOS_USER, else the acting user.
An agent adds a record with eidos records add, takes one out with eidos records remove, and never numbers labels by hand: the plugin keeps them in sequence and the links to them current. It writes the record’s sentence as the owner’s words, keeps a field line for values, and labels an existing list only when asked.
What the check reports
Section titled “What the check reports”All warnings: records/label-gap (labels out of sequence, a slotted label, or a label held twice; Renumber fixes it, as eidos records renumber does), records/label-duplicate (a label held twice in a blueprint, or by two files of a type), records/field-required (a required field left empty), records/field-option (a Choice field’s value outside its choices), records/field-type (a Number or Yes or no field holding something else), records/reference-missing (a link whose label its blueprint does not hold), records/type-unknown (a template section marked for a type the root does not declare), records/blueprint-missing (a file-based record serving a blueprint the root does not have), records/task-missing (a record naming a task the backlog does not have), and records/list-stale (a records:list region no longer what its records say; its fix writes it again). Off again, nothing in a blueprint changes and nothing of the plugin runs.