Releases: JyMinet/squelette
Release list
3.21.1 — every copy has an end
Every copy of the repository now has a ticket, a fate and a proven end. This release carries 3.21.0 (the feature) and 3.21.1 (a fix to its tests).
The problem: folders copied to protect the original — work sites, reviews, rehearsals — were born well and never ended; they multiplied under different names, and work drifted into them.
What changes:
- The original keeps the register of its copies (
copy open): each one has a ticket (the decision the double stop produces), a fate decided up front, a return date and an exit slip laid in the copy. - Returning a copy is proven (
copy return): everything it holds — files, ignored folders, index, references, stash, commits a reflog still reaches, what.gitkeeps — is back in the original or abandoned by name. copy checkreads a copy just before any erasure;copy cleanupwrites the script the owner runs — the controller never erases anything itself.copy moveandcopy closefollow moves and ends.- A work item does not close, and a version is not tagged, while a registered copy is still open (
COPIES_RETURNEDaudit); being late is only a warning. - Reading a copy runs nothing it names: no file monitor, no transport, no signature check. A partial clone, a special file or a hidden copy are refused.
3.21.1 fixes the tests only: four tests assumed the template's journal and licence, which a derived project does not have. Found while rehearsing the upgrade of a real project, where they failed before testing anything; that project, upgraded with this core, runs the suite without a single failure.
Review: an independent code review (ten holes), a code review by a second AI (six findings), then three successive controls; each defect is closed by a test. 221 tests, 38 of them new in these two versions.
Squelette 3.20.2 — the fake newer template starts from blank registers too
Second fix to the template suite for derived projects, right after 3.20.1. Not a single line of the controller changes; for the template itself, nothing changes.
What was broken. The upgrade tests build a "newer version" of the template by copying the tree the suite runs in (make_template_source). Inside a derived project, that copy carried the project's own records — its ideas list, whose ideas point at its Work Items and its decisions — and --seed-required planted them into a pristine copy that has neither: the rehearsal audit failed on IDEAS. Found while rehearsing a real project's upgrade to 3.20.1 on a throwaway copy: 182 tests, 1 red — the last one the bound volume had been hiding.
What changes.
- Fixture (
tests/test_template.py,make_template_source): the template source goes throughreset_to_not_started_fixture, like every test copy — blank records, template role, not initialized. - New test (B16,
test_a_template_source_built_inside_a_derived_project_carries_none_of_its_records): from a bound derived project holding an idea aimed at its own Work Item, it builds a template source, checks it carries no idea, no decision and no volume, then replays the path that fell (--seed-required,--apply). Red on 3.20.1, green on 3.20.2. - Core manifest at 3.20.2; demo and transcript regenerated; changelog, roadmap and view updated.
Verified. Template: 183 tests green, audit, bootstrap-audit, traceability and demo.py --check PASS. A real derived project upgraded with this core: 183 tests, 173 passed, 10 skipped, 0 failures.
For derived projects. A routine upgrade with template-upgrade from tag v3.20.2 (one core file changes: tests/test_template.py) — straight from 3.20.0 if 3.20.1 was skipped —, under a Work Item and the double stop, then install-gate.
Squelette 3.20.1 — the test fixture starts from blank decision registers
A fix to the template's own test suite. Not a single line of the controller changes; a project that never bound anything sees no difference.
What was broken. A derived project that had bound its volume 1 of Human Decisions (decision bind, introduced in 3.20.0) could no longer run the template suite on itself: 144 of 181 tests failed on one and the same line, DECISION_VOLUMES_CONSISTENT — cannot read docs/governance/HUMAN_DECISIONS.md at the binding origin … : the comparison term is unavailable. The control was right to refuse. The cause was in the test fixture: every test works on a copy of the project with no Git history (a single commit), and docs/governance/ was copied as it was — bound volume included. The volume names the commit it was bound at, a commit of the project's own history that no fixture copy has. Found on a real project one week after its binding; reproduced without it, on a throwaway derived project built from the template, with the very same numbers.
What changes.
- Fixture (
tests/test_template.py,reset_to_not_started_fixture): the test copy starts from blank decision registers — a living notebook with no recorded decision and no summary (the summary is removed with the controller's ownstrip_decisions_summary), and no bound volume (HUMAN_DECISIONS_VOLUME_*.mdremoved from the copy). Volume 1 of real projects is untouched. - New test (B15,
test_the_suite_still_runs_from_a_derived_project_that_bound_its_volume): from a derived project whose volume is bound, it replaysmake_copy+bootstrap-audit,make_normal_copy+audit, then one test of the suite in a subprocess. Red on 3.20.0, green on 3.20.1. - Core manifest at 3.20.1; demo and transcript regenerated; changelog, roadmap and view updated; the full diagnostic is under
provenance/maintenance/2026-09-27-diagnostic-3.20.1-fixture-volume-relie.md(in French).
Verified. Template: 182 tests green (Python 3.10 and 3.11), audit, bootstrap-audit, traceability and demo.py --check PASS. A derived project with a bound volume, rebuilt on 3.20.1: 182 tests, 172 passed, 10 skipped (template-only tests), 0 failures — against 144 failures on 3.20.0.
3.20.0 — the living notebook and the bound volume
Since 3.6.0 a work item only starts once the agent has really read the authorities routed for its
scope — and the Human Decisions register is one of them, for every work item. It is read in full
at every start, every resume and every acknowledgement, and it only ever grows.
Measured on a real governed project before a single line was written: the register accounts for
63 % of everything an agent must read before writing, and 69 % of it is frozen by the
project's adoption baseline.
This version cuts it in two, along a line the project has already declared.
What is new
decision bindmoves the decisions frozen at the adoption baseline into
docs/governance/HUMAN_DECISIONS_VOLUME_1.md, byte for byte, and writes a summary in the
living notebook — one line per bound decision, quoting the opening of each field and marking
where it cuts. The living notebook stays a routed authority; the bound volume is routed nowhere,
so it never enters a manifest — while the controller still resolves, audits and shows every
decision in it.decision show HD-NNNprints one recorded decision, from either volume, and writes nothing.DECISION_VOLUMES_CONSISTENTstarts from the commit the volume names itself and checks that
no decision has disappeared — even one no record cites —, that every bound block is identical
to its form at that origin, and that the summary is complete and faithful.- The controller reminds; it never binds by itself. While no volume exists, an adoption
baseline is declared and the frozen decisions take up at least a third of the register,status
says so and names the command, in French and in English.
What does not change
A project that has bound nothing behaves exactly as in 3.19.2. No decision is rewritten,
summarised or requalified: the promise that frozen closures are never reconstructed nor
requalified is extended to the move, and the vocabulary exemption of frozen decisions follows the
decision into its volume. The proof of reading is not relaxed — what changes is what must be
read.
Summary lines are pointers, not statements of a decision: a cut line does not say what follows it,
and two decisions can share the same opening. Only the recorded text states the human choice.
Measured, not asserted
Rehearsed on a throwaway clone of a real governed project holding 86 decisions: 64 bound, living
notebook down from 186 333 to 69 168 bytes, reading footprint of a business work item down from
294 143 to 188 885 bytes — about 26 300 fewer tokens at every start. Audit 23 PASS, 0 FAIL,
before and after the cut.
Independent review
The scope was reviewed by an independent controller: P19_CADRAGE_REQUIRES_MAJOR_REDLINE, nine
findings. The counter-review rejected none of them. The major red line was well founded and
reproduced: the audit verified that every block it found was intact without ever starting from
the expected set, so a decision no record cites could vanish together with its summary line. Fixed
by pinning the binding origin inside the volume itself. Reports live under provenance/maintenance/.
181 tests, sixteen of them born with this version, each verified red before and green after.
Two debts are assumed and written down: binding a second time once the notebook has grown again is
not built, and the template's own decision journal is routed for nobody.
---
## Note
La copie publique est un miroir anonymisé, produit par un script depuis le dépôt privé et jamais
édité à la main. Elle contient le code, les essais, la doctrine et les rapports de contrôle ; le
projet adopté y est renommé « Alpha » et l'outil d'export reste privé.
Squelette v3.19.2 — a blocked work item can resume again
A patch release, and a small lesson about tests that measure the wrong thing.
The defect
With the commit gate installed — the way a real project runs — a blocked work item carrying its
own commits could no longer resume once another work item had been closed on the canonical
branch in the meantime. The alignment merge was refused: the closing commit of the sibling work
item was judged against the current branch alone, which does not contain it yet. The gate did
exactly what it was told, and what it was told was wrong.
Why the suite did not see it
The test suite builds its repositories without installing the commit gate. Only two tests
installed it. So the resume scenario was measured on a path that does not exist on a user's
machine: it passed without the gate and failed with it.
The rule that follows: a test about what the gate sees has to install the gate. The new test
test_resume_merges_under_the_installed_commit_gate does, and it is red on 3.19.1, green here.
The fix
Two touches of the same idea. history_heads() names what the next commit will descend from —
HEAD, plus every parent written in MERGE_HEAD, read line by line so an octopus merge does not
lose a parent. in_current_history() judges ancestry against that set instead of HEAD alone, and
done_evidence_errors uses it. And staged_worktree now builds its photograph of the index with
the same parents as the real commit — which is what its own docstring already promised.
Nothing to reinstall: scripts/hooks/pre-commit is unchanged. It calls the controller, and the
controller is what was fixed. A project upgrades with template-upgrade as usual.
The scope is deliberately narrow. The other ancestry checks against HEAD — declared baselines,
closure checks, status — are untouched, for want of a demonstrated failure. The observation is
recorded: they would judge a commit arriving through an in-progress merge the same way.
Also in this version
The scoping dossier of work item P7, "the question of what already exists" — a proposed extra
line on every work item: what already exists on this subject, and where? Two answers only, and the
controller refuses to start while the answer is missing. The mandate, its amendment, the read-only
measurement report and two independent review reports are published under
provenance/maintenance/. The work is scoped, not built: the eligibility boundary is decided
(the mark travels in the work item's own record), and the amendment records the four definitions
without which the rule contradicts itself in real use.
Verification
165 tests in the private repository, all green. In this mirror, 164 run and pass and one skips —
the check of the export tool, which stays private. audit, the demo check and the core manifest
agree with the tree.
Detail in provenance/CHANGELOG.md (decisions TPL-D-070 to TPL-D-072) and in
provenance/maintenance/scopes/p7-scope-question-de-l-existant.md.
Licence MIT.
Squelette v3.19.1 — first public version
Squelette v3.19.1 — first public version
Governance and control for AI-assisted projects. Squelette keeps the goal, the scope, the human
authority and the evidence of completion explicit — even when several AI agents work on a project
over weeks or months. A project made from it carries its own controller (scripts/project_control.py),
a commit gate installed outside the worktree, structured human decisions, work items with a
governed lifecycle, and evidence that is checked against what the repository actually holds.
This is the first public version. The repository is a mirror of a private one where the
template is developed: it is produced by a script at every version, never edited by hand. In the
copy, the owner's machine paths are neutralised, one adopted private project is called « Alpha »,
and the backup machine is just « a NAS ». Everything else — the code, the tests, the journal and
the five independent control reports — is published as it is.
What 3.19.1 is
The version that closes the fifth independent control: twenty-one demonstrated defects found by
five adversarial passes since September 10, all fixed with a test shown red before and green after.
The last six: a sweep of throwaway checkouts that could erase a worktree that was not its own (now
proved by a marker and a lock), file names Git quotes — accents, tabs — that escaped the content
rule of integration merges and the closure check, a legitimate rename refused at integration, a
decision that "chose" twice, a JSON check that read ignored files. Full detail in
provenance/CHANGELOG.md (decisions TPL-D-065 to TPL-D-067) and in
provenance/maintenance/2026-09-11-controle-independant-3.18.2.md.
Try it in two minutes
git clone https://github.com/JyMinet/squelette.git && cd squelette
python3 -B examples/hello-squelette/demo.py --verboseThe demo replays one governed change, for real, in a temporary copy: initialisation, a refused
then accepted bootstrap, a work item, a change outside its scope refused by the gate, evidence,
closure. README.md explains what the template is — and what it is not. ADOPTION.md says how to
start a project from it, or adopt it on a repository that already has a history.
Verification
164 tests in the private repository; 163 run in this mirror (the one that checks the export itself
stays private) and pass; audit, the demo check and the core manifest agree with the tree.
Licence MIT.