Squelette – keep AI coding agents inside the scope you approved Squelette, a project-control layer that sits between humans and AI coding agents, ships at version 3.20.0 as a standard-library Python controller (scripts/project_control.py) that fails closed rather than advising when a rule is violated. The controller refuses writes outside a Work Item's authorized paths — its demo preflight on WI-001 exits 1 with BUSINESS_CHANGE_AUTHORIZATION and AUTHORIZED_PATHS failures after an agent touched modules/billing/invoice.py — and requires proof of reading governing documents plus evidence for every gate before DONE. Squelette targets long-running multi-agent projects where agents drift from approved scope, using one Git branch per Work Item and a commit hook installed outside the worktree. Governance and control for AI-assisted projects. Keep the goal, the scope, the human authority and the evidence of completion explicit — even when several AI agents work on the project over weeks or months. Who decides. Who does. What proves it's done. Version française ci-dessous ↓ squelette--en-fran%C3%A7ais Human │ defines the goal, the scope, the decisions ▼ SQUELETTE — a controller inside the repository ├── Project Charter and recorded human decisions ├── Authorized Work Items, one branch each, explicit paths only ├── Preflight: fail-closed checks before any write ├── Proof of reading the governing documents ├── Git provenance and a commit hook └── Definition of Done: evidence for every applicable gate ▼ AI agents — ChatGPT · Claude · Codex · Gemini · others ▼ Work + evidence, both in Git Long-running AI projects drift. An agent forgets a constraint, reinterprets a decision, edits files outside the intended scope, or declares the work complete without evidence — and nobody notices until much later. Squelette adds a project-control layer between the human and the agents. It is not a prompt: the rules are checks run by a small controller scripts/project control.py , standard-library Python, no service . When a rule is not met, the controller refuses — it does not advise. | Without a frame | With Squelette | |---|---| | "Carry on with the project" | A Work Item explicitly authorized by a recorded human decision | | Context lives in the chat | State lives in the repository, as records the controller audits | | Decisions mixed into conversations | Human decisions registered, with their scope, options and reasons | | The agent widens the scope as it goes | Authorized paths; the preflight and the commit hook refuse the rest | | "The agent says it read the rules" | Proof of reading: a digest of the governing documents, required to start | | "It should work" | Evidence required for every applicable gate before DONE | | Hard-to-explain changes | Git provenance: one branch per Work Item, explicit paths, no git add -A | | A new agent means a painful restart | status rebuilds the state from the records | | The agent picks how it talks to you | You choose the reporting style: technical, or plain language | | An agent wanders into another folder | Two distinct human confirmations, or the controller refuses the decision | examples/hello-squelette/ replays a complete cycle in a temporary copy: initialization, one human decision, one authorized Work Item, one refused drift, one proven change. The block below is the controller's real output — regenerated by the demo and checked by the test suite, so the README cannot drift from the controller. bash $ python3 -B scripts/project control.py status Project: Hello Squelette | NORMAL MODE Reporting to the Project Owner: plain PLAIN — what happened, what it changes, what he has to do Language: english EN Branch: work/wi-001-greeting | HEAD: