How the Method-Kit code is laid out — module roles, the per-tool code vocabulary, and the tool → codes → floor → gate topology a contributor needs before touching the code.
Two halves, two sources. The prose below (the layered model, the why, the gate topology) is authored by hand. The inventory at the bottom (tool → codes → floor) is generated from each tool's
CODES/FLOORregistries byscripts/gen_architecture.pyand must never be edited by hand — the living source is the registry, the table is a regenerated projection. A--checkrun in thequalitygate fails the build if the committed block drifts from the registries.
The kit lives across three tiers, and the repository is only one of them.
- Dev — the steering state (roadmap, journal, glossary) and the design-before-code discussion. It is private and never committed live: a single source, held outside the repository.
- Recette — this repository. It carries the deliverable: the
project-pilotskill suite, the repo-level tooling, the red floors, the public contributor docs, and the CI gates. Nothing is accepted until the gates are green and a squash-merge is ratified. - Déploiement — the suite installed at the account level (or published), plus frozen pilotage archives kept in the repo for durability (never re-read to steer).
Only the deliverable climbs the ladder; the pilotage state stays in Dev. That is why you will not find a live roadmap or journal in this repository.
The deliverable is built from four layers: (1) the transverse method itself; (2) the templates for steering docs, instantiated once per project; (3) the skills — the executable, reloadable procedural knowledge that travels with a project; (4) the account/project instructions that prime the start-up reflex. This repository is where layers 2–3 are developed, gated, and packaged.
The installable deliverable is the project-pilot suite under
skills/project-pilot/:
- an orchestrator (
SKILL.md) that routes a piloting request to the right module by context and carries the step-0 resume probe; - nine modules under
modules/, each a self-contained capability with its own scripts and red floor:close,command-lint,diagram-generation,doc-drift,filename-timestamp,prelint,remontee-runbook,skill-packaging,steering-docs-editing.
Alongside the suite, repo-level tooling under scripts/ serves
this repository's own CI and is not part of the installable suite:
discover_floors.py (find and run the floors), check_floor_coverage.py (prove
every declared code is exercised), check_action_drift.py (watch the SHA-pinned
actions), and gen_architecture.py (regenerate the inventory below). An adopter
who installs the suite never needs this plumbing.
Every rule-bearing tool emits codes (e.g. command_lint emits R1…R10),
and a floor — a deterministic test marked with a # FLOOR line — proves
those codes bite, one decidable case per code, plus mutation teeth. Since the
floor-coverage work, a tool declares its registry at module level so the
vocabulary and the location of its proof are single-sourced:
CODES = frozenset({"R1", "R2", "R3"}) # what this tool can emit
FLOOR = "check_remontee_runbook.py" # the floor that exercises themA tool with no code vocabulary (a generator, a parser, a discoverer) declares
CODES = frozenset() and still names its FLOOR, so the floor is claimed and
the tool is audited rather than silently invisible.
discover_floors.py scans for the # FLOOR marker
in the head of each *.py file and runs every marked floor with the current
interpreter; adding a capability means dropping a marked floor, never editing the
workflow. pytest-style floors live under tests/ and are run by pytest tests/. The tests gate is exactly discover_floors.py --run followed by
pytest tests/.
check_floor_coverage.py is the meta-check:
it confronts each tool's declared CODES against its FLOOR and reddens four
cases — a non-empty CODES with no FLOOR (F1), a missing FLOOR file
(F2), a declared code never exercised (F3), and a discovered floor claimed by
no tool (F4). Coverage (is there a case at all) is decidable and gated;
whether a case bites is the orthogonal job of mutation.
CI runs three decisional gates, each reproducible locally from the
single-source runners under scripts/gates/ (see
CONTRIBUTING.md):
quality—rufflint + format check,doc_driftover the public docs, andgen_architecture.py --check ARCHITECTURE.md(the inventory below must match the registries).tests—discover_floors.py --run(the standalone# FLOORfloors) thenpytest tests/.security—banditover the tree.docs-privacy— private-marker scan overdocs/**.
A fifth check, Analyze (python) (CodeQL), is non-decisional: SARIF
upload is blocked on the free private tier, so it shows nominally red and is
never a merge signal. Read the verdict on the machine field
(statusCheckRollup[].name / .conclusion) filtered to
the decisional set named in the CI-verdict policy that read_ci_verdict.py reads — not re-listed here — never on the rendered status line. A squash-merge
is authorised only when every decisional gate reports SUCCESS.
Generated from the CODES/FLOOR registries — do not edit by hand. Regenerate
with python scripts/gen_architecture.py --write ARCHITECTURE.md; the quality
gate enforces that this block matches the registries.
| Tool | Codes | Floor |
|---|---|---|
scripts/check_action_drift.py |
R1, R2, R3 |
../tests/test_check_action_drift.py |
scripts/check_docs_private_markers.py |
L1, L2, L3, L4 |
test_check_docs_private_markers.py |
scripts/check_floor_coverage.py |
F1, F2, F3, F4 |
test_check_floor_coverage.py |
scripts/check_job_deps.py |
J1, J2, J3 |
test_check_job_deps.py |
scripts/check_required_checks.py |
RC1, RC2, RC3 |
test_check_required_checks.py |
scripts/discover_floors.py |
(no codes) | test_discover_floors.py |
scripts/gen_architecture.py |
(no codes) | test_gen_architecture.py |
scripts/read_ci_verdict.py |
(no codes) | test_read_ci_verdict.py |
skills/project-pilot/modules/close/scripts/close.py |
C1, C2, C3, C4, C5, C6, C7, C8, C9 |
check_close.py |
skills/project-pilot/modules/command-lint/scripts/command_lint.py |
R1, R10, R2, R3, R4, R5, R6, R7, R8, R9 |
check_command_lint.py |
skills/project-pilot/modules/diagram-generation/scripts/extract_roadmap.py |
(no codes) | test_extract_roadmap.py |
skills/project-pilot/modules/diagram-generation/scripts/gen_diagram.py |
(no codes) | check_diagram.py |
skills/project-pilot/modules/doc-drift/scripts/check_manifest_coverage.py |
M1 |
test_check_manifest_coverage.py |
skills/project-pilot/modules/doc-drift/scripts/doc_drift.py |
R1, R2, R3 |
check_doc_drift.py |
skills/project-pilot/modules/prelint/scripts/prelint.py |
PL1, PL2, PL3 |
check_prelint.py |
skills/project-pilot/modules/remontee-runbook/scripts/remontee_runbook.py |
R1, R2, R3 |
check_remontee_runbook.py |
skills/project-pilot/modules/skill-packaging/scripts/validate_skill.py |
E_COMPAT_LENGTH, E_DESC_CHEVRON, E_DESC_LENGTH, E_DESC_MISSING, E_MULTIPLE_SKILL_MD, E_NAME_FORMAT, E_NAME_LENGTH, E_NAME_MISSING, E_NO_FRONTMATTER, E_NO_SKILL_MD, E_UNKNOWN_KEY, E_VERSION_FORMAT, E_VERSION_MISSING |
check_package_skill.py |
skills/project-pilot/modules/steering-docs-editing/scripts/check_steering_doc.py |
A1, A2, A3, B-impact, D1a, D1b, D2, D3, G1, H1, R1a, R1b, R2, R3, R4, R5 |
test_check_steering_doc.py |
skills/project-pilot/modules/steering-docs-editing/scripts/reslice_journal.py |
(no codes) | test_reslice_journal.py |
19 tool(s), 75 declared code(s) - regenerated by scripts/gen_architecture.py from the CODES/FLOOR registries.