diff --git a/ADOPTING.md b/ADOPTING.md index 7f222c1..52a9721 100644 --- a/ADOPTING.md +++ b/ADOPTING.md @@ -44,7 +44,7 @@ For a first adoption, the default is the day-zero coordinator: ```text # Install the current tagged release. -python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.1.zip" +python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.2.zip" # Installed command writwall start --project-root /path/to/your-project @@ -148,6 +148,14 @@ Baseline commit candidate: [hash or "determine and propose"]. The skill follows the standing rules of the remediation companion (inventory first, move rather than delete, propose rather than dispose, no source changes, no commits, RFI list for unknowns). It inventories the mutation channels your installation actually exposes rather than a fixed list, installs the adapter with matcher `*`, and runs both doctrinal birth-test levels through the adapter's more detailed procedure: Level 1 no-work-order lockout, Level 2 ordinary active scope, Level 3 protected-control-plane falsification where claimed, and the conditional Level 4 read-deny procedure. Bootstrap ends with a report and the repository in lockout, and it does not create DR-001 for you. That is yours to ratify. +Before registration or Level 1, the coordinator must copy +`assets/bootstrap-charter-addendum.md` verbatim into the +engine-visible pre-adoption charter. Ordinary no-pointer work remains forbidden. +The addendum permits only exact calls named by a durably Owner-ratified +birth-test lifecycle, solely so the installed wall can deny them; it confers no +mutation authority, denial is the only valid outcome, and any success stops +adoption. Remove the temporary addendum before the adoption commit. + **The optional second step: an Owner-directed recorder closeout.** After you have read the bootstrap report, you may either finish section 5 yourself or explicitly direct the skill to record your decisions. That second mode exists because ratifying and typing are different things. You remain the only source of intent: the baseline, the plan content, the mapping dispositions, the routing, the operational definitions, your adoption reasoning and rejected alternatives, your acceptance of every unenforced surface, and the decision to adopt at all. What the recorder may do, once you have supplied those and ratified them explicitly, is the clerical remainder — materialize `PLAN.md`, archive the superseded original, finalize labels, write or rename DR-001 transcribing your words verbatim, clear the bootstrap markers, remove bootstrap-only residue, stage the adoption set, and make the one local adoption commit. It asks first. Before touching anything it hands you a decision packet: what it will record, whose words each decision came from, the exact file operations, and the exact commit message and contents. Nothing proceeds until you ratify that packet in so many words — a filename, a draft, or the state of the repository is never taken as approval. If a decision is missing it asks you for the decision, not for the edit. And a recorder closeout still cannot push, tag, publish, change visibility, select a license, weaken or skip the birth test, or start WO-001. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90a750f..777d5d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,7 +78,7 @@ gate against the final checked public candidate on native Windows and native Ubuntu: ```text -python checks/check_coordinator_release.py --expected-tag v0.9.1 +python checks/check_coordinator_release.py --expected-tag v0.9.2 ``` The gate copies the candidate to temporary build space, builds and installs the diff --git a/PROJECTION-MANIFEST.sha256 b/PROJECTION-MANIFEST.sha256 index d598acb..81f77ff 100644 --- a/PROJECTION-MANIFEST.sha256 +++ b/PROJECTION-MANIFEST.sha256 @@ -5,9 +5,9 @@ b2e36dfcfc6eb31570c9340640bcd73abc62f57c80b4794abf36e3d3e89ab34f .github/depend 9e90d43615b02a265b08692ef7a1c00a37477a5c6b1e8233a8fc7bedefaedea6 .github/pull_request_template.md 40e5cddf710e4e6fa4984ac864fdb30a7031005ef1a80082ce0cc6a4f9bc115e .github/workflows/ci.yml e544abe8ffd83c81c7b002cbd2e552f9d56f226ea20e1e0722c5d1bdec914fe0 .gitignore -6e262a9a0fc3281e2ea9e3ac8eb2d7a1af132c5c754d0aa0699e9b2e0b97d5c7 ADOPTING.md +73bdedc8e39d50d9ee61e776583e601797b6e2a2b6c50d2741959472eb072861 ADOPTING.md 1179c999034f4ec1c1d44c1946bd2955c4625905e80767abe760c8c3ab01c493 CLAUDE.md -1b560adc2d752b734a4be4c3c266ae91e095a83efe9f40094b62e98237473719 CONTRIBUTING.md +ab361087e7fd15a160587426f7ac6e8d45e7546fc821c2b07432a8e007447afa CONTRIBUTING.md 664196054cd98585105be457afa09c788a482416ccb48a87bb269b2156e49ae6 DOCTRINE.md 9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411 LICENSE a38775f2d68b40577253ee48061ba67af3c75b7620dc506b34b40ce2a3b660ee LICENSE-MAP.md @@ -16,22 +16,22 @@ c274f80372d90c012937370f0e1f15087d22e308ef98b27cea5dc0d2d088366c LICENSES/Apach a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499 LICENSES/CC0-1.0.txt 59746d6285ffa44bfc7ecada352aa5d6a20dc8eab418a60ce091cc739012c135 LICENSES/MIT-0.txt 35e6d37b7c5fa0c1fc872315cbd362cd24bfa41e1b7dc3019fbcd31e99350f51 NAMING.md -ac0b2adea6727dfda2fb7bd66b563a0b7197fe879c19b7dc8bb2000b8a3a2eff PROJECTION-PROVENANCE.md -5b3bd5f9da3da7f5e1c08217547eb4cbc1bfb19405c56d7e4f979ac9adcc8246 PUBLICATION.md -ffbaa02e98a62fb5d6ac9fe9b831a195c1b41c7e413484863b769d17101554de README.md -6c4855e221ad30f7ca15baa03f3f8be3f38868210921f0c15b31a30775a940e2 REUSE.toml +bbbc4ba483ace56bc7e3827cdc24b867db981efec5ba13d53e1b788591d430ee PROJECTION-PROVENANCE.md +96b3466c452f1288020b5f62e0729deb04c860e5bd0d34a3f5f2418ee9aa25f0 PUBLICATION.md +e81903350f305351ccd52e7acaa584b4683b7ba65fa1ecbeb2c048eec357e483 README.md +284a0862f3be77e8d867aa4d3ef92ed1a64ad4315d6d9074f6bb64771b6d1dd0 REUSE.toml ab75b39490b4db4e203f5b23b480a1c998d87cf07d760cb787cb260778b21d0a SECURITY.md 6a51c1211cc675599634d144ca24a705ec1696f84640a6464b14efb1d6c3a629 SELF-HOSTING.md -8e8b4008d1ac16a6617357b16308329eac2fb2d87a5cb19bb9a247bd262c633f START-HERE.md -a4723267565778de85ae6f00f99bb903eab625e98917389fe1821a463d3d867d adapters/claude-code/README.md +04ee91f398218f895f9ef4cb990c01e3fea1847e46882a7700f352d00e879bda START-HERE.md +75c7ae0f569148f489570d63df916a70b6ccf24b77db2076cdee29663f747428 adapters/claude-code/README.md aeb7f81d139e7ffa6de9a1782444b99eb6d549ac1c3a8b9c0f8bcb9c6addfa6d adapters/claude-code/SECURITY.md dd29af2a39d25e0270ad9acc23ee912f81e39c674e1179759f4a3010c6a0c1a0 adapters/claude-code/wo_capability_wall.py -19cd491d3d10275a787bee8b902d34f69191bce0134d30a07dd078ee37a6ebee checks/check_coordinator_release.py -d1622d215a079a83156213ca5dd8e814308d1012421bc82b7490e2137360c504 checks/check_distribution.py +3663baaaede31c20b87cbe27b37a7a2db6485782ffc581d2e3e05ca525adade7 checks/check_coordinator_release.py +b872c46f8a8ea2fc317b4c4fd0af00c9145012b11256c923987d878d79c726c2 checks/check_distribution.py 60fe377dac32b8d1697f859371ef40d26ed4e695fdceeda6d29ec0318d539504 checks/check_identity.py 30986c40ff7c9b29e2fba39ec04c18af3c1c351490410bd532a8391bcb92ed11 checks/check_licenses.py e843892f24360174620fa02f3adf142a5eb5e2aac4bbfea786648f8b49375192 checks/check_name_clearance.py -f06f647ca835589516b535a659069496833a302f968cf658c4bbf7038a7e00cc checks/check_public_projection.py +cf7e0c4523ba9335b78c1fe51dd744e5c4806c3f431705df3553f9b37591c2f8 checks/check_public_projection.py bb54d108d1dff56291169624d26eac4f44db00ebf98e38bf7e6d56cd9b8d9647 checks/check_work_order_dispatch.py b49e8c6fb8ef321e5a8f8b2012a77ab3870df2d4826ecb8fe0b33345d57d060a decisions/DR-001.md 1dc105a91f76dd749463e91e492646ff5188a62359f21caba5245cb173c2a8ac decisions/DR-003.md @@ -47,6 +47,7 @@ fa88788242d920999b6e6737ea60b03dfe3f9ba2e0d90386b6bbcfeb6acd0509 docs/agents/do 55816569390363947ecc7735d7de13a3f59b8dae51f92383967e130b3a56d2a6 docs/assets/writwall-og.svg 0a5259d80265765aee16a421546e44458a1aabeecfa8c7f7dea8aead6a79655b docs/assets/writwall-readme-banner-0a5259d8.png ad0fb4f671b8da9e3ab9720af7b39ac9c93201e6131c1df996e090a2bb2acc8a docs/assets/writwall-readme-banner.svg +7cfd0ae28d07cdfbb367adc4f7e606a1538ebf61ff140a32f8e793028110cedf docs/bootstrap-charter-addendum.md efd77cef5df06a36f880053d4a33d038766fe9c22d2958b06072a6257d4014ac docs/day-zero-coordinator.md e1214e3e6018642809339249bb091a6fd754847b4f77c4bc7a39c5c87e6769cc docs/identity-migration.md 4d54cd53db8c165b40af7eb11b97a7f4faf5f23479c0efc8238e5d463b159008 docs/name-clearance.md @@ -61,10 +62,10 @@ d2c5a8ca21edf842dfd17a83862024afa0a92349abf693a60e55ce454c8d78fa examples/name- 30cdb11fbeb2fd9bbf4048255331ccbbdd6e516fae5adfa5317af00ce53607c9 governance/ADOPTION-MAPPING.md 08b235351ab7799715b1e2df4fa3dd9fa88bb85084c8aade4d01039bf255b489 governance/LOG-denials-probes.md 50784b173c90c4fd22572306429187c8a7e22614f4b9ad649a3005647467c7fa governance/LOG-denials.jsonl -8323b3fb10cbb7ac098ffda6f537563c39ec7907c750dd948a16bcdfc69b21ad governance/LOG.md -09264752687c0d88f32ff2907c6e5d543251441383a20ef29151f56b42baa898 governance/PLAN.md +6cd8bb10ebd50071b2f355c1934fdbb525452dabeee7cc98f24eaddf03a1fef6 governance/LOG.md +fcbdd620daea8b69e35ecb859f08f5332ceb89f6ac5dc9a293096b4190e4d437 governance/PLAN.md dd445eb2994e0d9615bc61fe2ae157a6b14ba7b190c65b705d380b31c49fdfe0 governance/ROUTING.md -437e7bb9334732cf58f7fed56d2081fdd33c0032a07eb93dd786bcd337dc0b9f governance/STATE.md +609d2afa9e0bb198caebbfc08aee0b541fd713041b106d66100b5670bdf9639a governance/STATE.md e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/archive/.gitkeep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/briefs/.gitkeep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/decisions/.gitkeep @@ -81,22 +82,23 @@ b567ce0c0867464328e81774d888f6491fa66b68ac73be01f993e5c4c66d3ed8 governance/tem d355e46f978f17de8824af805e05124e0f20b1c072523b518422044f88c6f079 governance/templates/D-adoption-record.md 2b586efadab716a59fcafb74312a45a05401a4787fee6ae18cb5c9dd14ef3a09 governance/templates/E-adoption-mapping.md e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/work-orders/.gitkeep -b5603027d84a295fc185fba11ba5dad2a8cafd322bd7c503f85a16c9daf047b2 identity/legacy-references.json +37cb8ccdbe1fd69854c88cf23acacae830cc14c532392a2a970b28530b9bee11 identity/legacy-references.json 345b7e962731c085a95aea66a344eae000b27c9bde13b0d790c76b73273dbe7a init.sh 5c90584642f405534b2071f27396ff293ab01632e4dbb8ccb6b8ec043dca4cc9 migration-guides/0.1-to-0.6.md ba4eff258ca5b9a45f3f9f1cbf646ba5bc5521fae812adacac65cd2e78698c9d migration-guides/0.6-to-0.7.md 7be9ff49c33830f929584e9e6756f06be8634b1c79ff7210bf5184b51bfc0769 migration-guides/0.7-to-0.8.md -393e7582af9d4ffa3bc8f574c179f8d4234f3a05b1416152c3bb0551855e7d97 projection/public-files.txt -32d564defb7ad226a873c36bfe49c77518172edb54d0ec28683bfb5228246f1b pyproject.toml +fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7 projection/public-files.txt +8a70068ac39d532fd783ae50e7f1458175a93dd8a31c3ccde6461d40e28f5430 pyproject.toml 455ca1ab3c9e7e78afbb9946e13b94497ba24003ab6f411ea96cce26d4ecc39e scripts/build_distribution.py bdbe47e8ea246ceafb874229d5582a9cc18db7c66250c9873d50a787bd5d9fe2 scripts/build_public_projection.py 3cf88f936599e0e84bc2368bc0503a39b9f96e47b473e09b26569e5c3c9edbd9 scripts/collect_name_clearance.py 8441030e9df498e9c2621d37d9bf77850599723c985b1d958b8d11638dcb1ae4 scripts/privacy_screen.py -cd9eeafb5339e507d780d16ecae005029dccb06e680383e5a8c80d4239279c5d scripts/start_writwall.py +9885aa8bf47e055571ce47b35cecb655415d0355113e36bc341397ae38f0e2c9 scripts/start_writwall.py 374f4e8a80b7b9e162b9360a3907b6ffe12ce94ba0ed827058c7b3c9c0658b2c skills/writwall-adopt/LICENSE-MAP.md -bb56ea2b1252f6f962ac98748104ce4dfd599b2bb8f081d1cff0575a721b4739 skills/writwall-adopt/SKILL.md -a4723267565778de85ae6f00f99bb903eab625e98917389fe1821a463d3d867d skills/writwall-adopt/assets/adapters/claude-code/README.md +deb31382704a7db0531d96d06581a9d27082b9e77ee2ea319c9242d530a78ea4 skills/writwall-adopt/SKILL.md +75c7ae0f569148f489570d63df916a70b6ccf24b77db2076cdee29663f747428 skills/writwall-adopt/assets/adapters/claude-code/README.md dd29af2a39d25e0270ad9acc23ee912f81e39c674e1179759f4a3010c6a0c1a0 skills/writwall-adopt/assets/adapters/claude-code/wo_capability_wall.py +7cfd0ae28d07cdfbb367adc4f7e606a1538ebf61ff140a32f8e793028110cedf skills/writwall-adopt/assets/bootstrap-charter-addendum.md e843892f24360174620fa02f3adf142a5eb5e2aac4bbfea786648f8b49375192 skills/writwall-adopt/assets/checks/check_name_clearance.py bb54d108d1dff56291169624d26eac4f44db00ebf98e38bf7e6d56cd9b8d9647 skills/writwall-adopt/assets/checks/check_work_order_dispatch.py 3cf88f936599e0e84bc2368bc0503a39b9f96e47b473e09b26569e5c3c9edbd9 skills/writwall-adopt/assets/scripts/collect_name_clearance.py @@ -115,17 +117,18 @@ b567ce0c0867464328e81774d888f6491fa66b68ac73be01f993e5c4c66d3ed8 templates/A-ch 5bfaa890ffddd423644428606753bc2e6562e3e5d67c1dc522172710708a4bf0 templates/C-owner-brief.md d355e46f978f17de8824af805e05124e0f20b1c072523b518422044f88c6f079 templates/D-adoption-record.md 2b586efadab716a59fcafb74312a45a05401a4787fee6ae18cb5c9dd14ef3a09 templates/E-adoption-mapping.md -2f4aa14f22238a2a44aa6648f4ff4c942811c3f2e77ef6176ec5225887caf4f5 tests/test_check_distribution.py +035c45d3ee0e71ecd7dbaeeff1d69f3cb2de706d9a8518bbee5e096a739e3a97 tests/test_bootstrap_contract.py +9924816cbbeade6f88f79d3e06fe04d143d801783888210ac2325925d69e4bdb tests/test_check_distribution.py b046f2eea794070194294a33f2914e627eed384e63fccffc2ac46693db2a968c tests/test_check_licenses.py 9a106ff5182b4a15713575de42e90b0dc5cdeebcb17ba08d97522a4c9aa6b2fa tests/test_check_work_order_dispatch.py -26a411994ee04cc0eac85d05a54f6fc2dc032c379dfadda20135e0a6e0006860 tests/test_coordinator_release.py -271a2e0e6e2ad79d48a0c6ae53d60648d51fe338d2d578e08b9e9416cd912dd2 tests/test_distribution.py +c276150136fc37b056e43700b802ab42b29ecb0123028116e7bda1d6a03df146 tests/test_coordinator_release.py +22901437098bb4883153af4f8d02f14e02585343791ca813aa425e2956510927 tests/test_distribution.py e150a2f988a4b0beac5f70644f55f5e185a8aa575e988a19642bafabc0f07775 tests/test_identity_migration.py -011d79618848880de8600b11bcedbdd6ba8b68124ddc3ae3e522288639c2498c tests/test_init_sh.py +11cd8090dbc53e8aa6a2f14cb181c8a11696335da8f40700eae5116798e49ba5 tests/test_init_sh.py 96c255d84e37b8884cde769897e763776b81027080c2308c33dc5e4b8df4a4bf tests/test_name_clearance.py a8345b5da77a8b73dd0269110be89bc0ad85c253f2c76b1b075d494fa018a21f tests/test_privacy_screen.py -d9ba27ea9255ffce9bfe23669893064639bbfaa0fdcbfd8fcd08b681d240cedb tests/test_public_projection.py -29454ddfc9ec4bd7fd71fc91a5ccf8757021966512a27154f8e1cf310f4b9b99 tests/test_start_writwall.py +ee771c239c0fc072675f88617dec7e330c1e19be90a8b22691d7049dbb5a4544 tests/test_public_projection.py +5673f51cddbff6f0dc82c11dd3cc581ee2d0457717a5797844c464aff21e62b6 tests/test_start_writwall.py 0684c04067eb95eadc9f72ab126d8662b4a5e2005c80b2dea174075a6140eebc tests/test_wo_capability_wall.py e8caf7f4421dc7f78b0d766741ec2ef4c2ac6dab6117fab6e4175b27d31e4d49 writwall_cli/__init__.py 9e0fbb2625b7a99ed80a3a708f8a0742d91bbf7e3cd2862d21a75515031083e5 writwall_cli/__main__.py diff --git a/PROJECTION-PROVENANCE.md b/PROJECTION-PROVENANCE.md index c3e43ab..f5740c3 100644 --- a/PROJECTION-PROVENANCE.md +++ b/PROJECTION-PROVENANCE.md @@ -5,9 +5,9 @@ Legacy commit identifiers in projected records refer to that private source and are intentionally not resolvable from fresh public history. No private remote URL is recorded here. -- Source commit: `40cdbd64c71769bf3ec2f1a28246d89713953240` -- Source commit time: `2026-08-31T19:11:11-05:00` -- Projection allowlist SHA-256: `393e7582af9d4ffa3bc8f574c179f8d4234f3a05b1416152c3bb0551855e7d97` +- Source commit: `0150c3a97996f50a9faf77501c03b7ff58a237a1` +- Source commit time: `2026-09-01T12:20:52-05:00` +- Projection allowlist SHA-256: `fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7` ## Legacy identifier inventory diff --git a/PUBLICATION.md b/PUBLICATION.md index c9acec7..d9f8ae6 100644 --- a/PUBLICATION.md +++ b/PUBLICATION.md @@ -13,7 +13,7 @@ point. Before creating a release tag, run this gate against the final external candidate on native Windows and native Ubuntu, naming the exact intended tag: ```text -python checks/check_coordinator_release.py --expected-tag v0.9.1 +python checks/check_coordinator_release.py --expected-tag v0.9.2 ``` The command fails before building unless the canonical intended tag matches diff --git a/README.md b/README.md index 63f5858..01c4753 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ wall or claiming adoption: ```text # Install the current tagged release. -python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.1.zip" +python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.2.zip" # Installed command writwall start --project-root /path/to/your-project diff --git a/REUSE.toml b/REUSE.toml index 2630da5..28c72db 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -16,6 +16,7 @@ path = [ "docs/assets/**", "docs/agents/**", "docs/architect-interview.md", + "docs/bootstrap-charter-addendum.md", "docs/day-zero-coordinator.md", "docs/identity-migration.md", "docs/name-clearance.md", @@ -26,6 +27,7 @@ path = [ "migration-guides/**", "projection/**", "skills/writwall-adopt/*.md", + "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", "skills/writwall-adopt/references/**", ] SPDX-FileCopyrightText = "2026 HLLMR Ventures LLC" diff --git a/START-HERE.md b/START-HERE.md index eeb6477..ba5fda4 100644 --- a/START-HERE.md +++ b/START-HERE.md @@ -63,13 +63,14 @@ not clear results. project: ```text - python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.1.zip" + python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.9.2.zip" ``` - Release `v0.9.0` first introduced the coordinator. Release `v0.9.1` corrects - first-use bytecode residue and is the minimum recommended coordinator - release. If you are testing an unpublished release candidate, use its checked - external candidate tree and the release gate in `PUBLICATION.md`. + Release `v0.9.0` first introduced the coordinator. Release `v0.9.1` corrected + first-use bytecode residue. Release `v0.9.2` corrects the bootstrap + expected-denial contract and is the minimum recommended coordinator release. + If you are testing an unpublished release candidate, use its checked external + candidate tree and the release gate in `PUBLICATION.md`. 2. Run one command: ```text @@ -192,6 +193,15 @@ not retroactively promoted into a birth test. ## Make the birth test safe +Before registering the wall or starting Level 1, confirm the provider's +engine-visible pre-adoption charter contains the complete text of +`assets/bootstrap-charter-addendum.md` from the local adoption bundle. That temporary +rule resolves the bootstrap boundary without weakening it: ordinary no-pointer +work remains forbidden, while exact calls named by a durably Owner-ratified +birth-test lifecycle may be dispatched solely so the wall can deny them. The +attempt confers no mutation authority; denial is the only valid outcome, and +any success stops adoption. Remove the addendum before the adoption commit. + Start with a **minimal provider profile**. Disable unrelated plugins, connectors, MCP servers, and delegated agents before inventorying the mutation surface. If an external mutation tool must remain available, test it only when diff --git a/adapters/claude-code/README.md b/adapters/claude-code/README.md index 83e2d94..8b0defb 100644 --- a/adapters/claude-code/README.md +++ b/adapters/claude-code/README.md @@ -272,7 +272,13 @@ The birth test is worthless if run outside the operating envelope. Establish the 4. **Confirm the displayed command resolves through `${CLAUDE_PROJECT_DIR}`.** 5. **Run `--preflight`** with the exact installed digest, settings path, and native platform. It must pass without a denial-log change. 6. **Confirm no active-WO pointer exists** (`.claude/active-wo.txt` absent). -7. **Only then begin real provider-level mutation probes.** +7. **Confirm the engine-visible pre-adoption charter contains the complete + `assets/bootstrap-charter-addendum.md` text from the local adoption bundle.** + Ordinary no-pointer work remains forbidden; only exact calls named by a + durably Owner-ratified lifecycle may be dispatched solely to test denial. + The attempt confers no mutation authority, denial is the only valid outcome, + and any success stops adoption. +8. **Only then begin real provider-level mutation probes.** **The `/hooks` inspection is necessary configuration evidence, not proof of live enforcement.** It shows what Claude Code believes it has loaded. It does not show that the session executing your probes actually loaded it. Only observed denial of real tool calls constitutes the birth test (8.3.5). Invoking the adapter directly with a synthetic payload verifies its logic and nothing else; it must never be recorded as a passing birth test. diff --git a/checks/check_coordinator_release.py b/checks/check_coordinator_release.py index e419630..ff98b83 100644 --- a/checks/check_coordinator_release.py +++ b/checks/check_coordinator_release.py @@ -34,6 +34,7 @@ "NAME-CLEARANCE.md", "OWNER-RATIFICATION.md", "writwall-adopt/SKILL.md", + "writwall-adopt/assets/bootstrap-charter-addendum.md", "writwall-adopt/assets/scripts/collect_name_clearance.py", "writwall-adopt/assets/checks/check_name_clearance.py", "writwall-adopt/references/name-clearance.md", diff --git a/checks/check_distribution.py b/checks/check_distribution.py index 280853d..afaacd6 100644 --- a/checks/check_distribution.py +++ b/checks/check_distribution.py @@ -138,6 +138,8 @@ def machine_path_occurs(text: str, needle: str) -> bool: REPO_ROOT / "checks" / "check_name_clearance.py", SKILL / "references" / "name-clearance.md": REPO_ROOT / "docs" / "name-clearance.md", + SKILL / "assets" / "bootstrap-charter-addendum.md": + REPO_ROOT / "docs" / "bootstrap-charter-addendum.md", **{ SKILL / "assets" / "templates" / name: REPO_ROOT / "templates" / name for name in TEMPLATE_FILES.values() diff --git a/checks/check_public_projection.py b/checks/check_public_projection.py index 10b35ab..a2da714 100644 --- a/checks/check_public_projection.py +++ b/checks/check_public_projection.py @@ -105,12 +105,39 @@ def find_retained_tokens(line: str) -> list[str]: "at the source commit named in `PROJECTION-PROVENANCE.md`. Push, " "publication, visibility, and queued-work statements below describe that " "checkpoint, not the current public copy.") +CURRENT_PUBLIC_RECORDS = frozenset({ + "README.md", + "ADOPTING.md", + "START-HERE.md", + "PUBLICATION.md", + "CONTRIBUTING.md", + "SECURITY.md", + "governance/PLAN.md", + "governance/STATE.md", +}) +WINDOWS_ABSOLUTE_PATH = re.compile( + r"(?|]+)") +WINDOWS_PATH_PLACEHOLDER = re.compile( + r"^[A-Za-z]:\\+path\\+to\\+your-project(?:[\\/]|$)", re.IGNORECASE) +POSIX_CONCRETE_HOST_PATH = re.compile( + r"(?|]+/[^\s`\"'<>|]+" + r"|/mnt/[A-Za-z]/[^\s`\"'<>|]+)") PRIVATE_EVIDENCE_REDACTION_FILES = frozenset({ "governance/LOG.md", }) PRIVATE_EVIDENCE_REDACTION = "[private governed-source identifier omitted]" +def current_record_has_concrete_host_path(relative: str, text: str) -> bool: + """Reject concrete host paths in current public records, not history.""" + if relative not in CURRENT_PUBLIC_RECORDS: + return False + if any(not WINDOWS_PATH_PLACEHOLDER.match(match.group(1)) + for match in WINDOWS_ABSOLUTE_PATH.finditer(text)): + return True + return POSIX_CONCRETE_HOST_PATH.search(text) is not None + + def transform_expected_private_evidence(relative: str, data: bytes, patterns: list[str]) -> bytes: if relative not in PRIVATE_EVIDENCE_REDACTION_FILES: @@ -377,6 +404,8 @@ def verify(root: Path, pattern_file: Path | None = None) -> None: identifiers.setdefault(identifier, set()).add(relative) if any(pattern.casefold() in folded for pattern in patterns): fail("candidate contains a private disclosure pattern") + if current_record_has_concrete_host_path(relative, text): + fail("candidate contains host-specific data in a current public record") if any(needle and machine_path_occurs(text, needle) for needle in host_needles): fail("candidate contains host-specific data") diff --git a/docs/bootstrap-charter-addendum.md b/docs/bootstrap-charter-addendum.md new file mode 100644 index 0000000..9d3918e --- /dev/null +++ b/docs/bootstrap-charter-addendum.md @@ -0,0 +1,17 @@ +# Pre-adoption charter addendum: expected-denial probes + +This temporary addendum applies only during Writwall bootstrap. Copy its rule +verbatim into the provider's engine-visible pre-adoption charter before wall +registration or any Level 1 probe, and remove it before the adoption commit. + +Ordinary no-pointer work remains forbidden. The sole exception is an exact, +durably Owner-ratified birth-test lifecycle that names specific expected-denial +probe calls while no active-work-order pointer exists. The agent may dispatch +only those named calls, solely so the installed wall can deny them. Each call is +a falsification probe, not product work, and confers no mutation authority. +Denial is the only valid outcome. Any mutation success, required call rejected +before hook dispatch, missing denial evidence, or target-byte drift stops the +birth test and leaves adoption ineffective. This exception grants no authority +to create or alter an activation pointer, work order, control-plane file, +project content, external object, or any target not named by the ratified +lifecycle. diff --git a/governance/LOG.md b/governance/LOG.md index 31cb3fe..5d57809 100644 --- a/governance/LOG.md +++ b/governance/LOG.md @@ -739,6 +739,139 @@ and whitespace passed; distribution reported exactly the three expected active records. No tag, release, public issue #20 PR, pilot regeneration, adoption, or external-project mutation occurred before acceptance. +### Post-pilot WO-WW-010 completed record + +WO-WW-010 is post-pilot and does not add an eleventh metrics row or change the +accepted ten-order aggregate. The Owner accepted it on 2026-09-01 and reported +active minutes **NOT REPORTED**. + +External Pilot A exposed public issue #22 when the generated pre-adoption +charter's ordinary no-pointer prohibition also caused a conforming provider to +refuse the exact Level 1 probes before hook dispatch. No forbidden mutation +succeeded and no adoption was claimed. The accepted correction adds one +temporary engine-visible bootstrap contract: ordinary no-pointer work remains +forbidden; only exact calls named by a durably Owner-ratified lifecycle may be +attempted solely so the wall can deny them; denial is the only valid outcome; +and any success or missing evidence stops adoption. + +The first fresh review returned four blockers in contract-test strength, the +permanent-template negative assertion, record truth, and the missing final +governed-source Windows rerun. All were corrected. The same Reviewer returned +**ACCEPT — HIGH confidence** after independently confirming the corrected +contract tests, permanent-template exclusion, active dispatch, identity, three +expected release transients, and byte-identical bundle pairs. + +Final governed-source Windows passed 735 tests with two skips; native Ubuntu +passed 735 with three. Two independent 136-file public candidates were +checker-clean and byte-identical at complete-ledger SHA-256 +`D14629AE590B8E1DC556D428B0B06F6EC4EAAA07F4146E374654815C9BEA800F`. +Identity, licensing, dispatch, and whitespace passed. Disclosed deviations were +environment-only Python/Git diagnostics, test-mediated and one coordinator +read-boundary departure with no implementation impact, and detected/removed +bytecode residue. No commit, push, public projection mutation, release, or +external-project mutation occurred before acceptance. + +### Post-pilot WO-WW-011 completed record + +WO-WW-011 is post-pilot and does not add an eleventh metrics row or change the +accepted ten-order aggregate. The Owner accepted it on 2026-09-01 and reported +active minutes **NOT REPORTED**. + +The first authorized post-WO-WW-010 public candidates were projection-clean and +byte-identical but correctly failed the existing intended-tag gate because +current metadata still declared `0.9.1`. Both candidates were deleted. A narrow +RED/GREEN release-identity order advanced package metadata, current install URLs, +publication/contribution commands, and executable tests to exact `0.9.2` / +`v0.9.2` while preserving historical `v0.9.0` and `v0.9.1` facts. The release +checker itself remained byte-unchanged. + +Windows passed the complete 735-test suite with two skips; native Ubuntu passed +all 13 release-gate tests. Two independent 136-file candidates passed projection +and installed-release gates and were byte-identical at manifest SHA-256 +`DAF33DFC8CFF973B2590B4A2D591C1A61596BF2AEFAB3EC2FC2762EEB11E0514`. +Fresh review returned one report-only distribution-evidence omission; after +correction and exact rerun, re-review returned **ACCEPT — HIGH confidence**. + +One Ubuntu test trap left its temporary F: mount busy because the shell still +occupied the mounted working directory; a separate command from `/` removed the +mount and empty mountpoint and verified absence. No persistent environment, +repository, public, or external-project mutation occurred before acceptance. + +### Post-pilot WO-WW-012 completed record + +WO-WW-012 is post-pilot and does not add an eleventh metrics row or change the +accepted ten-order aggregate. The Owner accepted it on 2026-09-01 and reported +active minutes **NOT REPORTED**. + +Fresh publication review of the otherwise valid post-WO-WW-011 candidates found +that the wheel's exhaustive installed-file map omitted the canonical bootstrap +charter addendum and that the release gate did not require it while claiming a +complete handoff. Both invalid candidates were deleted before this order began. +RED tests proved the missing required inventory, missing packaging entry, and +fail-open omission path. GREEN added the exact existing asset to the wheel map +and mandatory handoff inventory without broad discovery or another source copy. + +Windows passed 738 tests with two skips; native Ubuntu passed all 16 release +tests. Two independent 136-file candidates passed projection and installed +`v0.9.2` release gates and were byte-identical at manifest SHA-256 +`56F9B5F262A399642ECC098329312C0BA75A6B962884CDDEC4C2ECC89178E724`. +Fresh review returned one record-only wording correction; corrected re-review +returned **ACCEPT — HIGH confidence**. Temporary candidates, cache residue, and +the Ubuntu mount were deleted and verified absent. No public mutation, release, +tag, deployment, visibility change, or External Pilot A mutation occurred before +acceptance. The unrelated Owner deletion of `dist/plumbline-0.6.zip` (private governed-source reference, not present in this candidate) remained outside this +work order. + +### Post-pilot WO-WW-013 completed record + +WO-WW-013 is post-pilot and does not add an eleventh metrics row or change the +accepted ten-order aggregate. The Owner accepted it on 2026-09-01 and reported +active minutes **NOT REPORTED**. + +The first post-WO-WW-012 projection pair failed closed because that completed +record named an omitted private distribution path without the exact same-line +private-source qualifier. Both candidates were deleted. The first correction +wrapped the qualifier onto the next physical line and remained RED; the next +pair exposed the same literal unnecessarily repeated in the newly issued Plan. +That pair was also deleted. The LOG qualifier was kept on the path's physical +line and the Plan was rewritten without the literal; no checker was weakened. + +Two final 136-file candidates passed projection and installed `v0.9.2` release +gates and were byte-identical at manifest SHA-256 +`0ED0848BDF05F56B9564D9904B3A4711DEEC15BCFA918F928B57C5C13DF7B07B`. +The unchanged governed-source release suite passed 16/16. Identity, licensing, +dispatch, and whitespace passed. Fresh review returned **ACCEPT — HIGH +confidence**. All temporary candidates were deleted and verified absent. No +product, checker, public, release, tag, deployment, visibility, or External +Pilot A mutation occurred before acceptance. + +### Post-pilot WO-WW-014 completed record + +WO-WW-014 is post-pilot and does not add an eleventh metrics row or change the +accepted ten-order aggregate. The Owner accepted it on 2026-09-01 and reported +active minutes **NOT REPORTED**. + +Fresh final publication review blocked an otherwise valid `v0.9.2` candidate +pair because an earlier current-use Plan section retained a concrete sibling +project path. The Plan reference is now host-neutral, and the independent +projection checker rejects concrete Windows, macOS, Linux-home, and mounted-drive +paths in current public records without echoing their values. Canonical path +placeholders and historical evidence remain permitted. + +Windows passed 743 tests with two skips; the Windows and Ubuntu projection suites +each passed 68 tests. Two 136-file candidates passed projection and installed +`v0.9.2` release gates and were byte-identical at manifest SHA-256 +`6B0B72CDBA64CDA7BA684BCFAE7139AE185C965BBE5FCE0066B22C28DFC744E5`. +Fresh review initially blocked on missing replay commands. The source gate then +rejected the first corrected record for embedding concrete local command paths; +environment-derived commands resolved both findings, and corrected re-review +returned **ACCEPT — HIGH confidence**. The order's candidates were deleted. One +inaccessible invalid candidate from the preceding publication review remains +isolated under the OS temporary area after ordinary and native-Ubuntu cleanup +were denied by its ACL; it contains no accepted release bytes or private input. +No public mutation, release, tag, deployment, visibility change, or External +Pilot A mutation occurred before acceptance. + --- ## Column definitions diff --git a/governance/PLAN.md b/governance/PLAN.md index 630ed24..e902bdc 100644 --- a/governance/PLAN.md +++ b/governance/PLAN.md @@ -484,8 +484,8 @@ the Writwall migration. The remaining sequence is: the Owner accepted the disclosed deviations. The separate `v0.9.0` publication decision remains unmade. 2. **External pilot A — `hllmr-media`.** After the release gate is accepted, - move the current unversioned `F:\Projects\LinkedIn` corpus to the truthful - broader project identity, run `writwall start`, and exercise the complete + move the current unversioned external media corpus to the truthful broader + project identity, run `writwall start`, and exercise the complete handoff and adoption path on low-risk content operations. 3. **External pilot B — `hllmr-site`.** Recover from the abandoned partial bootstrap using a fresh session and the accepted coordinator packet. The @@ -527,3 +527,106 @@ regenerated topology keeps the human as Owner, the Owner-Agent as coordinator and dispatcher, the repository agent as bounded Operator, and the existing infrastructure agent behind a separate inert operations packet. Adoption of the external project and content mutation remain separate decisions. + +## 19. External Pilot A bootstrap-contract correction — 2026-08-31 + +External Pilot A reached the installed v0.9.1 birth test and exposed public +issue #22. The generated pre-adoption charter correctly forbids ordinary +mutation without an active work order, but the same absolute instruction made +a conforming provider refuse the exact Owner-ratified Level 1 expected-denial +probes before the installed hook could inspect them. Three provider sessions +were consumed without a complete birth test; no forbidden mutation succeeded +and no birth certificate is claimed. + +**WO-WW-010 — COMPLETE, accepted 2026-09-01: bootstrap expected-denial probe +contract.** Preserve the +ordinary no-pointer prohibition while defining one narrow engine-visible +bootstrap exception: an exact Owner-ratified birth-test lifecycle may direct +named probe attempts solely to falsify the wall, the attempts confer no +mutation authority, every valid outcome is denial, and any success stops the +adoption. Bind the coordinator handoff, adoption skill, adopter documentation, +adapter README copies, and executable generated-text regressions to the same +contract. After acceptance and publication through a separately authorized +patch release, regenerate only External Pilot A's affected bootstrap/adoption +material and repeat one fresh native Windows birth test. Media-content work, +website work, DNS/mail work, and other external mutation remain unauthorized. +Final governed-source Windows and Ubuntu suites each passed 735 tests; two +136-file public candidates were byte-identical; corrected fresh review returned +ACCEPT/HIGH. + +## 20. v0.9.2 release identity — 2026-09-01 + +WO-WW-010 closed the bootstrap expected-denial contract and its private +closeout commit was pushed. The first authorized post-closeout public candidates +were independently checker-clean and byte-identical, but the executable release +gate correctly refused intended tag `v0.9.2` because package metadata and current +install/publication guidance still declared `v0.9.1`. Those invalid candidates +were deleted. + +**WO-WW-011 — COMPLETE, accepted 2026-09-01: v0.9.2 release identity.** Advance only the current +release identity across package metadata, installation and publication guidance, +and the executable release contract. Preserve truthful historical `v0.9.0` and +`v0.9.1` statements. After verification and acceptance, resume the already +authorized dual projection, fresh publication review, issue #22 PR, protected-CI +merge, `v0.9.2` release, and exactly one regenerated External Pilot A native +Windows birth test. No media-content, website, DNS, mail, or unrelated product +work is authorized. +Final Windows passed 735 tests; native Ubuntu passed the complete 13-test release +file; two 136-file candidates passed projection and installed-release checks and +were byte-identical; corrected fresh review returned ACCEPT/HIGH. + +## 21. Installed bootstrap-bundle completeness — 2026-09-01 + +After WO-WW-011 closeout, two final 136-file public candidates passed the +existing projection and release gates and were byte-identical. Fresh publication +review blocked release: the wheel's exhaustive data-file map omitted +`skills/writwall-adopt/assets/bootstrap-charter-addendum.md`, and the release +gate did not enumerate that file while claiming a complete installed handoff. +Both invalid candidates were deleted; no public branch, PR, tag, release, or +pilot rerun occurred. + +**WO-WW-012 — COMPLETE, accepted 2026-09-01: installed bootstrap-bundle +completeness.** The existing canonical addendum is now packaged at the installed +path named by generated guidance, the release gate requires that exact path, and +executable tests prove both the complete installed handoff and deterministic +failure when the packaging entry is removed. Windows passed 738 tests with two +skips; Ubuntu passed the complete 16-test release file; two 136-file candidates +were projection/release-clean and byte-identical; corrected fresh review returned +ACCEPT/HIGH. Resume the authorized dual post-closeout projection, fresh +publication review, issue #22 PR, protected-CI merge, `v0.9.2` release, and one +External Pilot A Windows birth test. No other feature, media, website, DNS, mail, +or external work is active. + +## 22. Post-closeout projection-reference truth — 2026-09-01 + +The first post-WO-WW-012 projection pair failed closed before release because +the new completed LOG record named an omitted private distribution path without +the required private-governed-source retained-reference qualifier. Both invalid +candidates were deleted and no public state changed. + +**WO-WW-013 — COMPLETE, accepted 2026-09-01: post-closeout +projection-reference truth.** The completed WO-WW-012 LOG record now carries the +exact same-line private-source qualifier required for its omitted path. The +unchanged checker also caught and removed an unnecessary repetition of that +literal from the issued Plan. Two final 136-file candidates passed projection +and installed `v0.9.2` release gates and were byte-identical; fresh review +returned ACCEPT/HIGH. Resume the authorized public release and External Pilot A +tail without changing product or checker bytes. + +## 23. Public current-record host-path privacy — 2026-09-01 + +Fresh final publication review blocked the otherwise valid v0.9.2 candidate pair +because an earlier current-use Plan section retained a concrete host path to the +external media corpus. Existing gates rejected this machine's repository root +and human-supplied private patterns but did not reject a concrete sibling-project +path when the private profile omitted it. No public state changed. + +**WO-WW-014 — COMPLETE, accepted 2026-09-01: public current-record host-path +privacy.** The current-use Plan reference is host-neutral, and the independent +projection checker now rejects concrete Windows, macOS, Linux-home, and +mounted-drive paths in current public-facing records while preserving canonical +placeholders and historical evidence. Windows passed 743 tests with two skips; +the Windows and Ubuntu projection suites each passed 68 tests; two 136-file +candidates passed projection and installed `v0.9.2` release gates and were +byte-identical. Fresh corrected-record review returned ACCEPT/HIGH. Resume the +authorized public release and External Pilot A tail. diff --git a/governance/STATE.md b/governance/STATE.md index 8d90538..03aa924 100644 --- a/governance/STATE.md +++ b/governance/STATE.md @@ -15,21 +15,50 @@ accepted WO-WW-003 retained-identity ledger refresh, accepted WO-WW-004 managed day-zero privacy screening, accepted WO-WW-005 GitHub Actions Node 24 refresh, and accepted WO-WW-006 coordinator release readiness and external smoke work, accepted WO-WW-007 first-use bytecode-residue correction, -accepted WO-WW-008 State derivation endpoint correction, and accepted -WO-WW-009 patch-release identity correction. -Release `v0.9.0` is public. External Pilot A reached an unratified bootstrap +accepted WO-WW-008 State derivation endpoint correction, accepted WO-WW-009 +patch-release identity correction, and accepted WO-WW-010 bootstrap +expected-denial probe contract correction, accepted WO-WW-011 v0.9.2 release +identity correction, accepted WO-WW-012 installed bootstrap-bundle completeness +correction, accepted WO-WW-013 post-closeout projection-reference truth, and +accepted WO-WW-014 public current-record host-path privacy. +Release `v0.9.1` is public. External Pilot A reached an unratified bootstrap handoff and exposed public issue #16: normal first use could copy Python bytecode residue into coordinator output. Public PR #17 merged the accepted correction and closed issue #16. **WO-WW-009 is COMPLETE and accepted**; package metadata, current install guidance, and the mandatory intended-tag gate agree on `v0.9.1`. The authorized post-closeout projection, public PR, protected-CI -merge, patch release, and pilot regeneration remain unstarted. +merge, patch release, and pilot regeneration completed. External Pilot A then +exposed public issue #22 when a conforming provider followed the bootstrap +charter and refused the required no-pointer birth-test probes before hook +dispatch. **WO-WW-010 is COMPLETE and accepted**; its authorized private +closeout, public patch-release tail, and one regenerated External Pilot A birth +test are in progress. The first two post-closeout candidates were checker-clean +and byte-identical but correctly failed the intended-tag gate because their +current release identity remained `v0.9.1`; they were deleted. **WO-WW-011 is +COMPLETE and accepted** with exact current identity `v0.9.2`; its authorized +private closeout, public release tail, and one External Pilot A birth test are in +progress. The first final publication review blocked because the installed wheel +and release gate both omitted the new bootstrap addendum; both candidates were +deleted. **WO-WW-012 is COMPLETE and accepted**: the canonical addendum is now +packaged in the installed adoption bundle and required by the external release +gate. Its authorized private closeout, public release tail, and one External +Pilot A birth test are in progress. The first post-closeout candidates failed +closed on one unqualified private-only path in the new LOG record and were +deleted. **WO-WW-013 is COMPLETE and accepted**: the record is qualified, the +issued Plan no longer repeats the literal, and the final pair passed. The public +release and pilot tail remain in progress. No external media content, website, +DNS, or mail mutation is active. Fresh final publication review then found one +concrete sibling-project host path in an earlier current-use Plan section. +**WO-WW-014 is COMPLETE and accepted**: the Plan reference is host-neutral and +the projection checker now rejects concrete Windows, macOS, Linux-home, and +mounted-drive paths in current public records without echoing their values. The +authorized public release and pilot tail resume. **Derived:** 2026-08-31 from the ten accepted pilot records, the Doctrine 9.3.1 fresh-agent evaluation, ratified DR-002 and project-migration DR-003, and accepted WO-PL-017 through WO-PL-023 and WO-PL-025 through WO-PL-033 records, the WO-PL-024 sequencing recovery, the verified public-release event, and the -accepted WO-WW-001 through WO-WW-009 closeout records. +accepted WO-WW-001 through WO-WW-014 closeout records. **Boundary:** post-adoption, all 10 counted pilot work orders and their evaluation complete; WO-PL-017 remediation complete; DR-003 ratified; WO-PL-018 through WO-PL-023 complete; WO-PL-024 void before implementation; @@ -41,7 +70,7 @@ the current identity with the two-line wall glyph; WO-PL-039 complete and accepted, with public PR #5 merged after the required CI passed and issue #4 closed; WO-PL-040 complete and accepted; public PR #8 merged and issue #1 closed; the historical `WO-PL` series ends at 040; **WO-WW-001 through -WO-WW-009 are COMPLETE and accepted**; public PR #9, #12, #13, and #17 merged with +WO-WW-014 are COMPLETE and accepted**; public PR #9, #12, #13, and #17 merged with protected CI green; public issue #11 is closed; public issue #14 records the coordinator release gate; release `v0.9.0` is published; public issue #16 records the corrected cache-residue defect found by the first unratified @@ -110,7 +139,12 @@ externally. | WO-WW-007 | **COMPLETE**, accepted 2026-08-31; first-use bytecode-residue correction. Installed wheel evidence proved 3 cache directories and 4 `.pyc` files existed before first start and were copied into the handoff. Two public-interface RED/GREEN cycles made output intrinsically cache-free and made the release gate run normal bytecode behavior and reject residue. Windows passed 725 tests with two skips; native Ubuntu external-candidate verification passed; fresh review returned **ACCEPT WITH NON-BLOCKING NOTE/HIGH confidence**. Owner active minutes **NOT REPORTED**. Public issue #16 remains open pending the separately authorized projection PR and patch release; the unratified external bootstrap remains preserved pending published correction | | WO-WW-008 | **COMPLETE**, accepted 2026-08-31; record-only State derivation endpoint correction. The accepted State snapshot endpoint now includes WO-WW-007, and ordinary closeout advances the derivation endpoint through WO-WW-008. The State correction changed only its two mechanically dependent identity digests; closeout also refreshed the retained LOG source digest after appending this completion record. Focused regression passed 462 tests with two skips; corrected fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. Public issue #16 remains open pending the separately authorized projection PR; merge and release remain unauthorized | | WO-WW-009 | **COMPLETE**, accepted 2026-08-31; patch-release identity correction. Package metadata and current onboarding guidance now identify `v0.9.1`; the external release checker requires a canonical ASCII intended tag and proves exact metadata agreement before building. Windows passed 729 tests with two skips; native Ubuntu passed 13 affected tests; corrected fresh re-review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. Public issue #20 proceeds through the authorized post-closeout projection/PR and protected-CI release tail | -| Post-pilot sequence | **WO-PL-017 through WO-PL-023 COMPLETE**; WO-PL-024 **VOID BEFORE IMPLEMENTATION**; WO-PL-025 through WO-PL-040 **COMPLETE**; historical `WO-PL` identifiers end at 040; **WO-WW-001 through WO-WW-009 COMPLETE and accepted**; public PR #9, #12, #13, and #17 merged with protected CI green; public issues #1, #4, #10, #11, and #16 closed; public issue #14 records the accepted release gate; `v0.9.0` is published; issue #20 awaits the authorized `v0.9.1` release-identity PR; external media regeneration, website, DNS, and mail pilots remain queued | +| WO-WW-010 | **COMPLETE**, accepted 2026-09-01; public issue #22 records the External Pilot A bootstrap-contract contradiction. Ordinary no-pointer mutation remains forbidden; only exact calls named by a durably Owner-ratified lifecycle may reach the wall as expected-denial probes, with denial the sole valid outcome and any success stopping adoption. Final Windows passed 735 tests with two skips; native Ubuntu passed 735 with three; two 136-file public candidates were checker-clean and byte-identical; corrected fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. Authorized private closeout, public v0.9.2 release tail, and one regenerated External Pilot A birth test remain in progress | +| WO-WW-011 | **COMPLETE**, accepted 2026-09-01; the existing release gate caught package/docs identity `v0.9.1` before an intended `v0.9.2` release. Current metadata, install URLs, publication/contribution commands, and executable tests now agree on `0.9.2` / `v0.9.2`, while historical `v0.9.0` and `v0.9.1` facts remain. Windows passed 735 tests with two skips; Ubuntu passed 13 release tests; two 136-file candidates were projection/release-clean and byte-identical; corrected fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. Authorized private closeout, public release tail, and one External Pilot A birth test remain in progress | +| WO-WW-012 | **COMPLETE**, accepted 2026-09-01; the installed wheel now includes the exact canonical bootstrap addendum and the release gate requires it as part of every complete handoff. Removing the packaging entry fails deterministically. Windows passed 738 tests with two skips; native Ubuntu passed 16 release tests; two 136-file candidates were projection/release-clean and byte-identical; corrected fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. The authorized v0.9.2 release tail and one External Pilot A birth test remain in progress | +| WO-WW-013 | **COMPLETE**, accepted 2026-09-01; the completed WO-WW-012 LOG record now qualifies its omitted private-only path on the same physical line. The unchanged checker also caught an unnecessary repetition in the issued Plan before publication. Two final 136-file candidates passed projection and installed `v0.9.2` release gates and were byte-identical; fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. Product and checker bytes were unchanged; the public release and pilot tail remain in progress | +| WO-WW-014 | **COMPLETE**, accepted 2026-09-01; the earlier current-use Plan reference is host-neutral and the projection checker rejects concrete Windows, macOS, Linux-home, and mounted-drive paths in current public records without echoing values. Windows passed 743 tests with two skips; Windows and Ubuntu projection suites each passed 68 tests; two 136-file candidates were projection/release-clean and byte-identical; corrected fresh review returned **ACCEPT — HIGH confidence**. Owner active minutes **NOT REPORTED**. The authorized public release and External Pilot A tail resume | +| Post-pilot sequence | **WO-PL-017 through WO-PL-023 COMPLETE**; WO-PL-024 **VOID BEFORE IMPLEMENTATION**; WO-PL-025 through WO-PL-040 **COMPLETE**; historical `WO-PL` identifiers end at 040; **WO-WW-001 through WO-WW-014 COMPLETE and accepted**; public PR #9, #12, #13, #17, and #21 merged with protected CI green; public issues #1, #4, #10, #11, #16, and #20 closed; public issue #14 records the accepted release gate; `v0.9.1` is published; issue #22 proceeds through the authorized v0.9.2 release tail; external media regeneration, website, DNS, and mail pilots remain queued | | Bootstrap history | Eleven completed work orders retained as uncounted pre-adoption evidence under `archive/pre-adoption-bootstrap/` | ### Verification accepted at WO-PL-016 closeout diff --git a/identity/legacy-references.json b/identity/legacy-references.json index 960e520..97ba437 100644 --- a/identity/legacy-references.json +++ b/identity/legacy-references.json @@ -16,7 +16,7 @@ { "path": "README.md", "context": "migration_provenance", - "sha256": "ffbaa02e98a62fb5d6ac9fe9b831a195c1b41c7e413484863b769d17101554de" + "sha256": "e81903350f305351ccd52e7acaa584b4683b7ba65fa1ecbeb2c048eec357e483" }, { "path": "SELF-HOSTING.md", @@ -31,7 +31,7 @@ { "path": "checks/check_distribution.py", "context": "historical_evidence_path", - "sha256": "d1622d215a079a83156213ca5dd8e814308d1012421bc82b7490e2137360c504" + "sha256": "b872c46f8a8ea2fc317b4c4fd0af00c9145012b11256c923987d878d79c726c2" }, { "path": "checks/check_identity.py", @@ -94,19 +94,19 @@ { "path": "governance/LOG.md", "context": "historical_pilot_summary", - "sha256": "8323b3fb10cbb7ac098ffda6f537563c39ec7907c750dd948a16bcdfc69b21ad", + "sha256": "6cd8bb10ebd50071b2f355c1934fdbb525452dabeee7cc98f24eaddf03a1fef6", "projection_transform": "private_evidence_redaction" }, { "path": "governance/PLAN.md", "context": "ratified_historical_intent", - "sha256": "09264752687c0d88f32ff2907c6e5d543251441383a20ef29151f56b42baa898" + "sha256": "fcbdd620daea8b69e35ecb859f08f5332ceb89f6ac5dc9a293096b4190e4d437" }, { "path": "governance/STATE.md", "context": "mixed_current_state_and_history", - "sha256": "7d1f655ba103262270200e512032dd5c850af84c1cacabf4d04a4edb9eb8f128", - "projection_sha256": "437e7bb9334732cf58f7fed56d2081fdd33c0032a07eb93dd786bcd337dc0b9f" + "sha256": "0340951b66d939bcdff576a8f0bff66401aea4353f021882a81646370994c474", + "projection_sha256": "609d2afa9e0bb198caebbfc08aee0b541fd713041b106d66100b5670bdf9639a" }, { "path": "governance/decisions/DR-001.md", @@ -122,12 +122,12 @@ { "path": "projection/public-files.txt", "context": "historical_path_index", - "sha256": "393e7582af9d4ffa3bc8f574c179f8d4234f3a05b1416152c3bb0551855e7d97" + "sha256": "fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7" }, { "path": "tests/test_distribution.py", "context": "historical_evidence_fixture", - "sha256": "271a2e0e6e2ad79d48a0c6ae53d60648d51fe338d2d578e08b9e9416cd912dd2" + "sha256": "22901437098bb4883153af4f8d02f14e02585343791ca813aa425e2956510927" }, { "path": "tests/test_identity_migration.py", diff --git a/projection/public-files.txt b/projection/public-files.txt index c967b94..64a5642 100644 --- a/projection/public-files.txt +++ b/projection/public-files.txt @@ -46,6 +46,7 @@ docs/assets/writwall-og.png docs/assets/writwall-og.svg docs/assets/writwall-readme-banner-0a5259d8.png docs/assets/writwall-readme-banner.svg +docs/bootstrap-charter-addendum.md docs/day-zero-coordinator.md docs/identity-migration.md docs/name-clearance.md @@ -96,6 +97,7 @@ skills/writwall-adopt/LICENSE-MAP.md skills/writwall-adopt/SKILL.md skills/writwall-adopt/assets/adapters/claude-code/README.md skills/writwall-adopt/assets/adapters/claude-code/wo_capability_wall.py +skills/writwall-adopt/assets/bootstrap-charter-addendum.md skills/writwall-adopt/assets/checks/check_name_clearance.py skills/writwall-adopt/assets/checks/check_work_order_dispatch.py skills/writwall-adopt/assets/scripts/collect_name_clearance.py @@ -114,6 +116,7 @@ templates/B-work-order.md templates/C-owner-brief.md templates/D-adoption-record.md templates/E-adoption-mapping.md +tests/test_bootstrap_contract.py tests/test_check_distribution.py tests/test_check_licenses.py tests/test_check_work_order_dispatch.py diff --git a/pyproject.toml b/pyproject.toml index 849396e..b176d1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "writwall" -version = "0.9.1" +version = "0.9.2" description = "Start governed project work from an idea." requires-python = ">=3.10" license = "Apache-2.0" @@ -31,6 +31,9 @@ include-package-data = false "skills/writwall-adopt/references/migration-guides/0.6-to-0.7.md", "skills/writwall-adopt/references/migration-guides/0.7-to-0.8.md", ] +"share/writwall/writwall-adopt/assets" = [ + "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", +] "share/writwall/writwall-adopt/assets/adapters/claude-code" = [ "skills/writwall-adopt/assets/adapters/claude-code/README.md", "skills/writwall-adopt/assets/adapters/claude-code/wo_capability_wall.py", diff --git a/scripts/start_writwall.py b/scripts/start_writwall.py index 11a01dd..cf8b2b2 100644 --- a/scripts/start_writwall.py +++ b/scripts/start_writwall.py @@ -452,7 +452,13 @@ def next_prompt(state: ObservedState) -> tuple[str, str]: and ratify; perform every clerical step an authorized recorder may perform. Ask one question at a time in plain language, recommendation first. Do not install or register the wall until the complete bundle and recovery instructions -are locally readable. Do not begin product work or WO-001 before adoption.""", +are locally readable. Before registration or any Level 1 call, copy +`.writwall-bootstrap/writwall-adopt/assets/bootstrap-charter-addendum.md` +verbatim into the engine-visible pre-adoption charter. Ordinary no-pointer work +remains forbidden; the addendum permits only exact expected-denial probes named +by a durably Owner-ratified lifecycle and confers no mutation authority. Denial +is the only valid outcome, and any success stops adoption. Remove it before the +adoption commit. Do not begin product work or WO-001 before adoption.""", ) if state.name == "partial_bootstrap": return ( diff --git a/skills/writwall-adopt/SKILL.md b/skills/writwall-adopt/SKILL.md index 86970a8..850bc67 100644 --- a/skills/writwall-adopt/SKILL.md +++ b/skills/writwall-adopt/SKILL.md @@ -143,7 +143,7 @@ surfaces and follow the same collision check. **Phase B: Layout.** Create `governance/` per Doctrine 5.2 (`PLAN.md` is NOT created by you; `STATE.md` OBSERVED only; `ROUTING.md` proposed only; `decisions/`, `work-orders/`, `reports/`, `briefs/`, `rfis/`, `history/`, `archive/`, `LOG.md` with the 9.2 column header, `LOG-denials.jsonl` empty). Copy the templates from `assets/templates/` into `governance/templates/`. Move any prior-revision artifacts to `history/` or `archive/` with headers. -**Phase C: Charter.** If the tooling already auto-loads a file (Claude Code: `CLAUDE.md`), that file is the charter (5.2). Restructure it to the clause layout of `assets/templates/A-charter.md`, preserving every substantive line, and add at the top: "Doctrine rev [x], pre-adoption. This charter is in bootstrap. No work order under it is counted until DR-001 exists." Verify the token budget (8.1.2); if over, report which section, do not trim. +**Phase C: Charter.** If the tooling already auto-loads a file (Claude Code: `CLAUDE.md`), that file is the charter (5.2). Restructure it to the clause layout of `assets/templates/A-charter.md`, preserving every substantive line, and add at the top: "Doctrine rev [x], pre-adoption. This charter is in bootstrap. No work order under it is counted until DR-001 exists." Before wall registration or any Level 1 call, also copy the complete rule from `assets/bootstrap-charter-addendum.md` verbatim into that engine-visible charter. Ordinary no-pointer work remains forbidden. That temporary addendum is the sole bootstrap exception: it permits only the exact expected-denial calls named by a durably Owner-ratified lifecycle, solely so the wall can deny them; it confers no mutation authority, denial is the only valid outcome, and any success stops adoption. Verify the token budget (8.1.2); if over, report which section, do not trim. **Phase D: Enforcement.** Install `assets/adapters/claude-code/wo_capability_wall.py` unmodified at `.claude/hooks/wo_capability_wall.py` only through the exact Owner-ratified adoption lifecycle after its authorization is durably recorded and verified. The adapter supports CPython 3.10-3.14. Register it for PreToolUse with matcher `*`, an explicit timeout, `${CLAUDE_PROJECT_DIR}`, and the native command: `py -3` on Windows or `python3` on POSIX. The adapter classifies tools itself so an unknown tool denies rather than silently escaping the wall. Never register an absolute path. @@ -220,7 +220,7 @@ begin any protected lifecycle mechanic until that durable record exists. - Execute every disposition in the adoption mapping exactly as the Owner dispositioned it (6.3.3 through 6.3.6). - Finalize labels: drop PROPOSED and DRAFT markers from records the Owner has ratified, and rename the files accordingly. - Write or rename `DR-001` (6.2). Owner-authored fields — D.8 reasoning, D.9 rejected alternatives — are transcribed **verbatim** from what the Owner supplied. You do not paraphrase, polish, complete, or infer them. A blank you cannot fill from the Owner's words is a question, not a gap to close. -- Update the bootstrap markers: remove the "pre-adoption / in bootstrap" line from the charter, and update `STATE.md` to the state you can observe. +- Update the bootstrap markers: remove the "pre-adoption / in bootstrap" line and the complete `assets/bootstrap-charter-addendum.md` text from the charter, and update `STATE.md` to the state you can observe. - Remove bootstrap-only residue that carries no intent — `REMEDIATION-INVENTORY.md`, `REMEDIATION-REPORT.md` if the Owner dispositioned it, and this skill bundle — only where the Owner's disposition covers it. Intent-bearing material is still archived, never deleted (standing rule 2). - Stage exactly the adoption set, and make one local adoption commit whose message names the baseline hash (2.25, 6.1.2). One commit, in this repository, and only if the Owner authorized it in the packet. - Remove the active-WO pointer, returning the repository to lockout, and only where the ratified packet names that removal. Activating a work order is the Owner's decision (7.2.4), and so is ending one; the removal itself is a keystroke you may perform on their behalf once they have named it. Never infer that authority from a closeout that ended tidily, from a grant you consider spent, or from lockout being the correct resting state. If the packet does not name it, leave the pointer where it is and report it as outstanding for the Owner. diff --git a/skills/writwall-adopt/assets/adapters/claude-code/README.md b/skills/writwall-adopt/assets/adapters/claude-code/README.md index 83e2d94..8b0defb 100644 --- a/skills/writwall-adopt/assets/adapters/claude-code/README.md +++ b/skills/writwall-adopt/assets/adapters/claude-code/README.md @@ -272,7 +272,13 @@ The birth test is worthless if run outside the operating envelope. Establish the 4. **Confirm the displayed command resolves through `${CLAUDE_PROJECT_DIR}`.** 5. **Run `--preflight`** with the exact installed digest, settings path, and native platform. It must pass without a denial-log change. 6. **Confirm no active-WO pointer exists** (`.claude/active-wo.txt` absent). -7. **Only then begin real provider-level mutation probes.** +7. **Confirm the engine-visible pre-adoption charter contains the complete + `assets/bootstrap-charter-addendum.md` text from the local adoption bundle.** + Ordinary no-pointer work remains forbidden; only exact calls named by a + durably Owner-ratified lifecycle may be dispatched solely to test denial. + The attempt confers no mutation authority, denial is the only valid outcome, + and any success stops adoption. +8. **Only then begin real provider-level mutation probes.** **The `/hooks` inspection is necessary configuration evidence, not proof of live enforcement.** It shows what Claude Code believes it has loaded. It does not show that the session executing your probes actually loaded it. Only observed denial of real tool calls constitutes the birth test (8.3.5). Invoking the adapter directly with a synthetic payload verifies its logic and nothing else; it must never be recorded as a passing birth test. diff --git a/skills/writwall-adopt/assets/bootstrap-charter-addendum.md b/skills/writwall-adopt/assets/bootstrap-charter-addendum.md new file mode 100644 index 0000000..9d3918e --- /dev/null +++ b/skills/writwall-adopt/assets/bootstrap-charter-addendum.md @@ -0,0 +1,17 @@ +# Pre-adoption charter addendum: expected-denial probes + +This temporary addendum applies only during Writwall bootstrap. Copy its rule +verbatim into the provider's engine-visible pre-adoption charter before wall +registration or any Level 1 probe, and remove it before the adoption commit. + +Ordinary no-pointer work remains forbidden. The sole exception is an exact, +durably Owner-ratified birth-test lifecycle that names specific expected-denial +probe calls while no active-work-order pointer exists. The agent may dispatch +only those named calls, solely so the installed wall can deny them. Each call is +a falsification probe, not product work, and confers no mutation authority. +Denial is the only valid outcome. Any mutation success, required call rejected +before hook dispatch, missing denial evidence, or target-byte drift stops the +birth test and leaves adoption ineffective. This exception grants no authority +to create or alter an activation pointer, work order, control-plane file, +project content, external object, or any target not named by the ratified +lifecycle. diff --git a/tests/test_bootstrap_contract.py b/tests/test_bootstrap_contract.py new file mode 100644 index 0000000..d59869d --- /dev/null +++ b/tests/test_bootstrap_contract.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 HLLMR Ventures LLC +# SPDX-License-Identifier: Apache-2.0 +"""Executable contract for pre-adoption expected-denial probes.""" + +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +CANONICAL = REPO_ROOT / "docs" / "bootstrap-charter-addendum.md" +BUNDLED = (REPO_ROOT / "skills" / "writwall-adopt" / "assets" / + "bootstrap-charter-addendum.md") + +REQUIRED = ( + "exact, durably owner-ratified birth-test lifecycle", + "no active-work-order pointer", + "confers no mutation authority", + "denial is the only valid outcome", + "ordinary no-pointer work remains forbidden", +) + +CARRIER_REQUIRED = ( + "bootstrap-charter-addendum.md", + "ordinary no-pointer", + "durably owner-ratified", + "confers no mutation authority", + "denial is the only valid outcome", + "any success stops adoption", +) + +PERMANENT_TEMPLATE_FORBIDDEN = ( + "bootstrap-charter-addendum", + "expected-denial", + "falsification probe", + "durably owner-ratified birth-test lifecycle", + "denial is the only valid outcome", +) + +CARRIERS = ( + "ADOPTING.md", + "START-HERE.md", + "scripts/start_writwall.py", + "skills/writwall-adopt/SKILL.md", + "adapters/claude-code/README.md", + "skills/writwall-adopt/assets/adapters/claude-code/README.md", +) + + +class BootstrapExpectedDenialContractTests(unittest.TestCase): + def test_exact_addendum_exists_and_bundle_is_byte_identical(self): + self.assertTrue(CANONICAL.is_file()) + self.assertTrue(BUNDLED.is_file()) + self.assertEqual(BUNDLED.read_bytes(), CANONICAL.read_bytes()) + text = " ".join(CANONICAL.read_text(encoding="utf-8").lower().split()) + for phrase in REQUIRED: + self.assertIn(phrase, text) + + def test_every_shipped_carrier_routes_the_exact_addendum_and_contract(self): + for relative in CARRIERS: + with self.subTest(relative=relative): + text = " ".join((REPO_ROOT / relative).read_text( + encoding="utf-8").lower().split()) + for phrase in CARRIER_REQUIRED: + self.assertIn(phrase, text) + + def test_permanent_charter_template_keeps_ordinary_lockout(self): + text = (REPO_ROOT / "templates" / "A-charter.md").read_text( + encoding="utf-8") + self.assertIn("With no\n active work order, no mutating action is permitted.", text) + normalized = " ".join(text.lower().split()) + for phrase in PERMANENT_TEMPLATE_FORBIDDEN: + self.assertNotIn(phrase, normalized) + self.assertNotIn(CANONICAL.read_text(encoding="utf-8"), text) + + def test_public_projection_carries_the_addendum(self): + allowlist = (REPO_ROOT / "projection" / "public-files.txt").read_text( + encoding="utf-8").splitlines() + self.assertIn("docs/bootstrap-charter-addendum.md", allowlist) + self.assertIn( + "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", + allowlist, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_check_distribution.py b/tests/test_check_distribution.py index 715d418..c944e7c 100644 --- a/tests/test_check_distribution.py +++ b/tests/test_check_distribution.py @@ -32,6 +32,10 @@ ) BUNDLE_CHECKER_RELPATH = "skills/writwall-adopt/assets/checks/check_work_order_dispatch.py" +BOOTSTRAP_ADDENDUM_COPY = ( + "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", + "docs/bootstrap-charter-addendum.md", +) NAME_CLEARANCE_BUNDLE_COPIES = { "skills/writwall-adopt/assets/scripts/collect_name_clearance.py": @@ -362,6 +366,21 @@ def test_bundle_checker_copy_is_declared(self): "the bundled adoption-skill checker copy is not declared in " "check_distribution.py BUNDLE_COPIES") + def test_bootstrap_charter_addendum_copy_is_declared(self): + import importlib.util + spec = importlib.util.spec_from_file_location( + "_check_distribution_bootstrap_addendum", + REPO_ROOT / "checks" / "check_distribution.py") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + declared = { + copy.relative_to(REPO_ROOT).as_posix(): + source.relative_to(REPO_ROOT).as_posix() + for copy, source in module.BUNDLE_COPIES.items() + } + copy, source = BOOTSTRAP_ADDENDUM_COPY + self.assertEqual(declared.get(copy), source) + def test_missing_bundle_checker_copy_fails_distribution_gate(self): (self.repo / BUNDLE_CHECKER_RELPATH).unlink() result = self.check() diff --git a/tests/test_coordinator_release.py b/tests/test_coordinator_release.py index b58178e..bc290c6 100644 --- a/tests/test_coordinator_release.py +++ b/tests/test_coordinator_release.py @@ -53,7 +53,7 @@ def setUp(self) -> None: def run_checker(self, candidate: Path, *extra: str): arguments = [str(candidate), *extra] if "--expected-tag" not in extra: - arguments.extend(("--expected-tag", "v0.9.1")) + arguments.extend(("--expected-tag", "v0.9.2")) return subprocess.run( [sys.executable, "-B", str(CHECKER), *arguments], cwd=REPO_ROOT, @@ -158,6 +158,46 @@ def test_missing_promised_handoff_fails_with_diagnostic(self): self.assertNotEqual(result.returncode, 0) self.assertIn("complete handoff failed", result.stdout + result.stderr) + def test_release_gate_requires_bootstrap_addendum(self): + checker = load_checker() + self.assertIn( + "writwall-adopt/assets/bootstrap-charter-addendum.md", + checker.REQUIRED_HANDOFF_PATHS, + ) + + def test_wheel_data_files_include_bootstrap_addendum(self): + with (REPO_ROOT / "pyproject.toml").open("rb") as handle: + project = tomllib.load(handle) + data_files = project["tool"]["setuptools"]["data-files"] + packaged = { + path + for paths in data_files.values() + for path in paths + } + self.assertIn( + "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", + packaged, + ) + + def test_omitted_packaged_bootstrap_addendum_fails_release_gate(self): + candidate = self.make_candidate() + pyproject = candidate / "pyproject.toml" + pyproject.write_text( + pyproject.read_text(encoding="utf-8").replace( + ' "skills/writwall-adopt/assets/bootstrap-charter-addendum.md",\n', + "", + ), + encoding="utf-8", + newline="\n", + ) + result = self.run_checker(candidate) + self.assertNotEqual(result.returncode, 0) + self.assertIn("complete handoff failed", result.stdout + result.stderr) + self.assertIn( + "bootstrap-charter-addendum.md", + result.stdout + result.stderr, + ) + def test_emitted_bytecode_residue_fails_with_diagnostic(self): candidate = self.make_candidate() start = candidate / "scripts" / "start_writwall.py" @@ -187,15 +227,15 @@ def test_intended_release_tag_must_match_candidate_metadata(self): pyproject = candidate / "pyproject.toml" pyproject.write_text( pyproject.read_text(encoding="utf-8").replace( - 'version = "0.9.1"', 'version = "0.9.0"' + 'version = "0.9.2"', 'version = "0.9.0"' ), encoding="utf-8", newline="\n", ) - result = self.run_checker(candidate, "--expected-tag", "v0.9.1") + result = self.run_checker(candidate, "--expected-tag", "v0.9.2") self.assertNotEqual(result.returncode, 0) self.assertIn( - "candidate version '0.9.0' does not match intended tag 'v0.9.1'", + "candidate version '0.9.0' does not match intended tag 'v0.9.2'", result.stdout + result.stderr, ) @@ -229,18 +269,21 @@ def test_candidate_mutation_is_rejected(self): def test_release_identity_and_public_payload_are_coherent(self): with (REPO_ROOT / "pyproject.toml").open("rb") as handle: project = tomllib.load(handle)["project"] - self.assertEqual(project["version"], "0.9.1") + self.assertEqual(project["version"], "0.9.2") readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8") adopting = (REPO_ROOT / "ADOPTING.md").read_text(encoding="utf-8") contributing = (REPO_ROOT / "CONTRIBUTING.md").read_text(encoding="utf-8") publication = (REPO_ROOT / "PUBLICATION.md").read_text(encoding="utf-8") start = (REPO_ROOT / "START-HERE.md").read_text(encoding="utf-8") - tagged_archive = "archive/refs/tags/v0.9.1.zip" + tagged_archive = "archive/refs/tags/v0.9.2.zip" self.assertIn(tagged_archive, readme) self.assertIn(tagged_archive, adopting) self.assertIn(tagged_archive, start) - self.assertIn("--expected-tag v0.9.1", publication) - self.assertIn("--expected-tag v0.9.1", contributing) + self.assertIn("--expected-tag v0.9.2", publication) + self.assertIn("--expected-tag v0.9.2", contributing) + self.assertIn("Release `v0.9.0` first introduced", start) + self.assertIn("Release `v0.9.1` corrected", start) + self.assertIn("Release `v0.9.2` corrects", start) public_files = PUBLIC_FILES.read_text(encoding="utf-8").splitlines() self.assertIn("checks/check_coordinator_release.py", public_files) self.assertIn("tests/test_coordinator_release.py", public_files) diff --git a/tests/test_distribution.py b/tests/test_distribution.py index aab84d0..01e610d 100644 --- a/tests/test_distribution.py +++ b/tests/test_distribution.py @@ -656,6 +656,7 @@ def test_clean_bundle_carries_only_skill_and_declared_copies(self): "SKILL.md", "assets/adapters/claude-code/README.md", "assets/adapters/claude-code/wo_capability_wall.py", + "assets/bootstrap-charter-addendum.md", "assets/checks/check_name_clearance.py", "assets/checks/check_work_order_dispatch.py", "assets/scripts/collect_name_clearance.py", diff --git a/tests/test_init_sh.py b/tests/test_init_sh.py index a8d9897..34a19ee 100644 --- a/tests/test_init_sh.py +++ b/tests/test_init_sh.py @@ -326,7 +326,7 @@ def test_does_not_overwrite_existing_checker(self): self.assertIn("checks/check_work_order_dispatch.py", result.stdout) self.assertIn("skipped", result.stdout) - def test_scaffolder_and_bundle_routes_agree_on_b_template_and_migration_guide(self): + def test_scaffolder_and_bundle_routes_agree_on_templates_and_migration_guide(self): """Route-consistency lock for Doctrine 0.7 (DR-004): the scaffolder route installs the current canonical B-work-order template byte-for-byte, with exactly one enforced_by: {} default and exactly @@ -350,6 +350,17 @@ def test_scaffolder_and_bundle_routes_agree_on_b_template_and_migration_guide(se "templates" / "B-work-order.md").read_bytes() self.assertEqual(bundled_b, canonical_b) + canonical_addendum = (REPO_ROOT / "docs" / + "bootstrap-charter-addendum.md").read_bytes() + bundled_addendum = (REPO_ROOT / "skills" / "writwall-adopt" / + "assets" / + "bootstrap-charter-addendum.md").read_bytes() + self.assertEqual(bundled_addendum, canonical_addendum) + self.assertFalse( + (self.target / "governance" / "templates" / + "bootstrap-charter-addendum.md").exists(), + "the temporary pre-adoption addendum is not an adopted template") + canonical_guide = REPO_ROOT / "migration-guides" / "0.6-to-0.7.md" bundled_guide = (REPO_ROOT / "skills" / "writwall-adopt" / "references" / "migration-guides" / "0.6-to-0.7.md") diff --git a/tests/test_public_projection.py b/tests/test_public_projection.py index 1861378..031c47d 100644 --- a/tests/test_public_projection.py +++ b/tests/test_public_projection.py @@ -549,6 +549,57 @@ def test_actual_host_path_fails_without_echoing_it(self) -> None: self.assertIn("host-specific", combined.lower()) self.assertNotIn(needle, combined) + def test_concrete_foreign_windows_path_in_current_plan_fails_without_echoing_it(self) -> None: + needle = r"Z:\client\media" + self.allow("governance/PLAN.md", f"Current corpus: `{needle}`.\n") + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + combined = checked.stdout + checked.stderr + self.assertNotEqual(checked.returncode, 0) + self.assertIn("host-specific", combined.lower()) + self.assertNotIn(needle, combined) + + def test_concrete_foreign_posix_home_path_in_current_state_fails_without_echoing_it(self) -> None: + needle = "/home/alice/client-media" + self.allow("governance/STATE.md", f"Current corpus: `{needle}`.\n") + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + combined = checked.stdout + checked.stderr + self.assertNotEqual(checked.returncode, 0) + self.assertIn("host-specific", combined.lower()) + self.assertNotIn(needle, combined) + + def test_concrete_foreign_macos_path_in_current_plan_fails_without_echoing_it(self) -> None: + needle = "/Users/alice/client-media" + self.allow("governance/PLAN.md", f"Current corpus: `{needle}`.\n") + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + combined = checked.stdout + checked.stderr + self.assertNotEqual(checked.returncode, 0) + self.assertIn("host-specific", combined.lower()) + self.assertNotIn(needle, combined) + + def test_concrete_foreign_mounted_drive_path_in_current_plan_fails_without_echoing_it(self) -> None: + needle = "/mnt/z/client-media" + self.allow("governance/PLAN.md", f"Current corpus: `{needle}`.\n") + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + combined = checked.stdout + checked.stderr + self.assertNotEqual(checked.returncode, 0) + self.assertIn("host-specific", combined.lower()) + self.assertNotIn(needle, combined) + + def test_canonical_windows_and_posix_placeholders_remain_allowed(self) -> None: + (self.source / "README.md").write_text( + "Windows: `C:\\path\\to\\your-project`\n" + "POSIX: `/path/to/your-project`\n", + encoding="utf-8", + ) + built = self.run_builder() + self.assertEqual(built.returncode, 0, built.stdout + built.stderr) + checked = self.run_checker() + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + def test_empty_inherited_git_directory_fails(self) -> None: self.assertEqual(self.run_builder().returncode, 0) (self.output / ".git").mkdir() diff --git a/tests/test_start_writwall.py b/tests/test_start_writwall.py index cdee2c5..7de180f 100644 --- a/tests/test_start_writwall.py +++ b/tests/test_start_writwall.py @@ -572,6 +572,18 @@ def test_complete_bundle_is_byte_identical_to_source(self): self.assertEqual((copied / relative).read_bytes(), (source / relative).read_bytes(), relative) + def test_clean_new_handoff_routes_bootstrap_charter_addendum(self): + result = self.run_start() + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + handoff = self.handoff() + self.assertIn( + ".writwall-bootstrap/writwall-adopt/assets/" + "bootstrap-charter-addendum.md", + handoff, + ) + self.assertIn("Ordinary no-pointer work", handoff) + self.assertIn("confers no mutation authority", handoff) + def test_name_clearance_proof_tools_are_canonical_in_emitted_bundle(self): result = self.run_start() self.assertEqual(result.returncode, 0, result.stdout + result.stderr)