Where the lookup material lives
This site is the narrative half. The reference half — commands, flags, file locations, conventions, decisions — lives in the repo's markdown, and that is where it stays. This page tells you what is over there and when you will want it, and carries the four things the markdown does not own.
How this site and the markdown divide the work
This site is narrative and human-facing: it exists to explain why the toolkit behaves the way it does. knowledge-base/README.md and its siblings are lookup-shaped and agent-facing, and they are the single source of truth for reference material. This page does not restate them; it says what is there and links to it. Two copies of one table drift — and drift is what rotted the thirty-three research briefs that were deleted rather than repaired.
Four blocks below have no owner in the markdown: the glossary (no glossary exists in
philosophy.md, architecture.md, patterns.md,
conventions.md or skill-reference.md), and three tables that are
short, enumerable, and consulted while you are debugging exactly one thing. Everything else
on this page is a pointer.
The markdown map
One row per file. The column that matters is the last one.
| File | What it is | When you want it |
|---|---|---|
| knowledge-base/README.md | The index, with a "where to start" table and the shape of the ten skills. | You know you need the markdown but not which file. |
| knowledge-base/philosophy.md | Why any of this exists: the mental model and the seven core concepts. | Before you decide whether to adopt it, or when a skill's behaviour looks arbitrary and you want the reasoning. This site deliberately does not restate the seven — its old five-item version was already a stale subset of them. |
| knowledge-base/reference/ARCHITECTURE.md | How the skills connect: bin/ and skills/, the data flow
through wrap-up, the tracking files, the output-artifact tree. |
You are tracing where a value came from, or which skill wrote a file you did not expect. |
| knowledge-base/patterns.md | Coordinator + workers, two-commit separation, incremental updates, certainty-score bands, resolution logs. | You are writing a skill and want the shape before the rules. |
| knowledge-base/reference/DEVELOPER.md | What makes a skill fit: frontmatter declarations, cross-references by installed name, artifact locations, dated-report idempotency, tracking-file naming. | Your skill works and you want it to stop looking foreign next to the other ten. |
| knowledge-base/reference/SKILL_REFERENCE.md | Every skill, every command, what it reads and what it writes. | You need the precise invocation rather than the idea behind it. spec-manager alone carries a sixteen-row command table, which is why this site does not try to mirror it. |
| knowledge-base/decisions/README.md | Thirty-one ADRs — what was decided, why, and what was rejected. | A question is about to be re-litigated. The navigable version is on this site's Decisions page; the records themselves are the authority. |
| knowledge-base/roadmap.md | The single live backlog: next initiative, deferred capabilities, verified open defects, platform-blocked items. | Anything is outstanding. Every item was re-verified against shipped code, and nothing outstanding lives anywhere else — including on this site. |
| knowledge-base/migrations/README.md | Runnable, idempotent recipes for adopting projects — knowledge-base/migrations/skill-rename.md and knowledge-base/migrations/knowledge-base.md. | You are moving a project across a release. Run them; don't read them. Re-running a recipe that is already applied is a no-op. |
| CONTRIBUTING.md | The conventions a contribution must preserve, and the contract of the CI gate. | Before you commit anything under skills/. The gate is separate from
the test suite: a shipped SKILL.md can violate most of the rules with the
whole suite green, because only the gate reads the tree that actually ships. |
| bin/commands.json | The seventeen registered freya commands, machine-readable. |
You need to know whether a command exists, or you are adding one. A test fails if
an entry points at a missing script, and another fails if a script with a
__main__ block is not registered. |
| bin/check_skill_conformance.py | Fourteen rules, R1–R14, each carrying its own failure message at the top of the file. Thirteen are portability; R14 is a secrets rule. | The gate failed and you want to know what R9 actually objects to. The messages are the documentation. |
| skills/freya-codebase-security-scan/SKILL.md | The scan's exit-code table and its finding statuses — eight in the prose report,
collapsed to three in findings.json. |
A scan returned nothing and you need to know whether that means clean. |
| skills/freya-spec-manager/SKILL.md | The behavior-record field schema — state, adapter,
locator, entry, related_code — and what
verify rejects. |
You are hand-writing or debugging a behavior's frontmatter. |
Glossary
Site-only: no glossary exists anywhere in the markdown. Each entry carries the distinction rather than the definition, because in every case the distinction is what people get wrong.
- Blast radius
- A file plus everything that transitively depends on it. What a change reaches, not what you edited.
- Internal edge
- An import that resolved to a real project file, rather than to an
external:,unresolved:oroutside:tag. Zero internal edges on a large repo means the resolver failed, not that the code is unwired. outside:<alias>/<path>- An import that resolved under a directory this project declared outside its own root, in
knowledge-base/settings.json. It resolved and is still not a node: the declaration buys resolution only — nothing under a declared root is scanned, walked or globbed and the declaration causes no file under one to be read, the whole reach being arealpath, oneis_file()and one cachedlistdirof the named file's own directory — and an untaught consumer joining the token onto any root gets a path that names nothing. Undeclared, nothing outside the root is reached — an..or absolute import comes backunresolved:, and a committed symlink resolving out of the project is refused and reported undersubstrate.escaping_linksrather than followed. Only the built-inhomegrownresolver emits this tag;graphifydoes not consult declarations, so on that backend a declared root reportscrossings: 0whether or not anything crossed it. - BEH-NNN
- A behavior record: one intended, observable fact about the system, numbered stably and never renumbered.
- Lifecycle state
proposed → confirmed → accepted, withquarantinedanddeprecatedoff to the side. Trust is the state; only accepted gates.- Adapter
- How a behavior reaches its test — a Gherkin scaffold, a native link to a test that already exists, or
manual. - Locator
- The address of that test:
path#scenario-slugorpath::node. The governance gate is keyed off this path and nothing else. - Entry
- The route or handler file an integration behavior drives. Its code-graph closure is the static coverage.
- Coverage fingerprint
- The set of files one test actually executed — the
TEST → CODEedge. Never asserted as precise. - Trust order
explicit > observed > static.explicitis reserved and not emitted today; every shipped edge is observed or static, with a confidence and a freshness commit. Higher trust wins on merge.- Coverage-unknown
- An edge the graph knew it should resolve and could not, kept with a reason instead of dropped — so "no dependencies" and "could not resolve" never look alike.
- Direction A / B
- A: a code change → the behaviors it affects (regression). B: a behavior → the code that implements it (planning).
- Generated projection
- A read-only view derived from one source of truth. Allowed. A hand-maintained second copy of the same facts is not.
- Certainty score
- 0–100 on an inferred spec. A review heuristic for prose, not the trust signal for executable behavior — that is the lifecycle state.
spec_ref/behavior_ref- Both mark a security finding intentional. A
spec_refnames a spec that says so in prose; abehavior_refnames anacceptedbehavior whose locator resolves to a file in the project and whose exercised path carriessource: observed— a recorded run, never an edge inferred from the import graph. The second is the stronger of the two and the difference is not cosmetic — but plain--coveringruns no test, so without--verifyit is a claim that a test passed once, at the commitfreshnessnames, checked for shape rather than re-checked for truth.--covering --verifyre-runs the linked test and is how the security scan calls it. Either way the query returns anevidencestring saying exactly what it trusted, and the scan is required to copy that string into the report verbatim. - INTENT-NNN
- A declared-intent record — behaviors touched, rationale, approver. The only legitimate reason to change an accepted behavior's test.
- ADR
- A cross-cutting architecture decision in
decisions/. It records the decision, not the implementation. - Principle
- A project-wide rule in
principles.md— the constitution. - Authority order
- principle > ADR > spec, and shipped code beats all three. Where the code and an ADR disagree, the ADR gets a dated correction rather than a rewrite.
- Resolution log
- An append-only JSONL recording how a resolve-to-proceed finding was settled, so it is not re-litigated on the next run.
- Resolve-to-proceed
- A model judgment must be fixed, refuted, amended or reconciled before wrap-up completes. "Ignore and push" is not a resolution.
- Two-commit pattern
- Code changes in one commit, generated artifacts in a second. Clean history, stable references.
- The store
- The git checkout the skills are symlinked from. There is no second installed copy, so
freya updatefast-forwards the files you were editing. - The launcher
bin/freya. It works out where the suite lives from its own location on disk and runs the target with the interpreter already running — so noSKILL.mdnames a path or a Python.- Conformance rule
- One of R1–R14, checked over the shipped skill layer. A
SKILL.mdcan break most of them with the entire test suite green. R1–R13 are portability; R14 requires a skill that sends a worker at secret-bearing material to state the redaction rule, and to restate it in the slot where source gets copied. - Driver-owned fan-out
- Parallel work scheduled by a Python worker pool instead of requested of the agent in prose. Whether the fan-out happened is then a fact, not a claim.
- Validate-on-hit
- wrap-up surfacing the proposed and confirmed behaviors a change touched, plus touched code no behavior covers. Advisory, and skippable in one action.
- Cold tail
- The behaviors no change ever touches, so validate-on-hit never surfaces them.
freya statusworklists grind them down one at a time; without that, an inferred corpus never drains. - Never-synced guard
- wrap-up's refusal to let an incremental
updatequietly full-generate on a project that was never synced in the first place.
Three tables that live here
Exactly three. Each is short, enumerable, and consulted while debugging one specific
thing. Only the lifecycle table has no enumerable owner in the markdown; the other two
reprint a list a shipped SKILL.md owns, and are kept in that shape because a
truth table is what you want when a run has just stopped on you. Where a table here and its
owner disagree, the markdown is the authority.
Behavior lifecycle
| State | In behavior.json? |
Run? | Gates? | Staged in |
|---|---|---|---|---|
| proposed | no — specs only | no | no | artifacts commit |
| confirmed | yes, advisory — static coverage if it declares an entry | no | no | artifacts commit |
| accepted | yes | yes | yes, on failure | code commit |
| quarantined | no — specs only | no | no | — |
| deprecated | no — specs only | no | no | — |
The interactive explorer on How it works walks the same five states. This table exists so the widget is never the only route to the answer.
Coverage-unknown reasons
| Reason | What it means for you |
|---|---|
toolchain-missing: <program> | The runner could not start the test at all — no pytest in this interpreter, or no pnpm on PATH. Not a red test, so it preserves what was already known. Install the toolchain and re-run; nothing is claimed about the code in the meantime. |
locator-selected-nothing | The locator addressed no test — usually a renamed test method. Resolving locators is verify-links' job, so this is a stale link rather than a result. |
level-deferred | The behavior's level or adapter is not implemented yet. Not a failure. |
test-failed | The test ran and was red. The only reason that invalidates a prior edge — every other reason leaves what was already known standing. |
no-coverage | The test passed but produced no coverage file. The reporter is misconfigured. |
no-entry | An integration or confirmed behavior declares no entry, so there is nothing to take a static closure of. |
entry-missing | The declared entry file does not exist on disk. Usually a moved route. |
no-graph | No built code-graph cache. Run a graph build; this one is fixed in a single command. |
not-run | Projected into the graph, but the runner emitted nothing for it. |
- skills/freya-behavior-runner/SKILL.md — owns the
reasonlist
When a test edit needs a declared-intent record
The G1 gate is keyed off an accepted behavior's locator changing since the
.intent-last-verified baseline commit — committed changes and uncommitted
working-tree edits both count — using the behavior's state as it stands in the working tree.
With no baseline marker the gate skips entirely.
| Locator change | Behavior accepted in the working tree? |
INTENT record required? |
|---|---|---|
| Modified | yes | required regardless of what the edit is — there is no cosmetic exemption |
| Deleted | yes | required — removing a live guarantee is an intent change |
| Added (a brand-new behavior) | yes | no — that is the normal accept flow, not a change to an existing guarantee |
| Pure rename, no content change | yes | no — moving a file is not changing the guarantee. A rename with edits counts as modified |
| Any change | no (proposed, confirmed, quarantined, deprecated) | no — only accepted guarantees are governed |
The gate is path-based, and that is a known blind spot: editing a shared test helper that is not itself a locator is not caught. Quarantining or deprecating a behavior in the same change as its test edit exits the gate legitimately, because the gate reads each behavior's state off disk and it is no longer accepted there.
- skills/freya-spec-manager/SKILL.md — its "Scope & rules" list owns these rows
The security scan's exit codes are agent-facing and owned by the skill, so they are not
reprinted here. The one thing worth memorising: an empty result with exit 0
means clean; an empty result with any other exit code means the scan did not run.
Where every artifact lands
Everything the toolkit generates goes under one knowledge-base/ root at the top
of the project. The path-by-path layout — every artifact, its owning skill, and whether it is
committed — is markdown-owned; the links below are the list. One line of it is worth stating
here, because it is the line that surprises people.
The parse cache is not version-controlled, and behavior.json
is. .graph/ writes its own .gitignore the first time it
is created, naming the regenerable files individually — graph.json,
graph.*.json, classifications.json, docs.json —
rather than a blanket *, so an adopting project never has to touch its root
.gitignore. It names them individually precisely because
behavior.json lives in the same directory and must be committed: its observed
coverage comes from running the test suite and cannot be rebuilt by re-reading source.
knowledge-base/settings.json, one level up, is committed too — it holds the
backend choice, any exclusion overrides, and any outside declarations, all of
which have to reach CI.
ADR-017
The full layout is in the repo, with every owner named and every line marked tracked or
ignored — an annotated tree in architecture.md, and a per-path table with an
In git? column in skill-reference.md.