26 Every finding code
Crystalline has two checkers, and this chapter lists every code either of them can put in front of you: what it means and what clears it. Come here when a code turns up in a verify report, a CI annotation or the maintenance queue and you want to know what it wants from you. The story behind the sweep and how the agent works its queue are in the chapter on evolving (Chapter 10); this one is just the lookup.
26.1 Two checkers
Verify asks whether the format holds. It reads files and needs no daemon, and its codes carry a letter for what they check: E for format, T for temporal metadata, L for links, Q for content quality, S for schemas and M for the MANIFEST. Each finding has a severity: error, warning or info (the report tags them E, W and I). The sweep asks whether the knowledge is still true and well organized. Its codes all start with V, and instead of a severity each finding carries a family, a priority and a class.
Verify codes show up in more than one place, and not every place runs every family:
| Where you see it | Codes | Domain overrides |
|---|---|---|
crystalline verify |
E, T, L, Q, S, M | yes, plus --strict |
validate_engrams |
S020 to S033, T, E011, M108 | file domains |
| Fluid’s editor | E001 to E008, E010, E011, T except T006, Q006 to Q008 | file domains |
| MANIFEST edit receipt | M except M001, M105 and the team repository rules | file domains |
Write receipts (markdown_findings) |
Q006 to Q008 | every domain (Q008 on engrams only) |
crystalline verify scans folders, so a virtual domain is checked through validate_engrams, or with verify after an export (Chapter 25). That tool reports a schema finding under a name, not its number (the schema section below gives both). In Fluid’s editor the check runs whenever you pause typing, and a hard error holds the save back until you fix it. The sweep’s codes show in crystalline evolve, the evolve_engrams tool and Fluid’s maintenance page, all three reading the same queue.
26.2 Format: the E codes
An engram has to parse and carry a title, a permalink, a type and tags; the E codes tell you which part doesn’t hold.
E001frontmatter doesn’t parse-
The YAML between the
---lines is invalid or isn’t a mapping of keys to values (error); a repeated key on its own is E010. Fix the YAML first, because no other rule looks at a file that doesn’t parse. E002title or permalink missing-
The engram lacks a
titleor apermalink(error); add the one that’s missing. E003type missing or unusual-
Leaving out
typeis an error. A type outside the recommended set (manifest, schema, engram, guide, decision, architecture, runbook and reference) is only info and needs nothing, since Crystalline never enforces a closed list. E004no tags-
The engram has no
tags, or the list is empty (error). Add at least one, reusing whatvocabularyshows is already in use. E005permalink isn’t a slug- The permalink holds capitals, spaces or other characters a lowercase slug path doesn’t (error). Use the slug the report’s fix line suggests.
E006not plain UTF-8- The file starts with a UTF-8 byte order mark, contains a null byte or isn’t valid UTF-8 at all (error). Save it again as plain UTF-8.
E007tag spelled oddly-
A tag isn’t lowercase-with-hyphens (warning).
crystalline tags renamechanges it on every engram that carries it. E008permalink starts with the domain’s name- A permalink is relative to its domain and the domain’s name is each person’s own configuration, so a prefix that repeats it breaks under any other name (warning). Drop the prefix as the fix line shows; a real subfolder of the same name doesn’t count.
E009paths differ only in case- Two paths in the domain differ only in upper and lower case (error). A checkout on macOS or Windows holds only one of them and loses the other without a word, so rename one.
E010frontmatter key repeated-
One frontmatter key appears more than once and the file would parse without the later copies (error). Keep one line with the right value and delete the rest. When every repeated key in the file holds the same value,
crystalline doctor --fixremoves the extra copies. E011frontmatter too large for the index-
A frontmatter key is over 256 bytes, or a value (each element, for a list) is over 1024 bytes, so the metadata index skips it and a search’s list filter (
$contains) never finds it (warning). Shorten the key or the value, and keep long text in the body.
26.3 Temporal metadata: the T codes
These check the lifecycle and provenance fields; a malformed date here (T003) is one the sweep’s V rules can’t read.
T001status or recorded date missing-
The engram has no
statusor norecorded_at(error); add whichever is missing. T002unusual status- The status is outside the recommended set: stable, current, implemented, draft, proposed, idea, poc, deprecated, superseded, archived and legacy (info). Status is free form, so there’s nothing you have to change.
T003malformed date or provenance-
A date field (
recorded_at,valid_from,valid_to,source_date,stale_afteror the olderlast_verifiedandreview_after) isn’t a plainYYYY-MM-DD, atimestampisn’t RFC 3339,generatedisn’t a mapping with aby, orverifiedisn’t a{ by, at }entry or a list of them (error). Write the value in that shape. T004window inverted-
valid_fromlies aftervalid_to(error). Correct whichever date is wrong. T005superseded without a successor field-
The status says superseded and no
superseded_byrelation is present (warning). Add- superseded_by [[Successor]], or pick the retirement status that fits when nothing replaced it (Chapter 10). The sweep’s V004 also catches a relation that doesn’t resolve. T006no write provenance-
The engram carries no
generatedblock and no oldertimestamp(warning). Every write and edit through Crystalline stamps one, so a file written by hand clears on its first edit through the agent or Fluid. T007unknown temporal confidence-
temporal_confidenceis set to something other thanexplicitorinferred(warning); pick one of those two. T008placeholder end date-
valid_tolies in the year 9000 or later, a stand-in for “forever” (warning). Remove the field; with no end date the window stays open, and that’s how an engram says it holds indefinitely.
26.4 Links: the L codes
These check that every link and relation reaches something, within the domains the run scanned.
L001broken link-
A
[[wikilink]]or relation target resolves to nothing, in this domain or in another domain the same run scanned (warning). When a bare link’s target lives in another domain of the run, the message names that domain and the prefixed link to write. Fix the spelling, add the prefix or capture the engram the link expects. L002permalink used twice- Two files share one permalink, so one address names two engrams (error); change one of them.
L003title used twice-
Two files share one title, so a
[[Title]]link can’t tell them apart (warning); retitle one or merge them. L004self-link- An engram links or relates to itself (warning); remove the link.
L005broken crystalline:// address-
A
crystalline://address in the body names an engram that doesn’t exist in a domain the run scanned (warning). Correct the address or remove it. Addresses inside code fences and backticks are skipped. L006link leaves the run- A link names a domain this run didn’t scan, so verify can’t check it (info). Pass that domain’s root to the same run when you want it checked.
L007link to a file the domain doesn’t have- A relative link or image whose target isn’t a note names a file the domain doesn’t have, such as an attachment an import left behind (warning). A link to a note is L001’s. Add the file, or fix or remove the link.
26.5 Content quality: the Q codes
These look at the body: whether there is one, whether it fits, whether its bullets parse and whether its Markdown elements are ones Fluid knows.
Q001almost no content- The body has fewer than three non-blank lines outside code fences (error). Write the knowledge down, fold it into the engram that owns the topic or delete the file.
Q002over the size budget-
The body is over its token budget, counted roughly as characters divided by four: 2,500 by default and four times that for a
type: sourceengram (error). Split it; the sweep’s V105 says which split fits, and the budget can be tuned per domain (see “Silencing and tuning” below). Q003duplicate heading- Two headings at the same level carry the same text (warning). Rename one or merge the two sections.
Q004near-duplicate sections-
Two
##sections of one engram carry nearly the same text, usually a paste nobody finished (warning); fold them into one. Q005near-miss bullet-
A bullet almost matches the observation or relation grammar:
-[category]without the space, an unclosed[categoryor an unclosed[[Target(info). Fix the typo, or the line never becomes an observation or a relation. Q006unknown status colour-
A status label names a colour outside grey, blue, green, yellow, red and purple, as in
:status[Done]{orange}(warning). It renders grey; pick one of the six. Q007unknown callout kind-
A callout names a kind Fluid doesn’t know, as in
> [!DANGER](warning). It renders as a plain quote; use NOTE, TIP, IMPORTANT, WARNING, CAUTION or DETAILS. Q008observation inside a quote-
An observation or a relation sits inside a callout or any other
>quote, where it isn’t indexed (info). Move it out to a top-level bullet. Only engrams get this one.
26.6 Schemas: the S codes
You’ll only meet these in a domain with schema engrams (the reference on the engram describes their format, Chapter 24). S001 to S004 are errors on the schema engram itself and S010 is a warning. S020 to S033 check an engram against its schema, and their severity comes from the schema’s settings.validation: warn makes them warnings, strict makes them errors and off silences them. In validate_engrams they carry the name in parentheses instead of the number.
S001schema without an entity-
The schema engram has no
entity(error); add the type it governs. S002schema without declarations-
There’s nothing under
schema:(error), so declare the fields there. S003malformed declaration-
A field declaration has an empty name, a modifier other than
array,enumorobject, an enum that isn’t a non-empty list, an object that isn’t a mapping, an unclosed parenthesis or a type other thanstring,integer,number,boolean,anyor a capitalized entity name (error). Correct the declaration, in the body or undersettings.frontmatter. S004unknown validation mode-
settings.validationisn’twarn,strictoroff(error); use one of the three. S010schema reference matches nothing-
An engram’s
schema:key names an entity no schema engram in the domain declares (warning); fix the name or write the schema. S020required relation missing (MissingRequiredRelation)- The engram lacks a relation its schema requires; add it.
S021required observation missing (MissingRequiredObservation)- The engram lacks an observation category its schema requires; add one.
S022observation value outside its list (ObservationEnumViolation)- An observation holds a value the schema’s enum doesn’t allow; use an allowed one or extend the enum.
S023observation value of the wrong type (ObservationTypeMismatch)- An observation’s value doesn’t match the scalar type its schema declares; correct the value.
S030required frontmatter field missing (MissingRequiredFrontmatter)- The engram lacks a frontmatter key its schema requires; add it.
S031frontmatter value outside its list (FrontmatterEnumViolation)- A frontmatter value isn’t one the schema’s enum allows; use an allowed one.
S032frontmatter field isn’t a list (FrontmatterNotArray)- The schema declares the key as an array and the engram holds a single value; write it as a list.
S033frontmatter value of the wrong type (FrontmatterTypeMismatch)- A frontmatter value, or an item in a list, doesn’t match the declared scalar type; correct it.
26.7 The MANIFEST: the M codes
The MANIFEST is configuration as well as an engram: its When to Use bullets route every session to the domain (Chapter 24). M001 to M013 are errors and M101 to M109 warnings. M011, M012 and M109 are the team repository rules: they run only with crystalline verify --team-repository, the check for the repository of a team domain (Verify in CI below). You can put the same structural checks on any other file of a domain through the verify file described below.
M001MANIFEST missing-
The domain root has no
MANIFEST.md, or a file the domain requires is missing. Create it; a MANIFEST carriestype: manifest. M002wrong type-
The MANIFEST’s type isn’t
manifest, or a required file lacks the frontmatter the domain asks for. Correct the type or add the frontmatter. M003required section missing-
## Scopeor## When to Useis absent, or a section the domain requires of another file; add it. M004section without bullets-
Scope or When to Use has no top-level bullets (a
-at the start of the line), or a configured section has fewer than its minimum; write the bullets. M005invalid provisioning path-
A Provisioning path is absolute, home-relative, a bare
.or contains a component that isn’t allowed, and nothing is provisioned from it. Give a relative path to the folder. M006unknowngenerated_indexesvalue-
The key says neither
localnorshared. It’s read aslocal, so the folder listings stay on your machine; fix the spelling. M007unknownsharingvalue-
The key says neither
proposalnordirect. It’s read asproposal, so shares still go through review; fix the spelling. M008invaliddomain_name- The declared name isn’t text at all (a number or a list, say), or it’s text that breaks the naming rule (Chapter 25). Crystalline ignores it and the domain keeps the name it has, so this code and the receipt of an edit are the only places that tell you; write a valid name.
M009unknownread_onlyvalue-
The key says neither
onnoroff. It’s read asoff, so the domain stays open to writes; fix the spelling. M010unknownteamvalue-
The key says something other than
github. It’s read as absent, so this copy isn’t treated as a team domain and nothing keeps its Reflection at the team server. Writeteam: github, or remove the line and let the next share from an instance connected to the domain add it. M011Reflection on without a home-
In a team repository the MANIFEST says
reflection: onand has no validreflection_home, so any clone could keep its own Reflection and push its pages and threads to the shared branch. Setreflectionback tooff, or switch Reflection on at the team server, which fills in the home. M012Reflection files in a team repository-
While Reflection is on, the shared branch holds files under
reflections/, in any letter case, and one finding lists them. The Reflection lives at the team server and is backed up tocrystalline/reflections, never to the shared branch, because its pages and threads can hold comments from people who may not read the engrams. Remove the files from the branch and switch Reflection on at the team server instead. M013invalidevolve_home- The key isn’t a server address. It’s read as absent, so every clone of the team domain may run a scheduled evolve. Remove the line, and the next scheduled evolve run at the team server fills it in.
M101When to Use empty- When to Use has no bullets and routing falls back to Scope. It comes along with M003 or M004 and says what sessions do in the meantime. Writing the bullets clears all of them. In a required file it means a configured fallback section stood in.
M102bullet too long-
A bullet in any
##section runs over 180 characters, or over a required file’s configured maximum; shorten it or split it into two. M103duplicate section heading-
The same
##heading appears twice and the reader keeps only the first; merge the two sections. M104unknown provisioning type-
A Provisioning bullet names a type other than
skills,commands,agentsormcps, so pick one of those. M105provisioned folder missing- A folder the Provisioning section declares inside the domain doesn’t exist; create it or correct the path. Folders outside the domain root aren’t checked.
M106malformed provisioning bullet-
A Provisioning bullet has no colon or no path, or declares a type twice. Write one
- type: pathline per type. M107tag alias problem-
A Tag Aliases bullet lacks the
old -> canonicalshape, maps a tag to itself, maps an alias a second time (the first wins), points at a target that isn’t lowercase-with-hyphens or points at another alias. Correct the bullet; an alias resolves in one hop. M108verify settings problem-
The domain’s
.crystalline.yamlholds a severity word verify doesn’t know (E007: of), or the file doesn’t parse at all, so the override you meant isn’t there. It’s reported against.crystalline.yamlincrystalline verifyand invalidate_engrams. Fix the word or the YAML; the rule keeps its default until you do. M109team marker missing-
In a team repository the MANIFEST has no
team: github, or spells it another way, so nothing stops a plain clone from switching Reflection on. Share once from an instance connected to the domain, and the share adds the line.
26.8 Reading a V code
Every sweep finding carries a family, a priority and a class. The number beside each code here is the rule’s starting priority, what an unremarkable engram shows in brackets. The queue adds up to ten for salience, five for an engram three or more others link to and eight for one a person wrote, capped at 100, and min_priority (--min-priority in a terminal) drops what scores under a floor. The mechanical rules, which the agent completes without asking, are V005, V103, V110 and V102 when the nearest title is a near-exact match in the domain the link named. The rest are judgment, which the agent brings to you one at a time. Engrams with the status draft, proposed, idea or poc are exempt from V002, V003 and V006, and retired engrams are never called old, unverified or unlinked.
26.9 Sweep, temporal: V001 to V010
The temporal family watches dates and the retirement lifecycle, plus attachments and unshared work that have waited too long.
V001expired window still current (85)-
The
valid_todate is in the past and the status still says current. If the fact still holds, extend or removevalid_to; if it ended, retire the engram and wire the supersede pair when something replaced it. V002review date passed (70)-
The
stale_afterdate has passed and nobody has verified the engram since. Re-check the claim: record averifiedentry and a laterstale_afterwhen it holds, correct or supersede it when it doesn’t. V003old and never verified (25)-
A current engram is over 180 days old with no verification and no
stale_after. Confirm it and record averifiedentry, or set astale_afterso a later sweep has a real date to compare. V004superseded without a successor (65)-
The status says superseded and no
superseded_byrelation resolves. Name the successor, or switch to deprecated, archived or legacy when nothing replaced it. V005replaced but still current (90, mechanical)-
Another engram declares that it supersedes this one, and this one still reads current. Set the status to superseded, add
superseded_byand setvalid_towhen the end date is known. V006human capture never reviewed (50)-
A person captured this directly (its
generated.bystarts withhuman:) on an earlier day and nobody has recorded a verification. Verify the claim, align the tags, wire the relations both ways and record averifiedentry. A person’s capture is teaching, so any change to the wording is proposed to its author first (Chapter 7). V007attachment never analyzed (50)-
An engram shows an attachment and no engram claims it with
analyzes. Read the attachment, capture what it teaches, and setanalyzesandanalyzed_hashon the engram that covers it. V008attachment changed since analysis (60)-
The attachment’s current hash no longer matches the engram’s
analyzed_hash. Re-read it, bring the engram in line, updateanalyzed_hashand record averifiedentry. V009unshared work aging (40)- A team domain holds substantive local changes that have waited a week or more to be shared. The finding is about the domain rather than an engram, and regenerated folder listings never count. Share the changes after a yes (Chapter 17).
V010carry-forward gap (55)-
A retired engram holds observations that appear in no live engram of its domain. Move the ones that still hold into their own engram with
split_engram, or acknowledge the finding when they expired too. Matching is by text, so a fact carried forward in other words takes an acknowledgment as well. A retired engram that already declaressplit_intostays quiet.
26.10 Sweep, structure: V101 to V112
The structure family watches the graph: links, relation pairs, size and where files and attachments sit.
V101live link to retired knowledge (55)- A current engram links to a retired one. Repoint the link at the successor the evidence names, or keep it as a historical citation and acknowledge the finding.
V102unresolved link (50, mechanical or judgment)- A link or relation points at nothing. Fix the spelling (the fix line names the nearest title), add a domain prefix or capture the engram the link expects; the target is never created automatically.
V103one-sided relation pair (35, mechanical)-
One half of
supersedes/superseded_by,summarizes/summarized_byorderived_from/split_intois missing on the engram the finding names. Append the inverse there, as the fix line spells it out. V104orphan (30)- Nothing links to the engram and it links to nothing, 14 days after it was recorded. The rule runs only in a domain where at least a quarter of the engrams are linked, and it skips the MANIFEST and schemas. Link it into the neighbourhood its tags suggest, or acknowledge that it stands alone on purpose.
V105oversized (60)-
The body is over its token budget, the same size verify’s Q002 flags. The fix line picks the split: a distilled summary with the full text moved to a
type: sourceengram undersources/, sequential parts when the engram is already a source or a split by topic when the observations alone are over. V106stub (45)- The body has fewer than three content lines, the shape verify’s Q001 flags. Enrich it, fold it into the engram that owns the topic or retire it.
V107attachment reference to nothing (45)- The engram references an attachment path that holds no file. Restore the file (a Fluid upload or an archive import) or correct the reference, after asking, since either changes what the agent reads.
V108orphaned attachment (55)-
A file under
assets/is referenced or claimed by no engram. Delete it (delete_engramwith theassets/path, or Fluid’s Delete attachment button), or analyze it into an engram that claims it first. Deleting can’t be undone, so the agent asks. V109permalink off its folder (45)-
The permalink names a different folder than the one the file sits in, usually after a move made by hand, so a
build_contextglob on the folder misses it. Files at the domain root never raise it. Repair it withmove_engram, passing the file’s current path as destination andpathas permalink, which rewrites every reference; ask first, since the new address breaks bookmarks outside Crystalline. A deliberate custom permalink is acknowledged instead, which holds until the permalink or the path changes. V110domain named by a local-only name (40, mechanical)-
A
[[domain:Title]]link names a domain by a name only this machine uses, a local name that differs from the declared one or a former name, so it reaches nothing on a colleague’s machine. The fix line gives the exactedit_engramfind-and-replace that swaps in the declared name, andcrystalline doctor --fixrewrites the same links in one go. An acknowledgment covers one spelling, so a second local-only name on the same engram is its own finding. V111ingested without a resource (40)-
An ingestion record links to the engram, or the engram declares
ingested_from, and the engram carries noresource, so an answer from it can’t say where the knowledge came from. Setresourceto the page or file it was distilled from (for a git source, the file at the ingested commit) andsource_datewhere the source has one. A guessed location is a false citation, so the agent asks first; acknowledge the finding when no single location fits. Records, manifests, schemas and retired engrams never raise it. V112sibling folders with close names (40)-
Two folders side by side carry names that read as one topic: equal apart from case,
_and-(plan_view,plan-view), one name plus more words (planview,planview-work) or one or two letters apart (note,notes). A shared start alone (project,projection) and names that differ only in digits (week-01,week-02) aren’t close. Abuild_contextglob on either folder misses half the topic. Read both; when they hold one topic, move the engrams of the smaller folder into the other withmove_engram, and when the topics differ, acknowledge the finding. There’s one finding per pair. The acknowledgment can sit on any engram of the two folders and holds until one of them is renamed, andremove V112takes it back from every engram of the two folders you can write, naming any it had to leave.
26.11 Sweep, redundancy: V201 to V203
The redundancy family watches for knowledge written down twice, in the text, the titles or the tags.
V201near-duplicate content (80)- Several engrams carry nearly the same text. Merge into the richest one, then supersede or delete the others after repointing every inbound link. Detection compares wording, so a paraphrase can only show up as V301.
V202near-duplicate titles (55)- Two engrams in one domain carry titles so close that links and search can’t tell them apart. Merge them or retitle one.
V203tag drift (30)-
One concept is spelled several ways in the domain’s tags, a finding about the domain rather than an engram. Run the
crystalline tags mergecommand the fix line spells out; the agent hands it to you rather than rewriting tags itself.
26.12 Sweep, meaning: V301 and V302
The meaning family reads what two engrams say rather than how they say it. Both of its rules are judgment, and an acknowledgment answers for one pair, so an engram in two pairs keeps a separate entry for each.
V301semantic twins (75)- Two current engrams say close to the same thing in different words, measured by their embeddings, so the rule runs only where the instance computes them. If one owns the topic, merge into it and supersede the other; if they disagree on a fact, reconcile them; if they are distinct, link them and acknowledge the pair. A pair already in a V201 cluster shows only there.
V302possible contradiction (85)-
A local model read an observation line of one engram and one of another as contradicting each other. The rule runs only with
evolve.contradictionsset tofull(Chapter 23), and it is a question, never a verdict: the model can be wrong and can’t see dates. Read both engrams, then supersede the one that is false going forward or correct its stale line; when both held at different times, the newer one supersedes the older, whosevalid_tois set to the real date; or acknowledge the finding. There is one finding per pair of engrams, and an acknowledgment holds for exactly those two lines, so a new disagreement between the same engrams still shows. Engrams with the status draft, proposed, idea or poc, retired ones and ones past theirvalid_toare never scored.
26.13 Silencing and tuning
A sweep finding is silenced where it stands, in the engram, and a verify code is tuned for a whole domain in a file at its root. Neither mechanism reaches the other’s codes.
26.13.1 Acknowledging a sweep finding
An acknowledgment is a note that a person looked at a finding and ruled it intentional. It lives in the engram’s evolve_ack frontmatter, names the V code with an optional note and holds while the evidence it was given for holds; when the evidence changes, the finding comes back marked stale. The agent writes it with edit_engram and set_frontmatter on evolve_ack, the value being the code and the note (V109 kept for the wiki's links), and takes it back with remove V109. On Fluid’s maintenance page anyone with write access gets an Acknowledge button with a note field on each row about an engram, Re-acknowledge once its evidence has moved and Unacknowledge on one already silenced. V009, V108 and V203 name no engram, so there is nowhere to put an acknowledgment and doing the work is the only way to clear them. How an acknowledgment differs from a verification is part of the evolving story (Chapter 10).
26.13.2 The domain’s verify file
A .crystalline.yaml at a domain’s root can carry a verify block, which tunes the checker for that one domain and leaves every other domain alone. The workspace file of the same name is a different one (Chapter 25):
verify:
rules:
E007: "off"
L003: info
M102: error
token_budget: 3000
token_budgets:
reference/api-catalogue.md: 8000
changelog.md: 0
required_files:
- path: GLOSSARY.md
require_frontmatter: true
required_sections: [Terms]
sections:
Terms:
min_top_level_bullets: 5
max_bullet_length: 240rules sets a code’s severity to off, error, warning or info (e, warn, w and i work too). An override wins over --strict, so a rule you set to warning stays a warning in a strict run. An unknown word keeps the rule’s default and a file that doesn’t parse is ignored whole, and each raises M108: a warning that fails a run only under --strict. The rule a typo was meant for still takes --strict like any other. The overrides apply everywhere a verify code shows: crystalline verify, validate_engrams, Fluid’s editor and MANIFEST edit receipts. In a team repository run the domain’s own settings can’t lower M010, M011, M012 or M109, so a pull request can’t switch off the check that guards it, and --strict still promotes M109.
token_budget sets the budget for every file of the domain and token_budgets for single files, keyed by their path from the domain root. A budget of 0 turns Q002 and V105 off for that file, and a type: source engram still gets four times whatever applies. The budget is the one part of the file the sweep reads.
required_files puts the MANIFEST’s structural checks on other files. A missing file raises M001, missing frontmatter M002 when require_frontmatter is set and a missing section M003. A section under its min_top_level_bullets raises M004, or M101 when its fallback_section has enough; a bullet over max_bullet_length (180 by default) raises M102, and a doubled ## heading M103.
An agent changes rules and token_budget with configure and the domain (Chapter 23), which writes the file without its comments; token_budgets and required_files stay hand edits.
With crystalline verify --config you load one such file for every domain in the run, in place of each domain’s own. A --config file that doesn’t load stops the run with a message and exit code 1.
26.13.3 MANIFEST edits answer at once
An edit of a MANIFEST, or a write that replaces one open in Fluid’s editor, returns its M findings on the receipt, as manifest_findings with code, severity, message and line, and an error among them comes with the guidance that routing for the domain is broken. The edit lands anyway, and the findings come at the severities the domain’s verify block sets (a virtual domain has none and gets the defaults), so the agent that just emptied When to Use can fix it in its next call. M001 is never on the receipt because the file exists. M105 isn’t either: it needs a full verify to look at the folders.
26.14 Verify in CI
crystalline verify takes one or more domain roots and defaults to the current directory. It exits with 0 when no error was found, 1 when at least one was and 2 when a path doesn’t exist, isn’t a directory or can’t be read. Warnings never fail a run unless --strict promotes them. --format chooses human, json (a stable report, version 1) or github, which writes annotations: errors and warnings as such, info as notices that never fail the job. Verify belongs on every proposal a team reviews (Chapter 8), and the bundled action does it in one step:
- uses: jordiboehme/crystalline/action@v0.30.0
with:
paths: knowledge/engineering knowledge/payments
strict: 'false'
version: v0.30.0paths takes space-separated domain roots, strict promotes warnings, version pins the binary it downloads (latest by default) and comment (on by default) keeps one summary comment on the pull request up to date. The step’s exit-code output carries verify’s own exit code, and the step fails the job when it isn’t 0. In the repository of a team domain, set team-repository: 'true' to add the team repository rules (crystalline verify --team-repository), and run that job on the shared branch only, since crystalline/reflections holds the Reflection’s pages on purpose.
Verify’s E, T, L, Q, S and M codes say whether the files hold their format, and the sweep’s V codes say what the knowledge needs, in four families, each finding with a priority and a class. Each entry above names what the code means and the action that clears it. A sweep finding a person ruled intentional is acknowledged in the engram with evolve_ack or on Fluid’s maintenance page, except the three that name no engram. Verify codes are tuned per domain in the verify block of .crystalline.yaml: severities, token budgets and required files. In CI, crystalline verify exits 1 on any error and 2 on a bad path, and --strict makes warnings count.