← ArchkeelCONTENT HISTORY

Update to Archkeel

Snapshot Oct 24, 2026 · 13:37 UTC · version 1.0.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Archkeel and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Use when setting up or changing architecture rules, or checking architecture before submitting code, in a repository that uses Archkeel.",
  "included_files": [],
  "name": "archkeel",
  "skill_md_contents": "---\nname: archkeel\ndescription: Use when setting up or changing architecture rules, or checking architecture before submitting code, in a repository that uses Archkeel.\n---\n\n# Archkeel\n\nArchkeel is a deterministic architecture checker. It observes Python, TypeScript and Dart imports, evaluates a\ndeclared contract of components and rules against that observation, and distinguishes\nPASS, FAIL and UNKNOWN. Rules live in `architecture-contract.json` and its explicit nested\ncontracts; nothing is enforced by convention alone.\n\n## Onboarding (first time in this repository): a target, not a description\n\n`architecture-contract.json` is the target architecture — where the system should be, not\nwhere the code already is. `archkeel report` measures declared constraints, not the quality\nof the whole architecture. The architect owns the target and review scope; within that scope,\ninspect the physical structure at every depth, not just the top level. Support them with evidence\nfrom the repository and the architect's quality goals for this codebase (which components\nmust scale, stay easy to change, or are performance-critical). Read those goals from ADRs\nand architecture documents first; ask the architect only when a goal is unknown and would\nchange your recommendation. Every\nrecommendation and every rationale cites the goal it rests on. There is no contract field\nfor a quality goal: record it next to the rule it justifies, following the chosen decision\nmode below.\n\nFor requested first-time onboarding, inspect existing files, then run\n`archkeel init [--root DIR] [--source DIR] [--namespace NAME] [--force] [--json]` once.\nA read-only assessment uses existing contracts, reports and source; it does not authorize\ninitialization, contract edits, file moves or commits.\nPreserve existing contracts and their `inside` references. If onboarding files already exist,\ncontinue from them; do not use `--force` without explicit approval to replace those files.\n`init` detects the Python package (the only top-level one, or the one `pyproject.toml`'s\n`[project] name` names when a test package sits beside it; otherwise it exits 2 and asks for\n`--source` and `--namespace`), requires an existing Git repository with at least one\ncommit, and writes three files: `archkeel.toml`, `architecture-contract.json` (one component\nper top-level subpackage/module, plus `complete_assignment` and — only when no component\ncycle exists — `no_component_cycles`, and `interface_boundary` when it drafts public\ninterfaces; no dependency rule), and\n`docs/architecture/architecture.md` (component table, each component's modules and inner\nedges, and a Mermaid graph of observed edges).\nEvery rule `init` drafts carries `decided_by: \"agent\"` as a placeholder you must resolve, not\nan answer, and so does every component whose `public` list it drafted. It refuses to overwrite existing files without `--force`.\n\n`init` does not infer a foundation or decide where classes belong. Ask who owns a shared type\nfirst; foundation is not the default owner for domain enums or models. Record the architect's\nchoice with the existing `symbol_placement` rule: set `source` to the package, `class_kinds` to\nthe types it owns, and `exact_sources` to the chosen module (or `allowed_sources` to a package\nsubtree). Follow the ownership example in the target-first guide. Run `archkeel validate` after\nadding it; a misplaced matching class is a `rule.violated`.\n\nFor TypeScript, use `archkeel init --language typescript --source src --namespace app\n--tsconfig tsconfig.json`; for Dart, use `archkeel init --language dart --source lib\n--namespace app`. Repeat `--source` for multiple roots. A non-empty namespace initializer\nrequires explicit ownership via `exact_modules`; inspect it before recording the owner.\n`init` shows DRAFT while its completed scan remains PASS. Review measured\n`measurements.scalars.cycle_edges`: a cyclic component graph receives no drafted\n`no_component_cycles` rule. Cycles are an advisory, not an error diagnostic.\nIgnore `/test-artifacts/` in `.gitignore` for default report output, or choose `--output`.\nRestore missing configuration in existing setups or select `--config PATH`; use `init`\nonly for a new setup. Without Git history, run `git init` and create a commit first.\n\nFor example, after defining storage's responsibility and approving `storage -> domain`,\nadd this fragment to the existing `storage` component. Replace the example reason with\nthe decision owner's actual reason; keep its existing ownership and public interface fields.\n\n```json\n{\n  \"responsibilities\": [\"Persist and retrieve domain records.\"],\n  \"decided_by\": \"architect\",\n  \"requires\": [\n    {\n      \"component\": \"domain\",\n      \"rationale\": \"Storage persists domain records.\",\n      \"decided_by\": \"architect\"\n    }\n  ]\n}\n```\n\nAppend this rule to the existing `rules` list. An empty or absent `requires` list then\nforbids all outbound component pairs; it does not grant observed imports.\n\n```json\n{\n  \"id\": \"REQUIRES-COMPLETE\",\n  \"kind\": \"complete_requires\",\n  \"rationale\": \"Each source states its approved outbound dependencies.\",\n  \"provenance\": [\"docs/architecture/architecture.md\"],\n  \"decided_by\": \"architect\"\n}\n```\n\nReview drafted `public` entries and replace each structural rule's TODO with its own real\nreason and decision author. A non-empty namespace initializer needs explicit ownership via\n`exact_modules`; inspect it before adding that ownership. Rule kinds and selectors are in\nthe [rule catalog](https://github.com/rapiddweller/archkeel/blob/main/docs/rules.md).\n\nThen pick one of two modes. The architect chooses; do not choose for them.\n\n### Physical structure review (both modes)\n\nAfter `init`, and during architecture assessments, inspect every maintained source package\nin scope recursively down to leaf packages, whether or not it has an `inside` contract.\nThe generated inventory and a green contract are not evidence that this structure is good.\n\n- Count direct source modules and immediate subpackages at each level; exclude `__init__.py`\n  from this count, not from ownership, behavior or dependency review. Record excluded generated\n  or vendored trees.\n  More than seven direct children triggers a review, not an automatic split or a failing\n  rule. Five to seven understandable groups is a review heuristic, not a cognitive law.\n- Challenge mixed responsibilities, unclear names, oversized leaf modules, excessive\n  nesting, cycles and cross-package coupling even below that threshold. Trace entry points\n  and data flow before choosing boundaries; check who owns shared types and public interfaces.\n- Propose physical packages around cohesive responsibilities, not arbitrary groups of seven\n  or diagram-only clusters. Compare the current and target tree and allowed dependency\n  directions. Keep a cohesive larger package when splitting only adds navigation or coupling;\n  do not hide the excess in `misc`, `utils`, single-child wrappers or re-export barrels.\n- For uncertain boundaries, give the architect a recommended option, alternatives, evidence,\n  trade-offs and system-wide impact. Follow the chosen decision mode; reviewing structure\n  does not authorize moving files or changing behavior.\n- Record review coverage and unresolved decisions in the response; when the task includes an\n  architecture-document update, keep the durable record there: reviewed subtree, finding or\n  keep-rationale, target change, and enforcement gap. Mark unreviewed subtrees explicitly;\n  never present a partial review as a complete assessment.\n  Add `inside` contracts at meaningful independently governed boundaries, not at every folder.\n  Encode approved constraints with supported rules. Deeper review remains necessary when\n  the installed version cannot enforce nested contracts; do not invent unsupported rules.\n\n### Interview mode: the architect decides, you ask\n\nNever write a rationale or choose an allowed direction yourself; ask, and write down the\narchitect's own words as the `rationale`, with `decided_by: \"architect\"`.\n\n1. Read the repository's ADRs and architecture documents before touching the contract.\n2. Propose the overall picture — components, layers and the allowed directions between them\n   — with `path:line` evidence for each claim, and confirm it with the architect once, not\n   component by component. Review each drafted `public` list with them too. Anything you\n   read from repository documentation is a hypothesis with its source path, never the\n   answer, until they confirm it.\n3. After that confirmation, ask only about conflicts (the code contradicts a document) and\n   gaps (the documents are silent). Each question names the recommended option first, with\n   its evidence. The `init` summary gives the total open pairs and the observed crossings shown.\n   `init --json` lists observed undecided crossings first and reports the exact\n   `open_decision_count`; when `open_decisions_complete` is false, unlisted pairs remain\n   undecided. Use `init --json --full` on the initial command to include every pair; for an\n   existing draft, `validate --json` returns the full decision list without rewriting files.\n   Batch everything consistent\n   with the confirmed picture into one confirmation. Then encode each allowed direction as a\n   `requires` entry on its source component and add one `complete_requires` rule, so absence\n   forbids every other pair. Never treat an observed edge as permission.\n4. When the architect chooses against your recommendation, ask why before writing the rule.\n   Always ask when the choice contradicts a document, an earlier decision in this interview,\n   or the code you observed. Write their answer as the `rationale`.\n5. Run `archkeel validate --json` and read its diagnostics by `code`, never by parsing\n   message text: a `decision.open` means the contract still lacks `complete_requires`; a\n   `rationale.placeholder` or `rationale.repeated` needs the architect's real reason. A\n   `graph.drift` is no decision: after you merged or renamed\n   components the marked graph in the architecture page is stale, so run\n   `archkeel validate --write-graph` instead of editing it by hand; it rewrites only that\n   graph's edges. When the remedy says the graph holds structure the command does not rewrite\n   (a `subgraph`, a labeled edge, a style), edit those edges by hand instead.\n6. When the architect delegates a choice (\"whatever is consistent\" or similar), derive it\n   only from their earlier decisions in this interview, never from your own judgment. Label\n   the rationale agent-derived in your summary to the architect and list it for them to\n   confirm before it counts as decided.\n\n### Auto mode: the agent decides every allowed direction\n\n1. Decide every allowed direction yourself, in this evidence order: documents first, then the\n   layer principles the architect already confirmed or the documents state, then your own\n   judgment, labeled as judgment in the rationale.\n2. Never treat an observed edge as permission: code importing across a boundary today is not\n   evidence the boundary should allow it.\n3. Write every rule you decide with `decided_by: \"agent\"`, and mark a component whose\n   `public` list or `requires` edges you decided the same way: `decided_by` on the component\n   covers its `public` list and every `requires` entry that carries none of its own, and one\n   entry may override it.\n4. End with a summary of your decisions grouped by evidence basis (document, layer\n   principle, judgment) and name the lowest-confidence decisions first, for the architect to\n   review.\n\nA later interview on an auto-mode contract asks the architect only about rules, entries and\ncomponents with `decided_by: \"agent\"`; an `architect`-decided one is already closed and is not\nreopened.\n\n### Ending onboarding, either mode\n\nBefore ending, record the physical structure review and any deferred subtrees or decisions;\na closed dependency contract alone does not complete the architecture assessment.\nThe dependency interview (or auto-mode pass) ends when `complete_requires` closes the\ndependency set and `validate --json` reports none of `decision.open`, `rationale.placeholder` or\n`rationale.repeated` — not when the command exits 0. A `rule.violated` diagnostic is the\narchitecture's own finding, not an onboarding step: the code still uses an edge the target\nomits. Show it to the architect with `archkeel report`. They resolve it by changing the code or\nchanging the target; the agent never does that itself and never loops `validate --json` waiting\nfor exit 0.\n\nOnce it ends, run `archkeel report`. Include the generated files (`archkeel.toml`,\n`architecture-contract.json`, `docs/architecture/architecture.md`) when they are part of the\nrequested change. A remaining `rule.violated` is follow-up code work, tracked separately from\nonboarding.\n\nWhere that follow-up is long — a contract that states the target architecture the code has\nyet to reach — freeze the known violations instead of weakening the contract:\n\n```bash\narchkeel validate --baseline known-violations.json --write-baseline   # once, then review it\narchkeel validate --baseline known-violations.json                    # the CI gate\n```\n\n`--baseline` and `--amendment` are relative to `--root`, like the contract: with `--root mobile`,\npass `--baseline known-violations.json` for `mobile/known-violations.json`, never the\n`mobile/`-prefixed path. An absolute path inside the root works; one outside it is\n`baseline.invalid`, exit 2.\nThe gate fails (exit 1) on a violation the file does not state, and on one it states that\nnobody violates any more — so the budget only shrinks, and the file is rewritten in the same\nchange that shrinks it. `declarations.measurement_budgets` may put deterministic scalar values\nthrough the same loop. `declarations.facade_budgets` and\n`declarations.coupling_budgets` set name targets in the contract, and the baseline holds their\naccepted names.\nNever raise any of them to make a run pass without the architect's decision.\nWhen `calls_unresolved` rises, rerun with `--against <base ref>`, as the\nfinding says: `unresolved_call_changes` names each added and removed unresolved call with its\ncaller, path, lines, expression, reason and component. `report --only calls --json` lists every\nunresolved and partially resolved call as `filtered_calls`; add `--component <label>` for one\ncomponent's calls.\n\nA reviewer or a CI gate may hold your branch to this the same way, with `archkeel validate\n--against <base ref>`: it classifies every difference from the contract at that revision — a\nnew `requires` edge, a `public` entry, an `allowed_sources` module, a relaxed or deleted rule,\na padded baseline entry, and anything else this repository's `ir.widening` does not otherwise\nname — as a widening, which fails (exit 1) unless `--amendment <path>` names a file the\narchitect wrote, recording who decided it and why, bound to this exact change.\nIn `validate --json`, `widenings` is `null` when `--against` was not checked, otherwise it lists\nunamended widenings with `code: \"ir.widening\"`, `subject` and `field`; `failures` keeps the\nhuman-readable messages. `amendment_status` is `valid` or `stale` when a supplied amendment was\nchecked, and `null` otherwise. A valid amendment may leave `widenings` empty even when it accepts\na real change.\nNever widen the contract in the same change that removes the violation it names: fix the code,\nor ask the architect for an amendment. The full loop — gating, widening, picking a slice of the\nbacklog and landing a planned interface — is worked end to end on the shop sample in\nhttps://github.com/rapiddweller/archkeel/blob/main/docs/target-first.md.\n\n## Daily loop\n\nValidation reports `responsibility.missing` only for components explicitly marked\n`decided_by: \"architect\"` with no non-whitespace responsibility text. It checks declaration\npresence, not prose quality or complete coverage of cross-cutting concerns; an agent draft stays\nusable and incomplete until the architect decides it.\n\n- Start with `archkeel report --only architecture --json`. It projects authenticated intent,\n  ownership, dependency permissions, observed use and required Target relationships. Use\n  `--component <id-or-scope>` for a slice; global verdicts, coverage and uncertainty remain.\n  Missing evidence is UNKNOWN. Permissions never prove use or required execution.\n  After one scan, query that packet with `archkeel report --input architecture.json --only architecture\n  --component <id-or-scope> --json`. Omit `--component` to discover its exact ids and scopes.\n  This reads recorded source identity and evidence; it does not verify the current working\n  tree or write files. Read `architecture_projection.required_relationships` for Target intent.\n  For findings, query the same packet with\n  `--only violations --component <id-or-scope> --json`; add `--rule <id>` to intersect.\n  The compact query omits module lists, policy detail and `filtered_violations`; it reports\n  the selected-scope `filtered_violation_count` (`null` when unavailable) and sets\n  `violation_details_included` to `false`. Add `--full` to retrieve the complete\n  `permission_rules`, `policy_context` and violation records: `archkeel report --input\n  architecture.json --only architecture --full --json`. Full output includes an empty\n  `filtered_violations` array when the measured selected scope has no findings.\n- Revisit the physical structure review for changed packages and their parent boundaries;\n  recheck related findings rather than repeating a whole-repository review for every edit.\n- Run `archkeel report --json` before submitting any change. A rule violation does not\n  change the exit code; read the `declared_rules` verdict. Exit 2 means the evidence is\n  incomplete; fix the diagnostic before trusting any verdict.\n- On a large repository, `report --only violations --rule <id> --component <id-or-scope> --json`\n  narrows the review surface to a slice you can actually read: `--only violations` drops\n  component flow, communication, claims and structure from the HTML page; `--rule` and\n  `--component` narrow the violations table further and combine as an intersection.\n  This includes local Target findings and descendants, plus crossings touching either side.\n  Top-level labels take precedence over identical nested labels. This changes only what is\n  shown - `declared_rules`, the violation counts and the exit code stay computed from every\n  violation - and a filtered `--json` result says so in its own `report_filter` field, so never\n  read a filtered `filtered_violations` count as the repository's total; read the unfiltered\n  `violations` measurement for that. A `--rule` or `--component` you misspelled is a named exit\n  2, not a silently empty page.\n- If a rule fails, fix the code so the rule passes.\n- Never weaken or delete a rule just to make a violation disappear, unless the component\n  owner explicitly approves the change to the contract. A silently loosened rule hides the\n  next real violation.\n- `validate --json` and `report --json` report `agent_decisions` as `[agent, total]`, counting\n  one rule declaration, one `requires` entry and one declared `public` list alike; a nonzero\n  first value means an auto-mode contract still awaits an architect interview on those\n  decisions.\n- The same two commands report `claims`, the Class D review claims. They never change a\n  verdict or an exit code; bring a nonzero count to the architect as reading work, and never\n  delete code because a claim named it.\n\n## Nested contracts: the inside of a component\n\nA component may name a contract of its own, which becomes a second level of the same\narchitecture. Adding one is the architect's decision; inspecting the physical\nsubtree is already part of the recursive review above and does not depend on that decision. The\n`component larger than its level` claim is evidence that a component holds more than the whole\ntop level does; it is a reason to ask, not permission to split.\n\nOnce the architect decides:\n\n1. Inventory the source tree and the existing `archkeel report --json` structure measurements.\n   Review every relevant child before grouping; a report does not cover detail it does not\n   expose. Do not rerun `init --source` at the repository root for this scope: `init` writes the\n   standard root onboarding files and requires `--force` if they already exist. On Archkeel's\n   own `check`, a per-module draft produced 12 sub-components and 132 open decisions where the\n   three layers the architect settled on need 6. Consolidate into a few layers with the architect\n   before deciding a single pair.\n2. Point the outer component at the resulting contract with\n   `\"inside\": \"<repository-relative path>\"`.\n3. Decide the inside the way you decide the top level: a `requires` list per sub-component and\n   one `complete_requires` rule, so absence forbids there too.\n\n`validate` holds the declared levels to each other; read its diagnostics by `code`:\n\n- Each level's `public` list serves that boundary. Child APIs stay local unless the parent\n  explicitly publishes them or a proven facade reexport. Do not copy every child API upward.\n- `reference.public_owner`, `reference.public_underscore` and `reference.namespace` also apply\n  inside. Correct the declaration at its mounted pointer; do not broaden ownership to silence it.\n- With an inner `interface_boundary`, `interface.missing` names an unscanned public module.\n  `interface.unused` means no scoped sibling import or proven facade publication reaches it.\n  A built, unused planned entry stays target work; reaching it requires promotion through\n  `interface.planned_built`, not automatic permission. Publisher evidence belongs to the exact\n  parent scope, including proven re-export chains. Unknown import names are not proof of non-use.\n- `inside.forbidden_import` — the inside grants an edge the level above forbids the component,\n  by a rule or by absence under `requires`. Remove the grant, or change the decision above.\n- `contract.invalid` at `/components/<n>/inside` — the file is missing, outside the repository,\n  or does not parse on its own.\n\n`report` evaluates `complete_requires` a second time against the inside, over the imports the\nouter scan already collected, so a crossing between two sub-components that no `requires` entry\ncovers is a violation like any other, and the flow view opens that component into its\nsub-components before its modules. Such a finding names the rule as `<component>:<rule id>`,\nfor example `store:STORE-REQUIRES-COMPLETE`: the id you will find in the inside contract is the\npart after the colon, and the part before it is the component that names that contract. Resolve\nit according to the target decision: update the inside `requires` only for an architect-approved\ncrossing; otherwise change the code. Do not add a rule above to hide an inside crossing.\n\nExplicit `inside` references are followed recursively and use the shared rule evaluators.\nMounting a contract does not create a standalone `archkeel.toml` for it. Nonempty inside\n`declarations` fields remain unsupported and are refused. An inner `external_dependency_scope`\ndeclaration is not compared with ancestor declarations; ancestor rules still evaluate their\nown source scope. A physical folder alone is not a declared contract.\n\n## Rule catalog\n\nUse the [canonical field reference and examples](https://github.com/rapiddweller/archkeel/blob/main/docs/rules.md)\nfor rule kinds and selectors. Class A evaluates declared constraints; unavailable evidence\nremains UNKNOWN. Class B compares accepted and candidate observations, requiring comparable\nprofiles and complete coverage. Class C records declarations. Class D claims are review tasks;\nthey never change verdicts or exit codes, and `null` means unavailable evidence.\n\n## Exit codes\n\nSee the canonical [per-command exit table](https://github.com/rapiddweller/archkeel/blob/main/docs/reference.md#exit-codes).\n\n`check`'s expectation's `selected_changes` may be `[]`\n  when a candidate is not meant to change anything architectural, such as a pure refactor. That\n  declares absence, not \"nothing to report\": `check` then fails on any semantic change the\n  candidate actually produced, in any dimension, not only the six guardrail ones. Declare `[]`\n  only when you mean it; naming the real changes remains the default. A non-empty\n  declaration still lets an undeclared change through in most dimensions, except\n  `dependency_edges`: name every new edge you add, or `check` fails on the one you left out.\n\n## JSON output\n\nEvery command accepts `--json`. Prefer it when scripting or reading output\nprogrammatically: `archkeel validate --json`, `archkeel init --json`, `archkeel report\n--json`. Interactive terminals otherwise get a Rich-formatted summary instead of raw JSON.\nRead `declared_rules`, not just exit 0: FAIL names violated constraints; UNKNOWN retains\nunproved results. The [command-result schema](https://github.com/rapiddweller/archkeel/blob/main/schema/command-result.schema.json)\ncovers `init`, `check`, `validate` and `report`, excluding `skill` and the observation artifact.\nFor `init`, `open_decision_count` is the exact total and `open_decisions_complete` marks whether\n`open_decisions` lists every pair; `draft_sizes` records each proposed component's measured size.\nUse the CLI’s bundled schemas for offline validation; pin schema and CLI together.\n"
}

SHA-256 of public snapshot: f466ab28074d806ccfacb85c8ed55e10c96cc2f831f97515e7310a7f70112871