diff --git a/ADOPTING.md b/ADOPTING.md index abfbe3f..b93713d 100644 --- a/ADOPTING.md +++ b/ADOPTING.md @@ -49,6 +49,26 @@ the adopted repository to a fresh General. The General routes bounded Operators and fresh Reviewers; new design or design-conformance questions go back to a fresh Architect. +Every reply any of these functions addresses to the Owner opens with a +compact header: project; the current work order or batch and its +plain-language purpose; and status (Doctrine 7.12.1) -- never inside a +generated JSON file, pasted command, or other machine-readable artifact +(7.12.4). Owner approval of a roadmap or plan discussion is never execution +approval for one work order or batch member by itself (7.10.1); a fresh +Owner approval is required outside an already-approved batch or at a +reserved milestone (7.10.4), and the General never activates, expands, or +manufactures follow-on work once a batch's last member completes (7.10.7). +A routine, fully conforming batch member's acceptance stays the Owner's +unless a separately ratified delegated conforming-completion disposition +policy names a delegate (2.33, 7.10.6); rework and deviation ratification +are never delegable. The Reviewer's findings reach the Owner through the +Architect for delivery only -- the Architect may not suppress, rewrite, +condition, delay, or waive any finding, and the Owner keeps standing access +to the complete original findings (7.6.4). An Operator files an RFI as one +of three kinds -- informational, resolvable, or a blocking scope/authority/ +safety contradiction (7.11.1) -- and treats doubtful independence from a +blocking matter as blocking rather than declaring it unilaterally (7.11.2). + The installed coordinator is the ordinary entry point. Prompt-only use, the bundled skill, structured intake, and `init.sh` are execution methods or fallbacks inside the same lifecycle. They do not change authority or role @@ -56,12 +76,14 @@ separation. Make the self-contained adoption bundle and these instructions local **before the wall is registered**. A correctly locked session may deny the network request that would otherwise retrieve them. -Release `v0.11.0` packages the conversation-first Architect handoff, -canonical-root enforcement, corrected lifecycle classification, and the -repository-nonmutating `writwall inspect` entry described below. +Release `v0.12.0` packages the conversation-first Architect handoff, +canonical-root enforcement, corrected lifecycle classification, the +repository-nonmutating `writwall inspect` entry described below, and the +accepted compact `--brief` continuation and classified +`--external-operator-task` operational preflight. ```text -python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.11.0.zip" +python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.12.0.zip" # Installed command writwall start --project-root /path/to/your-project @@ -88,8 +110,7 @@ creates no project, bootstrap, temporary, profile, privacy-screen, cache, or bytecode state. The command still requires an installed Writwall package or a local source tree; when neither exists, use section 2's prompt-only fallback. -Adding `--brief` (**unreleased source work; not part of any published -release, including `v0.11.0`**) replaces that full copy-paste prompt with an +Adding `--brief` (available since `v0.12.0`) replaces that full copy-paste prompt with an opt-in, zero-write compact continuation brief: labeled sections (observed evidence, decision/authority references, proposals, next permitted step, mandatory evidence, optional references) bounded to 500 whitespace-delimited @@ -118,8 +139,7 @@ onboarding step, and never replaces the full charter, active work-order grant, and routed requirements. Adding an optional, repeatable `--external-operator-task "NAME=classification"` -(**unreleased source work; not part of any published release, including -`v0.11.0`**) to `writwall start` explicitly and instruction-boundly classifies +(available since `v0.12.0`) to `writwall start` explicitly and instruction-boundly classifies one already-named `--external-operator` function as `deployment`, `migration`, `source_freeze`, or `cutover`; `NAME` must match that Operator function exactly. This is elicitation guidance for the generated packet only, never a @@ -166,8 +186,8 @@ The idea-first qualification and identity gate are documented in |---|---|---| | `writwall start` | A new idea or clean project may receive create-only bootstrap bytes | Emits the fresh Architect handoff and makes the complete temporary adoption bundle local | | `writwall inspect --role architect` | An existing or workplace repository needs a zero-write first conversation, or an Architect must re-enter later | Prints bounded lifecycle evidence and a fresh Architect prompt without creating any state | -| `writwall inspect --brief` (unreleased source work; not part of any published release, including `v0.11.0`) | A continuing agent needs a compact, evidence-linked recap instead of the full copy-paste prompt | Prints labeled sections bounded to 500 words of prose, plus an unbounded evidence index of current files with real byte sizes and explicit unknowns; opt-in only, never a replacement for the full charter, active grant, and routed requirements | -| `writwall start --external-operator-task "NAME=classification"` (unreleased source work; not part of any published release, including `v0.11.0`) | An already-named `--external-operator` function needs a bounded, opt-in operational preflight before deployment/migration/source_freeze/cutover execution | Adds one `## Operational preflight` section and `intake.json["external_operator_tasks"]` entry for that exact Operator only; never inferred from its name, never imposed on ordinary local coding | +| `writwall inspect --brief` (available since `v0.12.0`) | A continuing agent needs a compact, evidence-linked recap instead of the full copy-paste prompt | Prints labeled sections bounded to 500 words of prose, plus an unbounded evidence index of current files with real byte sizes and explicit unknowns; opt-in only, never a replacement for the full charter, active grant, and routed requirements | +| `writwall start --external-operator-task "NAME=classification"` (available since `v0.12.0`) | An already-named `--external-operator` function needs a bounded, opt-in operational preflight before deployment/migration/source_freeze/cutover execution | Adds one `## Operational preflight` section and `intake.json["external_operator_tasks"]` entry for that exact Operator only; never inferred from its name, never imposed on ordinary local coding | | Prompt-only fallback | The package and source tree are unavailable, or policy permits a model conversation but no local tool | Starts the same Architect function; repository mechanics wait until the bundle is local | | Bundled `writwall-adopt` skill | The Owner has promoted the sketch and wants agent-assisted adoption mechanics | Inventories, proposes, and performs only separately ratified recorder actions | | `--structured-intake` or `init.sh` | Deterministic intake or expert low-level scaffolding is specifically needed | Preserves compatibility and feeds the fresh Architect; neither creates a second lifecycle nor changes authority | @@ -369,9 +389,9 @@ It does not fix whose fingers move. Once you have made a decision and ratified i In the order of Doctrine 6.4.1: -5.1 Confirm the doctrine revision you are binding to is ratified (DC.3.5). Check `DOCTRINE.md` DC.1. Revision 0.8 is current, ratified on 2026-08-21 by `decisions/DR-005.md`, superseding 0.7; a new adoption should bind to 0.8. Revision 0.7 was ratified on 2026-08-20 by `decisions/DR-004.md`; revision 0.6 was ratified on 2026-08-16 by `decisions/DR-001.md` and was the first authoritative revision of the methodology. Both 0.6 and 0.7 remain valid revisions to be bound to by a project that has not migrated. Revisions 0.1 through 0.5 were never ratified and you may not bind to any of them. Always check DC.1 yourself rather than trusting this sentence: DC.1 is the authority, and a revision that looks finished is not the same as one that has been ratified. +5.1 Confirm the doctrine revision you are binding to is ratified (DC.3.5). Check `DOCTRINE.md` DC.1. Revision 0.9 is current, ratified on 2026-09-16 by `decisions/DR-006.md`, superseding 0.8; a new adoption should bind to 0.9. Revision 0.8 was ratified on 2026-08-21 by `decisions/DR-005.md`; revision 0.7 was ratified on 2026-08-20 by `decisions/DR-004.md`; revision 0.6 was ratified on 2026-08-16 by `decisions/DR-001.md` and was the first authoritative revision of the methodology. Revisions 0.6, 0.7, and 0.8 all remain valid revisions to be bound to by a project that has not migrated. Revisions 0.1 through 0.5 were never ratified and you may not bind to any of them. Always check DC.1 yourself rather than trusting this sentence: DC.1 is the authority, and a revision that looks finished is not the same as one that has been ratified. -Binding to 0.8 means the Appendix B work order you complete in step 5.10 and every one after it follows 0.8's classification rule: every capability surface named under `grant` is classified exactly once, either in `enforced_by` (naming the mechanism that covers the whole surface) or in `unenforced_boundaries` (honored by instruction only). The template's default is `enforced_by: {}` — an empty mapping — with all eight minimum surfaces (`filesystem.write`, `filesystem.read.deny`, `shell.execute`, `network.egress`, `package.install`, `secrets.read`, `git.commit`, `git.push`) listed under `unenforced_boundaries`; move a surface into `enforced_by` only after you have named and validated the mechanism that covers it in full. After completing the frontmatter, run the pre-dispatch validator's `--emit-boundaries --work-order ` and replace only the content **between** the existing `` and `` marker comments, now under the `## B.7 Generated boundaries` heading (B.4 is BOUNDARIES, unchanged prose; Doctrine DC.2's 0.8 erratum explains the renumbering), with its exact output; then run the ordinary `--work-order ` check again, and it must pass before you activate the candidate. A project already bound to 0.6 or 0.7 does not gain any of this automatically: see section 6 and the applicable migration guide (`migration-guides/0.6-to-0.7.md`, `migration-guides/0.7-to-0.8.md`) for the explicit, Owner-ratified migration this requires. +Binding to 0.9 (Appendix B carries no content change from 0.8) means the Appendix B work order you complete in step 5.10 and every one after it follows this classification rule: every capability surface named under `grant` is classified exactly once, either in `enforced_by` (naming the mechanism that covers the whole surface) or in `unenforced_boundaries` (honored by instruction only). The template's default is `enforced_by: {}` — an empty mapping — with all eight minimum surfaces (`filesystem.write`, `filesystem.read.deny`, `shell.execute`, `network.egress`, `package.install`, `secrets.read`, `git.commit`, `git.push`) listed under `unenforced_boundaries`; move a surface into `enforced_by` only after you have named and validated the mechanism that covers it in full. After completing the frontmatter, run the pre-dispatch validator's `--emit-boundaries --work-order ` and replace only the content **between** the existing `` and `` marker comments, now under the `## B.7 Generated boundaries` heading (B.4 is BOUNDARIES, unchanged prose; Doctrine DC.2's 0.8 erratum explains the renumbering), with its exact output; then run the ordinary `--work-order ` check again, and it must pass before you activate the candidate. A project already bound to 0.6, 0.7, or 0.8 does not gain any of this automatically: see section 6 and the applicable migration guide (`migration-guides/0.6-to-0.7.md`, `migration-guides/0.7-to-0.8.md`, `migration-guides/0.8-to-0.9.md`) for the explicit, Owner-ratified migration this requires. The validator also checks repository-looking paths in B.3 and B.4 against the machine-readable grant. A path that is mentioned for a read-only or @@ -456,10 +476,37 @@ Independent provider denial: reports the provider's own denial as the exact bloc Environment prerequisite failure: names the exact missing or failed environment prerequisite as the blocker. Unapproved task creation or data transmission: never creates or transmits a task, message, or dataset outside the approved action. +Owner approval of a roadmap, plan section, or discussion is not execution approval for any +individual work order or batch member. A fresh Owner approval is required outside an +already-approved batch or at a reserved milestone; an approved finite sequence confers no +release, publish, deploy, push, tag, or external-account authority beyond what each member's own +grant already authorizes, and a nonapproved successor stops for a fresh Owner decision. Once an +approved batch's last member is complete, blocked, or exhausted, report results and recommend, +but never activate, expand, or manufacture, follow-on work. Acceptance of a routine, fully +conforming batch member stays the Owner's own disposition unless the Owner has separately +ratified a delegated conforming-completion disposition policy naming a delegate; such closure is +recorded as disposed under that policy, never described as "the Owner accepted," and rework or +deviation ratification are never delegable under any policy. Track a handoff between functions +through its distinguishable state -- prepared, sent, acknowledged, returned, or reviewed -- and +report a status not actually observed as unknown, never inferred as favorable; preserve a +human-relayed message together with its provenance, that it was relayed, by whom, and when, and +never present it as a direct machine-to-machine handoff record. Begin every reply that addresses +the Owner directly with a one-line header stating the project, the current work order or batch +and its plain-language purpose, and status -- proposed, no active work order, active, blocked, or +reporting on completion -- never as a line inside a generated JSON file, a pasted command, or +another machine-readable or reusable artifact. For an approved batch, distinguish overall batch +progress from the currently active member. This is instruction only: it proves the requirement +was generated, never that a future invocation will actually follow it. + Once approved, perform every -mechanically available authorized step. Do not ask for the same decision again. The human Owner -alone ratifies intent and activates work; preserve a distinct fresh Reviewer after -implementation. The onboarding coordinator stops here and does not continue into project work. +mechanically available authorized step. Do not ask for the same decision again. Whenever you +delegate a bounded task to a fresh Operator, announce the delegated role and bounded task, name a +discoverable monitoring location or state plainly that none exists, state the last verified +execution/handoff state, and name the result/question return route; ending a conversational reply +must never imply that delegated work keeps running or has stopped when that is not actually +observed. The human Owner alone ratifies intent and activates work; preserve a distinct fresh Reviewer +after implementation. The onboarding coordinator stops here and does not continue into +project work. ``` The Authorization section above is filled in by the General itself from @@ -488,7 +535,7 @@ or recorder run activates or implements that work. ## 6. Migrating between doctrine revisions -Nothing happens automatically (DC.4). When you decide to move a project from one ratified revision to another: read the DC.2 rows between them; list every local artifact the differences touch (charter structure, work-order frontmatter, adapter, brief format, routing rules); update them; write a decision record naming both revisions and the affected artifacts; commit. Where a `migration-guides/-to-.md` exists, follow it; it is the companion document for that specific transition, in the same spirit as the 0.1-to-0.6 remediation companion that produced this section. A project bound to 0.6 that wants to move to 0.7 follows `migration-guides/0.6-to-0.7.md` explicitly; a project bound to 0.7 that wants to move to the current 0.8 revision follows `migration-guides/0.7-to-0.8.md` explicitly. No script, adapter, skill, or agent invocation performs any migration on its own initiative, and a project remains correctly bound to its recorded revision until its Owner ratifies otherwise. +Nothing happens automatically (DC.4). When you decide to move a project from one ratified revision to another: read the DC.2 rows between them; list every local artifact the differences touch (charter structure, work-order frontmatter, adapter, brief format, routing rules); update them; write a decision record naming both revisions and the affected artifacts; commit. Where a `migration-guides/-to-.md` exists, follow it; it is the companion document for that specific transition, in the same spirit as the 0.1-to-0.6 remediation companion that produced this section. A project bound to 0.6 that wants to move to 0.7 follows `migration-guides/0.6-to-0.7.md` explicitly; a project bound to 0.7 that wants to move to 0.8 follows `migration-guides/0.7-to-0.8.md` explicitly; a project bound to 0.8 that wants to move to the current 0.9 revision follows `migration-guides/0.8-to-0.9.md` explicitly. No script, adapter, skill, or agent invocation performs any migration on its own initiative, and a project remains correctly bound to its recorded revision until its Owner ratifies otherwise. ## 7. Public-source boundary diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e1f427..1ccbc71 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.11.0 +python checks/check_coordinator_release.py --expected-tag v0.12.0 ``` The gate copies the candidate to temporary build space, builds and installs the diff --git a/DOCTRINE.md b/DOCTRINE.md index c9b7453..490387c 100644 --- a/DOCTRINE.md +++ b/DOCTRINE.md @@ -10,11 +10,11 @@ | Field | Value | |---|---| | Document | The Doctrine: Document-Controlled AI-Assisted Development | -| Revision | 0.8 | +| Revision | 0.9 | | Status | Ratified | | Amendment authority | The Owner of the methodology repository | -| Supersedes | 0.7 | -| Effective | 2026-08-21, ratified by DR-005 (`decisions/DR-005.md`) | +| Supersedes | 0.8 | +| Effective | 2026-09-16, ratified by DR-006 (`decisions/DR-006.md`) | ### DC.2 Revision History @@ -28,6 +28,7 @@ | 0.6 | 2026-08 | Corrections from formal review: baseline versus adoption commit; two-level birth test; transactional record category; archive semantics; Dispatcher and Reviewer inputs; Owner disposition; control taxonomy; instrument qualification event; operational definitions moved to adoption record. Pre-ratification touch-ups: 2.18, 6.2.1.1, 7.6.1; bootstrap-agent exception and post-adoption role inputs (1.2.2-1.2.4); provider configuration at adoption (5.1.3); repository roles versus physical repositories, permitting a segregated self-hosted instance (5.1.1, 5.1.4-5.1.6); charter current-state updated by the Owner and never by agents (Appendix A A.3); qualification cross-references corrected to 8.4.4 (Appendix D D.5, 9.2.8); methodology-maintenance exception preserved after adoption (1.2.4); methodology repository described as distribution and reference implementation rather than documentation alone (5.1.2) | Yes | | 0.7 | 2026-08 | Align Appendix B with the shipped pre-dispatch validator: classify every declared grant surface exactly once in `enforced_by` or `unenforced_boundaries`; default the provider-neutral template to no mechanically enforced whole surfaces; add generated-boundary markers and the checker-emission workflow. No other Doctrine clause changes. | Yes | | 0.8 | 2026-08-21 | Corrected Appendix A's unqualified "blocked and logged" claim to be provider-contingent, matching this repository's own already-corrected charter; corrected Appendix B's B.4/B.7 numbering defect (see erratum below); added `governance/templates/` to the Part 5.2.1 reference layout with invariant 5.3.8 governing its refresh, and revised 5.1.3 to affirmatively require whatever deterministic dispatch-preparation tooling the revision's workflow needs (described generically, never naming a product) while stating plainly that a scaffolded skeleton without populated governance records, that tooling, and a ratified adoption record with the adoption commit containing it is not itself adoption; defined the birth-test instrument (2.28), narrowed to the active-scope, per-surface birth test only, and cross-referenced it from 6.1.3; and added Part 8.7, Protected Control Plane, governing mutation authority (not read-deny) over the active-work-order pointer, installed enforcement configuration, the active work order or instrument itself, and the denial-evidence log — unconditionally, with no exception for an Owner-authored grant — treating activation, retirement, recorder actions that themselves mutate a control-plane artifact, and the specifically defined adoption-recorder action as Owner lifecycle actions outside any capability grant while leaving ordinary Part 7 closeout governed and requiring durable pre-execution authorization; and defining a labeled `instrument_kind: birth-test` / `control_plane_probes` dispatch exception whose exact protected-path entries confer no authority and must still be denied by the runtime wall, with enforcement remaining provider-contingent and birth-test-gated (8.7.4), resolving RFI-22's Doctrine-level question without closing the RFI itself | Yes | +| 0.9 | 2026-09-16 | Added definitions 2.29 Architect, 2.30 General, 2.31 Operator (with 2.31.1 shared-hosting distinctness and 2.31.2 external-operations packet), 2.32 Batch, and 2.33 Delegated conforming-completion disposition. Amended 4.1.2 to bar only standing/carried authority rather than the function names themselves; added 4.1.4 (authority is delegation-chain-derived, citing 3.2.5) and 4.1.5 (shared-provider hosting, reconciled with 4.1.3's unchanged different-vendor preference for Implementer/Reviewer). Amended 4.2.4 to route Reviewer briefs through the Architect as a delivery channel only; added 4.2.5-4.2.7 (Architect, General, Operator role-table rows) and 7.6.4 (Reviewer independence from Architect/General, reconciled with 7.6.1, 7.6.3, and Appendix C). Amended 7.2.4 to state that ratifying a batch is the activation decision for its named members; amended 7.7.1 to allow a named delegate to exercise acceptance under an Owner-ratified delegated conforming-completion disposition policy while reserving deviation ratification to the Owner alone. Added Part 7.10 (batch approval and delegated execution, 7.10.1-7.10.9, reconciling activation with the amended 7.2.4/existing 8.7.6 Owner-lifecycle mechanism and delegated disposition with the amended 7.7.1/existing 7.7.3), Part 7.11 (RFI severity and handoff continuity), and Part 7.12 (reporting headers, including the "proposed" status form). Amended Appendix A A.5 to require the 7.12 header. Added Part 6.5 (existing-project realignment). Added 8.7.7 (function names confer no additional control-plane authority). No enforcement, adapter, or template mechanism is implemented by this revision alone. | Yes | **Erratum, recorded 2026-08-21.** Revision 0.7's addition of "B.4 Generated boundaries" collided with the pre-existing B.4 ("BOUNDARIES") identity @@ -147,6 +148,69 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 2.28 **Birth-test instrument.** A capability-grant-bearing artifact, sharing the work-order frontmatter and pointer-activation mechanism (Appendix B, 8.3.5) for engineering convenience, used only for the active-scope, per-surface birth test (8.3.5.2), where an Owner-directed test mechanically requires an active pointer and grant to exercise scoped enforcement. It is not a work order (2.16): it carries no Part 7 disposition cycle and is never counted under Part 9 (6.1.3). This does not forbid a Dispatcher-equivalent function from drafting one or a Reviewer-equivalent function from inspecting its outcome; the boundary that matters is that it never carries or ratifies intent (2.6-2.7) and never substitutes for a counted work order. Like any work order, its own capability grant is bound by 8.7.2 and never reaches a control-plane artifact — except that its manifest may name an exact control-plane path solely as a falsification probe under the schema at 8.7.4, which confers no authority under 8.7.2; it is validation metadata, never a grant. It is distinct from the no-work-order lockout (8.3.5.1), which is not an instrument at all: that test observes the absence of any active pointer, and its pass condition is precisely that nothing is active to grant anything. It is also distinct from an Owner lifecycle action (8.7.6), including the adoption-recorder lifecycle action: neither is ever performed under a birth-test instrument's or any work order's capability grant. +2.29 **Architect.** The function that is the primary human point of contact +during discovery, adoption, construction, and recovery conversation (4.2.5). +It listens, inspects bounded evidence, challenges the pitch, drafts a project +sketch or design proposal, and conveys existing Owner authority. It never +ratifies intent and never activates a work order. + +2.30 **General.** The post-adoption continuity function (4.2.6) that +maintains awareness of the plan and open transactional records, prepares +bounded dispatch (performing the Dispatcher function, 4.2.2, when it does), +routes work to Operators, records only decisions the Owner has already +ratified, and routes new design or design-conformance questions to a fresh +Architect invocation rather than deciding them itself. + +2.31 **Operator.** The function that executes one active work order or one +bounded external-operations packet (2.31.2) inside its capability grant +(4.2.7). An Operator working a repository work order performs exactly the +Implementer function (4.2.3) under that name; an Operator working an +external packet (infrastructure, DNS, mail, deployment, or a similar +account-bearing function) remains outside the repository's installed-provider +wall coverage (2.31.2, 8.3.4) unless and until it edits repository bytes, at +which point it is an ordinary Operator under a work order. + +2.31.1 **General distinctness under shared hosting.** The General function +(2.30) exists as a distinct function from the Architect (2.29) even where +one provider hosts both, and even where both run under the same subscription +or account. What makes them distinct functions is fresh, separate +invocations (4.1.2, 4.1.5) — separate sessions performing the +discovery/design function and the continuity/dispatch function respectively +— not a different vendor, product, or human login. A small project may run +both functions from the same underlying model without collapsing them into +one persistent persona, provided each invocation begins fresh from the +record. This shared-hosting allowance concerns only the Architect/General/ +Operator functions defined here; it does not diminish or satisfy 4.1.3's +separate, unchanged preference that the Implementer and Reviewer functions +be performed by different model vendors where practical. + +2.31.2 **External-operations packet.** A bounded, project-specific +instruction packet an Operator (2.31) executes for an infrastructure, DNS, +mail, deployment, or similarly account-bearing function that lies outside +this repository's own capability-wall coverage. It is not a Doctrine-defined +capability-grant surface in the sense of 8.3.1's minimum list; it is the +kind of project-specific surface 8.3.1 already contemplates ("any +project-specific surfaces such as database mutation, infrastructure +changes, or model runs") and 8.3.4 already requires be declared unenforced +where no installed provider covers it. Its exact preconditions, permitted +and prohibited actions, verification, rollback, and credential handling are +defined by the adopting project issuing it, never by this Doctrine, which +states only that such a packet exists as a category and that it remains +outside the repository's installed-provider wall coverage unless and until +it edits repository bytes under an ordinary work order. + +2.32 **Batch.** A finite, named, Owner-approved sequence of already-drafted +work orders or work-order revisions that an explicit Owner instruction +authorizes for sequential activation without a fresh approval request at +each member's activation (7.10). A batch is not a standing authorization: it +names its members, and approving it approves only those members. + +2.33 **Delegated conforming-completion disposition.** An Owner-ratified +policy (7.10.6) that lets a named function close a routine, fully conforming +batch member without an individual Owner acceptance turn for that member. It +is distinct from Owner acceptance (7.7.1) and is never recorded as if it +were one. + --- ## PART 3. THESIS AND PRINCIPLES @@ -185,10 +249,43 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 4.1.1 The doctrine defines roles as functions rather than as persistent processes or personas. Any function may be performed by any capable model. What matters is what each function receives, what it is permitted to do, and what it must produce. -4.1.2 There is no manager-agent, architect-agent, or orchestrator-agent. Continuity lives in the record. Enforcement lives in mechanism. Judgment about intent lives in the Owner. Every agent invocation begins from the record as if it had never seen the project, because it has not. +4.1.2 There is no *standing* manager-agent, architect-agent, or +orchestrator-agent carrying memory or authority across sessions. The +Architect, General, and Operator (2.29-2.31, 4.2.5-4.2.7) are functions +performed by a fresh agent invocation with no carried authority, exactly +like every other function this Part defines; naming a function is not +granting it standing continuity. Continuity lives in the record. +Enforcement lives in mechanism. Judgment about intent lives in the Owner. +Every agent invocation begins from the record as if it had never seen the +project, because it has not — including an Architect or General +invocation, and including one immediately following another in the same +conversation. 4.1.3 Where practical, the Implementer and Reviewer functions should be performed by different model vendors. Independent failure modes make agreement-by-shared-blindspot less likely. +4.1.4 A function name is not authority. Authority derives from the recorded +delegation chain (3.2.5, 2.7, 7.9.1), never from title, memory, apparent +seniority, or physical or conversational proximity to the Owner. Downstream +delegation may narrow scope but never enlarge it. A reporting relationship +among functions — for example, an Operator reporting through a General — +does not abolish the fresh-invocation boundary of 4.1.2 or the review +independence of 4.2.4 and 7.6. + +4.1.5 One provider may host multiple Architect/General/Operator functions +(4.2.5-4.2.7) without requiring separate subscriptions or vendors, provided +each invocation is fresh per 4.1.2 and execution/review independence is +preserved per 7.6. This shared-hosting allowance does not satisfy, diminish, +or substitute for 4.1.3's separate, unchanged preference that the +Implementer and Reviewer be performed by different model vendors where +practical; 4.1.3 concerns the Implementer/Reviewer pair specifically and is +not relaxed by this clause, which concerns only the newer +Architect/General/Operator functions. No function may silently take over a +stalled or unresponsive downstream function's work. Reassignment requires +either authority already present in an existing mandate or a fresh Owner +decision, and any reassignment must still preserve fresh execution/review +separation for the reassigned work — an Architect that reassigns a stalled +Operator's task does not thereby become that task's Reviewer. + ### 4.2 Role Table | Clause | Role | Performed by | Continuity | Authority | @@ -196,7 +293,10 @@ Terms are defined for use within the doctrine. Where a term has a wider industry | 4.2.1 | Owner | Human | Durable | Sole ratifier of intent: charter, plan, routing map, decisions, amendments. Reads owner briefs by default and evidence on escalation. | | 4.2.2 | Dispatcher | Agent, fresh per invocation | None | Drafts work orders from ratified intent. Self-checks each for internal contradiction before issue. Never writes code. | | 4.2.3 | Implementer | Agent, fresh per work order | None | Executes exactly one work order inside its capability grant. Halts and files RFIs on ambiguity. Never amends intent-bearing documents. | -| 4.2.4 | Reviewer | Agent, fresh per artifact | None | Diffs work reports against the work order and plan. Produces owner briefs. Never writes code, never amends intent. | +| 4.2.4 | Reviewer | Agent, fresh per artifact | None | Diffs work reports against the work order and plan. Produces owner briefs, addressed to the Owner and, for routing purposes, delivered through the Architect (4.2.5) rather than the General (4.2.6), per the Owner-escalation guarantee of 7.6.4. Routing a brief through the Architect is a delivery channel, not an approval gate: the Architect conveys the brief and may not suppress, rewrite, or condition its delivery on anything (7.6.4). Never writes code, never amends intent, never reviews its own implementation. | +| 4.2.5 | Architect | Agent, fresh per invocation | None | Primary human point of contact for discovery, adoption, construction-phase design, and recovery. Listens, inspects bounded evidence, challenges the pitch, drafts a project sketch or design proposal, conveys existing Owner authority, and performs only exactly authorized recorder mechanics (8.7.6). Never ratifies intent, never activates a work order, never suppresses or rewrites a Reviewer finding (7.6.4). | +| 4.2.6 | General | Agent, fresh per invocation | None | Post-adoption continuity function. Prepares bounded dispatch (may perform the Dispatcher function, 4.2.2), routes work to Operators, records only already-ratified Owner decisions, and routes new design or design-conformance questions to a fresh Architect. Prepares batch members for activation but never itself activates one; activation is an Owner lifecycle action under 8.7.6/7.10.3. Never ratifies intent; never prepares a member beyond the Owner-approved sequence or past a reserved milestone (7.10.4). | +| 4.2.7 | Operator | Agent, fresh per work order or bounded external-operations packet | None | Executes one active work order or one bounded external-operations packet (2.31.2) inside its capability grant. Performs the Implementer function (4.2.3) when working a repository work order. Halts and files RFIs per 7.11 on ambiguity. Never reviews or authorizes its own work. | --- @@ -328,6 +428,25 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 6.4.2 The birth test has two levels with different consequences. The no-work-order lockout (8.3.5.1) is an adoption precondition: if any mutation channel available to the Implementer can mutate anything with no active work order, the project has not adopted the doctrine. Active-work-order scope enforcement (8.3.5.2) is tested per surface: a surface that fails through any channel is downgraded to unenforced-by-declaration for that project, which does not invalidate adoption unless the Owner judges the resulting risk unacceptable under 8.3.4. +### 6.5 Existing-Project Realignment + +6.5.1 A read-only realignment may summarize an already-adopted project's +current responsibilities, approved scope, evidence age, blockers, and next +permitted action without touching project bytes. It is available to any +function re-entering a project, including the Architect and the General, and +creates no lifecycle event by itself. + +6.5.2 Realignment preserves every prior adoption, approval, active work, +command compatibility, and canonical project root. It never forces a fresh +interview, an automatic migration or re-adoption, retrieval of archived +history, or repair of anything outside an active work order's grant. Evidence +it cannot find is reported as missing, never guessed or invented. + +6.5.3 A project remains bound to the doctrine revision it last ratified +(DC.4.1) regardless of any later revision this methodology repository +publishes. Publishing a revised methodology revision is not itself a +migration of any adopting project, including a self-hosted instance (5.1.6). + --- ## PART 7. THE WORKFLOW @@ -352,7 +471,12 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.2.3 The Dispatcher self-checks the draft for internal contradiction between the grant, the required work, and the stated prohibitions, and resolves any contradiction before issue. -7.2.4 The Owner activates the work order. +7.2.4 The Owner activates the work order. For a member of an Owner-ratified +batch (7.10), the Owner's ratification of the batch is the activation +decision for each named member, made once for the sequence rather than once +per member; the mechanical act of creating or updating the activation +pointer for that member still proceeds only through the separately +authorized lifecycle actor 8.7.6 requires (7.10.3). ### 7.3 The Wall Goes Up @@ -382,9 +506,32 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.6.3 The Reviewer is an information-loss boundary. The brief is the Owner's default read, but the Reviewer must attach or link supporting evidence, and the Owner must read it, whenever any of the following holds: the verdict is DEVIATION; the Reviewer rates its own confidence LOW on the fixed HIGH/MEDIUM/LOW scale of Appendix C, which threshold is not the Reviewer's to set; the change is security-relevant or irreversible; or the Implementer's claims, the Reviewer's findings, and any empirical instrument's results disagree. +7.6.4 The Reviewer's owner brief (2.18, Appendix C) is addressed to the +Owner and, for delivery purposes only, is conveyed to the Owner through the +Architect (4.2.5) rather than the General (4.2.6). Conveying is not +reviewing: the Architect may not suppress, rewrite, condition, delay, or +waive any Reviewer finding, verdict, escalation, or required evidence. The +Architect's channel does not become a second information-loss boundary +alongside the one 7.6.3 already establishes for the Reviewer; the Owner +retains standing access to the Reviewer's complete original findings +regardless of any summary the Architect adds when conveying them. Where a +Reviewer's finding or a brief's contents implicate a decision the Architect +itself made, escalation to the Owner proceeds directly and is not filtered +or mediated by the Architect. Design advice the Architect offers about the +work under review is not independent review and never substitutes for the +Reviewer's function (4.2.4, 8.0.3). + ### 7.7 Owner Disposition -7.7.1 Reading the brief, and the evidence when escalated, the Owner disposes of the work: acceptance, rework, or ratification of a deviation. Acceptance and rework are ordinary dispositions. Ratification is reserved for dispositions that change intent (2.7). +7.7.1 Reading the brief, and the evidence when escalated, the Owner +disposes of the work: acceptance, rework, or ratification of a deviation. +Acceptance and rework are ordinary dispositions. Ratification is reserved +for dispositions that change intent (2.7). For a routine, fully conforming +member covered by an Owner-ratified delegated conforming-completion +disposition policy (7.10.6), acceptance may be exercised by the named +delegate that policy identifies rather than by the Owner directly. +Ratification of a deviation remains reserved to the Owner alone and is +never delegable under any policy. 7.7.2 Any disposition that changes intent becomes a decision record at that moment. @@ -408,6 +555,195 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.9.5 No control depends on an agent remembering an instruction. +### 7.10 Batch Approval and Delegated Execution + +7.10.1 Owner approval of a roadmap, a plan section, or a discussion is not +execution approval for any individual work order (2.16). Execution approval +requires an explicit Owner instruction identifying either one work order or a +finite batch (2.32) of named, already-drafted work-order revisions. + +7.10.2 A batch record states: member work-order identifiers and revisions; +the batch objective; sequence and dependencies among members; the resources +and actions each member's own grant already authorizes; delegated +responsibilities; falsifiable acceptance conditions; any Owner-reserved +milestone at which the sequence stops for a fresh decision; stop conditions; +and the exact Owner instruction that authorized it. An existing record is +reused where one already states this; a batch does not require a new +administrative document for every routine transition. + +7.10.3 Owner approval of a batch does not activate every member +simultaneously. Consistent with 7.3 and the project's one-active-work-order +control model, once a member's prerequisites and any reserved milestone have +passed, the General (4.2.6) prepares that next approved, unblocked batch +member for activation. The General never itself performs activation. +Activation remains exactly the pointer-creation act 8.3.5.1 and 8.7.1 name +as a control-plane artifact, and 8.7.6 requires that act to be an Owner +lifecycle action performed by a separately authorized recorder, never under +any work order's or batch's own capability grant; no agent edits the +activation pointer under a capability grant, under this clause or any other. +The Owner's ratification of the batch record supplies the durable, +pre-execution authorization 8.7.6 requires for each named member, recorded +once at batch ratification rather than re-obtained once per member; this is +what lets the sequence proceed without a repeated per-member Owner ask, +while the mechanical act of activation still passes through the same +separately authorized recorder 8.7.6 always requires. 7.2.4's requirement +that the Owner activates the work order is unchanged: for a batch member, +the Owner's act of ratifying the batch is the 7.2.4 activation decision, +made once for the named sequence rather than once per member; the +recorder's later keystroke executes a decision the Owner already made, +exactly as 8.7.6 already permits for any other lifecycle action. + +7.10.4 A fresh Owner approval is required before dispatching a work order +that is not already part of an approved batch, or at any milestone the Owner +reserved in the batch record. A session change, by itself, is never grounds +to request an approval the batch record does not require. + +7.10.5 No function may reclassify an intent, scope, capability, +acceptance-condition, resource-limit, or reserved-milestone change as +clerical. Only Owner ratification changes any of these (7.9.1, 2.7). A +platform permission prompt is not an Owner re-ratification, and a mandate +never substitutes for one. A genuinely clerical lifecycle correction — one +that preserves the exact meaning the Owner already approved and merely +repairs its administrative form — proceeds only through a separately +authorized lifecycle actor acting under 8.7.6, and only with a durable trace +recording what was corrected, against what already-ratified text, and by +whom. A correction that leaves any doubt about whether meaning changed is +not clerical by this clause's own terms and requires ordinary Owner +ratification instead. + +7.10.6 The Owner may separately ratify a delegated conforming-completion +disposition policy (2.33) letting the General or Reviewer close a routine, +fully conforming batch member without an individual Owner acceptance turn. +This is an instance of 7.7.1's acceptance disposition, delegated in advance, +not a fourth disposition alongside acceptance/rework/ratification. 7.7.2 and +7.7.3 continue to apply exactly as written to every member closed this way: +a disposition that changes intent still becomes a decision record at that +moment regardless of who or what closed the member (7.7.2), and the cycle's +metrics are still appended to LOG.md and the next work order still +dispatches (7.7.3), with the LOG.md entry for a delegation-disposed member +stating plainly that disposition was by the ratified delegated policy, not +by the Owner's own reading, so a later reader can distinguish the two +dispositions without inferring it from context. Such a policy: is itself a +decision record; states exactly which conditions qualify as routine and +fully conforming; and is never described as "the Owner accepted" when only +the delegated policy's own criteria were met — the record instead states +plainly that the delegated policy disposed of it under 7.7.1, distinct from +the Owner personally reading and accepting it. Nonconformance, deviation, or +unresolved ambiguity still escalates under 7.6.2-7.6.3 regardless of any +delegated policy; no function may waive it, and a delegated policy is +defined precisely because 7.7.1's rework and deviation-ratification +dispositions are excluded from it by definition — only the plain-acceptance +case is delegable. Absent a ratified delegated policy, ordinary Owner +disposition (7.7) continues to govern every member, exactly as it does +today. + +7.10.7 Execution stops when an approved batch's last member is complete, +blocked, or exhausted. The General reports results and may recommend, but +may not activate, expand, or manufacture, follow-on work; a new batch or +work order requires a fresh Owner approval under 7.10.1. Batch approval +implies no authority to release, publish, deploy, push, tag, or act on any +external account; each requires its own explicit inclusion in the approval +that grants it. + +7.10.8 A reserved Owner milestone (7.10.2, 7.10.4) and the mandatory +escalation conditions of 7.6.3 are independent controls, both of which apply +in full to work performed under a batch. Passing a reserved milestone check +does not satisfy or substitute for a 7.6.3 escalation condition that is +separately triggered, and satisfying 7.6.3 does not waive a reserved +milestone the batch record separately names. Batch approval under 7.10.1 +never supersedes, narrows, or creates an exception to 7.6.2's default block +on nonconformance, 7.6.3's mandatory escalation, or any other standing +review requirement; a batch is a sequencing authorization, not a review or +escalation waiver. + +7.10.9 The complete semantic-state mapping for a batch member, using only +representations the project's existing pre-dispatch validation and +Appendix B's existing status enum already support; this candidate invents +no new status value, pointer format, or frontmatter field: + +| Semantic state | Where it lives | Existing machine-readable representation | +|---|---|---| +| Proposed / planned | The batch record itself, or an ordinary plan section, before Owner approval | No work-order frontmatter exists yet for an unapproved member, or it exists as an ordinary draft file not yet named in any ratified batch record. Nothing to parse; this is a plan-level state, not a work-order state. | +| Approved-for-execution (batch member, not yet active) | The ratified batch record | The member is named, by its existing `id:`, in an Owner-ratified batch record (7.10.2). It does not yet exist as an activated pointer target: the existing activation pointer does not name it. "Approved-for-execution" is a batch-record fact, not a work-order frontmatter fact. | +| Active | The work order itself, once activated | The activation pointer names it, and its frontmatter reads `status: ACTIVE` — Appendix B's existing enum, unchanged. | +| Blocked | The work order itself | Frontmatter `status: RFI-BLOCKED` — Appendix B's existing enum, unchanged. Corresponds to 7.11.1's blocking RFI class. | +| Complete | The work order, then its historical record | Frontmatter `status: COMPLETE`, then moved to the project's historical record at closure (5.3.7) — unchanged. | + +### 7.11 RFIs, Blocking, and Handoff Continuity + +7.11.1 An RFI (2.20) is filed as one of three explicitly stated kinds: an +informational clarification that does not block ongoing work; a resolvable +execution problem that blocks only the work it affects until answered; or a +blocking scope, authority, or safety contradiction that halts the affected +work immediately, before or concurrently with filing the RFI itself. + +7.11.2 A blocking RFI halts the work it affects and any work that depends on +it. Independently authorized work may continue only once its independence +from the blocked matter is established, not merely asserted. Where that +judgment is itself in doubt, the dependency is treated as blocking rather +than resolved by assertion, and neither the Architect nor the General +declares independence unilaterally in that circumstance. + +7.11.3 An RFI presented to the Owner as an executive decision brief states: +the question; the evidence; the affected scope; the consequence of each +option; a recommendation; and the exact decision needed. The lower-level +technical record behind the brief is preserved and remains available; the +brief never replaces it. + +7.11.4 Resolving an RFI changes only the scope the resolution names. +Approvals unrelated to that scope remain valid without replay. Evidence that +depended on the resolved question is rechecked before being relied on again, +but the entire authorization chain is not re-litigated because one question +in it was resolved. + +7.11.5 A handoff between functions is tracked through distinguishable states: +prepared (drafted, not transmitted); sent (transmitted to the receiving +session or human); acknowledged (receipt confirmed); returned (work product +delivered back); and reviewed (a fresh Reviewer has checked it). No function +fabricates a dispatch, a session identifier, a completion, or continuous +awareness of a handoff's status; a status not actually observed is reported +as unknown, never inferred as favorable. + +7.11.6 A human-relayed message is preserved together with its provenance — +that it was relayed, by whom, and when — and is never presented as if it +were a direct machine-to-machine handoff record. + +7.11.7 The Architect remains free to discuss design with the Owner while a +General is executing an approved batch. That conversation alone does not +interrupt, reauthorize, or expand the executing work. Any resulting change to +scope, intent, or grant still requires ordinary Owner ratification and an +ordinary batch-record update under 7.10.5. + +### 7.12 Reporting Headers + +7.12.1 Every agent-authored user-facing progress or final reply to the Owner +begins with a compact header stating: the project; the current work order or +batch identifier and its plain-language purpose; and the current activity or +status, using one of: proposed (an idea, sketch, or draft not yet ratified or +activated); no active work order; active work on a named work order or batch +member; blocked; or reporting on a completed work order or batch. Where none +is active, the header states so plainly rather than omitting the line. + +7.12.2 For an approved batch, the header distinguishes overall batch progress +from the currently active member. + +7.12.3 A report states what happened, why it matters to the Owner's +decision, what the evidence proves and does not prove, any decision or +blocker, and the next permitted action. A pull-request identifier or a +passing test count supports that statement; it never substitutes for it. + +7.12.4 This requirement binds the Architect, General, Operator, and Reviewer +whenever addressing the Owner directly. It does not require a header inside +machine-readable output, a pasted command, or another reusable artifact not +meant for direct human reading. + +7.12.5 Canonical prompts, skill instructions, and generated role packets +state this requirement so a freshly invoked function is instructed to +comply. Compliance itself remains instruction-bound, not mechanically +enforced; a test of generated bytes proves only that the instruction is +present in what was generated, never that a future invocation will follow +it. + --- ## PART 8. ENFORCEMENT @@ -516,6 +852,15 @@ Pre-dispatch validation passes such an instrument only when every control-plane 8.7.6 Activating or retiring the active-work-order pointer; changing the installed enforcement configuration; amending the active work order's or birth-test instrument's own frontmatter or body; and, narrowly, any recorder action that itself mutates a control-plane artifact, together with the adoption-recorder lifecycle action defined in Part 6 (the Owner-directed recorder closeout that records already-ratified adoption decisions), are Owner lifecycle actions. Ordinary Part 7 work-order reporting, review, acceptance, history retirement, State and metrics update, and closeout remain inside the governed Part 7 cycle (7.5-7.8) and are not reclassified under this clause merely because they record an already-ratified Owner disposition; 8.7.6 reaches only control-plane mutation itself and the named adoption-recorder action. None is performed under a work order's or birth-test instrument's own capability grant, and none is self-authorized by the artifact being changed. The Owner may delegate the clerical keystrokes of such an action to a separately authorized recorder or mechanism acting on exact, already-ratified Owner instructions, but authority over the action stays with the Owner, never with the Implementer or the instrument executing it, and no active Implementer uses its own capability grant to perform one. That separate Owner lifecycle authorization is recorded before execution in a durable Owner disposition or lifecycle packet in the canonical record; a chat exchange alone is not authorization. +8.7.7 The Architect, General, and Operator functions defined in 2.29-2.31 +and 4.2.5-4.2.7 are ordinary names for the same actors 8.7.6 already +describes as "a separately authorized recorder or mechanism" and "the +Implementer." Naming a function under 4.2 confers no control-plane authority +beyond what 8.7.2 and 8.7.6 already permit or forbid. A General or Architect +acting under 8.7.6 remains bound by every condition stated there, including +durable, pre-execution Owner authorization recorded in the canonical record +rather than in chat alone. + --- ## PART 9. MEASUREMENT @@ -607,8 +952,10 @@ A.4.1 [path or subsystem] -> [document] A.4.2 Unmapped and unsure -> RFI. ## A.5 REPORTING -End every work order with the report format specified in the work order, -addressed to the Reviewer. Completeness over brevity. +Begin every reply to the Owner with a one-line header: project, current work +order or batch and its plain-language purpose, and status (7.12). End every +work order with the report format specified in the work order, addressed to +the Reviewer. Completeness over brevity. ## A.6 ENVIRONMENT [build and test commands, platform notes: the minimum an agent needs @@ -745,4 +1092,4 @@ Rules: every intent-bearing document lands in exactly one row; a Tier-2 row with --- -*Revision 0.8. Ratified 2026-08-21 by DR-005. See DC.2 for history and DC.3 for the rules under which this document changes.* +*Revision 0.9. Ratified 2026-09-16 by DR-006. See DC.2 for history and DC.3 for the rules under which this document changes.* diff --git a/PROJECTION-MANIFEST.sha256 b/PROJECTION-MANIFEST.sha256 index 0af0bdf..6993a4e 100644 --- a/PROJECTION-MANIFEST.sha256 +++ b/PROJECTION-MANIFEST.sha256 @@ -5,10 +5,10 @@ b2e36dfcfc6eb31570c9340640bcd73abc62f57c80b4794abf36e3d3e89ab34f .github/depend 9e90d43615b02a265b08692ef7a1c00a37477a5c6b1e8233a8fc7bedefaedea6 .github/pull_request_template.md 3c35b31bc2b80d101a3a549da68fec55587b6a6428ce6b32112670276490ce23 .github/workflows/ci.yml e544abe8ffd83c81c7b002cbd2e552f9d56f226ea20e1e0722c5d1bdec914fe0 .gitignore -b7868acc0741492f237d7320ab34a202203714d7ec25d81224695fe692f53bfc ADOPTING.md +e560e8a944fb8df31f7088cb9023dd54fd9067801b9a2f2474f7c9d71a87e00e ADOPTING.md 1179c999034f4ec1c1d44c1946bd2955c4625905e80767abe760c8c3ab01c493 CLAUDE.md -074908ecfc14027823851f9cea118a985c85dd947c17870a44f9c903cd28a348 CONTRIBUTING.md -664196054cd98585105be457afa09c788a482416ccb48a87bb269b2156e49ae6 DOCTRINE.md +01cc42aa109377ce00414f95d54725d6336e395302d7287b5502e72eab6942b0 CONTRIBUTING.md +6d66b658ea58a3ccf94ebd4194243cbc816fa350b3c0f95d0fa85590ef3de1ae DOCTRINE.md 9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411 LICENSE a38775f2d68b40577253ee48061ba67af3c75b7620dc506b34b40ce2a3b660ee LICENSE-MAP.md c274f80372d90c012937370f0e1f15087d22e308ef98b27cea5dc0d2d088366c LICENSES/Apache-2.0.txt @@ -16,39 +16,40 @@ c274f80372d90c012937370f0e1f15087d22e308ef98b27cea5dc0d2d088366c LICENSES/Apach a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499 LICENSES/CC0-1.0.txt 59746d6285ffa44bfc7ecada352aa5d6a20dc8eab418a60ce091cc739012c135 LICENSES/MIT-0.txt 35e6d37b7c5fa0c1fc872315cbd362cd24bfa41e1b7dc3019fbcd31e99350f51 NAMING.md -1323a57e5e23bac07f057fef73fa296684963ecb9e92792e9623fc548e681949 PROJECTION-PROVENANCE.md -5dec4f02eeaef72ea93b66dd548520ef5af6c7d246b261a5c82804da94f71b63 PUBLICATION.md -bb9083c43def4a803c3f01e296ccbdb0402068ec39145e3ddd892ac3e922eea3 README.md +19c771b511ce6802405b2c8581f0c62cc319f4d6255da372d9b7f574e43f9d8c PROJECTION-PROVENANCE.md +655ebe242bd67cfe5891e390980ff8f4404d84d2d10e096aba23d11e54c6f0bc PUBLICATION.md +4f49c016aba20e207a72f9e19c6a7057954e87c753f8208e31bce6c13b39f9aa README.md 284a0862f3be77e8d867aa4d3ef92ed1a64ad4315d6d9074f6bb64771b6d1dd0 REUSE.toml ab75b39490b4db4e203f5b23b480a1c998d87cf07d760cb787cb260778b21d0a SECURITY.md -6a51c1211cc675599634d144ca24a705ec1696f84640a6464b14efb1d6c3a629 SELF-HOSTING.md -5082f28ba1dec841e74b0dc371b54f7d3285c463e25d09e2ff9d99212d3364a1 START-HERE.md +ca53dba00262f47351796b07ca236926b517e5a19ac3667df9a1045dcc4dbccf SELF-HOSTING.md +4e59ad3907148bef7e790eb0ab306f1908c9f9ba0362785f1838503ba826e596 START-HERE.md 75c7ae0f569148f489570d63df916a70b6ccf24b77db2076cdee29663f747428 adapters/claude-code/README.md aeb7f81d139e7ffa6de9a1782444b99eb6d549ac1c3a8b9c0f8bcb9c6addfa6d adapters/claude-code/SECURITY.md dd29af2a39d25e0270ad9acc23ee912f81e39c674e1179759f4a3010c6a0c1a0 adapters/claude-code/wo_capability_wall.py 2ffc8e711d3b3006a8b9490890727c16c38a97e184d16d8a8cfbe84c1dbfcbe8 checks/check_coordinator_release.py -20df8e937b6efeb7930894b7d4eba42761283b6d0166e78bcabaa2ab6dc75a7c checks/check_distribution.py +0c36b90c28084c3bcf808298bec54f02c50117d3307e307bf793ff61d8284f8f checks/check_distribution.py 60fe377dac32b8d1697f859371ef40d26ed4e695fdceeda6d29ec0318d539504 checks/check_identity.py 30986c40ff7c9b29e2fba39ec04c18af3c1c351490410bd532a8391bcb92ed11 checks/check_licenses.py 6a5162c40e9df9bf198d391a937603907a019e04029298c3567f5e1df647c73b checks/check_name_clearance.py -cf7e0c4523ba9335b78c1fe51dd744e5c4806c3f431705df3553f9b37591c2f8 checks/check_public_projection.py +1a46f20b70f21ac55abb8c9af41f3bb3d3e3c820667a6246600e9205e74a0569 checks/check_public_projection.py bb54d108d1dff56291169624d26eac4f44db00ebf98e38bf7e6d56cd9b8d9647 checks/check_work_order_dispatch.py b49e8c6fb8ef321e5a8f8b2012a77ab3870df2d4826ecb8fe0b33345d57d060a decisions/DR-001.md 1dc105a91f76dd749463e91e492646ff5188a62359f21caba5245cb173c2a8ac decisions/DR-003.md f73c71c7aac19f4a979f7fc4926464ceaa912b1d24f37447af695785d7a889ae decisions/DR-004.md 7cb90c45d8246464872a2158f21dc4213116843d543a3b0d1b5bf1b865fcb9a6 decisions/DR-005.md +385fbb6d47cf58e396f86b32a74e05944827e855c5c0fe42a5762b41a1d84771 decisions/DR-006.md d9f01820bd45d8dad46e7fd307e0b6986a41d6cd2071da353530421aeea46f70 decisions/LICENSING-DIRECTION.md -745f853760c5656ba1475f011f88d9c64b282e1f723475dfee4b0262120a8495 decisions/README.md +9f67832a5e23a4c03019a216c19e2c04cbdb0c7b9c473eac593a8d1be39bf418 decisions/README.md fa88788242d920999b6e6737ea60b03dfe3f9ba2e0d90386b6bbcfeb6acd0509 docs/agents/domain.md 98305d69cb8ff9ebdd44d815248c4619aecc09295891c043e1423d1189888a49 docs/agents/issue-tracker.md 2177e1dbec58d14cb20e3b15fcb2cfb3ba6671025ba86a72e603c59d5cc09a06 docs/agents/triage-labels.md -09038d48dfb92a83cc18cdd966dca5ebce8c870f5a74dcb7d47e9a08adefafe4 docs/architect-interview.md +61b05ee40c070591170694cb784bcac9d56833b62e1b41fea2e9b0844fef92b4 docs/architect-interview.md 5200a1511a781cfe49baf10177880cfc6e4e18eb8f9a55ca9e17ab4f9b35a312 docs/assets/writwall-og.png 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 -b961435c3e50093e590cdf151de8d4831d35dc7397c665c7fd9e5334d994d4ad docs/day-zero-coordinator.md +4768fe93d2805335841afa3eb27b32bb3064247fb353717d2e12980295e142f1 docs/day-zero-coordinator.md e1214e3e6018642809339249bb091a6fd754847b4f77c4bc7a39c5c87e6769cc docs/identity-migration.md b664a305cea2ea7de364df3aa05b9644c334c6ded7e4e0771ae11a512205d4d8 docs/name-clearance.md 1eef400dd2e12b109ceb9b30c107dbd7f25d3c64182346dd0f370bf9ccaa7088 docs/privacy-screen.md @@ -60,12 +61,12 @@ dbab45d15702d32ea745076b0dee05c293346b4f42581fd2cb869deb1c5b51b3 examples/name- d2c5a8ca21edf842dfd17a83862024afa0a92349abf693a60e55ce454c8d78fa examples/name-clearance-ledgers/writwall-candidate.json 0d62666ddc07a4283309bcbc8f9501add4ecec052d26369d30ce232e17c17702 examples/plumbline-self-hosting-pilot.md 30cdb11fbeb2fd9bbf4048255331ccbbdd6e516fae5adfa5317af00ce53607c9 governance/ADOPTION-MAPPING.md -bb0470a1cd3543c135d6c3cbdaaff8ba6f29c5a208c11061e8423556456964e0 governance/LOG-denials-probes.md -c705d8babe7d934feaf5ac627991f22273f284eab395f959cc384dab402ccfd5 governance/LOG-denials.jsonl -fe23a4b929fdfb3440da3e239405bbd4a6e9d430d34e7820a9a94a76aff6bcda governance/LOG.md -f18d83c92cc2da4b2fe22a20376bea7ca7ccc331638f30d996ff52afe3af6784 governance/PLAN.md -dd445eb2994e0d9615bc61fe2ae157a6b14ba7b190c65b705d380b31c49fdfe0 governance/ROUTING.md -bec6857daf55f1576f51c6ea7b9d7729501b59e2dfc565768309640b6fff8592 governance/STATE.md +540f8a7ef20356ff85a673d9a238d1b8e3a575e5571f69a04a9f293a78466b91 governance/LOG-denials-probes.md +a410ee460216b818482ecf1df9583a8a0cf17542b92fcaf1a3503f21cdfcc64c governance/LOG-denials.jsonl +ba4bd0d79505aa32782b41cf3143f27d2ed0509c2125482502b3737b9aeb754c governance/LOG.md +a6036b492d0f3aca7c5bd455ccc4314f3d67d1d407936f6c6e17c55e4a39f250 governance/PLAN.md +2c71b1468e99fa29abb310ba323f7cd0f0a21447bb03d97aada683be0360ba0a governance/ROUTING.md +7421478c01f4e343c3d255b3daa22e9cb3ce232915ab87c1e490f6be1e79fea3 governance/STATE.md e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/archive/.gitkeep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/briefs/.gitkeep e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/decisions/.gitkeep @@ -82,53 +83,55 @@ b567ce0c0867464328e81774d888f6491fa66b68ac73be01f993e5c4c66d3ed8 governance/tem d355e46f978f17de8824af805e05124e0f20b1c072523b518422044f88c6f079 governance/templates/D-adoption-record.md 2b586efadab716a59fcafb74312a45a05401a4787fee6ae18cb5c9dd14ef3a09 governance/templates/E-adoption-mapping.md e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 governance/work-orders/.gitkeep -bc0dd0f459b657bcbb3644f00acda07bb925bf4a89767a26c9ec0928f4948af0 identity/legacy-references.json +b1622ace4bb600a17997bebbb6943be25cd597eec4f6622fef07b0ef2eb3b138 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 -fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7 projection/public-files.txt -90a4b90139c1a23bbd98a2fb8b150a82cef0c17973d4c445c1206a26eeb4f8b6 pyproject.toml +33d73dd0a32788d673df486b3dcf301ed03edd05c8f8d7920687e0f77da97d49 migration-guides/0.8-to-0.9.md +28ba77c4dfd9370bfe9fca2d349cd042c9a55ac8c6f1c09efca70e73a86d278f projection/public-files.txt +0dfedba0dae8b67ea395cfe30d81c5571516133cae1d6aae59dfa4fd060378b3 pyproject.toml 455ca1ab3c9e7e78afbb9946e13b94497ba24003ab6f411ea96cce26d4ecc39e scripts/build_distribution.py -08fa88f3a1de7a26c14c383ea3f18e86838499d9eacb7cf57819fb27c2f20c30 scripts/build_public_projection.py +df3573c418fda6fbd048f79f7845451b0fe4d394f0d47ccc7ca8f236b2fdac7f scripts/build_public_projection.py 3cf88f936599e0e84bc2368bc0503a39b9f96e47b473e09b26569e5c3c9edbd9 scripts/collect_name_clearance.py c372f7f1736eb77bedaca43696ea0b060333733f912053479b363442022c4b24 scripts/privacy_screen.py -4ffcdb25a87587f622759c824d91a04200ed68f4fbbd8cff258f4aec54d1f0db scripts/start_writwall.py +75d6274cb4f8cec18d8712ac66e5da4da00cfd8cb93089d7f19187ca39906fa8 scripts/start_writwall.py 374f4e8a80b7b9e162b9360a3907b6ffe12ce94ba0ed827058c7b3c9c0658b2c skills/writwall-adopt/LICENSE-MAP.md -c5a46b8f6bedce839f8144050479ed3254a98f55b053a42481de45841609693b skills/writwall-adopt/SKILL.md +84eb284d1972c55f5901b315bdeb7a179c71145817bbff09d83d5befdce515ae 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 6a5162c40e9df9bf198d391a937603907a019e04029298c3567f5e1df647c73b 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 -b567ce0c0867464328e81774d888f6491fa66b68ac73be01f993e5c4c66d3ed8 skills/writwall-adopt/assets/templates/A-charter.md -0a0c3c8c2317733b7ca951799de74a045c35d9a944a6448985f023feb49dcb4e skills/writwall-adopt/assets/templates/B-work-order.md -5bfaa890ffddd423644428606753bc2e6562e3e5d67c1dc522172710708a4bf0 skills/writwall-adopt/assets/templates/C-owner-brief.md -d355e46f978f17de8824af805e05124e0f20b1c072523b518422044f88c6f079 skills/writwall-adopt/assets/templates/D-adoption-record.md -2b586efadab716a59fcafb74312a45a05401a4787fee6ae18cb5c9dd14ef3a09 skills/writwall-adopt/assets/templates/E-adoption-mapping.md -664196054cd98585105be457afa09c788a482416ccb48a87bb269b2156e49ae6 skills/writwall-adopt/references/DOCTRINE.md +be09209791ca5ba63831b6e98ce8c313196fab0ae6767ee2c28a750f57976a08 skills/writwall-adopt/assets/templates/A-charter.md +b00e2e1b48ee6759f1f7fe458ca3019d7fd4f79c4f931f920ab7bcafda764bb6 skills/writwall-adopt/assets/templates/B-work-order.md +149b5f7bf1876478fca5c428f937cff71d84e9cc46d7fd7d1258bb961133f67d skills/writwall-adopt/assets/templates/C-owner-brief.md +5a6ef08b85ac58b2487795fb636ebd218fa5196180dbf49584d541d969ad0db4 skills/writwall-adopt/assets/templates/D-adoption-record.md +b70d788604399b60f7cb4cc3695b2d990d4a44094532a6b8c5751430eeb1f446 skills/writwall-adopt/assets/templates/E-adoption-mapping.md +6d66b658ea58a3ccf94ebd4194243cbc816fa350b3c0f95d0fa85590ef3de1ae skills/writwall-adopt/references/DOCTRINE.md 5c90584642f405534b2071f27396ff293ab01632e4dbb8ccb6b8ec043dca4cc9 skills/writwall-adopt/references/migration-guides/0.1-to-0.6.md ba4eff258ca5b9a45f3f9f1cbf646ba5bc5521fae812adacac65cd2e78698c9d skills/writwall-adopt/references/migration-guides/0.6-to-0.7.md 7be9ff49c33830f929584e9e6756f06be8634b1c79ff7210bf5184b51bfc0769 skills/writwall-adopt/references/migration-guides/0.7-to-0.8.md +33d73dd0a32788d673df486b3dcf301ed03edd05c8f8d7920687e0f77da97d49 skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md b664a305cea2ea7de364df3aa05b9644c334c6ded7e4e0771ae11a512205d4d8 skills/writwall-adopt/references/name-clearance.md -b567ce0c0867464328e81774d888f6491fa66b68ac73be01f993e5c4c66d3ed8 templates/A-charter.md -0a0c3c8c2317733b7ca951799de74a045c35d9a944a6448985f023feb49dcb4e templates/B-work-order.md -5bfaa890ffddd423644428606753bc2e6562e3e5d67c1dc522172710708a4bf0 templates/C-owner-brief.md -d355e46f978f17de8824af805e05124e0f20b1c072523b518422044f88c6f079 templates/D-adoption-record.md -2b586efadab716a59fcafb74312a45a05401a4787fee6ae18cb5c9dd14ef3a09 templates/E-adoption-mapping.md +be09209791ca5ba63831b6e98ce8c313196fab0ae6767ee2c28a750f57976a08 templates/A-charter.md +b00e2e1b48ee6759f1f7fe458ca3019d7fd4f79c4f931f920ab7bcafda764bb6 templates/B-work-order.md +149b5f7bf1876478fca5c428f937cff71d84e9cc46d7fd7d1258bb961133f67d templates/C-owner-brief.md +5a6ef08b85ac58b2487795fb636ebd218fa5196180dbf49584d541d969ad0db4 templates/D-adoption-record.md +b70d788604399b60f7cb4cc3695b2d990d4a44094532a6b8c5751430eeb1f446 templates/E-adoption-mapping.md 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 -3004ff0a5550df05ba76c5893435b8694c1833435e9db9cbfa4cbc945af528b7 tests/test_coordinator_release.py -13478c88a9d9951f4a90ef15fa389fc0bf19894f917cbada62fc366cbe70a635 tests/test_distribution.py +2257ab23529c93b974ec5cf9c506ab67b9e8f7a1896cad18d31c7dddba17af2e tests/test_coordinator_release.py +9badf3dc8e783db4dc6f3ab3af8246e2da34d111ba936466e9e2055ca8665c63 tests/test_distribution.py e150a2f988a4b0beac5f70644f55f5e185a8aa575e988a19642bafabc0f07775 tests/test_identity_migration.py 11cd8090dbc53e8aa6a2f14cb181c8a11696335da8f40700eae5116798e49ba5 tests/test_init_sh.py a2df93f79791a884d9c6c2db308591a3b18e95ee34702ad5330ccc7a4b683fa4 tests/test_name_clearance.py 677d5b532450ace267be9c834269c081368697cd83defa5531ce673f6d0ca252 tests/test_privacy_screen.py -0d1d5cc19779e3539d46caba978fe18de7af751c8c98fe435dbf2e924860ca81 tests/test_public_projection.py -8174feb2fc3b9957f746db67cfdc971b71f65172e32d2dc8629dc4d0f4311b90 tests/test_start_writwall.py +a4135c3da96be9ce1769e62d07e1bca52517e3918d7f945212fcbb661ac3a7cc tests/test_public_projection.py +4658309c242c743026c121a12861162c443c8068b710639cfbabfbbb183fcac7 tests/test_start_writwall.py 0684c04067eb95eadc9f72ab126d8662b4a5e2005c80b2dea174075a6140eebc tests/test_wo_capability_wall.py e8caf7f4421dc7f78b0d766741ec2ef4c2ac6dab6117fab6e4175b27d31e4d49 writwall_cli/__init__.py 31e39820e3a747f97cb9fc2fc0e1062108913c7a8755b88eb6810af3d55429ad writwall_cli/__main__.py diff --git a/PROJECTION-PROVENANCE.md b/PROJECTION-PROVENANCE.md index 25cfb01..07707d5 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: `c68f862ca6bb28df992a55a0d80d85f8d18cf2d4` -- Source commit time: `2026-09-16T12:31:50-05:00` -- Projection allowlist SHA-256: `fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7` +- Source commit: `86da925db1baee92fa56dc09d5e699a10dea3a2c` +- Source commit time: `2026-09-17T13:21:49-05:00` +- Projection allowlist SHA-256: `28ba77c4dfd9370bfe9fca2d349cd042c9a55ac8c6f1c09efca70e73a86d278f` ## Legacy identifier inventory diff --git a/PUBLICATION.md b/PUBLICATION.md index ec00b76..cd60e4d 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.11.0 +python checks/check_coordinator_release.py --expected-tag v0.12.0 ``` For a future GitHub release that is required to be immutable, save the diff --git a/README.md b/README.md index 0cac266..11b98c1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@

CI Latest release - Doctrine 0.8 + Doctrine 0.9 Security policy

@@ -94,10 +94,10 @@ actually blocks the current session before real work begins. ## Try it in five minutes -Release `v0.11.0` has one canonical lifecycle and two ordinary entry commands: +Release `v0.12.0` has one canonical lifecycle and two ordinary entry commands: ```text -python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.11.0.zip" +python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.12.0.zip" # New idea or clean project: create a temporary local handoff writwall start --project-root /path/to/your-project @@ -250,6 +250,17 @@ Writwall has one canonical lifecycle: Owner → fresh Architect → explicit promotion → adoption materialization → fresh General → bounded Operator → fresh Reviewer → Owner disposition. The coordinator is the normal front door. +Every function's reply to the Owner opens with a compact header naming the +project, the current work order or batch, and its status — never inside a +generated JSON file or other machine-readable output (Doctrine 7.12). A +roadmap or plan conversation is never execution approval for one work order +on its own; the General still asks for a fresh approval outside an +already-approved batch or at a reserved milestone, and never activates, +expands, or invents follow-on work once a batch ends (7.10). The Reviewer's +findings reach the Owner through the Architect for delivery only, never +filtered, with standing Owner access to the complete original findings +(7.6.4). + Prompt-only Architect conversation, the bundled `writwall-adopt` skill, `--structured-intake`, and the low-level `init.sh` scaffolder are fallback or specialized execution methods inside that lifecycle. They are not separate @@ -278,7 +289,8 @@ Three things carry three different names here: - **A project-local instantiation is a governance system.** It belongs to the adopting project from the moment it is created. -Current revision: **0.8, ratified 2026-08-21** by `decisions/DR-005.md`, +Current revision: **0.9, ratified 2026-09-16** by `decisions/DR-006.md`, +superseding 0.8, which was ratified by `decisions/DR-005.md` on 2026-08-21, superseding 0.7, which was ratified by `decisions/DR-004.md` on 2026-08-20. Revision 0.6 was ratified by `decisions/DR-001.md` on 2026-08-16 and was the first authoritative methodology revision; 0.1 through 0.5 were never @@ -290,8 +302,8 @@ This repository's private self-hosting instance first adopted 0.6 under the former identity and later migrated cumulatively to 0.8. Its ratifying project decision is a private record not carried by public candidates; `SELF-HOSTING.md` preserves the public-safe -summary. See `DOCTRINE.md` DC.1, `decisions/README.md`, and the two guides under -`migration-guides/` for the complete revision history. +summary. See `DOCTRINE.md` DC.1, `decisions/README.md`, and the four guides +under `migration-guides/` for the complete revision history. Ratification establishes a stable baseline for testing. It does not claim the methodology is proven. @@ -455,7 +467,7 @@ separate Owner-only publication decision. The ten-work-order self-hosting pilot and its fresh-agent evaluation are complete. Disclosure cleanup, license mechanization, and the clean-history projection gate and cumulative project-local migration are complete. Doctrine -0.8 is the current ratified revision (`decisions/DR-005.md`). The separate +0.9 is the current ratified revision (`decisions/DR-006.md`). The separate private governed source's project-side governance instance is operatively bound to Doctrine 0.8; its ratifying `governance/decisions/DR-003.md` is not carried by public candidates, while `SELF-HOSTING.md` carries the public-safe summary. diff --git a/SELF-HOSTING.md b/SELF-HOSTING.md index 5fea058..1d88fcd 100644 --- a/SELF-HOSTING.md +++ b/SELF-HOSTING.md @@ -205,14 +205,17 @@ separate Owner decision. This paragraph records that checkpoint; it does not assert the current publication status of the copy being read. External actions require their own authority. -Doctrine 0.8 is the current ratified revision (`decisions/DR-005.md`, -2026-08-21), superseding 0.7. The separate private governed source's self- +Doctrine 0.9 is the current ratified revision (`decisions/DR-006.md`, +2026-09-16), superseding 0.8, which was ratified by `decisions/DR-005.md` +(2026-08-21), superseding 0.7. The separate private governed source's self- hosted instance first completed self-adoption bound to revision 0.6, as recorded above. Its Owner later ratified and completed the cumulative project-local migration under private-source record `governance/decisions/DR-003.md` (not carried by public candidates), applying `migration-guides/0.6-to-0.7.md` and `migration-guides/0.7-to-0.8.md` in order -(DC.4). That private governed source is now operatively bound to Doctrine 0.8. +(DC.4). That private governed source remains operatively bound to Doctrine 0.8. +The migration to distributed ratified Doctrine 0.9 has not been made and is +not implied by anything in this document. ## `filesystem.read.deny` (Level 3), added under WO-PL-012 diff --git a/START-HERE.md b/START-HERE.md index 3666986..c7c83df 100644 --- a/START-HERE.md +++ b/START-HERE.md @@ -104,6 +104,27 @@ These are functions, not permanent job titles. One model can perform several functions sequentially for a small project, but it does not carry authority between them and does not review its own implementation in the same context. +Every reply any of these functions sends you directly opens with a compact +header: project; the current work order or batch and its plain-language +purpose; and status (proposed, no active work order, active, blocked, or +reporting on completion). For an approved batch, the header distinguishes +overall batch progress from the currently active member, not just the +active item. Stating this requirement in a prompt or generated packet +instructs the invoked function to comply; it proves the instruction is +present, never that a future invocation actually followed it -- that header +is instruction for replies to you, and it never appears inside a generated +JSON file, a pasted command, or any other machine-readable artifact. Your +approval of a roadmap or plan discussion is +never execution approval for one work order or batch member on its own; the +General still asks for a fresh approval outside an already-approved batch or +at a milestone you reserved, and never activates, expands, or invents +follow-on work once a batch ends. The Reviewer's findings reach you through +the Architect for delivery only -- never filtered, rewritten, or delayed -- +and you keep standing access to its complete original findings regardless of +any summary. An Operator halts and files one of three RFI kinds +(informational, resolvable, or a blocking contradiction) rather than +improvising through ambiguity. + ## Pick an operating model ### Small project @@ -139,13 +160,15 @@ names, repository slugs, domains, logos, or launch copy. The coordinator may collect evidence, but the Owner chooses the identity; unavailable sources are not clear results. -1. Release `v0.11.0` packages the conversation-first Architect handoff, - canonical-root enforcement, corrected lifecycle classification, and the - repository-nonmutating `writwall inspect` entry. +1. Release `v0.12.0` packages the conversation-first Architect handoff, + canonical-root enforcement, corrected lifecycle classification, the + repository-nonmutating `writwall inspect` entry, and the accepted compact + `--brief` continuation and classified `--external-operator-task` + operational preflight. Install it without unpacking it over your project: ```text - python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.11.0.zip" + python -m pip install "https://github.com/HLLMR/writwall/archive/refs/tags/v0.12.0.zip" ``` Release `v0.9.0` first introduced the coordinator. Release `v0.9.1` corrected @@ -155,7 +178,9 @@ not clear results. conversation-first inception, corrected adoption-state classification, and canonical project-root enforcement. Release `v0.11.0` adds the installed, read-only `writwall inspect` entry and - prospective immutable-release verification. + prospective immutable-release verification. Release `v0.12.0` adds the + compact `--brief` continuation and classified `--external-operator-task` + operational preflight. 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: @@ -211,8 +236,7 @@ not clear results. lockout; explicit recovery only for a partial bootstrap. An active work order remains routed only to its bounded Operator under `--role auto`. - **`--brief` (unreleased source work; not part of any published release, - including `v0.11.0`).** Adding `--brief` to `inspect` prints an opt-in, + **`--brief` (available since `v0.12.0`).** Adding `--brief` to `inspect` prints an opt-in, zero-write compact continuation brief instead of the full copy-paste prompt: labeled sections (observed evidence, decision/authority references, proposals, next permitted step, mandatory evidence, optional @@ -241,8 +265,7 @@ not clear results. replaces the full charter, active work-order grant, and routed requirements — the ordinary full handoff remains the default. - **`--external-operator-task` (unreleased source work; not part of any - published release, including `v0.11.0`).** `start` accepts an optional, + **`--external-operator-task` (available since `v0.12.0`).** `start` accepts an optional, repeatable `--external-operator-task "NAME=classification"`, where `NAME` must exactly match one already-named `--external-operator` function and `classification` is one of `deployment`, `migration`, `source_freeze`, or @@ -277,7 +300,8 @@ not clear results. the target already holds work, the Architect's opening carries a bounded, local, non-secret inventory (Git branch, cleanliness, a few recent commit subjects, and top-level project-relative names) and asks whether to - explore that work or start elsewhere; if the target is empty, it opens + explore that work or start elsewhere; if the target is empty, after the + required reporting header (Doctrine 7.12.1) it opens the conversation with exactly: "Tell me what you are thinking." Later valid states emit a fresh-role prompt without changing target bytes. To use the former full questionnaire instead — Owner-time timer, one question at a time, no @@ -363,7 +387,7 @@ question at a time. Do not begin adoption until I ratify the recovery packet. If your coding agent supports skills, the shorter invocation is: ```text -Use the writwall-adopt skill. Bootstrap this repository for Doctrine 0.8 +Use the writwall-adopt skill. Bootstrap this repository for Doctrine adoption. Baseline commit candidate: determine and propose. Ask one question at a time and do not begin product work. ``` @@ -490,10 +514,37 @@ Independent provider denial: reports the provider's own denial as the exact bloc Environment prerequisite failure: names the exact missing or failed environment prerequisite as the blocker. Unapproved task creation or data transmission: never creates or transmits a task, message, or dataset outside the approved action. +Owner approval of a roadmap, plan section, or discussion is not execution approval for any +individual work order or batch member. A fresh Owner approval is required outside an +already-approved batch or at a reserved milestone; an approved finite sequence confers no +release, publish, deploy, push, tag, or external-account authority beyond what each member's own +grant already authorizes, and a nonapproved successor stops for a fresh Owner decision. Once an +approved batch's last member is complete, blocked, or exhausted, report results and recommend, +but never activate, expand, or manufacture, follow-on work. Acceptance of a routine, fully +conforming batch member stays the Owner's own disposition unless the Owner has separately +ratified a delegated conforming-completion disposition policy naming a delegate; such closure is +recorded as disposed under that policy, never described as "the Owner accepted," and rework or +deviation ratification are never delegable under any policy. Track a handoff between functions +through its distinguishable state -- prepared, sent, acknowledged, returned, or reviewed -- and +report a status not actually observed as unknown, never inferred as favorable; preserve a +human-relayed message together with its provenance, that it was relayed, by whom, and when, and +never present it as a direct machine-to-machine handoff record. Begin every reply that addresses +the Owner directly with a one-line header stating the project, the current work order or batch +and its plain-language purpose, and status -- proposed, no active work order, active, blocked, or +reporting on completion -- never as a line inside a generated JSON file, a pasted command, or +another machine-readable or reusable artifact. For an approved batch, distinguish overall batch +progress from the currently active member. This is instruction only: it proves the requirement +was generated, never that a future invocation will actually follow it. + Once approved, perform every -mechanically available authorized step. Do not ask for the same decision again. The human Owner -alone ratifies intent and activates work; preserve a distinct fresh Reviewer after -implementation. The onboarding coordinator stops here and does not continue into project work. +mechanically available authorized step. Do not ask for the same decision again. Whenever you +delegate a bounded task to a fresh Operator, announce the delegated role and bounded task, name a +discoverable monitoring location or state plainly that none exists, state the last verified +execution/handoff state, and name the result/question return route; ending a conversational reply +must never imply that delegated work keeps running or has stopped when that is not actually +observed. The human Owner alone ratifies intent and activates work; preserve a distinct fresh Reviewer +after implementation. The onboarding coordinator stops here and does not continue into +project work. ``` The Authorization section above is filled in by the General itself from @@ -516,7 +567,13 @@ After you separately approve and activate a work order, start a fresh Implemente ```text Act as a fresh Implementer for the active work order only. Confirm the active dispatch and required live-wall canary before mutation. Execute the order, preserve RED -and GREEN evidence, write its report, and stop before acceptance or closeout. +and GREEN evidence, write its report, and stop before acceptance or closeout. Begin +every reply that addresses the Owner directly with a one-line header naming the +project, the current work order or batch and its plain-language purpose, and status +(proposed, no active work order, active, blocked, or reporting on completion); never +place it inside a generated JSON file, a pasted command, or another machine-readable +artifact. This is instruction only, proving the requirement was generated, never that +it will be followed. ``` For review, start a fresh session: @@ -524,7 +581,16 @@ For review, start a fresh session: ```text Act as a read-only Reviewer. Review the active work order, implementation diff, test evidence, and report for conformance and record truth. Do not implement a -fix. Return ACCEPT or specific findings with severity and evidence. +fix. Return ACCEPT or specific findings with severity and evidence. Your findings +are addressed to the Owner and, for delivery only, conveyed through the Architect, +who may not suppress, rewrite, condition, delay, or waive any finding; the Owner +retains standing access to your complete original findings, and a finding +implicating an Architect decision escalates to the Owner directly. Begin every +reply that addresses the Owner directly with a one-line header naming the project, +the current work order or batch and its plain-language purpose, and status +(proposed, no active work order, active, blocked, or reporting on completion); +never place it inside a generated JSON file, a pasted command, or another +machine-readable artifact. ``` The complete adoption contract, artifact sequence, and provider-specific birth diff --git a/checks/check_distribution.py b/checks/check_distribution.py index f6cb540..59e162c 100644 --- a/checks/check_distribution.py +++ b/checks/check_distribution.py @@ -98,6 +98,49 @@ def machine_path_occurs(text: str, needle: str) -> bool: "is a candidate", ) +# Doctrine 7.12.1 defines the "proposed" work-order/batch status value using +# prose shaped like a candidate-phrase match: "an idea, sketch, or draft not +# yet ratified or activated". That clause defines a status value; it asserts +# nothing about DOCTRINE.md's own DC.1 ratification state. +# +# The exemption below is POSITIONALLY scoped to clause 7.12.1's own text +# span, never applied to the whole document. A blanket string/regex +# replacement over all of DOCTRINE.md would also silently erase this exact +# phrase if it were quoted (with the same intervening whitespace) OUTSIDE +# 7.12.1 -- for example a sentence inserted before Part 1 falsely claiming +# "This Doctrine revision is a draft not yet ratified or activated" -- which +# is exactly the genuine contradiction this scan exists to catch. DOCTRINE.md +# remains in CANDIDATE_SCAN_DOCUMENTS and every occurrence of a candidate +# phrase anywhere OUTSIDE the located 7.12.1 span still scans normally; only +# the text located between the "7.12.1" and "7.12.2" clause markers has this +# one known phrase stripped before matching. The canonical clause wraps its +# line between "or" and "activated", so the match tolerates existing +# whitespace (a wrapped newline or a plain space) at exactly that point. +DOCTRINE_NORMATIVE_STATUS_DEFINITION_RE = re.compile( + r"draft not yet ratified or\s+activated") +DOCTRINE_CLAUSE_7121_START_RE = re.compile(r"7\.12\.1\s") +DOCTRINE_CLAUSE_7121_END_RE = re.compile(r"7\.12\.2\s") + + +def strip_doctrine_7121_normative_definition(lowered_text: str) -> str: + """Remove the benign 7.12.1 status-value phrase, scoped to 7.12.1 only. + + Locates clause 7.12.1's own span (from its "7.12.1" marker up to the + next "7.12.2" marker) in the already-lowercased DOCTRINE.md text and + applies the phrase substitution only inside that span. Text outside the + span -- including an identical-looking phrase quoted elsewhere in the + document -- is returned unmodified, so it remains subject to the + ordinary candidate-phrase scan. + """ + start_match = DOCTRINE_CLAUSE_7121_START_RE.search(lowered_text) + end_match = DOCTRINE_CLAUSE_7121_END_RE.search(lowered_text) + if not start_match or not end_match or end_match.start() <= start_match.start(): + return lowered_text + start, end = start_match.start(), end_match.start() + clause = DOCTRINE_NORMATIVE_STATUS_DEFINITION_RE.sub( + "", lowered_text[start:end]) + return lowered_text[:start] + clause + lowered_text[end:] + # v0.1 may never be presented as having carried authority. V01_AUTHORITY_CLAIM_PHRASES = ( "v0.1 was ratified", @@ -129,6 +172,8 @@ def machine_path_occurs(text: str, needle: str) -> bool: REPO_ROOT / "migration-guides" / "0.6-to-0.7.md", SKILL / "references" / "migration-guides" / "0.7-to-0.8.md": REPO_ROOT / "migration-guides" / "0.7-to-0.8.md", + SKILL / "references" / "migration-guides" / "0.8-to-0.9.md": + REPO_ROOT / "migration-guides" / "0.8-to-0.9.md", SKILL / "assets" / "adapters" / "claude-code" / "README.md": ADAPTER_README, SKILL / "assets" / "adapters" / "claude-code" / "wo_capability_wall.py": ADAPTER, SKILL / "assets" / "checks" / "check_work_order_dispatch.py": DISPATCH_CHECKER, @@ -202,6 +247,7 @@ def machine_path_occurs(text: str, needle: str) -> bool: "migration-guides/0.1-to-0.6.md", "migration-guides/0.6-to-0.7.md", "migration-guides/0.7-to-0.8.md", + "migration-guides/0.8-to-0.9.md", "scripts/build_distribution.py", "scripts/build_public_projection.py", "scripts/collect_name_clearance.py", @@ -458,6 +504,12 @@ def check_markers(control: dict, failures: Failures) -> None: if not path.is_file(): continue lowered = read_text(path).lower() + if name == "DOCTRINE.md": + # Strip only clause 7.12.1's own known-normative text, by + # position, not the whole document; every other occurrence + # of a candidate phrase in DOCTRINE.md -- including this + # same phrase quoted OUTSIDE 7.12.1 -- still scans. + lowered = strip_doctrine_7121_normative_definition(lowered) for phrase in CANDIDATE_CLAIM_PHRASES: if phrase in lowered: failures.add( diff --git a/checks/check_public_projection.py b/checks/check_public_projection.py index a2da714..f9cb50f 100644 --- a/checks/check_public_projection.py +++ b/checks/check_public_projection.py @@ -89,9 +89,11 @@ def find_retained_tokens(line: str) -> list[str]: "CLAUDE.md", "decisions/DR-001.md", "decisions/DR-005.md", + "decisions/DR-006.md", "governance/ADOPTION-MAPPING.md", "governance/LOG-denials-probes.md", "governance/ROUTING.md", + "governance/STATE.md", "governance/decisions/DR-001.md", "governance/decisions/DR-005.md", }) diff --git a/decisions/DR-006.md b/decisions/DR-006.md new file mode 100644 index 0000000..ec9bd9c --- /dev/null +++ b/decisions/DR-006.md @@ -0,0 +1,71 @@ +# DR-006: Ratification of Doctrine revision 0.9 — Architect-led coordination + +| Field | Value | +|---|---| +| Record | DR-006, methodology-source decision | +| Owner | HLLMR | +| Date | 2026-09-16 | +| Revision ratified | 0.9 | +| Supersedes | 0.8 | +| Authority | Doctrine DC.3.4 and DC.3.5 | +| Candidate transcribed from | governance/reports/WO-WW-030-METHODOLOGY-CANDIDATE.md, whole-file SHA-256 0ACBF638D71C0F41CE059D1AE1F8BEB7DA3B23325942B9ACE00F21E2491E9FAB (private governed-source reference, not present in this candidate) | + +## Decision + +Ratify Doctrine revision 0.9, superseding 0.8, with exactly the clause text in +WO-WW-030-METHODOLOGY-CANDIDATE.md section 2, and no other change. + +## Reasoning + +Ratified Doctrine 0.8's 4.1.2 states "there is no ... architect-agent," while +this repository's own shipped onboarding surface — README.md, +START-HERE.md, ADOPTING.md, docs/architect-interview.md, +docs/day-zero-coordinator.md, and skills/writwall-adopt/SKILL.md — already +names, generates, and routes to an Architect and a General as ordinary, +fresh, non-continuous functions. That is a live contradiction between the +ratified methodology and its own reference implementation, named in +governance/PLAN.md section 35 and public issue #41. The correct repair is to +recognize that the shipped functions already comply with 4.1.1's +function-not-persona model and to say so in the ratified text, rather than to +continue operating a coordinator the Doctrine's own charter text disavows. + +Separately, WO-PL-014 through WO-PL-016 exposed that this project's own pilot +required repeated identical Owner approvals for routine, already-approved +work-order sequencing (DR-002 adverse finding 2; PLAN.md section 27). +Formalizing batch approval (7.10) with reserved milestones and a +delegated-disposition option addresses that without removing the Owner's +ratification monopoly (2.7) or the Reviewer's independence (4.2.4, new +7.6.4). + +## Rejected alternatives + +1. Leave 4.1.2 as a purely instructional dead letter alongside a + contradicting shipped product. Rejected: an unenforced false statement in + ratified text is worse than no statement (Doctrine's own 8.3.4 principle, + applied to prose rather than a wall). +2. Rename the shipped Architect/General roles to avoid the banned words + rather than fix the clause. Rejected as cosmetic: the underlying practice + (fresh, non-persistent invocations) already conforms to 4.1.1 and 4.1.2's + actual concern, which is persistent authority, not a noun. +3. Grant a batch standing, open-ended authority to activate any future work + a General judges to be in scope. Rejected as contrary to 3.2.1 and 7.9.2. +4. Add a machine-readable `batch:` field to Appendix B's frontmatter and the + pre-dispatch validator now. Rejected: the shipped validator's complete + source defines no such key, and no observed defect requires adding one. +5. Define "General" as identical to the existing Dispatcher function rather + than a distinct function that may perform it. Rejected: the shipped + General also performs recorder mechanics and continuity awareness the + Dispatcher definition does not cover. +6. Silently broaden 8.7.6's existing "separately authorized recorder or + mechanism" language to cover the new function names without an explicit + cross-reference clause. Rejected in favor of the explicit, minimal + cross-reference at 8.7.7. + +## Project-binding boundary + +This methodology-source decision does not migrate this repository's own +project-side governance instance (bound to 0.8 per +`governance/decisions/DR-003.md`) or any adopting project. Each remains bound +to its recorded revision until its Owner separately ratifies migration under +DC.4. It does not publish, push, tag, change visibility, replace checked-in +`dist/`, or authorize access to another project. diff --git a/decisions/README.md b/decisions/README.md index 6c71be2..1b04765 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -15,9 +15,10 @@ the project's license map on 2026-08-20. It resolves RFI-03. `DR-004` ratified Doctrine revision 0.7 on 2026-08-20, superseding 0.6. `DR-005` ratified Doctrine revision 0.8 on 2026-08-21, superseding 0.7. -Revision 0.8 is the current ratified methodology revision (`DOCTRINE.md` -DC.1). Projects already bound to 0.6 or 0.7, including this repository's own -project-side governance instance bound to 0.6, remain bound to their recorded +`DR-006` ratified Doctrine revision 0.9 on 2026-09-16, superseding 0.8. +Revision 0.9 is the current ratified methodology revision (`DOCTRINE.md` +DC.1). Projects already bound to earlier revisions, including this repository's +own project-side governance instance bound to 0.8, remain bound to their recorded revision until their Owner separately ratifies migration (DC.4); see `migration-guides/0.6-to-0.7.md` and `migration-guides/0.7-to-0.8.md`. diff --git a/docs/architect-interview.md b/docs/architect-interview.md index 6a1f874..8f5b1a2 100644 --- a/docs/architect-interview.md +++ b/docs/architect-interview.md @@ -10,8 +10,9 @@ few recent commit subjects, and top-level project-relative names); the Architect begins read-only, uses that evidence before asking the Owner to restate anything already visible in repository bytes, summarizes what it found, and asks whether to explore that work or start elsewhere. For a -genuinely empty target it opens with exactly: "Tell me what you are -thinking," and imposes no fixed question list. A supplied project or command +genuinely empty target it imposes no fixed question list; after the required +reporting header (Doctrine 7.12.1), it opens the conversation with exactly: +"Tell me what you are thinking." A supplied project or command name is always a `working_candidate`; generated files never make it canonical, available, cleared, or accepted. @@ -54,15 +55,40 @@ The output separates adaptive judgment from mechanics: rejected, no adoption, work order, or construction control is created; - `GENERAL.md` is the exact prompt for post-adoption continuity: preparing bounded dispatch, routing work, and performing only explicitly authorized - recorder mechanics; -- `OPERATOR.md` is inert until a ratified plan and active work order; + recorder mechanics. Whenever it delegates a bounded task to a fresh + Operator, it announces the delegated role and task, names a discoverable + monitoring location or states plainly that none exists, states the last + verified execution/handoff state, and names the result/question return + route, so a conversational reply never implies delegated work keeps + running or has stopped when that is not actually observed. Its own mandate + is finite: a roadmap or plan approval is never execution approval for one + work order or batch member, a fresh Owner approval is required outside an + approved batch or at a reserved milestone, and it never activates, + expands, or manufactures follow-on work at a batch's end. A routine, + fully conforming batch member's acceptance stays the Owner's unless a + separately ratified delegated conforming-completion disposition policy + names a delegate, and rework or deviation ratification are never + delegable; +- `OPERATOR.md` is inert until a ratified plan and active work order, and + files an RFI as one of three kinds -- informational, resolvable, or + blocking -- treating doubtful independence from a blocking matter as + blocking rather than declaring it unilaterally; - `OWNER-AGENT.md` and `REPOSITORY-OPERATOR.md` are compatibility aliases for `ARCHITECT.md` and `OPERATOR.md`, kept for existing consumers of those two filenames; -- `REVIEWER.md` keeps fresh review separate from implementation; +- `REVIEWER.md` keeps fresh review separate from implementation; its brief + is addressed to the Owner and only conveyed, never filtered, through the + Architect, and the Owner retains standing access to its complete original + findings; - `NAME-CLEARANCE.md` routes the canonical seven-source evidence process; and - `OWNER-RATIFICATION.md` is the explicit stop before implementation. +Every packet that addresses the Owner directly opens with a compact +reporting header -- project; work order or batch identifier and its +plain-language purpose; and status, including `proposed` and `no active +work order` -- never inside `discovery.json`, `intake.json`, or another +machine-readable artifact (Doctrine 7.12). + Every one of these packets, plus `discovery.json` itself, carries the same one resolved canonical project root; see [`day-zero-coordinator.md`](day-zero-coordinator.md#canonical-project-root) diff --git a/docs/day-zero-coordinator.md b/docs/day-zero-coordinator.md index 6564c65..a5a5775 100644 --- a/docs/day-zero-coordinator.md +++ b/docs/day-zero-coordinator.md @@ -135,7 +135,8 @@ read-only, uses the recorded evidence before asking the Owner to restate anything already visible in repository bytes, summarizes the apparent project in plain language, and asks whether the Owner wants to explore that work or start elsewhere. If the target is genuinely empty, the opening -imposes no fixed question list and reads exactly: "Tell me what you are +imposes no fixed question list; after the required reporting header (Doctrine +7.12.1), it opens the conversation with exactly: "Tell me what you are thinking." Neither observation is ratified intent; `discovery.json` records it under `local_observations`, kept separate from Owner-supplied statements, alongside a deterministic, explicitly `unratified_recommendation` topology @@ -238,16 +239,72 @@ later design-conformance judgment: it interviews, drafts, routes, and performs exactly authorized lifecycle mechanics. After adoption, a fresh **General** owns continuity — preparing bounded dispatch, routing work, and performing only explicitly authorized recorder mechanics — without ratifying -intent or judging design conformance itself. An **Operator** works only +intent or judging design conformance itself. Whenever it delegates a bounded +task to a fresh Operator, it announces the delegated role and task, names a +discoverable monitoring location or states plainly that none exists, states +the last verified execution/handoff state (Doctrine 7.11.5), and names the +result/question return route; a conversational reply never implies delegated +work keeps running or has stopped when that is not actually observed. +Doctrine 7.11.5 tracks a handoff between functions through five +distinguishable states — prepared, sent, acknowledged, returned, and +reviewed — and a status not actually observed is reported as unknown, never +inferred as favorable. A human-relayed message is preserved together with +its provenance — that it was relayed, by whom, and when — and is never +presented as a direct machine-to-machine handoff record (Doctrine 7.11.6). +An **Operator** works only under one active, Owner-ratified work order. An infrastructure, DNS, mail, deployment, or other external Operator receives a bounded packet and returns evidence; it remains outside the repository wall unless it edits repository -bytes. A fresh **Reviewer** checks the relevant order, result, report, and -returned evidence. `OWNER-AGENT.md` and `REPOSITORY-OPERATOR.md` remain as +bytes. An Operator files an RFI as one of three kinds — an informational +clarification, a resolvable execution problem, or a blocking scope, +authority, or safety contradiction (Doctrine 7.11.1) — and where +independence from a blocking matter is itself in doubt, the dependency is +treated as blocking, never declared independent unilaterally by the +Architect or General (7.11.2). A fresh **Reviewer** checks the relevant +order, result, report, and returned evidence; its owner brief is addressed +to the Owner and, for delivery only, conveyed through the Architect, who may +not suppress, rewrite, condition, delay, or waive any finding — the Owner +retains standing access to the Reviewer's complete original findings, and a +finding implicating an Architect decision escalates to the Owner directly +(Doctrine 7.6.4). `OWNER-AGENT.md` and `REPOSITORY-OPERATOR.md` remain as compatibility aliases for the Architect and Operator packets. -The Architect and General keep the proverbial keys—authority and -routing—not literal passwords or cryptographic material. External packets +Owner approval of a roadmap, plan section, or discussion is not execution +approval for any individual work order or batch member (Doctrine 7.10.1); a +fresh Owner approval is required outside an already-approved batch or at a +reserved milestone (7.10.4). Once an approved batch's last member is +complete, blocked, or exhausted, the General reports results and may +recommend, but never activates, expands, or manufactures, follow-on work; +batch approval by itself confers no release, publish, deploy, push, tag, or +external-account authority (7.10.7). Acceptance of a routine, fully +conforming batch member stays the Owner's own disposition unless the Owner +has separately ratified a delegated conforming-completion disposition policy +naming a delegate (2.33, 7.10.6); such closure is recorded as disposed under +that policy, never described as "the Owner accepted," and rework or +deviation ratification are never delegable under any policy. + +## Reporting headers + +Every Architect, General, Operator, and Reviewer reply that addresses the +Owner directly opens with a compact header: the project; the current work +order or batch identifier and its plain-language purpose; and status — +proposed, no active work order, active work on a named item, blocked, or +reporting on a completed work order or batch (Doctrine 7.12.1). For an +approved batch, the header distinguishes overall batch progress from the +currently active member rather than naming only the active item (7.12.2). +This header never appears inside `intake.json`, `discovery.json`, a pasted +command, or another machine-readable or reusable artifact (7.12.4). + +Stating this requirement in canonical prompts, skill instructions, and +generated role packets instructs a freshly invoked function to comply; it +does not itself make compliance mechanical. A test of generated bytes proves +only that the instruction is present in what was generated, never that a +future invocation will actually follow it (Doctrine 7.12.5). + +The Architect and General keep the proverbial keys—routing and +sequencing—not literal passwords or cryptographic material, and not +authority, which stays with the Owner and the recorded delegation chain +(Doctrine 4.1.4, 8.7.7). External packets separate preconditions, permitted and prohibited actions, verification, rollback, evidence, and credential handling. Blank packet fields authorize nothing. An operation-packet scaffold confers no authority by itself. diff --git a/governance/LOG-denials-probes.md b/governance/LOG-denials-probes.md index 8c98329..2964e12 100644 --- a/governance/LOG-denials-probes.md +++ b/governance/LOG-denials-probes.md @@ -1448,3 +1448,120 @@ No additional denial record was appended during implementation or review; zero successful forbidden mutations observed. Whole-surface classification remains 8 / 0 / 8. The initial provider-launch rejection occurred before process creation and is not a capability-wall denial or a second canary. + +## WO-WW-030 session-local evidence — 2026-09-16 (post-pilot) + +Record **339** is this session's first mutation-capable call: a `Write` to +the excluded target `governance/scratch/WO-WW-030-canary-must-not-exist.txt` +named by the issued work order's B.1 "Session-local canary" section. It is +classified here as a **session-local excluded-target probe — EXCLUDED from +the 9.2.1 pilot total** (the same class as every prior canary in this log, +though this work order itself is post-pilot and contributes no pilot row). + +| Field | Value | +|---|---| +| Record | **339** | +| Class | **Session-local excluded-target probe (live-wall canary) — EXCLUDED** | +| Timestamp | `2026-09-16T21:44:08Z` | +| Executing session | `9ce35429-488e-467b-a92c-e42f13999030` | +| Tool | `Write` | +| Surface | `filesystem.write` | +| Work order | `governance/work-orders/WO-WW-030-architect-led-coordination.md` | +| Reason code | `write_target_out_of_grant` | +| Target | `governance/scratch/WO-WW-030-canary-must-not-exist.txt`, named by B.1 and deliberately excluded from `grant.filesystem.write` | + +**Exact arithmetic, verified directly from `governance/LOG-denials.jsonl` by +this Implementer, not assumed from the prior turn's description of a +coordinator's out-of-band check:** + +1. The provider blocked the call **before** mutation: the tool result was + `BLOCKED by WO-WW-030-architect-led-coordination.md: ... is outside + grant.filesystem.write (...)`. No file was written. +2. The target **remains absent**: no read of + `governance/scratch/WO-WW-030-canary-must-not-exist.txt` was attempted or + needed, because the Write tool itself reported the block before any + filesystem effect and no later step in this session created it. +3. Reading `governance/LOG-denials.jsonl` directly in this session shows + exactly **339** total lines, with line 339 being the only record whose + `work_order` names `WO-WW-030-architect-led-coordination.md`. Lines 1-338 + are unchanged from their content as already classified through record 338 + above; this session performed no write to that file and could not have + altered it, since the log is adapter-append-only and outside this grant's + `filesystem.write` entirely. +4. Record 339 carries `session_id: "9ce35429-488e-467b-a92c-e42f13999030"`, + `tool: "Write"`, `surface: "filesystem.write"`, the issued WO-WW-030 path, + and `reason_code: "write_target_out_of_grant"` — read directly from the + log line quoted above, not transcribed from the coordinator's prior + assertion. That assertion and this session's own direct read of the log + agree on the session ID and reason code. + +**What this session did not independently verify.** This Implementer has no +shell, hashing tool, or other mechanism under this grant to compute a +SHA-256 digest of any prefix of `governance/LOG-denials.jsonl`. The prior +turn's claimed digest for the first 338 records +(`C705D8BABE7D934FEAF5AC627991F22273F284EAB395F959CC384DAB402CCFD5`) is +recorded here as an **externally asserted, not independently recomputed,** +value. This session's own evidence is limited to: a direct read of the +complete 339-line file, confirmation that line 339 is the only WO-WW-030 +record and matches the denial this session observed at the tool boundary, +and the fact that this grant contains no tool capable of writing to +`governance/LOG-denials.jsonl` at all, which makes tampering by this session +structurally impossible rather than merely unobserved. + +**Scope.** This proves the file-edit channel was walled in session +`9ce35429…` for this one target and nothing more. It does not transfer to +any other session, and it says nothing about shell-mediated writes or any +other surface recorded elsewhere in this repository as unenforced. This +work order is post-pilot (WO-WW-030 postdates the ten counted orders) and +contributes no row to any pilot 9.2.1 total; it is recorded here only for +denial-evidence continuity and probe/canary classification. + +### Record 340 — genuine external-read denial, same session + +The coordinator directed this same session to read an external Codex review +artifact at a path outside this repository +(the external native Opus review event log named `ww030-review.md.jsonl`) +to cite a native Opus review session in this work order's report. This was +attempted as a genuine task action, not a deliberate probe or canary. + +| Field | Value | +|---|---| +| Record | **340** | +| Class | **Genuine out-of-grant read attempt — not a probe, not a canary.** Classified the same way as WO-WW-028's records 336-337: a real attempt to reach required task evidence, denied categorically | +| Timestamp | `2026-09-16T22:15:32Z` | +| Executing session | `9ce35429-488e-467b-a92c-e42f13999030` (same session as record 339) | +| Tool | `Read` | +| Surface | `filesystem.read` | +| Work order | `governance/work-orders/WO-WW-030-architect-led-coordination.md` | +| Reason code | `read_target_outside_repository` | +| Target | The external Codex visualization artifact named above, entirely outside this repository | + +**Effect on this work order's report.** Because this Read was denied before +any bytes were returned, this session never observed the cited review +file's actual contents, the exact text of any of its labeled findings +(B1-B6, C1-C8, D1-D3, E1-E3), or independent confirmation of native Opus +session `8f342106-6ec9-45c7-ab1c-a55123109030`. Every correction made in +response to that review in this work order's candidate, continuation, and +report is therefore sourced from the coordinator's own chat-relayed +paraphrase of the review's findings, not from this session's direct +inspection of the review artifact — a distinction `WO-WW-030-report.md` +states explicitly per Doctrine 7.11.6 (preserve a human-relayed message's +provenance; never present it as a direct record). + +**Scope.** This denial proves the read wall's categorical +outside-repository restriction held for this one external path in this one +session. It says nothing about any other surface, and it is not evidence +that the cited review file does not exist or is inaccessible to the Owner +by other means (e.g., pasted directly, or copied inside the repository by +an actor with filesystem access this session does not have). + +## WO-WW-031 native author canary — record341 + +Owner-authorized expected-denial Write canary, observed at2026-09-17T01:02:08Z. +Native session c1496e3e-7712-48e0-9a1d-543b27ab0ee9 attempted exactly one +Write to governance/scratch/WO-WW-031-canary-must-not-exist.txt; the hook denied +it with write_target_out_of_grant. Coordinator independently verified target +absence, exactly341 total records and the preceding340-record byte-prefix +SHA-256 C82B0C4AAF21CA221E3B83589BBA95FDD10936DB4207A468E283F0E38F34705E. +This is a canary, not an operational drift event; it qualifies only the observed +session/channel. All whole-surface enforcement declarations remain unchanged. diff --git a/governance/LOG-denials.jsonl b/governance/LOG-denials.jsonl index d6e9945..1c7e987 100644 --- a/governance/LOG-denials.jsonl +++ b/governance/LOG-denials.jsonl @@ -336,3 +336,9 @@ {"schema":1,"timestamp":"2026-09-15T13:04:30Z","session_id":"6c86ec97-bf2d-4e39-a6b7-026a038b3e09","tool":"Read","surface":"filesystem.read","work_order":"governance/work-orders/WO-WW-028-compact-continuation-brief.md","decision":"deny","reason_code":"read_target_outside_repository","reason":"Read target could not be resolved inside the repository."} {"schema":1,"timestamp":"2026-09-15T13:04:31Z","session_id":"6c86ec97-bf2d-4e39-a6b7-026a038b3e09","tool":"Read","surface":"filesystem.read","work_order":"governance/work-orders/WO-WW-028-compact-continuation-brief.md","decision":"deny","reason_code":"read_target_outside_repository","reason":"Read target could not be resolved inside the repository."} {"schema":1,"timestamp":"2026-09-16T16:41:58Z","session_id":"445c7652-2872-40d4-a4e7-9c15fb8952a4","tool":"Write","surface":"filesystem.write","work_order":"governance/work-orders/WO-WW-029-bounded-operational-preflight.md","decision":"deny","reason_code":"write_target_out_of_grant","reason":"Write target is outside grant.filesystem.write."} +{"schema":1,"timestamp":"2026-09-16T21:44:08Z","session_id":"9ce35429-488e-467b-a92c-e42f13999030","tool":"Write","surface":"filesystem.write","work_order":"governance/work-orders/WO-WW-030-architect-led-coordination.md","decision":"deny","reason_code":"write_target_out_of_grant","reason":"Write target is outside grant.filesystem.write."} +{"schema":1,"timestamp":"2026-09-16T22:15:32Z","session_id":"9ce35429-488e-467b-a92c-e42f13999030","tool":"Read","surface":"filesystem.read","work_order":"governance/work-orders/WO-WW-030-architect-led-coordination.md","decision":"deny","reason_code":"read_target_outside_repository","reason":"Read target could not be resolved inside the repository."} +{"schema":1,"timestamp":"2026-09-17T01:02:08Z","session_id":"c1496e3e-7712-48e0-9a1d-543b27ab0ee9","tool":"Write","surface":"filesystem.write","work_order":"governance/work-orders/WO-WW-031-doctrine-0.9-implementation.md","decision":"deny","reason_code":"write_target_out_of_grant","reason":"Write target is outside grant.filesystem.write."} +{"schema":1,"timestamp":"2026-09-17T16:31:27Z","session_id":"c1496e3e-7712-48e0-9a1d-543b27ab0ee9","tool":"Write","surface":"filesystem.write","work_order":"governance/work-orders/WO-WW-032-v0.12.0-delivery.md","decision":"deny","reason_code":"write_target_out_of_grant","reason":"Write target is outside grant.filesystem.write."} +{"schema":1,"timestamp":"2026-09-17T16:47:24Z","session_id":"51df66e8-5726-4e29-a83b-22859f915c82","tool":"Read","surface":"filesystem.read","work_order":"governance/work-orders/WO-WW-032-v0.12.0-delivery.md","decision":"deny","reason_code":"read_target_outside_repository","reason":"Read target could not be resolved inside the repository."} +{"schema":1,"timestamp":"2026-09-17T16:47:25Z","session_id":"51df66e8-5726-4e29-a83b-22859f915c82","tool":"Read","surface":"filesystem.read","work_order":"governance/work-orders/WO-WW-032-v0.12.0-delivery.md","decision":"deny","reason_code":"read_target_outside_repository","reason":"Read target could not be resolved inside the repository."} diff --git a/governance/LOG.md b/governance/LOG.md index 9e3d066..6b52869 100644 --- a/governance/LOG.md +++ b/governance/LOG.md @@ -1220,3 +1220,90 @@ Fresh Sonnet CONFORMANCE PASS, no substantive blocker; source-level review was independent, test execution was coordinator-attested. The preflight is instruction-bound guidance. No full-source suite or public projection was part of implementation acceptance; public delivery remains separately gated. + +## Post-pilot WO-WW-030 completed record — 2026-09-16 + +Owner accepted with disclosed deviations and ratified the frozen Doctrine 0.9 +candidate. Active minutes NOT REPORTED. This is not another counted pilot item. + +- 9.2.1: one excluded Write canary (339); one genuine non-mutating Read denial + (340), caused by coordinator transport of an outside-repository artifact path. + No successful forbidden mutation observed; first 338 record bytes preserved. +- 9.2.2: no numbered RFI created; local defects resolved within approved scope. +- 9.2.3/9.2.4: five substantive coordinator correction turns and one final + two-phrase non-normative cleanup; four independent-review result checkpoints + in one distinct Opus session, ending CONFORMANCE PASS. Earlier failures remain + preserved. Normalized drift totals NOT MEASURED, not reconstructed. +- 9.2.5: corpus/orphan counts NOT MEASURED. The continuation identifies three + unmapped and three subject-only routed implementation targets for remedy. +- 9.2.6: 8 declared / 0 wholly enforced / 8 unenforced. Canary evidence is + native-session/channel-local; coordinator authority is separate. +- 9.2.7: Owner reading minutes and mandatory reading total NOT REPORTED. +- 9.2.8: no qualified empirical instrument. Tabletop scenarios are not runtime + or operating-cost evidence. No Phase B tests or release occurred in Phase A. + +Final active validation, exact changed-path, whitespace, protected-WO/grant and +denial-prefix checks passed. Reviewer confidence HIGH on normative integrity and +resolved findings, with explicitly retained targeted-source coverage limits. +The separately recorded Owner approval authorizes bounded implementation and +later delivery, preserving required acceptance milestones and all project bindings. + +## Post-pilot WO-WW-031 completed record — 2026-09-17 + +Owner accepted with disclosed deviations: "Accepted, proceed". Active minutes +NOT REPORTED; this is not another counted pilot item. Distribution templates, +bundle, migration guide and generated/human role-coordination instructions now +implement ratified0.9; the project binding remains0.8, with no adopter migration. + +- 9.2.1: one fresh excluded Write canary341 denied before mutation; original340 + records preserved, target absent, no successful forbidden mutation observed. +- 9.2.2: no numbered RFI issued; exact routing/gate/resource amendments were + separately authorized. No authority gap was silently repaired by Implementer. +- 9.2.3/9.2.4: author/reviewer corrections and earlier failed gates retained; + normalized drift counts NOT MEASURED. Final independent Opus supported + acceptance after a report-only authority citation was corrected. +- 9.2.5: R.16 remedy and exact31-path grant validated; corpus/orphan counts + NOT MEASURED. No new general routing enforcement claim. +- 9.2.6:8 declared/0 wholly enforced/8 unenforced; canary session/channel-local. +- 9.2.7: Owner reading/active minutes and mandatory-reading total NOT REPORTED. +- 9.2.8: no empirical operating-cost instrument. An extra action-versus-record + approval round trip was observed and called adoption friction by the Owner; + this is a process finding, not new product scope or a quantified cost claim. + +Final Windows848 total/13 skips/PASS674.606s; native Ubuntu848 total/4 skips/ +PASS752.477s. Both installed/payload gates passed on unchanged frozen input; +clean source fixture and deliberate guide negatives passed with explicit limits. +Temporary account/home removed. Live source retained LOG digest mismatch remains +an explicit postcloseout refresh/regate prerequisite, not a concealed pass. +No release, public PR, tag or migration occurred within031 implementation. + +## Post-pilot WO-WW-032 completed record — 2026-09-17 + +Owner disposition: "ACCEPT WO-WW-032 including disclosed deviations; active +minutes: NOT REPORTED; proceed with authorized closeout and v0.12.0 publication." +This is not another counted pilot item. Version/install references and release +tests now consistently target0.12.0; canonical Doctrine0.9 remains distinct from +the operative private0.8 binding. Exactly five permitted retained-reference +digest fields changed during implementation; no membership or policy change. + +- 9.2.1: excluded executing-session Write canary342 denied before mutation; + two private Reviewer outside-root Read denials343/344, no successful forbidden + mutation. Original341-record prefix preserved. A separate public-candidate + Reviewer's unavailable Write request never executed; evidence retained. +- 9.2.2: no numbered RFI created; exact approved delivery scope unchanged. +- 9.2.3/9.2.4: initial SELF-HOSTING phrase regression, positive assertion + wrapping, verification-helper and recorder heading/encoding failures retained + beside corrected passes. Normalized drift/rework counts NOT MEASURED. +- 9.2.5: full applicable dispatch/prose scan and exact11-path audit passed; + corpus/orphan counts NOT MEASURED. Two read-only hash-input labels add no grant. +- 9.2.6:8 declared/0 wholly enforced/8 unenforced; canary session/channel-local. +- 9.2.7: Owner active minutes and mandatory-reading total NOT REPORTED. +- 9.2.8: no empirical operating-cost instrument or adopter migration claim. + +Final pre-acceptance Windows848/13 skips/PASS442.394s and native Ubuntu848/4 +skips/PASS338.020s ran sequentially. Installed/payload/archive gates passed on +both; two actual managed139-file candidates matched, final privacy checks PASS. +Fresh distinct public-candidate Opus inspected17 paths and returned ACCEPT-READY +with no blocking findings; execution/hashes were supplied Coordinator evidence. +No new account or host/system package change. Final postcloseout qualification +and authorized publication remain subsequent gates, not claimed complete here. diff --git a/governance/PLAN.md b/governance/PLAN.md index ec5c482..64dd53e 100644 --- a/governance/PLAN.md +++ b/governance/PLAN.md @@ -906,3 +906,61 @@ commit authorized; no push, public projection, PR, release or adopter change. Issue #37 remains open pending separately authorized public delivery. Issues #38 and #41 remain proposals; no successor is activated. The Reviewer suggested future documentation-pinning coverage; it is not new authorized work. + +## 35. Architect-led coordination and bounded execution mandates — 2026-09-16 + +Owner approved issuing WO-WW-030 Phase A from the reviewed draft, as recorded +in its live issuance lifecycle. Prepare and independently review an exact +methodology amendment and bounded implementation continuation for issue #41. +Architect remains the human point of contact; General coordinates execution; +Operators implement; Reviewer remains independent with intact Owner escalation. +Specify finite execution-approved batches, preserved delegation, reserved +milestones, blocking RFIs, no unapproved successors, meaningful status headers +and compatible read-only existing-project realignment. Distinguish guidance +from mechanical enforcement. Phase A changes candidate records only and stops +at exact-text Owner ratification. Existing Doctrine 0.8 remains operative. +No Phase B implementation, migration, commit, publication or release is authorized. + +### Owner disposition and bounded continuation — 2026-09-16 + +The Owner subsequently accepted WO-WW-030 with its disclosed deviations and +ratified the exact Doctrine 0.9 candidate, whole-file SHA-256 +0ACBF638D71C0F41CE059D1AE1F8BEB7DA3B23325942B9ACE00F21E2491E9FAB. +The frozen continuation SHA-256 is +9073E29218E13FC283E8A28B8393863EE9C2F5DB6B1872AE8327CF4F6AE0EDC0. +The preceding Phase A-only paragraph records the original issuance boundary; +this subsequent Owner disposition authorizes the bounded continuation below. +Literal authority is recorded in the WO-WW-030 ratification-closeout record. + +## 36. Doctrine 0.9 implementation and v0.12.0 delivery — 2026-09-16 + +Owner-authorized sequence: ordinary WO-WW-030 closeout; exact ratified Doctrine +and DR-006 transcription; scoped WO-WW-031 implementation of the frozen +continuation with its current-project routing prerequisite; independent review, +native Windows/Ubuntu and installed-wheel verification; then, after required +Owner acceptance milestones, coherently versioned v0.12.0 delivery containing +the accepted WO-WW-027/028/029 additions and accepted WO-WW-031 work. Publication +authority includes private push, public PR, CI-gated merge, tag and immutable +release through exact validated grants and the existing publication/privacy gates. +It is not a claim that these actions are already complete. Routine in-scope +correction and verification require no repeated Owner permission. + +WO-WW-031 retains an explicit Owner acceptance milestone. No self-host migration +or other-project access/migration is authorized; the self-hosted binding remains +0.8. A later adopter handoff is informational and read-only. No successor beyond +this finite implementation/delivery objective is authorized. Issue #38 provenance +investigation is outside this sequence. Exact grant, routing and verification +resource records must exist and validate before the corresponding execution. + +### Approved local gate-sequencing amendment — 2026-09-17 + +Owner approved the exact ww031-gate-reconciliation.md proposal with "Approved. +Resume." Proposal SHA-25644D5580C982610A31679D659703AA33D78B1EC022CEB47E0193C2E8FC4CAB75E. +The specified five-path local projection-compatibility/retained-digest subset +moves before031 acceptance, together with the exact two-reference Owner-recorder +correction and eight-line/six-carrier General-only historical diagnostic. The +current031 order enumerates every path and limit. Historical/detector repair is +not authorized by that diagnostic. Full native PASS and independent review are +still required; no acceptance criterion is waived. Version0.11.0 remains until +acceptance, and ordinary closeout,0.12.0 versioning and all publication mechanics +remain after the explicit031 Owner acceptance milestone. No migration is included. diff --git a/governance/ROUTING.md b/governance/ROUTING.md index ba7c09e..4f4063b 100644 --- a/governance/ROUTING.md +++ b/governance/ROUTING.md @@ -38,14 +38,15 @@ assigned, an identifier's number is never reused for a different route. | **R.12** | **`SELF-HOSTING.md`** | Doctrine 5.1, Part 6, and Part 9; root `decisions/DR-001.md`; `governance/PLAN.md`; the adoption record and current observed state | | **R.14** | **`checks/check_work_order_dispatch.py`, `tests/test_check_work_order_dispatch.py`** | Doctrine 8.2.5 and `SELF-HOSTING.md` "Pre-dispatch validation." **Dispatch-preparation scope only** — this checker is read-only tooling run before an Implementer session is launched; it is not part of `.claude/hooks/wo_capability_wall.py` and is never a runtime enforcement surface. Resolved RFI-25/27/28 records are provenance in governed history, not routed ordinary context | | **R.15** | **`PUBLICATION.md`, `projection/**`, `scripts/build_public_projection.py`, `checks/check_public_projection.py`, `tests/test_public_projection.py`, `scripts/privacy_screen.py`, `docs/privacy-screen.md`** | `governance/PLAN.md` post-pilot sequence; DR-003; `LICENSE-MAP.md`; current source/distribution/license gates; the managed project-specific privacy screen held only in OS-local user state; the active projection work order. Projection work may derive and verify an external candidate but never authorizes publication, Git initialization, remote configuration, or visibility change | +| **R.16** | **`START-HERE.md`, `docs/architect-interview.md`, `docs/day-zero-coordinator.md`, `pyproject.toml`, `tests/test_start_writwall.py`, `tests/test_distribution.py`** | Ratified Doctrine definitions 2.29-2.33, Parts 4, 6 and 7, 8.7 and Appendix A; `README.md`, `ADOPTING.md`, the three named entry documents, `skills/writwall-adopt/SKILL.md`, `scripts/start_writwall.py`, `checks/check_distribution.py`, `checks/check_coordinator_release.py`, `pyproject.toml`, the two named test files, and the active work order's exact implementation and verification requirements. Existing R.2/R.4/R.5/R.6/R.7 routes remain applicable to their mapped counterparts. This route supplies context; it grants no mutation, ratification, provider transmission, release or adopter authority. | | R.13 | Unmapped and unsure | **RFI.** Do not proceed on an inferred route | -**R.14 and R.15 sit above R.13 in this table despite being numbered after it.** +**R.14, R.15 and R.16 sit above R.13 in this table despite being numbered after it.** R.13, the unmapped fallback, stays the table's structurally last row by convention regardless of numeric order, so that "last row" and "fallback route" remain the same thing for a reader scanning the table. -R.14 and R.15 were appended following the R.12/R.13 amendment pattern noted -above; neither renumbers R.13 or changes R.13's meaning or position. +R.14, R.15 and R.16 were appended following the R.12/R.13 amendment pattern noted +above; none renumbers R.13 or changes R.13's meaning or position. ### R.11 note on authority @@ -98,4 +99,4 @@ Coverage gaps discovered during a work order are RFIs, and their remedy is a rou ## Known limitation at ratification -**No mechanical enforcement of routing exists.** No hook resolves these routes and injects the result; the capability wall covers grants, not routing. Until such a hook exists, R.1 through R.15 are honored by Dispatcher attachment (8.2.1) and by instruction — which 8.2.2 identifies as the weaker half of the control surface. This is an unenforced control, declared as such, and it is a candidate finding for the pilot. +**No mechanical enforcement of routing exists.** No hook resolves these routes and injects the result; the capability wall covers grants, not routing. Until such a hook exists, R.1 through R.16 are honored by Dispatcher attachment (8.2.1) and by instruction — which 8.2.2 identifies as the weaker half of the control surface. This is an unenforced control, declared as such, and it is a candidate finding for the pilot. diff --git a/governance/STATE.md b/governance/STATE.md index d360967..9f1e59d 100644 --- a/governance/STATE.md +++ b/governance/STATE.md @@ -2,6 +2,83 @@ # STATE — Writwall +## Current closeout checkpoint — 2026-09-17, WO-WW-032 + +**OBSERVED:** Owner accepted WO-WW-032 including disclosed deviations and +directed authorized closeout and v0.12.0 publication. Active minutes NOT +REPORTED. Release metadata, installation references and release regression +coverage now consistently specify v0.12.0. Final pre-acceptance Windows848 +tests/13 skips and Ubuntu848 tests/4 skips passed sequentially. Both native +installed, payload and archive gates passed; two independently managed139-file +candidates matched and final privacy checks passed. Independent public-candidate +review returned ACCEPT-READY with no blocking findings; test/hash execution +remains Coordinator evidence, not Reviewer recomputation. + +Accepted work-order/report/lifecycle records are retired byte-for-byte, with +pointer retirement last. Prior failures and provider denials remain preserved; +whole-surface classification remains8/0/8. Final between-work-order qualification, +independent publication review, private push, public PR and required CI-gated +merge precede exact-commit tag and verified immutable release. These later +actions are authorized but not claimed complete at this source snapshot. +Private operative binding remains0.8; no other-project access or migration. +The General reports through Architect; there is no separate internal-agent +sidebar. Evidence: governance/history/WO-WW-032-report.md and (private governed-source reference, not present in this candidate) +governance/history/WO-WW-032-issuance-lifecycle.md (private governed-source (private governed-source reference, not present in this candidate) +references, not present in the public candidate). + +## Current closeout checkpoint — 2026-09-17, WO-WW-031 + +**OBSERVED:** Owner accepted031 with "Accepted, proceed", including disclosed +deviations; active minutes NOT REPORTED. Final native Windows848 total/13 skips +and Ubuntu848 total/4 skips passed. Both installed/payload legs passed on unchanged +frozen input; independent Opus supported Owner acceptance after final report +clarification. The temporary locked verification account/home were removed. +Denialcount341, preceding340-record prefix unchanged, canary target absent; +whole-surface classification remains8/0/8. Earlier failed evidence is preserved. + +Accepted order/reports and the closeout/lifecycle records were retired +byte-for-byte, with pointer retirement last. The next bounded task is v0.12.0 +delivery preparation/qualification under existing Plan36, not a new normative +Plan amendment. Publication remains subject to exact grants, required acceptance +milestones, live retained-digest refresh and complete final delivery gates. +Self-hosting remains bound to0.8; no other-project access or migration occurs. +The internal General has no separate sidebar; Architect remains the Owner POC. +No public release or new interpreted assessment is claimed by this checkpoint. + +Evidence: governance/history/WO-WW-031-acceptance-closeout.md and (private governed-source reference, not present in this candidate) +governance/history/WO-WW-031-report.md (private governed-source references, (private governed-source reference, not present in this candidate) +not present in the public candidate). + +## Latest bounded checkpoint — 2026-09-16, WO-WW-030 + +**OBSERVED:** Owner accepted WO-WW-030 with its disclosed deviations and ratified +the exact Doctrine 0.9 candidate. Active minutes NOT REPORTED. Independent Opus +returned CONFORMANCE PASS on candidate content, with disclosed targeted-source +coverage limits; coordinator integrity, active dispatch and whitespace checks +passed. Tabletop scenarios remain analysis, not runtime or cost-reduction proof. + +All six current WO-WW-030 work/report/ratification records were retired to +governed history byte-for-byte. The accepted candidate digest is +0ACBF638D71C0F41CE059D1AE1F8BEB7DA3B23325942B9ACE00F21E2491E9FAB; +continuation digest is +9073E29218E13FC283E8A28B8393863EE9C2F5DB6B1872AE8327CF4F6AE0EDC0. +The active pointer was removed last. No successor is active at this checkpoint. +Denial log remains 340 records: one original Write canary (339), one separate +genuine Read transport denial (340), original 338-record prefix unchanged, +canary target absent. Whole-surface classification remains 8 / 0 / 8. + +The Owner authorized bounded WO-WW-031 implementation and later v0.12.0 delivery, +including verification, private push, public PR, CI-gated merge, tag and immutable +release. Required acceptance milestones remain. Those later actions are not +claimed complete. Canonical transcription and the exact routing/issuance packet +are pending preparation. Self-hosting remains bound to 0.8; no other-project +access or migration is authorized. No new INTERPRETED assessment is added. + +Evidence: `governance/history/WO-WW-030-ratification-closeout.md` and (private governed-source reference, not present in this candidate) +`governance/history/WO-WW-030-issuance-lifecycle.md` (private governed-source (private governed-source reference, not present in this candidate) +references, not present in the public candidate). Older checkpoints below are +dated snapshots, not current execution or authorization status. + ## Latest bounded checkpoint — 2026-09-16, WO-WW-029 **OBSERVED:** Owner accepted WO-WW-029 with disclosed sequencing overlap, diff --git a/identity/legacy-references.json b/identity/legacy-references.json index 4d5b5ce..1c3ec9d 100644 --- a/identity/legacy-references.json +++ b/identity/legacy-references.json @@ -16,12 +16,12 @@ { "path": "README.md", "context": "migration_provenance", - "sha256": "bb9083c43def4a803c3f01e296ccbdb0402068ec39145e3ddd892ac3e922eea3" + "sha256": "4f49c016aba20e207a72f9e19c6a7057954e87c753f8208e31bce6c13b39f9aa" }, { "path": "SELF-HOSTING.md", "context": "mixed_current_guidance_and_history", - "sha256": "6a51c1211cc675599634d144ca24a705ec1696f84640a6464b14efb1d6c3a629" + "sha256": "ca53dba00262f47351796b07ca236926b517e5a19ac3667df9a1045dcc4dbccf" }, { "path": "NAMING.md", @@ -31,7 +31,7 @@ { "path": "checks/check_distribution.py", "context": "historical_evidence_path", - "sha256": "20df8e937b6efeb7930894b7d4eba42761283b6d0166e78bcabaa2ab6dc75a7c" + "sha256": "0c36b90c28084c3bcf808298bec54f02c50117d3307e307bf793ff61d8284f8f" }, { "path": "checks/check_identity.py", @@ -94,19 +94,19 @@ { "path": "governance/LOG.md", "context": "historical_pilot_summary", - "sha256": "fe23a4b929fdfb3440da3e239405bbd4a6e9d430d34e7820a9a94a76aff6bcda", + "sha256": "ba4bd0d79505aa32782b41cf3143f27d2ed0509c2125482502b3737b9aeb754c", "projection_transform": "private_evidence_redaction" }, { "path": "governance/PLAN.md", "context": "ratified_historical_intent", - "sha256": "f18d83c92cc2da4b2fe22a20376bea7ca7ccc331638f30d996ff52afe3af6784" + "sha256": "a6036b492d0f3aca7c5bd455ccc4314f3d67d1d407936f6c6e17c55e4a39f250" }, { "path": "governance/STATE.md", "context": "mixed_current_state_and_history", - "sha256": "3b2587346c7a5a0c214b40433383fd256374a7597a6f54933a612a430cf5b7e7", - "projection_sha256": "bec6857daf55f1576f51c6ea7b9d7729501b59e2dfc565768309640b6fff8592" + "sha256": "85cf867035693dfa0019acd9db0151ac95dc98dd45cf31a052d32a8d9edf9508", + "projection_sha256": "7421478c01f4e343c3d255b3daa22e9cb3ce232915ab87c1e490f6be1e79fea3" }, { "path": "governance/decisions/DR-001.md", @@ -122,12 +122,12 @@ { "path": "projection/public-files.txt", "context": "historical_path_index", - "sha256": "fafcbf659c40d7260dddaa8a64b6b59c3b7de484f77d879a90323bb4b3e1a4a7" + "sha256": "28ba77c4dfd9370bfe9fca2d349cd042c9a55ac8c6f1c09efca70e73a86d278f" }, { "path": "tests/test_distribution.py", "context": "historical_evidence_fixture", - "sha256": "13478c88a9d9951f4a90ef15fa389fc0bf19894f917cbada62fc366cbe70a635" + "sha256": "9badf3dc8e783db4dc6f3ab3af8246e2da34d111ba936466e9e2055ca8665c63" }, { "path": "tests/test_identity_migration.py", diff --git a/migration-guides/0.8-to-0.9.md b/migration-guides/0.8-to-0.9.md new file mode 100644 index 0000000..ed81d95 --- /dev/null +++ b/migration-guides/0.8-to-0.9.md @@ -0,0 +1,55 @@ +# Migration guide: Doctrine 0.8 to 0.9 + +| Field | Value | +|---|---| +| From | Doctrine revision 0.8 | +| To | Doctrine revision 0.9, ratified by `decisions/DR-006.md` | +| Scope | Part 2 (new 2.29-2.33), Part 4 (4.1.2 amended in place, new 4.1.4-4.1.5, 4.2.4 amended in place, new 4.2.5-4.2.7 role rows), Part 6 (new 6.5), Part 7 (7.2.4 and 7.7.1 amended in place, new 7.6.4, 7.10, 7.11, 7.12), Appendix A (A.5 header requirement), Part 8 (new 8.7.7) | +| Applies to | A project bound to 0.8 (DC.4.1) whose Owner wants to move to 0.9 | + +## 1. Nothing moves automatically + +Moving a project to a later revision is a change-controlled event (Doctrine DC.4.2). This guide is followed only when the project's Owner has explicitly ratified migration in a project-local decision record naming both revisions. No script, adapter, skill, or agent invocation performs this migration on its own initiative, and nothing in this bundle updates an adopting project automatically. Until the Owner ratifies migration, the project remains correctly bound to 0.8. + +## 2. What changed + +1. **Part 2, new definitions.** 2.29 Architect, 2.30 General, and 2.31 Operator (with 2.31.1 shared-hosting distinctness and 2.31.2 external-operations packet) name the discovery/continuity/execution functions that 4.2 already implies but 0.8 left unnamed. New 2.32 Batch and 2.33 Delegated conforming-completion disposition support the new batch workflow (Part 7.10). +2. **Part 4.** 4.1.2 is amended in place: it now bars only *standing/carried* authority across sessions, not the Architect/General/Operator function names themselves, which are fresh-invocation functions exactly like every other role this Part defines. New 4.1.4 states that a function name is not authority; authority derives from the recorded delegation chain (3.2.5). New 4.1.5 permits one provider to host multiple Architect/General/Operator functions without separate subscriptions, provided each invocation is fresh and execution/review independence is preserved -- this does not relax 4.1.3's separate, unchanged different-model-vendor preference for Implementer/Reviewer. 4.2.4 is amended in place to route the Reviewer's owner brief through the Architect (4.2.5) as a delivery channel only, never an approval gate. New role-table rows 4.2.5 (Architect), 4.2.6 (General), and 4.2.7 (Operator) state what each function receives, does, and never does. +3. **Part 6.** New 6.5, Existing-Project Realignment: a read-only realignment may summarize an already-adopted project's current responsibilities, approved scope, evidence age, blockers, and next permitted action without touching project bytes, available to any re-entering function including the Architect and General, and creating no lifecycle event by itself. It never forces a fresh interview, an automatic migration or re-adoption, or archived-history retrieval, and a project remains bound to the revision it last ratified regardless of any later revision this methodology repository publishes. +4. **Part 7.** 7.2.4 is amended in place to state that ratifying a batch is the activation decision for its named members, made once for the sequence; the mechanical pointer-creation act still proceeds only through the separately authorized recorder 8.7.6 already requires. 7.7.1 is amended in place to allow a named delegate to exercise acceptance for a routine, fully conforming batch member under an Owner-ratified delegated conforming-completion disposition policy (7.10.6), while reserving deviation ratification to the Owner alone, never delegable. New 7.6.4 states the Reviewer's independence from the Architect and General: the Architect conveys the owner brief but may not suppress, rewrite, condition, delay, or waive any Reviewer finding, and an implicated Architect decision escalates directly to the Owner. New Part 7.10 (7.10.1-7.10.9) defines batch approval and delegated execution: an Owner instruction naming one work order or a finite batch is required for execution approval; the General prepares but never activates a batch member; a fresh Owner approval is required outside an approved batch or at a reserved milestone; no function may reclassify a substantive change as clerical; a delegated conforming-completion disposition policy covers only the plain-acceptance case, never rework or deviation ratification; and 7.10.9 maps batch-member semantic states onto the existing frontmatter status enum without inventing any new value. New Part 7.11 (7.11.1-7.11.7) states RFI severity classes (informational, resolvable, blocking), blocking-RFI dependency treatment, the RFI-as-executive-brief format, and handoff-state tracking (prepared/sent/acknowledged/returned/reviewed) in which an unobserved status is reported as unknown, never inferred as favorable; a human-relayed message is preserved with its relay provenance. New Part 7.12 (7.12.1-7.12.5) requires every agent-authored user-facing reply to the Owner to begin with a compact header stating the project, the current work order or batch identifier and purpose, and status (proposed/no active work order/active/blocked/reporting on completion), excluding machine-readable output, pasted commands, and other reusable artifacts not meant for direct human reading. +5. **Appendix A.** A.5 now requires the 7.12 header be stated in every reply to the Owner, in addition to the existing report-format-and-Reviewer-addressing requirement; no other appendix body text changed. +6. **Part 8.** New 8.7.7 states that the Architect, General, and Operator functions are ordinary names for the actors 8.7.6 already describes ("a separately authorized recorder or mechanism" and "the Implementer"); naming a function under 4.2 confers no control-plane authority beyond what 8.7.2 and 8.7.6 already permit or forbid. + +No other Doctrine clause changed. In particular, Appendices B, C, D, and E carry no content change in 0.9; only their footer's cited revision number advances. + +## 3. Affected local artifacts + +- The project-local charter template, conventionally `governance/templates/A-charter.md` (Doctrine Appendix A, `ADOPTING.md` section 0): superseded by a fresh copy of `templates/A-charter.md` from this distribution's Doctrine 0.9 if the Owner wants the updated A.5 wording naming the 7.12 header requirement; the live, instantiated charter itself is a separate Owner-ratified record. +- The project's own charter (`A.5 REPORTING`), if the Owner wants it to state the 7.12 header requirement explicitly: amended only by Owner ratification (Doctrine 7.9.1: no agent amends the charter). +- Any project-local documentation, generated role packets, or onboarding material describing the General, Architect, or Operator functions, delegation visibility, or handoff status should be reviewed against 7.11.5 (handoff states) and 7.12 (reporting headers) and updated by ordinary project change control; 0.9 does not itself change any installed adapter's enforcement behavior. +- The project-local work-order and other Appendix B/C/D/E templates need no content change; only the extraction footer's cited Doctrine revision advances if the Owner chooses to refresh it. + +## 4. Preparation procedure + +Performed once, by or under the direction of the project's Owner, after migration is ratified: + +1. Ratify migration in a project-local decision record naming both revisions (0.8 and 0.9) and listing the affected artifacts (Doctrine DC.4.2). +2. Replace `governance/templates/A-charter.md` with the 0.9 copy from this distribution if the Owner wants the A.5 wording naming the 7.12 header requirement. Copy it exactly; do not paraphrase (Doctrine 5.1.2, `ADOPTING.md` section 0). +3. Update the project's charter (`A.5`, and any A.2/A.3 lines naming the bound doctrine revision) by Owner ratification (Doctrine 7.9.1: no agent amends the charter). +4. Where the project generates role packets, prompts, or handoffs for an Architect, General, or Operator function, review and update them against 4.2.5-4.2.7, 7.6.4, 7.11.5, and 7.12 so a freshly invoked function is instructed to announce delegated role/task, name a monitoring location or its explicit absence, state the last verified handoff state, and open replies with the 7.12 header. +5. Every project-local grant classification already in force is preserved exactly as issued; this migration adds no new capability-grant surface, status enum value, or pointer format, and does not retroactively reclassify any surface an Owner has already declared for an issued work order. +6. If the project intends to use the batch-approval workflow (Part 7.10), the Owner drafts and ratifies a batch record (7.10.2) naming its members, sequence, and any reserved milestone before the General prepares the first member for activation. + +## 5. Deterministic post-migration check + +Before relying on the new revision, confirm the project's instantiated templates and generated role material agree with the 0.9 Doctrine text they cite: + +``` +python checks/check_distribution.py +``` + +Run from this methodology repository against its own self-hosted instance, this must exit 0. For a separately adopted project, the equivalent is whatever deterministic dispatch-preparation and template-consistency tooling that project installed at adoption (5.1.3); it must report the templates it instantiated as matching the cited Doctrine revision's appendices, byte-for-byte, and must report no stale footer citing 0.8 after the Owner has refreshed a template. + +## 6. What this migration does not do + +It does not change any surface a prior, already-issued 0.8 work order declared. It does not touch `DOCTRINE.md`, this repository's own governance instance, or any file outside the artifacts named in section 3. It does not migrate any project other than the one whose Owner ratified it (Doctrine 5.1.5, `DOCTRINE.md` DC.4.1). It does not implement or claim any new enforcement, adapter, or template mechanism; 0.9 itself states plainly that no enforcement, adapter, or template mechanism is implemented by this revision alone (DC.2). It does not activate any batch, delegate any acceptance, or create any monitoring, scheduler, or task-dispatch capability that did not already exist; Part 7.10-7.12 are instruction and reporting clarity over the existing workflow, not new mechanism. diff --git a/projection/public-files.txt b/projection/public-files.txt index 64a5642..d924854 100644 --- a/projection/public-files.txt +++ b/projection/public-files.txt @@ -36,6 +36,7 @@ decisions/DR-001.md decisions/DR-003.md decisions/DR-004.md decisions/DR-005.md +decisions/DR-006.md decisions/LICENSING-DIRECTION.md decisions/README.md docs/agents/domain.md @@ -86,6 +87,7 @@ init.sh migration-guides/0.1-to-0.6.md migration-guides/0.6-to-0.7.md migration-guides/0.7-to-0.8.md +migration-guides/0.8-to-0.9.md projection/public-files.txt pyproject.toml scripts/build_distribution.py @@ -110,6 +112,7 @@ skills/writwall-adopt/references/DOCTRINE.md skills/writwall-adopt/references/migration-guides/0.1-to-0.6.md skills/writwall-adopt/references/migration-guides/0.6-to-0.7.md skills/writwall-adopt/references/migration-guides/0.7-to-0.8.md +skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md skills/writwall-adopt/references/name-clearance.md templates/A-charter.md templates/B-work-order.md diff --git a/pyproject.toml b/pyproject.toml index 0238755..7e60df8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "writwall" -version = "0.11.0" +version = "0.12.0" description = "Start governed project work from an idea." requires-python = ">=3.10" license = "Apache-2.0" @@ -30,6 +30,7 @@ include-package-data = false "skills/writwall-adopt/references/migration-guides/0.1-to-0.6.md", "skills/writwall-adopt/references/migration-guides/0.6-to-0.7.md", "skills/writwall-adopt/references/migration-guides/0.7-to-0.8.md", + "skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md", ] "share/writwall/writwall-adopt/assets" = [ "skills/writwall-adopt/assets/bootstrap-charter-addendum.md", diff --git a/scripts/build_public_projection.py b/scripts/build_public_projection.py index c485b8f..afd2cfb 100644 --- a/scripts/build_public_projection.py +++ b/scripts/build_public_projection.py @@ -67,9 +67,11 @@ def find_retained_tokens(line: str) -> list[str]: "CLAUDE.md", "decisions/DR-001.md", "decisions/DR-005.md", + "decisions/DR-006.md", "governance/ADOPTION-MAPPING.md", "governance/LOG-denials-probes.md", "governance/ROUTING.md", + "governance/STATE.md", "governance/decisions/DR-001.md", "governance/decisions/DR-005.md", }) diff --git a/scripts/start_writwall.py b/scripts/start_writwall.py index 6355664..aeee695 100644 --- a/scripts/start_writwall.py +++ b/scripts/start_writwall.py @@ -109,33 +109,73 @@ def authorization_continuity_block( {authorization_continuity_block()} +Owner approval of a roadmap, plan section, or discussion is not execution approval for any +individual work order or batch member. A fresh Owner approval is required outside an +already-approved batch or at a reserved milestone; an approved finite sequence confers no +release, publish, deploy, push, tag, or external-account authority beyond what each member's own +grant already authorizes, and a nonapproved successor stops for a fresh Owner decision. Once an +approved batch's last member is complete, blocked, or exhausted, report results and recommend, +but never activate, expand, or manufacture, follow-on work. Acceptance of a routine, fully +conforming batch member stays the Owner's own disposition unless the Owner has separately +ratified a delegated conforming-completion disposition policy naming a delegate; such closure is +recorded as disposed under that policy, never described as "the Owner accepted," and rework or +deviation ratification are never delegable under any policy. Track a handoff between functions +through its distinguishable state -- prepared, sent, acknowledged, returned, or reviewed -- and +report a status not actually observed as unknown, never inferred as favorable; preserve a +human-relayed message together with its provenance, that it was relayed, by whom, and when, and +never present it as a direct machine-to-machine handoff record. Begin every reply that addresses +the Owner directly with a one-line header stating the project, the current work order or batch +and its plain-language purpose, and status -- proposed, no active work order, active, blocked, or +reporting on completion -- never as a line inside a generated JSON file, a pasted command, or +another machine-readable or reusable artifact. For an approved batch, distinguish overall batch +progress from the currently active member. This is instruction only: it proves the requirement +was generated, never that a future invocation will actually follow it. + Once approved, perform every -mechanically available authorized step. Do not ask for the same decision again. The human Owner -alone ratifies intent and activates work; preserve a distinct fresh Reviewer after -implementation. The onboarding coordinator stops here and does not continue into project work.""" +mechanically available authorized step. Do not ask for the same decision again. Whenever you +delegate a bounded task to a fresh Operator, announce the delegated role and bounded task, name a +discoverable monitoring location or state plainly that none exists, state the last verified +execution/handoff state, and name the result/question return route; ending a conversational reply +must never imply that delegated work keeps running or has stopped when that is not actually +observed. The human Owner alone ratifies intent and activates work; preserve a distinct fresh Reviewer +after implementation. The onboarding coordinator stops here and does not continue into +project work.""" # Compatibility export for existing imports and synchronized static handoff # tests. The post-adoption role formerly called Project-Architect is now the # General; retaining this symbol does not retain the obsolete role semantics. PROJECT_ARCHITECT_PROMPT = GENERAL_PROMPT -ARCHITECT_EXISTING_PROJECT_PROMPT = """Act as the Architect. Begin read-only; do not implement, install, or adopt +REPORTING_HEADER_INSTRUCTION = ( + "Begin every reply that addresses the Owner directly with a one-line header naming the " + "project, the current work order or batch and its plain-language purpose, and status " + "(proposed, no active work order, active, blocked, or reporting on completion); for an " + "approved batch, distinguish overall batch progress from the currently active member. " + "This is instruction only: it proves the requirement was generated, never that a future " + "invocation will actually follow it. Never place this header inside a generated JSON file, " + "a pasted command, or another machine-readable or reusable artifact." +) + +ARCHITECT_EXISTING_PROJECT_PROMPT = f"""Act as the Architect. Begin read-only; do not implement, install, or adopt anything yet. Before asking the Owner to restate anything already visible in repository bytes, use the observed lifecycle state and local evidence recorded above, and inspect other high-signal local material (README-like files, top-level structure, and recent history) the same way. Summarize the apparent project in plain language from that evidence alone. Then ask the Owner plainly whether they want to explore and develop this existing work, or start elsewhere with a different idea. Treat every local observation as evidence only, never as ratified intent; -the human Owner alone decides and ratifies. Read discovery.json and ARCHITECT.md in this +the human Owner alone decides and ratifies. {REPORTING_HEADER_INSTRUCTION} Read discovery.json +and ARCHITECT.md in this directory for the complete procedure, including the required project sketch, recommended Owner/Architect/General/Operator topology, provisional first backlog, key uncertainties and risks, and the one explicit Owner promotion decision before any adoption mechanics begin.""" -ARCHITECT_EMPTY_PROJECT_PROMPT = """Act as the Architect for a new, empty project; no existing +ARCHITECT_EMPTY_PROJECT_PROMPT = f"""Act as the Architect for a new, empty project; no existing project material was found at this root. Begin read-only and do not implement, install, or adopt anything yet. Do not impose a fixed list of qualification questions. -Open with exactly: "Tell me what you are thinking." +{REPORTING_HEADER_INSTRUCTION} + +After that required status header, begin the conversational body as follows. Open with exactly: "Tell me what you are thinking." Let the Owner's own words guide every question that follows, one at a time. Nothing said is ratified intent until the human Owner explicitly ratifies it. Read discovery.json and @@ -152,6 +192,7 @@ def authorization_continuity_block( one question at a time for as long as it is useful. Produce a project sketch, recommended Owner/Architect/General/Operator topology, provisional backlog, uncertainties, risks, and stop conditions. Nothing advances until the human Owner explicitly promotes that sketch. +{REPORTING_HEADER_INSTRUCTION} Only after explicit promotion, use the local `writwall-adopt` bundle to prepare the proposed adoption and recorder actions. The Owner separately ratifies material intent and authorizes @@ -1187,13 +1228,14 @@ def next_prompt(state: ObservedState) -> tuple[str, str]: if state.name == "partial_bootstrap": return ( "Fresh external recovery coordinator", - """Act as a fresh recovery coordinator for this accidental overlay or incomplete + f"""Act as a fresh recovery coordinator for this accidental overlay or incomplete Writwall adoption, not as an Implementer. Begin read-only. Use a complete local Writwall source or adoption bundle outside the locked session; do not assume a partial project-local bundle is complete. Inventory only: do not delete, overwrite, move, install, register, activate, or invent missing intent. Verify the lifecycle from repository bytes, propose an exact disposition packet, and -ask one question at a time. The prior session stops here.""", +ask one question at a time. The prior session stops here. +{REPORTING_HEADER_INSTRUCTION}""", ) if state.name in {"adopted_lockout", "retired_lockout"}: return ( @@ -1203,10 +1245,11 @@ def next_prompt(state: ObservedState) -> tuple[str, str]: if state.name == "active_work_order": return ( "Fresh walled repository Operator/Implementer", - """Act as a fresh Implementer for the active work order only. Re-read the activation + f"""Act as a fresh Implementer for the active work order only. Re-read the activation pointer and pointed work order from repository bytes, confirm the active dispatch and required live-wall canary before mutation, execute only its grant, -write its report, and stop before acceptance or closeout.""", +write its report, and stop before acceptance or closeout. +{REPORTING_HEADER_INSTRUCTION}""", ) raise CoordinatorError(f"inconsistent state: unsupported classification {state.name!r}") @@ -1228,15 +1271,18 @@ def _architect_inspection_prompt( state: ObservedState, inventory: LocalInventory | None = None ) -> str: if state.name == "public_distribution": - return """Act as a fresh Architect reviewing the Writwall public distribution. + return f"""Act as a fresh Architect reviewing the Writwall public distribution. Begin read-only, follow CONTRIBUTING.md, and ask what the Owner wants to explore. The retained source governance records do not adopt or govern this checkout. Do not initiate a General handoff or infer ratification from those records. -For a separate project, ask the Owner to select that target project instead.""" +For a separate project, ask the Owner to select that target project instead. +{REPORTING_HEADER_INSTRUCTION}""" if state.name == "clean_new" and inventory is not None and not inventory.is_existing: - return """Act as the Architect for a new, empty project. Begin read-only; do not + return f"""Act as the Architect for a new, empty project. Begin read-only; do not implement, install, adopt, activate a work order, or change lifecycle state. -Open with exactly: "Tell me what you are thinking." Let the Owner's words guide +{REPORTING_HEADER_INSTRUCTION} +After that required status header, begin the conversational body as follows. Open with exactly: "Tell me what you are thinking." +Let the Owner's words guide the conversation without imposing a fixed questionnaire. Nothing said becomes ratified intent until the human Owner ratifies it. This explicit role selection grants no mutation or lifecycle authority.""" @@ -1246,7 +1292,7 @@ def _architect_inspection_prompt( listen to the Owner's current intent, and distinguish preserved authority from legacy or incomplete material. Explain what the project appears to be doing, then ask what the Owner wants to explore. This explicit role selection grants -no mutation or lifecycle authority.""" +no mutation or lifecycle authority. {REPORTING_HEADER_INSTRUCTION}""" _ROUTING_LINE = re.compile(r"(?m)^Routing:[ \t]*(.+)$") @@ -1913,9 +1959,15 @@ def render_handoff(args: argparse.Namespace, state: ObservedState, explicitly authorized clerical lifecycle mechanics after adoption. - A repository Operator works only under the active work order. - A fresh Reviewer evaluates the order, result, evidence, and report without - implementing corrections in the same context. -- External Operators receive only bounded packets. The General retains the - proverbial keys: routing and authority, not passwords or cryptographic keys. + implementing corrections in the same context. Its brief is addressed to the + Owner and, for delivery only, conveyed through the Architect, who may not + suppress, rewrite, condition, delay, or waive any finding; the Owner keeps + standing access to the complete original findings, and a finding + implicating an Architect decision escalates to the Owner directly. +- External Operators receive only bounded packets. The Architect and General + retain the proverbial keys: routing and sequencing, not passwords or + cryptographic keys, and not authority, which stays with the Owner and the + recorded delegation chain. ## External Operator routing @@ -1998,11 +2050,13 @@ def architect_packets( "install, publish, configure, or operate an external system.\n" ) root_block = _canonical_root_block(canonical) + header_block = REPORTING_HEADER_INSTRUCTION + "\n" return { "ARCHITECT.md": f"""# Architect packet {common} {root_block} +{header_block} The Architect owns pre-adoption discovery and later design-conformance judgment. Before requesting promotion into adoption mechanics, the Architect returns a concise project sketch, a recommended Owner/Architect/General/ @@ -2042,6 +2096,7 @@ def architect_packets( {common} {root_block} +{header_block} {authorization_continuity_block()} ## Preconditions @@ -2054,11 +2109,20 @@ def architect_packets( - Return exact checks and observed results. ## Evidence to return - Changed paths, reasons, failures, and remaining boundaries. +## Requests for information +File an RFI as one of three kinds: an informational clarification that does +not block ongoing work; a resolvable execution problem that blocks only the +work it affects until answered; or a blocking scope, authority, or safety +contradiction that halts the affected work immediately. Where independence +from a blocking matter is itself in doubt, treat the dependency as blocking +rather than resolving it by assertion; never declare independence +unilaterally. """, "OWNER-AGENT.md": f"""# Owner-Agent packet (compatibility alias for Architect) {common} {root_block} +{header_block} This is a compatibility alias for the **Architect** role packet (`ARCHITECT.md`), kept for existing `OWNER-AGENT.md` consumers. New integrations should read `ARCHITECT.md` directly; both describe the same @@ -2079,6 +2143,7 @@ def architect_packets( {common} {root_block} +{header_block} This is a compatibility alias for the **Operator** role packet (`OPERATOR.md`), kept for existing `REPOSITORY-OPERATOR.md` consumers. New integrations should read `OPERATOR.md` directly; both describe the same @@ -2096,17 +2161,34 @@ def architect_packets( - Return exact checks and observed results. ## Evidence to return - Changed paths, reasons, failures, and remaining boundaries. +## Requests for information +File an RFI as one of three kinds: an informational clarification that does +not block ongoing work; a resolvable execution problem that blocks only the +work it affects until answered; or a blocking scope, authority, or safety +contradiction that halts the affected work immediately. Where independence +from a blocking matter is itself in doubt, treat the dependency as blocking +rather than resolving it by assertion; never declare independence +unilaterally. """, "REVIEWER.md": f"""# Fresh Reviewer packet {common} {root_block} +{header_block} ## Preconditions - Review only after the Architect returns a ratifiable packet or an Operator returns evidence. ## Review - Challenge intent traceability, boundary fit, name state, topology, failure safety, and evidence. ## Prohibited actions - Do not implement corrections in the same context. +## Independence and delivery +Your findings are addressed to the Owner. For delivery only, they are +conveyed through the Architect, who may not suppress, rewrite, condition, +delay, or waive any finding, verdict, escalation, or required evidence; the +Owner retains standing access to your complete original findings regardless +of any summary the Architect adds when conveying them. Where a finding +implicates a decision the Architect itself made, escalation to the Owner +proceeds directly and is not filtered or mediated by the Architect. ## Evidence to return - ACCEPT, ACCEPT WITH NON-BLOCKING POLISH, or RETURN with concrete findings. """, diff --git a/skills/writwall-adopt/SKILL.md b/skills/writwall-adopt/SKILL.md index b0d45f0..51a8609 100644 --- a/skills/writwall-adopt/SKILL.md +++ b/skills/writwall-adopt/SKILL.md @@ -20,7 +20,7 @@ replacement or register the wall before its recovery instructions are readable. For a compact, bounded re-entry recap instead of the full copy-paste prompt, a continuing agent may use `writwall inspect --project-root --brief` -(**unreleased source work; not part of any published release**). It is +(available since `v0.12.0`). It is opt-in, zero-write, bounded to 500 words of prose plus an unbounded evidence index of current files and explicit unknowns, and it never replaces this bundle's own instructions, the charter, or the ratified adoption record — @@ -31,8 +31,8 @@ credentials remain outside them, and infrastructure, DNS, and mail Operators remain outside the repository wall unless they edit repository bytes. The day-zero command's optional, repeatable -`--external-operator-task "NAME=classification"` flag (**unreleased source -work; not part of any published release**) explicitly and instruction-boundly +`--external-operator-task "NAME=classification"` flag (available since +`v0.12.0`) explicitly and instruction-boundly classifies one already-named `--external-operator` function as `deployment`, `migration`, `source_freeze`, or `cutover`; `NAME` must match that function exactly, and a malformed pair, an unmatched name, an unsupported @@ -116,7 +116,9 @@ writwall-adopt/ │ ├── DOCTRINE.md the methodology, for you, for this task only │ └── migration-guides/ followed only in migration mode │ ├── 0.1-to-0.6.md -│ └── 0.6-to-0.7.md +│ ├── 0.6-to-0.7.md +│ ├── 0.7-to-0.8.md +│ └── 0.8-to-0.9.md └── assets/ ├── adapters/claude-code/ │ ├── README.md what the wall does and does not enforce @@ -290,7 +292,22 @@ General, then stop. Do not continue as General, create or dispatch a user-owned task, activate a work order, or begin product work in the onboarding context. The fresh General may request task creation and dispatch only by including them explicitly in its single combined approval -request. +request. That General's mandate is finite even after approval: roadmap or +plan approval is never execution approval for one work order or batch member +on its own (Doctrine 7.10.1); a fresh Owner approval is required outside an +already-approved batch or at a reserved milestone (7.10.4); and once a +batch's last member completes, blocks, or is exhausted, the General reports +and may recommend, but never activates, expands, or manufactures, follow-on +work (7.10.7). A routine, fully conforming batch member's acceptance stays +the Owner's own disposition unless a separately ratified delegated +conforming-completion policy names a delegate (2.33, 7.10.6); rework and +deviation ratification are never delegable. Every reply addressed to the +Owner opens with a compact header naming the project, work order or batch, +and status (7.12.1) -- never inside a generated JSON file or other +machine-readable artifact (7.12.4). The Reviewer's findings reach the Owner +through the Architect for delivery only, never filtered, rewritten, or +delayed, and the Owner keeps standing access to the complete original +findings (7.6.4). ```text Act as a fresh General for this already-adopted project's continuity. Begin @@ -333,10 +350,37 @@ Independent provider denial: reports the provider's own denial as the exact bloc Environment prerequisite failure: names the exact missing or failed environment prerequisite as the blocker. Unapproved task creation or data transmission: never creates or transmits a task, message, or dataset outside the approved action. +Owner approval of a roadmap, plan section, or discussion is not execution approval for any +individual work order or batch member. A fresh Owner approval is required outside an +already-approved batch or at a reserved milestone; an approved finite sequence confers no +release, publish, deploy, push, tag, or external-account authority beyond what each member's own +grant already authorizes, and a nonapproved successor stops for a fresh Owner decision. Once an +approved batch's last member is complete, blocked, or exhausted, report results and recommend, +but never activate, expand, or manufacture, follow-on work. Acceptance of a routine, fully +conforming batch member stays the Owner's own disposition unless the Owner has separately +ratified a delegated conforming-completion disposition policy naming a delegate; such closure is +recorded as disposed under that policy, never described as "the Owner accepted," and rework or +deviation ratification are never delegable under any policy. Track a handoff between functions +through its distinguishable state -- prepared, sent, acknowledged, returned, or reviewed -- and +report a status not actually observed as unknown, never inferred as favorable; preserve a +human-relayed message together with its provenance, that it was relayed, by whom, and when, and +never present it as a direct machine-to-machine handoff record. Begin every reply that addresses +the Owner directly with a one-line header stating the project, the current work order or batch +and its plain-language purpose, and status -- proposed, no active work order, active, blocked, or +reporting on completion -- never as a line inside a generated JSON file, a pasted command, or +another machine-readable or reusable artifact. For an approved batch, distinguish overall batch +progress from the currently active member. This is instruction only: it proves the requirement +was generated, never that a future invocation will actually follow it. + Once approved, perform every -mechanically available authorized step. Do not ask for the same decision again. The human Owner -alone ratifies intent and activates work; preserve a distinct fresh Reviewer after -implementation. The onboarding coordinator stops here and does not continue into project work. +mechanically available authorized step. Do not ask for the same decision again. Whenever you +delegate a bounded task to a fresh Operator, announce the delegated role and bounded task, name a +discoverable monitoring location or state plainly that none exists, state the last verified +execution/handoff state, and name the result/question return route; ending a conversational reply +must never imply that delegated work keeps running or has stopped when that is not actually +observed. The human Owner alone ratifies intent and activates work; preserve a distinct fresh Reviewer +after implementation. The onboarding coordinator stops here and does not continue into +project work. ``` The Authorization section above is filled in by the General itself from @@ -347,4 +391,4 @@ a performance claim. ## Migration mode -If the Owner states the repository was bootstrapped under an earlier doctrine revision, look for `references/migration-guides/-to-.md` in this bundle and follow it instead of treating prior artifacts as unknowns. This bundle ships the 0.1-to-0.6 and 0.6-to-0.7 guides. Each requires the project's Owner to explicitly ratify migration before it is followed; neither runs on your own initiative. If no guide for the stated transition is bundled, say so, treat prior artifacts as Phase A inventory items, and propose dispositions; do not guess at what the earlier revision meant. +If the Owner states the repository was bootstrapped under an earlier doctrine revision, look for `references/migration-guides/-to-.md` in this bundle and follow it instead of treating prior artifacts as unknowns. This bundle ships the 0.1-to-0.6, 0.6-to-0.7, 0.7-to-0.8, and 0.8-to-0.9 guides. Each requires the project's Owner to explicitly ratify migration before it is followed; none runs on your own initiative. If no guide for the stated transition is bundled, say so, treat prior artifacts as Phase A inventory items, and propose dispositions; do not guess at what the earlier revision meant. diff --git a/skills/writwall-adopt/assets/templates/A-charter.md b/skills/writwall-adopt/assets/templates/A-charter.md index c44d9fa..f42ba51 100644 --- a/skills/writwall-adopt/assets/templates/A-charter.md +++ b/skills/writwall-adopt/assets/templates/A-charter.md @@ -34,12 +34,14 @@ A.4.1 [path or subsystem] -> [document] A.4.2 Unmapped and unsure -> RFI. ## A.5 REPORTING -End every work order with the report format specified in the work order, -addressed to the Reviewer. Completeness over brevity. +Begin every reply to the Owner with a one-line header: project, current work +order or batch and its plain-language purpose, and status (7.12). End every +work order with the report format specified in the work order, addressed to +the Reviewer. Completeness over brevity. ## A.6 ENVIRONMENT [build and test commands, platform notes: the minimum an agent needs every session] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/skills/writwall-adopt/assets/templates/B-work-order.md b/skills/writwall-adopt/assets/templates/B-work-order.md index 8182192..216702f 100644 --- a/skills/writwall-adopt/assets/templates/B-work-order.md +++ b/skills/writwall-adopt/assets/templates/B-work-order.md @@ -69,4 +69,4 @@ contradicts it.] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/skills/writwall-adopt/assets/templates/C-owner-brief.md b/skills/writwall-adopt/assets/templates/C-owner-brief.md index c588543..dda0bc8 100644 --- a/skills/writwall-adopt/assets/templates/C-owner-brief.md +++ b/skills/writwall-adopt/assets/templates/C-owner-brief.md @@ -16,4 +16,4 @@ C.6 REVIEWER CONFIDENCE: HIGH | MEDIUM | LOW. [LOW triggers C.5.] Reviewer notes, for the record and not the Owner: [anything longer] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/skills/writwall-adopt/assets/templates/D-adoption-record.md b/skills/writwall-adopt/assets/templates/D-adoption-record.md index 04d74e4..c72790b 100644 --- a/skills/writwall-adopt/assets/templates/D-adoption-record.md +++ b/skills/writwall-adopt/assets/templates/D-adoption-record.md @@ -27,4 +27,4 @@ D.10 Historical decisions carried forward (6.3.6), each with a note that it predates the boundary. ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/skills/writwall-adopt/assets/templates/E-adoption-mapping.md b/skills/writwall-adopt/assets/templates/E-adoption-mapping.md index 92ea5a8..7f1021c 100644 --- a/skills/writwall-adopt/assets/templates/E-adoption-mapping.md +++ b/skills/writwall-adopt/assets/templates/E-adoption-mapping.md @@ -8,4 +8,4 @@ For each existing document in the project, record one row. Rules: every intent-bearing document lands in exactly one row; a Tier-2 row without a route is an Archive row; two documents may not both be assigned to Plan for the same scope; the completed worksheet is attached to DR-001. -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/skills/writwall-adopt/references/DOCTRINE.md b/skills/writwall-adopt/references/DOCTRINE.md index c9b7453..490387c 100644 --- a/skills/writwall-adopt/references/DOCTRINE.md +++ b/skills/writwall-adopt/references/DOCTRINE.md @@ -10,11 +10,11 @@ | Field | Value | |---|---| | Document | The Doctrine: Document-Controlled AI-Assisted Development | -| Revision | 0.8 | +| Revision | 0.9 | | Status | Ratified | | Amendment authority | The Owner of the methodology repository | -| Supersedes | 0.7 | -| Effective | 2026-08-21, ratified by DR-005 (`decisions/DR-005.md`) | +| Supersedes | 0.8 | +| Effective | 2026-09-16, ratified by DR-006 (`decisions/DR-006.md`) | ### DC.2 Revision History @@ -28,6 +28,7 @@ | 0.6 | 2026-08 | Corrections from formal review: baseline versus adoption commit; two-level birth test; transactional record category; archive semantics; Dispatcher and Reviewer inputs; Owner disposition; control taxonomy; instrument qualification event; operational definitions moved to adoption record. Pre-ratification touch-ups: 2.18, 6.2.1.1, 7.6.1; bootstrap-agent exception and post-adoption role inputs (1.2.2-1.2.4); provider configuration at adoption (5.1.3); repository roles versus physical repositories, permitting a segregated self-hosted instance (5.1.1, 5.1.4-5.1.6); charter current-state updated by the Owner and never by agents (Appendix A A.3); qualification cross-references corrected to 8.4.4 (Appendix D D.5, 9.2.8); methodology-maintenance exception preserved after adoption (1.2.4); methodology repository described as distribution and reference implementation rather than documentation alone (5.1.2) | Yes | | 0.7 | 2026-08 | Align Appendix B with the shipped pre-dispatch validator: classify every declared grant surface exactly once in `enforced_by` or `unenforced_boundaries`; default the provider-neutral template to no mechanically enforced whole surfaces; add generated-boundary markers and the checker-emission workflow. No other Doctrine clause changes. | Yes | | 0.8 | 2026-08-21 | Corrected Appendix A's unqualified "blocked and logged" claim to be provider-contingent, matching this repository's own already-corrected charter; corrected Appendix B's B.4/B.7 numbering defect (see erratum below); added `governance/templates/` to the Part 5.2.1 reference layout with invariant 5.3.8 governing its refresh, and revised 5.1.3 to affirmatively require whatever deterministic dispatch-preparation tooling the revision's workflow needs (described generically, never naming a product) while stating plainly that a scaffolded skeleton without populated governance records, that tooling, and a ratified adoption record with the adoption commit containing it is not itself adoption; defined the birth-test instrument (2.28), narrowed to the active-scope, per-surface birth test only, and cross-referenced it from 6.1.3; and added Part 8.7, Protected Control Plane, governing mutation authority (not read-deny) over the active-work-order pointer, installed enforcement configuration, the active work order or instrument itself, and the denial-evidence log — unconditionally, with no exception for an Owner-authored grant — treating activation, retirement, recorder actions that themselves mutate a control-plane artifact, and the specifically defined adoption-recorder action as Owner lifecycle actions outside any capability grant while leaving ordinary Part 7 closeout governed and requiring durable pre-execution authorization; and defining a labeled `instrument_kind: birth-test` / `control_plane_probes` dispatch exception whose exact protected-path entries confer no authority and must still be denied by the runtime wall, with enforcement remaining provider-contingent and birth-test-gated (8.7.4), resolving RFI-22's Doctrine-level question without closing the RFI itself | Yes | +| 0.9 | 2026-09-16 | Added definitions 2.29 Architect, 2.30 General, 2.31 Operator (with 2.31.1 shared-hosting distinctness and 2.31.2 external-operations packet), 2.32 Batch, and 2.33 Delegated conforming-completion disposition. Amended 4.1.2 to bar only standing/carried authority rather than the function names themselves; added 4.1.4 (authority is delegation-chain-derived, citing 3.2.5) and 4.1.5 (shared-provider hosting, reconciled with 4.1.3's unchanged different-vendor preference for Implementer/Reviewer). Amended 4.2.4 to route Reviewer briefs through the Architect as a delivery channel only; added 4.2.5-4.2.7 (Architect, General, Operator role-table rows) and 7.6.4 (Reviewer independence from Architect/General, reconciled with 7.6.1, 7.6.3, and Appendix C). Amended 7.2.4 to state that ratifying a batch is the activation decision for its named members; amended 7.7.1 to allow a named delegate to exercise acceptance under an Owner-ratified delegated conforming-completion disposition policy while reserving deviation ratification to the Owner alone. Added Part 7.10 (batch approval and delegated execution, 7.10.1-7.10.9, reconciling activation with the amended 7.2.4/existing 8.7.6 Owner-lifecycle mechanism and delegated disposition with the amended 7.7.1/existing 7.7.3), Part 7.11 (RFI severity and handoff continuity), and Part 7.12 (reporting headers, including the "proposed" status form). Amended Appendix A A.5 to require the 7.12 header. Added Part 6.5 (existing-project realignment). Added 8.7.7 (function names confer no additional control-plane authority). No enforcement, adapter, or template mechanism is implemented by this revision alone. | Yes | **Erratum, recorded 2026-08-21.** Revision 0.7's addition of "B.4 Generated boundaries" collided with the pre-existing B.4 ("BOUNDARIES") identity @@ -147,6 +148,69 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 2.28 **Birth-test instrument.** A capability-grant-bearing artifact, sharing the work-order frontmatter and pointer-activation mechanism (Appendix B, 8.3.5) for engineering convenience, used only for the active-scope, per-surface birth test (8.3.5.2), where an Owner-directed test mechanically requires an active pointer and grant to exercise scoped enforcement. It is not a work order (2.16): it carries no Part 7 disposition cycle and is never counted under Part 9 (6.1.3). This does not forbid a Dispatcher-equivalent function from drafting one or a Reviewer-equivalent function from inspecting its outcome; the boundary that matters is that it never carries or ratifies intent (2.6-2.7) and never substitutes for a counted work order. Like any work order, its own capability grant is bound by 8.7.2 and never reaches a control-plane artifact — except that its manifest may name an exact control-plane path solely as a falsification probe under the schema at 8.7.4, which confers no authority under 8.7.2; it is validation metadata, never a grant. It is distinct from the no-work-order lockout (8.3.5.1), which is not an instrument at all: that test observes the absence of any active pointer, and its pass condition is precisely that nothing is active to grant anything. It is also distinct from an Owner lifecycle action (8.7.6), including the adoption-recorder lifecycle action: neither is ever performed under a birth-test instrument's or any work order's capability grant. +2.29 **Architect.** The function that is the primary human point of contact +during discovery, adoption, construction, and recovery conversation (4.2.5). +It listens, inspects bounded evidence, challenges the pitch, drafts a project +sketch or design proposal, and conveys existing Owner authority. It never +ratifies intent and never activates a work order. + +2.30 **General.** The post-adoption continuity function (4.2.6) that +maintains awareness of the plan and open transactional records, prepares +bounded dispatch (performing the Dispatcher function, 4.2.2, when it does), +routes work to Operators, records only decisions the Owner has already +ratified, and routes new design or design-conformance questions to a fresh +Architect invocation rather than deciding them itself. + +2.31 **Operator.** The function that executes one active work order or one +bounded external-operations packet (2.31.2) inside its capability grant +(4.2.7). An Operator working a repository work order performs exactly the +Implementer function (4.2.3) under that name; an Operator working an +external packet (infrastructure, DNS, mail, deployment, or a similar +account-bearing function) remains outside the repository's installed-provider +wall coverage (2.31.2, 8.3.4) unless and until it edits repository bytes, at +which point it is an ordinary Operator under a work order. + +2.31.1 **General distinctness under shared hosting.** The General function +(2.30) exists as a distinct function from the Architect (2.29) even where +one provider hosts both, and even where both run under the same subscription +or account. What makes them distinct functions is fresh, separate +invocations (4.1.2, 4.1.5) — separate sessions performing the +discovery/design function and the continuity/dispatch function respectively +— not a different vendor, product, or human login. A small project may run +both functions from the same underlying model without collapsing them into +one persistent persona, provided each invocation begins fresh from the +record. This shared-hosting allowance concerns only the Architect/General/ +Operator functions defined here; it does not diminish or satisfy 4.1.3's +separate, unchanged preference that the Implementer and Reviewer functions +be performed by different model vendors where practical. + +2.31.2 **External-operations packet.** A bounded, project-specific +instruction packet an Operator (2.31) executes for an infrastructure, DNS, +mail, deployment, or similarly account-bearing function that lies outside +this repository's own capability-wall coverage. It is not a Doctrine-defined +capability-grant surface in the sense of 8.3.1's minimum list; it is the +kind of project-specific surface 8.3.1 already contemplates ("any +project-specific surfaces such as database mutation, infrastructure +changes, or model runs") and 8.3.4 already requires be declared unenforced +where no installed provider covers it. Its exact preconditions, permitted +and prohibited actions, verification, rollback, and credential handling are +defined by the adopting project issuing it, never by this Doctrine, which +states only that such a packet exists as a category and that it remains +outside the repository's installed-provider wall coverage unless and until +it edits repository bytes under an ordinary work order. + +2.32 **Batch.** A finite, named, Owner-approved sequence of already-drafted +work orders or work-order revisions that an explicit Owner instruction +authorizes for sequential activation without a fresh approval request at +each member's activation (7.10). A batch is not a standing authorization: it +names its members, and approving it approves only those members. + +2.33 **Delegated conforming-completion disposition.** An Owner-ratified +policy (7.10.6) that lets a named function close a routine, fully conforming +batch member without an individual Owner acceptance turn for that member. It +is distinct from Owner acceptance (7.7.1) and is never recorded as if it +were one. + --- ## PART 3. THESIS AND PRINCIPLES @@ -185,10 +249,43 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 4.1.1 The doctrine defines roles as functions rather than as persistent processes or personas. Any function may be performed by any capable model. What matters is what each function receives, what it is permitted to do, and what it must produce. -4.1.2 There is no manager-agent, architect-agent, or orchestrator-agent. Continuity lives in the record. Enforcement lives in mechanism. Judgment about intent lives in the Owner. Every agent invocation begins from the record as if it had never seen the project, because it has not. +4.1.2 There is no *standing* manager-agent, architect-agent, or +orchestrator-agent carrying memory or authority across sessions. The +Architect, General, and Operator (2.29-2.31, 4.2.5-4.2.7) are functions +performed by a fresh agent invocation with no carried authority, exactly +like every other function this Part defines; naming a function is not +granting it standing continuity. Continuity lives in the record. +Enforcement lives in mechanism. Judgment about intent lives in the Owner. +Every agent invocation begins from the record as if it had never seen the +project, because it has not — including an Architect or General +invocation, and including one immediately following another in the same +conversation. 4.1.3 Where practical, the Implementer and Reviewer functions should be performed by different model vendors. Independent failure modes make agreement-by-shared-blindspot less likely. +4.1.4 A function name is not authority. Authority derives from the recorded +delegation chain (3.2.5, 2.7, 7.9.1), never from title, memory, apparent +seniority, or physical or conversational proximity to the Owner. Downstream +delegation may narrow scope but never enlarge it. A reporting relationship +among functions — for example, an Operator reporting through a General — +does not abolish the fresh-invocation boundary of 4.1.2 or the review +independence of 4.2.4 and 7.6. + +4.1.5 One provider may host multiple Architect/General/Operator functions +(4.2.5-4.2.7) without requiring separate subscriptions or vendors, provided +each invocation is fresh per 4.1.2 and execution/review independence is +preserved per 7.6. This shared-hosting allowance does not satisfy, diminish, +or substitute for 4.1.3's separate, unchanged preference that the +Implementer and Reviewer be performed by different model vendors where +practical; 4.1.3 concerns the Implementer/Reviewer pair specifically and is +not relaxed by this clause, which concerns only the newer +Architect/General/Operator functions. No function may silently take over a +stalled or unresponsive downstream function's work. Reassignment requires +either authority already present in an existing mandate or a fresh Owner +decision, and any reassignment must still preserve fresh execution/review +separation for the reassigned work — an Architect that reassigns a stalled +Operator's task does not thereby become that task's Reviewer. + ### 4.2 Role Table | Clause | Role | Performed by | Continuity | Authority | @@ -196,7 +293,10 @@ Terms are defined for use within the doctrine. Where a term has a wider industry | 4.2.1 | Owner | Human | Durable | Sole ratifier of intent: charter, plan, routing map, decisions, amendments. Reads owner briefs by default and evidence on escalation. | | 4.2.2 | Dispatcher | Agent, fresh per invocation | None | Drafts work orders from ratified intent. Self-checks each for internal contradiction before issue. Never writes code. | | 4.2.3 | Implementer | Agent, fresh per work order | None | Executes exactly one work order inside its capability grant. Halts and files RFIs on ambiguity. Never amends intent-bearing documents. | -| 4.2.4 | Reviewer | Agent, fresh per artifact | None | Diffs work reports against the work order and plan. Produces owner briefs. Never writes code, never amends intent. | +| 4.2.4 | Reviewer | Agent, fresh per artifact | None | Diffs work reports against the work order and plan. Produces owner briefs, addressed to the Owner and, for routing purposes, delivered through the Architect (4.2.5) rather than the General (4.2.6), per the Owner-escalation guarantee of 7.6.4. Routing a brief through the Architect is a delivery channel, not an approval gate: the Architect conveys the brief and may not suppress, rewrite, or condition its delivery on anything (7.6.4). Never writes code, never amends intent, never reviews its own implementation. | +| 4.2.5 | Architect | Agent, fresh per invocation | None | Primary human point of contact for discovery, adoption, construction-phase design, and recovery. Listens, inspects bounded evidence, challenges the pitch, drafts a project sketch or design proposal, conveys existing Owner authority, and performs only exactly authorized recorder mechanics (8.7.6). Never ratifies intent, never activates a work order, never suppresses or rewrites a Reviewer finding (7.6.4). | +| 4.2.6 | General | Agent, fresh per invocation | None | Post-adoption continuity function. Prepares bounded dispatch (may perform the Dispatcher function, 4.2.2), routes work to Operators, records only already-ratified Owner decisions, and routes new design or design-conformance questions to a fresh Architect. Prepares batch members for activation but never itself activates one; activation is an Owner lifecycle action under 8.7.6/7.10.3. Never ratifies intent; never prepares a member beyond the Owner-approved sequence or past a reserved milestone (7.10.4). | +| 4.2.7 | Operator | Agent, fresh per work order or bounded external-operations packet | None | Executes one active work order or one bounded external-operations packet (2.31.2) inside its capability grant. Performs the Implementer function (4.2.3) when working a repository work order. Halts and files RFIs per 7.11 on ambiguity. Never reviews or authorizes its own work. | --- @@ -328,6 +428,25 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 6.4.2 The birth test has two levels with different consequences. The no-work-order lockout (8.3.5.1) is an adoption precondition: if any mutation channel available to the Implementer can mutate anything with no active work order, the project has not adopted the doctrine. Active-work-order scope enforcement (8.3.5.2) is tested per surface: a surface that fails through any channel is downgraded to unenforced-by-declaration for that project, which does not invalidate adoption unless the Owner judges the resulting risk unacceptable under 8.3.4. +### 6.5 Existing-Project Realignment + +6.5.1 A read-only realignment may summarize an already-adopted project's +current responsibilities, approved scope, evidence age, blockers, and next +permitted action without touching project bytes. It is available to any +function re-entering a project, including the Architect and the General, and +creates no lifecycle event by itself. + +6.5.2 Realignment preserves every prior adoption, approval, active work, +command compatibility, and canonical project root. It never forces a fresh +interview, an automatic migration or re-adoption, retrieval of archived +history, or repair of anything outside an active work order's grant. Evidence +it cannot find is reported as missing, never guessed or invented. + +6.5.3 A project remains bound to the doctrine revision it last ratified +(DC.4.1) regardless of any later revision this methodology repository +publishes. Publishing a revised methodology revision is not itself a +migration of any adopting project, including a self-hosted instance (5.1.6). + --- ## PART 7. THE WORKFLOW @@ -352,7 +471,12 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.2.3 The Dispatcher self-checks the draft for internal contradiction between the grant, the required work, and the stated prohibitions, and resolves any contradiction before issue. -7.2.4 The Owner activates the work order. +7.2.4 The Owner activates the work order. For a member of an Owner-ratified +batch (7.10), the Owner's ratification of the batch is the activation +decision for each named member, made once for the sequence rather than once +per member; the mechanical act of creating or updating the activation +pointer for that member still proceeds only through the separately +authorized lifecycle actor 8.7.6 requires (7.10.3). ### 7.3 The Wall Goes Up @@ -382,9 +506,32 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.6.3 The Reviewer is an information-loss boundary. The brief is the Owner's default read, but the Reviewer must attach or link supporting evidence, and the Owner must read it, whenever any of the following holds: the verdict is DEVIATION; the Reviewer rates its own confidence LOW on the fixed HIGH/MEDIUM/LOW scale of Appendix C, which threshold is not the Reviewer's to set; the change is security-relevant or irreversible; or the Implementer's claims, the Reviewer's findings, and any empirical instrument's results disagree. +7.6.4 The Reviewer's owner brief (2.18, Appendix C) is addressed to the +Owner and, for delivery purposes only, is conveyed to the Owner through the +Architect (4.2.5) rather than the General (4.2.6). Conveying is not +reviewing: the Architect may not suppress, rewrite, condition, delay, or +waive any Reviewer finding, verdict, escalation, or required evidence. The +Architect's channel does not become a second information-loss boundary +alongside the one 7.6.3 already establishes for the Reviewer; the Owner +retains standing access to the Reviewer's complete original findings +regardless of any summary the Architect adds when conveying them. Where a +Reviewer's finding or a brief's contents implicate a decision the Architect +itself made, escalation to the Owner proceeds directly and is not filtered +or mediated by the Architect. Design advice the Architect offers about the +work under review is not independent review and never substitutes for the +Reviewer's function (4.2.4, 8.0.3). + ### 7.7 Owner Disposition -7.7.1 Reading the brief, and the evidence when escalated, the Owner disposes of the work: acceptance, rework, or ratification of a deviation. Acceptance and rework are ordinary dispositions. Ratification is reserved for dispositions that change intent (2.7). +7.7.1 Reading the brief, and the evidence when escalated, the Owner +disposes of the work: acceptance, rework, or ratification of a deviation. +Acceptance and rework are ordinary dispositions. Ratification is reserved +for dispositions that change intent (2.7). For a routine, fully conforming +member covered by an Owner-ratified delegated conforming-completion +disposition policy (7.10.6), acceptance may be exercised by the named +delegate that policy identifies rather than by the Owner directly. +Ratification of a deviation remains reserved to the Owner alone and is +never delegable under any policy. 7.7.2 Any disposition that changes intent becomes a decision record at that moment. @@ -408,6 +555,195 @@ Terms are defined for use within the doctrine. Where a term has a wider industry 7.9.5 No control depends on an agent remembering an instruction. +### 7.10 Batch Approval and Delegated Execution + +7.10.1 Owner approval of a roadmap, a plan section, or a discussion is not +execution approval for any individual work order (2.16). Execution approval +requires an explicit Owner instruction identifying either one work order or a +finite batch (2.32) of named, already-drafted work-order revisions. + +7.10.2 A batch record states: member work-order identifiers and revisions; +the batch objective; sequence and dependencies among members; the resources +and actions each member's own grant already authorizes; delegated +responsibilities; falsifiable acceptance conditions; any Owner-reserved +milestone at which the sequence stops for a fresh decision; stop conditions; +and the exact Owner instruction that authorized it. An existing record is +reused where one already states this; a batch does not require a new +administrative document for every routine transition. + +7.10.3 Owner approval of a batch does not activate every member +simultaneously. Consistent with 7.3 and the project's one-active-work-order +control model, once a member's prerequisites and any reserved milestone have +passed, the General (4.2.6) prepares that next approved, unblocked batch +member for activation. The General never itself performs activation. +Activation remains exactly the pointer-creation act 8.3.5.1 and 8.7.1 name +as a control-plane artifact, and 8.7.6 requires that act to be an Owner +lifecycle action performed by a separately authorized recorder, never under +any work order's or batch's own capability grant; no agent edits the +activation pointer under a capability grant, under this clause or any other. +The Owner's ratification of the batch record supplies the durable, +pre-execution authorization 8.7.6 requires for each named member, recorded +once at batch ratification rather than re-obtained once per member; this is +what lets the sequence proceed without a repeated per-member Owner ask, +while the mechanical act of activation still passes through the same +separately authorized recorder 8.7.6 always requires. 7.2.4's requirement +that the Owner activates the work order is unchanged: for a batch member, +the Owner's act of ratifying the batch is the 7.2.4 activation decision, +made once for the named sequence rather than once per member; the +recorder's later keystroke executes a decision the Owner already made, +exactly as 8.7.6 already permits for any other lifecycle action. + +7.10.4 A fresh Owner approval is required before dispatching a work order +that is not already part of an approved batch, or at any milestone the Owner +reserved in the batch record. A session change, by itself, is never grounds +to request an approval the batch record does not require. + +7.10.5 No function may reclassify an intent, scope, capability, +acceptance-condition, resource-limit, or reserved-milestone change as +clerical. Only Owner ratification changes any of these (7.9.1, 2.7). A +platform permission prompt is not an Owner re-ratification, and a mandate +never substitutes for one. A genuinely clerical lifecycle correction — one +that preserves the exact meaning the Owner already approved and merely +repairs its administrative form — proceeds only through a separately +authorized lifecycle actor acting under 8.7.6, and only with a durable trace +recording what was corrected, against what already-ratified text, and by +whom. A correction that leaves any doubt about whether meaning changed is +not clerical by this clause's own terms and requires ordinary Owner +ratification instead. + +7.10.6 The Owner may separately ratify a delegated conforming-completion +disposition policy (2.33) letting the General or Reviewer close a routine, +fully conforming batch member without an individual Owner acceptance turn. +This is an instance of 7.7.1's acceptance disposition, delegated in advance, +not a fourth disposition alongside acceptance/rework/ratification. 7.7.2 and +7.7.3 continue to apply exactly as written to every member closed this way: +a disposition that changes intent still becomes a decision record at that +moment regardless of who or what closed the member (7.7.2), and the cycle's +metrics are still appended to LOG.md and the next work order still +dispatches (7.7.3), with the LOG.md entry for a delegation-disposed member +stating plainly that disposition was by the ratified delegated policy, not +by the Owner's own reading, so a later reader can distinguish the two +dispositions without inferring it from context. Such a policy: is itself a +decision record; states exactly which conditions qualify as routine and +fully conforming; and is never described as "the Owner accepted" when only +the delegated policy's own criteria were met — the record instead states +plainly that the delegated policy disposed of it under 7.7.1, distinct from +the Owner personally reading and accepting it. Nonconformance, deviation, or +unresolved ambiguity still escalates under 7.6.2-7.6.3 regardless of any +delegated policy; no function may waive it, and a delegated policy is +defined precisely because 7.7.1's rework and deviation-ratification +dispositions are excluded from it by definition — only the plain-acceptance +case is delegable. Absent a ratified delegated policy, ordinary Owner +disposition (7.7) continues to govern every member, exactly as it does +today. + +7.10.7 Execution stops when an approved batch's last member is complete, +blocked, or exhausted. The General reports results and may recommend, but +may not activate, expand, or manufacture, follow-on work; a new batch or +work order requires a fresh Owner approval under 7.10.1. Batch approval +implies no authority to release, publish, deploy, push, tag, or act on any +external account; each requires its own explicit inclusion in the approval +that grants it. + +7.10.8 A reserved Owner milestone (7.10.2, 7.10.4) and the mandatory +escalation conditions of 7.6.3 are independent controls, both of which apply +in full to work performed under a batch. Passing a reserved milestone check +does not satisfy or substitute for a 7.6.3 escalation condition that is +separately triggered, and satisfying 7.6.3 does not waive a reserved +milestone the batch record separately names. Batch approval under 7.10.1 +never supersedes, narrows, or creates an exception to 7.6.2's default block +on nonconformance, 7.6.3's mandatory escalation, or any other standing +review requirement; a batch is a sequencing authorization, not a review or +escalation waiver. + +7.10.9 The complete semantic-state mapping for a batch member, using only +representations the project's existing pre-dispatch validation and +Appendix B's existing status enum already support; this candidate invents +no new status value, pointer format, or frontmatter field: + +| Semantic state | Where it lives | Existing machine-readable representation | +|---|---|---| +| Proposed / planned | The batch record itself, or an ordinary plan section, before Owner approval | No work-order frontmatter exists yet for an unapproved member, or it exists as an ordinary draft file not yet named in any ratified batch record. Nothing to parse; this is a plan-level state, not a work-order state. | +| Approved-for-execution (batch member, not yet active) | The ratified batch record | The member is named, by its existing `id:`, in an Owner-ratified batch record (7.10.2). It does not yet exist as an activated pointer target: the existing activation pointer does not name it. "Approved-for-execution" is a batch-record fact, not a work-order frontmatter fact. | +| Active | The work order itself, once activated | The activation pointer names it, and its frontmatter reads `status: ACTIVE` — Appendix B's existing enum, unchanged. | +| Blocked | The work order itself | Frontmatter `status: RFI-BLOCKED` — Appendix B's existing enum, unchanged. Corresponds to 7.11.1's blocking RFI class. | +| Complete | The work order, then its historical record | Frontmatter `status: COMPLETE`, then moved to the project's historical record at closure (5.3.7) — unchanged. | + +### 7.11 RFIs, Blocking, and Handoff Continuity + +7.11.1 An RFI (2.20) is filed as one of three explicitly stated kinds: an +informational clarification that does not block ongoing work; a resolvable +execution problem that blocks only the work it affects until answered; or a +blocking scope, authority, or safety contradiction that halts the affected +work immediately, before or concurrently with filing the RFI itself. + +7.11.2 A blocking RFI halts the work it affects and any work that depends on +it. Independently authorized work may continue only once its independence +from the blocked matter is established, not merely asserted. Where that +judgment is itself in doubt, the dependency is treated as blocking rather +than resolved by assertion, and neither the Architect nor the General +declares independence unilaterally in that circumstance. + +7.11.3 An RFI presented to the Owner as an executive decision brief states: +the question; the evidence; the affected scope; the consequence of each +option; a recommendation; and the exact decision needed. The lower-level +technical record behind the brief is preserved and remains available; the +brief never replaces it. + +7.11.4 Resolving an RFI changes only the scope the resolution names. +Approvals unrelated to that scope remain valid without replay. Evidence that +depended on the resolved question is rechecked before being relied on again, +but the entire authorization chain is not re-litigated because one question +in it was resolved. + +7.11.5 A handoff between functions is tracked through distinguishable states: +prepared (drafted, not transmitted); sent (transmitted to the receiving +session or human); acknowledged (receipt confirmed); returned (work product +delivered back); and reviewed (a fresh Reviewer has checked it). No function +fabricates a dispatch, a session identifier, a completion, or continuous +awareness of a handoff's status; a status not actually observed is reported +as unknown, never inferred as favorable. + +7.11.6 A human-relayed message is preserved together with its provenance — +that it was relayed, by whom, and when — and is never presented as if it +were a direct machine-to-machine handoff record. + +7.11.7 The Architect remains free to discuss design with the Owner while a +General is executing an approved batch. That conversation alone does not +interrupt, reauthorize, or expand the executing work. Any resulting change to +scope, intent, or grant still requires ordinary Owner ratification and an +ordinary batch-record update under 7.10.5. + +### 7.12 Reporting Headers + +7.12.1 Every agent-authored user-facing progress or final reply to the Owner +begins with a compact header stating: the project; the current work order or +batch identifier and its plain-language purpose; and the current activity or +status, using one of: proposed (an idea, sketch, or draft not yet ratified or +activated); no active work order; active work on a named work order or batch +member; blocked; or reporting on a completed work order or batch. Where none +is active, the header states so plainly rather than omitting the line. + +7.12.2 For an approved batch, the header distinguishes overall batch progress +from the currently active member. + +7.12.3 A report states what happened, why it matters to the Owner's +decision, what the evidence proves and does not prove, any decision or +blocker, and the next permitted action. A pull-request identifier or a +passing test count supports that statement; it never substitutes for it. + +7.12.4 This requirement binds the Architect, General, Operator, and Reviewer +whenever addressing the Owner directly. It does not require a header inside +machine-readable output, a pasted command, or another reusable artifact not +meant for direct human reading. + +7.12.5 Canonical prompts, skill instructions, and generated role packets +state this requirement so a freshly invoked function is instructed to +comply. Compliance itself remains instruction-bound, not mechanically +enforced; a test of generated bytes proves only that the instruction is +present in what was generated, never that a future invocation will follow +it. + --- ## PART 8. ENFORCEMENT @@ -516,6 +852,15 @@ Pre-dispatch validation passes such an instrument only when every control-plane 8.7.6 Activating or retiring the active-work-order pointer; changing the installed enforcement configuration; amending the active work order's or birth-test instrument's own frontmatter or body; and, narrowly, any recorder action that itself mutates a control-plane artifact, together with the adoption-recorder lifecycle action defined in Part 6 (the Owner-directed recorder closeout that records already-ratified adoption decisions), are Owner lifecycle actions. Ordinary Part 7 work-order reporting, review, acceptance, history retirement, State and metrics update, and closeout remain inside the governed Part 7 cycle (7.5-7.8) and are not reclassified under this clause merely because they record an already-ratified Owner disposition; 8.7.6 reaches only control-plane mutation itself and the named adoption-recorder action. None is performed under a work order's or birth-test instrument's own capability grant, and none is self-authorized by the artifact being changed. The Owner may delegate the clerical keystrokes of such an action to a separately authorized recorder or mechanism acting on exact, already-ratified Owner instructions, but authority over the action stays with the Owner, never with the Implementer or the instrument executing it, and no active Implementer uses its own capability grant to perform one. That separate Owner lifecycle authorization is recorded before execution in a durable Owner disposition or lifecycle packet in the canonical record; a chat exchange alone is not authorization. +8.7.7 The Architect, General, and Operator functions defined in 2.29-2.31 +and 4.2.5-4.2.7 are ordinary names for the same actors 8.7.6 already +describes as "a separately authorized recorder or mechanism" and "the +Implementer." Naming a function under 4.2 confers no control-plane authority +beyond what 8.7.2 and 8.7.6 already permit or forbid. A General or Architect +acting under 8.7.6 remains bound by every condition stated there, including +durable, pre-execution Owner authorization recorded in the canonical record +rather than in chat alone. + --- ## PART 9. MEASUREMENT @@ -607,8 +952,10 @@ A.4.1 [path or subsystem] -> [document] A.4.2 Unmapped and unsure -> RFI. ## A.5 REPORTING -End every work order with the report format specified in the work order, -addressed to the Reviewer. Completeness over brevity. +Begin every reply to the Owner with a one-line header: project, current work +order or batch and its plain-language purpose, and status (7.12). End every +work order with the report format specified in the work order, addressed to +the Reviewer. Completeness over brevity. ## A.6 ENVIRONMENT [build and test commands, platform notes: the minimum an agent needs @@ -745,4 +1092,4 @@ Rules: every intent-bearing document lands in exactly one row; a Tier-2 row with --- -*Revision 0.8. Ratified 2026-08-21 by DR-005. See DC.2 for history and DC.3 for the rules under which this document changes.* +*Revision 0.9. Ratified 2026-09-16 by DR-006. See DC.2 for history and DC.3 for the rules under which this document changes.* diff --git a/skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md b/skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md new file mode 100644 index 0000000..ed81d95 --- /dev/null +++ b/skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md @@ -0,0 +1,55 @@ +# Migration guide: Doctrine 0.8 to 0.9 + +| Field | Value | +|---|---| +| From | Doctrine revision 0.8 | +| To | Doctrine revision 0.9, ratified by `decisions/DR-006.md` | +| Scope | Part 2 (new 2.29-2.33), Part 4 (4.1.2 amended in place, new 4.1.4-4.1.5, 4.2.4 amended in place, new 4.2.5-4.2.7 role rows), Part 6 (new 6.5), Part 7 (7.2.4 and 7.7.1 amended in place, new 7.6.4, 7.10, 7.11, 7.12), Appendix A (A.5 header requirement), Part 8 (new 8.7.7) | +| Applies to | A project bound to 0.8 (DC.4.1) whose Owner wants to move to 0.9 | + +## 1. Nothing moves automatically + +Moving a project to a later revision is a change-controlled event (Doctrine DC.4.2). This guide is followed only when the project's Owner has explicitly ratified migration in a project-local decision record naming both revisions. No script, adapter, skill, or agent invocation performs this migration on its own initiative, and nothing in this bundle updates an adopting project automatically. Until the Owner ratifies migration, the project remains correctly bound to 0.8. + +## 2. What changed + +1. **Part 2, new definitions.** 2.29 Architect, 2.30 General, and 2.31 Operator (with 2.31.1 shared-hosting distinctness and 2.31.2 external-operations packet) name the discovery/continuity/execution functions that 4.2 already implies but 0.8 left unnamed. New 2.32 Batch and 2.33 Delegated conforming-completion disposition support the new batch workflow (Part 7.10). +2. **Part 4.** 4.1.2 is amended in place: it now bars only *standing/carried* authority across sessions, not the Architect/General/Operator function names themselves, which are fresh-invocation functions exactly like every other role this Part defines. New 4.1.4 states that a function name is not authority; authority derives from the recorded delegation chain (3.2.5). New 4.1.5 permits one provider to host multiple Architect/General/Operator functions without separate subscriptions, provided each invocation is fresh and execution/review independence is preserved -- this does not relax 4.1.3's separate, unchanged different-model-vendor preference for Implementer/Reviewer. 4.2.4 is amended in place to route the Reviewer's owner brief through the Architect (4.2.5) as a delivery channel only, never an approval gate. New role-table rows 4.2.5 (Architect), 4.2.6 (General), and 4.2.7 (Operator) state what each function receives, does, and never does. +3. **Part 6.** New 6.5, Existing-Project Realignment: a read-only realignment may summarize an already-adopted project's current responsibilities, approved scope, evidence age, blockers, and next permitted action without touching project bytes, available to any re-entering function including the Architect and General, and creating no lifecycle event by itself. It never forces a fresh interview, an automatic migration or re-adoption, or archived-history retrieval, and a project remains bound to the revision it last ratified regardless of any later revision this methodology repository publishes. +4. **Part 7.** 7.2.4 is amended in place to state that ratifying a batch is the activation decision for its named members, made once for the sequence; the mechanical pointer-creation act still proceeds only through the separately authorized recorder 8.7.6 already requires. 7.7.1 is amended in place to allow a named delegate to exercise acceptance for a routine, fully conforming batch member under an Owner-ratified delegated conforming-completion disposition policy (7.10.6), while reserving deviation ratification to the Owner alone, never delegable. New 7.6.4 states the Reviewer's independence from the Architect and General: the Architect conveys the owner brief but may not suppress, rewrite, condition, delay, or waive any Reviewer finding, and an implicated Architect decision escalates directly to the Owner. New Part 7.10 (7.10.1-7.10.9) defines batch approval and delegated execution: an Owner instruction naming one work order or a finite batch is required for execution approval; the General prepares but never activates a batch member; a fresh Owner approval is required outside an approved batch or at a reserved milestone; no function may reclassify a substantive change as clerical; a delegated conforming-completion disposition policy covers only the plain-acceptance case, never rework or deviation ratification; and 7.10.9 maps batch-member semantic states onto the existing frontmatter status enum without inventing any new value. New Part 7.11 (7.11.1-7.11.7) states RFI severity classes (informational, resolvable, blocking), blocking-RFI dependency treatment, the RFI-as-executive-brief format, and handoff-state tracking (prepared/sent/acknowledged/returned/reviewed) in which an unobserved status is reported as unknown, never inferred as favorable; a human-relayed message is preserved with its relay provenance. New Part 7.12 (7.12.1-7.12.5) requires every agent-authored user-facing reply to the Owner to begin with a compact header stating the project, the current work order or batch identifier and purpose, and status (proposed/no active work order/active/blocked/reporting on completion), excluding machine-readable output, pasted commands, and other reusable artifacts not meant for direct human reading. +5. **Appendix A.** A.5 now requires the 7.12 header be stated in every reply to the Owner, in addition to the existing report-format-and-Reviewer-addressing requirement; no other appendix body text changed. +6. **Part 8.** New 8.7.7 states that the Architect, General, and Operator functions are ordinary names for the actors 8.7.6 already describes ("a separately authorized recorder or mechanism" and "the Implementer"); naming a function under 4.2 confers no control-plane authority beyond what 8.7.2 and 8.7.6 already permit or forbid. + +No other Doctrine clause changed. In particular, Appendices B, C, D, and E carry no content change in 0.9; only their footer's cited revision number advances. + +## 3. Affected local artifacts + +- The project-local charter template, conventionally `governance/templates/A-charter.md` (Doctrine Appendix A, `ADOPTING.md` section 0): superseded by a fresh copy of `templates/A-charter.md` from this distribution's Doctrine 0.9 if the Owner wants the updated A.5 wording naming the 7.12 header requirement; the live, instantiated charter itself is a separate Owner-ratified record. +- The project's own charter (`A.5 REPORTING`), if the Owner wants it to state the 7.12 header requirement explicitly: amended only by Owner ratification (Doctrine 7.9.1: no agent amends the charter). +- Any project-local documentation, generated role packets, or onboarding material describing the General, Architect, or Operator functions, delegation visibility, or handoff status should be reviewed against 7.11.5 (handoff states) and 7.12 (reporting headers) and updated by ordinary project change control; 0.9 does not itself change any installed adapter's enforcement behavior. +- The project-local work-order and other Appendix B/C/D/E templates need no content change; only the extraction footer's cited Doctrine revision advances if the Owner chooses to refresh it. + +## 4. Preparation procedure + +Performed once, by or under the direction of the project's Owner, after migration is ratified: + +1. Ratify migration in a project-local decision record naming both revisions (0.8 and 0.9) and listing the affected artifacts (Doctrine DC.4.2). +2. Replace `governance/templates/A-charter.md` with the 0.9 copy from this distribution if the Owner wants the A.5 wording naming the 7.12 header requirement. Copy it exactly; do not paraphrase (Doctrine 5.1.2, `ADOPTING.md` section 0). +3. Update the project's charter (`A.5`, and any A.2/A.3 lines naming the bound doctrine revision) by Owner ratification (Doctrine 7.9.1: no agent amends the charter). +4. Where the project generates role packets, prompts, or handoffs for an Architect, General, or Operator function, review and update them against 4.2.5-4.2.7, 7.6.4, 7.11.5, and 7.12 so a freshly invoked function is instructed to announce delegated role/task, name a monitoring location or its explicit absence, state the last verified handoff state, and open replies with the 7.12 header. +5. Every project-local grant classification already in force is preserved exactly as issued; this migration adds no new capability-grant surface, status enum value, or pointer format, and does not retroactively reclassify any surface an Owner has already declared for an issued work order. +6. If the project intends to use the batch-approval workflow (Part 7.10), the Owner drafts and ratifies a batch record (7.10.2) naming its members, sequence, and any reserved milestone before the General prepares the first member for activation. + +## 5. Deterministic post-migration check + +Before relying on the new revision, confirm the project's instantiated templates and generated role material agree with the 0.9 Doctrine text they cite: + +``` +python checks/check_distribution.py +``` + +Run from this methodology repository against its own self-hosted instance, this must exit 0. For a separately adopted project, the equivalent is whatever deterministic dispatch-preparation and template-consistency tooling that project installed at adoption (5.1.3); it must report the templates it instantiated as matching the cited Doctrine revision's appendices, byte-for-byte, and must report no stale footer citing 0.8 after the Owner has refreshed a template. + +## 6. What this migration does not do + +It does not change any surface a prior, already-issued 0.8 work order declared. It does not touch `DOCTRINE.md`, this repository's own governance instance, or any file outside the artifacts named in section 3. It does not migrate any project other than the one whose Owner ratified it (Doctrine 5.1.5, `DOCTRINE.md` DC.4.1). It does not implement or claim any new enforcement, adapter, or template mechanism; 0.9 itself states plainly that no enforcement, adapter, or template mechanism is implemented by this revision alone (DC.2). It does not activate any batch, delegate any acceptance, or create any monitoring, scheduler, or task-dispatch capability that did not already exist; Part 7.10-7.12 are instruction and reporting clarity over the existing workflow, not new mechanism. diff --git a/templates/A-charter.md b/templates/A-charter.md index c44d9fa..f42ba51 100644 --- a/templates/A-charter.md +++ b/templates/A-charter.md @@ -34,12 +34,14 @@ A.4.1 [path or subsystem] -> [document] A.4.2 Unmapped and unsure -> RFI. ## A.5 REPORTING -End every work order with the report format specified in the work order, -addressed to the Reviewer. Completeness over brevity. +Begin every reply to the Owner with a one-line header: project, current work +order or batch and its plain-language purpose, and status (7.12). End every +work order with the report format specified in the work order, addressed to +the Reviewer. Completeness over brevity. ## A.6 ENVIRONMENT [build and test commands, platform notes: the minimum an agent needs every session] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/templates/B-work-order.md b/templates/B-work-order.md index 8182192..216702f 100644 --- a/templates/B-work-order.md +++ b/templates/B-work-order.md @@ -69,4 +69,4 @@ contradicts it.] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/templates/C-owner-brief.md b/templates/C-owner-brief.md index c588543..dda0bc8 100644 --- a/templates/C-owner-brief.md +++ b/templates/C-owner-brief.md @@ -16,4 +16,4 @@ C.6 REVIEWER CONFIDENCE: HIGH | MEDIUM | LOW. [LOW triggers C.5.] Reviewer notes, for the record and not the Owner: [anything longer] ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/templates/D-adoption-record.md b/templates/D-adoption-record.md index 04d74e4..c72790b 100644 --- a/templates/D-adoption-record.md +++ b/templates/D-adoption-record.md @@ -27,4 +27,4 @@ D.10 Historical decisions carried forward (6.3.6), each with a note that it predates the boundary. ``` -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/templates/E-adoption-mapping.md b/templates/E-adoption-mapping.md index 92ea5a8..7f1021c 100644 --- a/templates/E-adoption-mapping.md +++ b/templates/E-adoption-mapping.md @@ -8,4 +8,4 @@ For each existing document in the project, record one row. Rules: every intent-bearing document lands in exactly one row; a Tier-2 row without a route is an Archive row; two documents may not both be assigned to Plan for the same scope; the completed worksheet is attached to DR-001. -_Extracted verbatim from DOCTRINE.md rev 0.8. Do not edit here; templates change only when the doctrine does._ +_Extracted verbatim from DOCTRINE.md rev 0.9. Do not edit here; templates change only when the doctrine does._ diff --git a/tests/test_coordinator_release.py b/tests/test_coordinator_release.py index 6e4f7c7..34e9d1d 100644 --- a/tests/test_coordinator_release.py +++ b/tests/test_coordinator_release.py @@ -51,7 +51,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.11.0")) + arguments.extend(("--expected-tag", "v0.12.0")) return subprocess.run( [sys.executable, "-B", str(CHECKER), *arguments], cwd=REPO_ROOT, @@ -510,15 +510,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.11.0"', 'version = "0.9.0"' + 'version = "0.12.0"', 'version = "0.9.0"' ), encoding="utf-8", newline="\n", ) - result = self.run_checker(candidate, "--expected-tag", "v0.11.0") + result = self.run_checker(candidate, "--expected-tag", "v0.12.0") self.assertNotEqual(result.returncode, 0) self.assertIn( - "candidate version '0.9.0' does not match intended tag 'v0.11.0'", + "candidate version '0.9.0' does not match intended tag 'v0.12.0'", result.stdout + result.stderr, ) @@ -564,23 +564,25 @@ def test_release_check_exercises_nested_worktree_stop_on_the_installed_wheel(sel 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.11.0") + self.assertEqual(project["version"], "0.12.0") 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.11.0.zip" + skill = (REPO_ROOT / "skills" / "writwall-adopt" / "SKILL.md").read_text( + encoding="utf-8") + tagged_archive = "archive/refs/tags/v0.12.0.zip" self.assertIn(tagged_archive, readme) self.assertIn(tagged_archive, adopting) self.assertIn(tagged_archive, start) - self.assertIn("--expected-tag v0.11.0", publication) - self.assertIn("--expected-tag v0.11.0", contributing) + self.assertIn("--expected-tag v0.12.0", publication) + self.assertIn("--expected-tag v0.12.0", contributing) for document in (readme, adopting, start): self.assertNotIn("not yet published", document) self.assertIn( 'python -m pip install ' - '"https://github.com/HLLMR/writwall/archive/refs/tags/v0.11.0.zip"', + '"https://github.com/HLLMR/writwall/archive/refs/tags/v0.12.0.zip"', document, ) self.assertIn("writwall inspect", document) @@ -589,6 +591,23 @@ def test_release_identity_and_public_payload_are_coherent(self): self.assertIn("Release `v0.9.1` corrected", start) self.assertIn("Release `v0.9.2` corrects", start) self.assertIn("Release `v0.9.3` adds", start) + # Accepted brief/preflight capabilities are now released in 0.12.0, + # not caveated as unreleased-current-branch source work: the same + # documents this method already reads must no longer carry that + # caveat anywhere it previously qualified `--brief` or the + # operational-preflight contract. + for document in (readme, adopting, start, publication, skill): + self.assertNotIn("unreleased source work", document) + self.assertNotIn("not part of any published release", document) + available_since_marker = "available since `v0.12.0`" + for document in (adopting, start, skill): + normalized = " ".join(document.split()) + self.assertGreaterEqual( + normalized.count(available_since_marker), 2, + f"expected at least one marker each for --brief and the " + f"operational-preflight capability, got " + f"{normalized.count(available_since_marker)}", + ) 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 484ba47..ace0510 100644 --- a/tests/test_distribution.py +++ b/tests/test_distribution.py @@ -177,6 +177,53 @@ def materialize_source_provenance_fixture(repo: Path) -> Path: return repo +def normalize_identity_baseline(repo: Path) -> Path: + """Recompute this disposable fixture's own retained-identity digests. + + ``identity/legacy-references.json`` pins each retained path's SHA-256 as + evidence that specific historical bytes have not silently drifted in the + real, governed source repository -- that is a source/release-acceptance + concern, and this function makes no claim about it either way. A test + fixture copied by ``copy_repo`` is not that repository: many tests in + this module deliberately mutate the copy afterward (revision text, + work-order fixtures, CRLF conversion, and so on), and unrelated ordinary + churn in the real repository's own governance instance (LOG/PLAN/STATE) + is expected between sessions. Pinning the real repository's own + historical hashes against a disposable copy therefore asserts nothing + about drift in that copy; it just fails on the first incidental byte + difference between the two, before any test-specific mutation runs. + + This recomputes each retained entry's ``sha256`` from the corresponding + file exactly as it exists in THIS destination, right now -- before any + later, test-specific mutation in this module -- and writes only this + disposable copy's own ``identity/legacy-references.json``. It never + touches the real, governed source repository's identity file, any other + real authority or probe-evidence file, or any field on a retained entry + besides ``sha256`` (path, context, ``projection_sha256``, + ``projection_transform``, schema, and the ``current``/``former`` blocks + are preserved verbatim, and no entry is added or removed). Because this + runs before the mutations below, a genuine identity-negative test that + later edits a retained file (or an unrelated one) still produces a real, + detectable mismatch; this only removes the false mismatch that copying + the repository into a new, disposable location and running other tests + against it would otherwise introduce on every run. This is controlled + fixture baseline state for this test module only -- it is never a claim + that any source, release, or publication identity gate has passed. + """ + manifest_path = repo / "identity" / "legacy-references.json" + if not manifest_path.is_file(): + return repo + payload = json.loads(manifest_path.read_text(encoding="utf-8")) + for entry in payload.get("retained", []): + target = repo / entry["path"] + if target.is_file(): + entry["sha256"] = hashlib.sha256(target.read_bytes()).hexdigest() + manifest_path.write_text( + json.dumps(payload, indent=2) + "\n", encoding="utf-8", newline="\n" + ) + return repo + + def copy_repo(destination: Path) -> Path: shutil.copytree( REPO_ROOT, destination, @@ -199,15 +246,62 @@ def copy_repo(destination: Path) -> Path: }], }]}}, indent=2) + "\n", encoding="utf-8", newline="\n") materialize_source_provenance_fixture(destination) + normalize_identity_baseline(destination) return pre_adoption_fixture(clear_transient_release_state(destination)) +_DC1_EFFECTIVE_RE = re.compile( + r"^\|\s*Effective\s*\|\s*(\d{4}-\d{2}-\d{2}),\s*ratified by (DR-\d+)\s*\(`([^`]+)`\)") +_FOOTER_LINE_RE = re.compile(r"^\*Revision .*\*$") + + class DistributionTestCase(unittest.TestCase): def setUp(self): self.tmp = Path(tempfile.mkdtemp()).resolve() self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True) self.repo = copy_repo(self.tmp / "writwall") + def current_control(self): + """Derive current revision/ratification/footer facts from this + fixture's own, as-yet-unmutated DOCTRINE.md, rather than a + hardcoded revision string. This keeps tests meaningful across a + future ratified transition instead of pinning one revision number + that goes stale the moment the Owner ratifies the next one. Call + this before any of the mutations below, in the same style as the + historical-migration-specific tests, which deliberately keep their + own fixed revision numbers because they test one named transition.""" + text = (self.repo / "DOCTRINE.md").read_text(encoding="utf-8") + lines = text.splitlines() + revision = None + for line in lines: + if "|" not in line: + continue + cells = [c.strip() for c in line.strip().strip("|").split("|")] + if len(cells) == 2 and cells[0].lower() == "revision" and revision is None: + revision = cells[1] + self.assertIsNotNone(revision, "DOCTRINE.md DC.1 revision is unreadable") + effective_date = ratifying_dr = ratifying_path = None + for line in lines: + match = _DC1_EFFECTIVE_RE.match(line.strip()) + if match: + effective_date, ratifying_dr, ratifying_path = match.groups() + break + self.assertIsNotNone( + ratifying_path, "DOCTRINE.md DC.1 Effective row is unreadable") + footer_line = next( + (line.strip() for line in reversed(lines) + if _FOOTER_LINE_RE.match(line.strip())), + None, + ) + self.assertIsNotNone(footer_line, "DOCTRINE.md has no revision footer") + return { + "revision": revision, + "effective_date": effective_date, + "ratifying_dr": ratifying_dr, + "ratifying_path": ratifying_path, + "footer_line": footer_line, + } + def check(self, *extra): return subprocess.run( [sys.executable, str(self.repo / "checks" / "check_distribution.py"), @@ -233,19 +327,22 @@ def edit(self, relative, old, new, count=1): path.write_text(text.replace(old, new) if count == -1 else text.replace(old, new, count), encoding="utf-8", newline="\n") - def set_dc2_ratified(self, value): - """Rewrite only the DC.2 ratified cell for the current revision, never - the row's prose, which changes as corrections are recorded.""" + def set_dc2_ratified(self, value, revision=None): + """Rewrite only the DC.2 ratified cell for the given (or, by default, + this fixture's actual current) revision, never the row's prose, + which changes as corrections are recorded.""" + revision = revision or self.current_control()["revision"] path = self.repo / "DOCTRINE.md" lines = path.read_text(encoding="utf-8").splitlines(keepends=True) + prefix = f"| {revision} |" for index, line in enumerate(lines): - if line.startswith("| 0.8 |"): + if line.startswith(prefix): cells = line.rstrip("\r\n").strip("|").split("|") cells[-1] = f" {value} " lines[index] = "|" + "|".join(cells) + "|\n" break else: - self.fail("no DC.2 row for revision 0.8") + self.fail(f"no DC.2 row for revision {revision}") path.write_text("".join(lines), encoding="utf-8", newline="\n") def set_dc1_status(self, value): @@ -258,24 +355,30 @@ def set_dc1_status(self, value): def make_candidate(self): """Return the fixture to a pre-ratification candidate state, including - the artefacts that state requires.""" + the artefacts that state requires. Derived from this fixture's own + actual current revision/footer/ratification-record/effective-date, + never a hardcoded revision string, so this stays meaningful across a + future ratified transition.""" + control = self.current_control() + revision = control["revision"] + date = control["effective_date"] self.set_dc1_status("Ratification candidate") - self.set_dc2_ratified("Pending") - self.edit("DOCTRINE.md", "*Revision 0.8. Ratified 2026-08-21 by DR-005.", - "*Revision 0.8. Ratification candidate.") + self.set_dc2_ratified("Pending", revision) + self.edit("DOCTRINE.md", control["footer_line"], + f"*Revision {revision}. Ratification candidate.*") draft = self.repo / "decisions" / "RATIFICATION-RECORD-DRAFT.md" - draft.write_text("# DRAFT — NO AUTHORITY\n\nRevision 0.8, unsigned.\n", + draft.write_text(f"# DRAFT — NO AUTHORITY\n\nRevision {revision}, unsigned.\n", encoding="utf-8", newline="\n") - (self.repo / "decisions" / "DR-005.md").unlink() + (self.repo / control["ratifying_path"]).unlink() for name in ("README.md", "ADOPTING.md", "SELF-HOSTING.md", "decisions/README.md"): path = self.repo / name path.write_text( path.read_text(encoding="utf-8") - .replace("ratified 2026-08-21", "pending ratification") - .replace("Ratified 2026-08-21", "Pending ratification") - .replace("ratified on 2026-08-21", "not yet ratified") - .replace("ratified Doctrine revision 0.8 on 2026-08-21", - "not yet ratified Doctrine revision 0.8") + .replace(f"ratified {date}", "pending ratification") + .replace(f"Ratified {date}", "Pending ratification") + .replace(f"ratified on {date}", "not yet ratified") + .replace(f"ratified Doctrine revision {revision} on {date}", + f"not yet ratified Doctrine revision {revision}") .replace("is the current ratified revision", "is a ratification candidate") .replace("is the current ratified methodology revision", @@ -290,6 +393,25 @@ def test_clean_copy_passes(self): self.assertIn("all distribution checks passed", result.stdout) +class RatifiedNormativeQuotationTests(DistributionTestCase): + def test_ratified_normative_quotation_does_not_fail_the_public_checker(self): + """The public `check_distribution.py` command must not treat + DOCTRINE.md's own ratified 7.12.1 status-value definition ("an idea, + sketch, or draft not yet ratified or activated") as a claim that the + Doctrine document itself is an unratified candidate. That definition + names a work-order/batch status value; it asserts nothing about + DOCTRINE.md's own DC.1 state, which this same checker already + verifies directly from DC.1/DC.2 and the revision footer. + """ + result = self.check() + self.assertEqual(result.returncode, 0, result.stdout) + self.assertNotIn( + "not yet ratified", result.stdout, + "the public checker must not flag DOCTRINE.md's own ratified " + "7.12.1 text as an unratified-candidate claim", + ) + + class CIWorkflowTests(DistributionTestCase): def test_ci_declares_native_os_and_truthful_python_scopes(self): workflow = self.repo / ".github" / "workflows" / "ci.yml" @@ -548,43 +670,60 @@ def test_dc2_ratified_but_dc1_candidate_fails(self): self.assert_fails(self.check(), "markers") def test_missing_ratification_record_while_ratified_fails(self): - (self.repo / "decisions" / "DR-005.md").unlink() + ratifying_path = self.current_control()["ratifying_path"] + (self.repo / ratifying_path).unlink() result = self.check() self.assertNotEqual(result.returncode, 0) self.assertTrue("markers" in result.stdout or "required-file" in result.stdout) def test_ratification_record_still_carrying_draft_marker_fails(self): - path = self.repo / "decisions" / "DR-005.md" - path.write_text("# DRAFT — NO AUTHORITY\n\nRevision ratified | 0.8\n", - encoding="utf-8", newline="\n") + control = self.current_control() + path = self.repo / control["ratifying_path"] + path.write_text( + f"# DRAFT — NO AUTHORITY\n\nRevision ratified | {control['revision']}\n", + encoding="utf-8", newline="\n") self.assert_fails(self.check(), "markers") class DoctrineRatificationTests(DistributionTestCase): - def test_current_revision_resolves_to_dr005_ratified_0_8(self): + def test_current_revision_resolves_to_its_ratifying_decision_record(self): + control = self.current_control() result = self.check() self.assertEqual(result.returncode, 0, result.stdout) - self.assertIn("doctrine revision 0.8", result.stdout) + self.assertIn(f"doctrine revision {control['revision']}", result.stdout) self.assertIn("DC.1 status 'Ratified'", result.stdout) + self.assertTrue( + (self.repo / control["ratifying_path"]).is_file(), + f"{control['ratifying_path']} does not exist", + ) bundled = (self.repo / "skills" / "writwall-adopt" / "references" / "DOCTRINE.md").read_bytes() canonical = (self.repo / "DOCTRINE.md").read_bytes() self.assertEqual(bundled, canonical) - def test_second_dr_row_claiming_0_8_ratified_is_ambiguous_and_fails(self): + def test_second_dr_row_claiming_current_revision_ratified_is_ambiguous_and_fails(self): """resolve_ratification_record is fail-closed: exactly one decisions/ - DR-*.md record may name '| Revision ratified | 0.8 |'. A second one - makes the ratification record ambiguous rather than picked by name.""" - duplicate = self.repo / "decisions" / "DR-006.md" + DR-*.md record may name '| Revision ratified | |'. A second + one makes the ratification record ambiguous rather than picked by + name. Uses filename "DR-999.md", chosen because it never collides + with a real, numbered decision record -- this must never overwrite + the actual current ratification record the fixture already carries. + """ + control = self.current_control() + duplicate = self.repo / "decisions" / "DR-999.md" + self.assertFalse( + duplicate.exists(), + "fixture filename collides with a real decision record", + ) duplicate.write_text( - "# DR-006: Duplicate ratification claim (fixture)\n\n" + "# DR-999: Duplicate ratification claim (test fixture)\n\n" "| Field | Value |\n" "|---|---|\n" - "| Record | DR-006, methodology-source decision |\n" + "| Record | DR-999, methodology-source decision (test fixture) |\n" "| Owner | HLLMR |\n" - "| Date | 2026-08-21 |\n" - "| Revision ratified | 0.8 |\n" - "| Supersedes | 0.7 |\n", + f"| Date | {control['effective_date']} |\n" + f"| Revision ratified | {control['revision']} |\n" + "| Supersedes | n/a |\n", encoding="utf-8", newline="\n") result = self.check() self.assert_fails(result, "markers") @@ -609,9 +748,16 @@ def test_bundled_0_6_to_0_7_guide_exists_matches_and_drift_fails(self): self.assert_fails(self.check(), "bundle") def test_footer_still_calling_it_a_candidate_fails(self): - self.edit("DOCTRINE.md", "*Revision 0.8. Ratified 2026-08-21 by DR-005.", - "*Revision 0.8. Ratification candidate.") - self.assert_fails(self.check(), "markers") + control = self.current_control() + self.edit("DOCTRINE.md", control["footer_line"], + f"*Revision {control['revision']}. Ratification candidate.*") + result = self.check() + self.assert_fails(result, "markers") + self.assertIn( + f"DOCTRINE.md footer still calls {control['revision']} a candidate " + "while DC.1 records it as ratified", + result.stdout, + ) def test_readme_still_calling_it_a_candidate_fails(self): readme = self.repo / "README.md" @@ -620,10 +766,13 @@ def test_readme_still_calling_it_a_candidate_fails(self): self.assert_fails(self.check(), "markers") def test_ratified_claim_while_candidate_fails(self): + control = self.current_control() self.make_candidate() readme = self.repo / "README.md" - readme.write_text(readme.read_text(encoding="utf-8") + - "\nThis is the ratified revision 0.8.\n", encoding="utf-8", newline="\n") + readme.write_text( + readme.read_text(encoding="utf-8") + + f"\nThis is the ratified revision {control['revision']}.\n", + encoding="utf-8", newline="\n") self.assert_fails(self.check(), "markers") def test_missing_ratification_draft_fails_while_candidate(self): @@ -732,6 +881,7 @@ def test_clean_bundle_carries_only_skill_and_declared_copies(self): "references/migration-guides/0.1-to-0.6.md", "references/migration-guides/0.6-to-0.7.md", "references/migration-guides/0.7-to-0.8.md", + "references/migration-guides/0.8-to-0.9.md", "references/name-clearance.md", ]) @@ -991,6 +1141,61 @@ def test_historical_reports_are_not_rewritten(self): self.assertEqual(self.check().returncode, 0) +class DoctrineBodyCandidateContradictionRegressionTests(DistributionTestCase): + """DOCTRINE.md remains in CANDIDATE_SCAN_DOCUMENTS; only clause 7.12.1's + own known-normative text is exempted, and only by its actual position in + the document, never the whole document and never every occurrence of a + candidate phrase. Each test method below gets its own clean fixture copy + from `setUp` and injects independently, so neither case's assertion can + be satisfied by the other case's leftover injected text. Each mirrors + its injected sentence into the bundled copy so only the markers + contradiction is exercised, never an incidental bundle-drift failure. + """ + + ANCHOR = ( + "The doctrine is a governance methodology for building software " + "with AI agents without losing control of intent, scope, or truth." + ) + + def inject(self, replacement: str) -> None: + self.edit("DOCTRINE.md", self.ANCHOR, replacement) + self.edit( + "skills/writwall-adopt/references/DOCTRINE.md", + self.ANCHOR, replacement) + + def test_is_a_candidate_phrase_outside_dc1_dc2_footer_is_caught(self): + """The original case, unrelated to the 7.12.1 exemption's wording at + all -- this must never regress.""" + control = self.current_control() + self.inject(self.ANCHOR + f" Revision {control['revision']} is a candidate.") + result = self.check() + self.assert_fails(result, "markers") + + def test_7121_phrase_quoted_outside_its_own_clause_is_caught(self): + """The exact counterexample a positionally-unscoped exemption would + miss: quoting 7.12.1's benign phrase itself ("a draft not yet + ratified or activated") in an ordinary sentence OUTSIDE clause + 7.12.1 -- before Part 1 -- falsely claiming the Doctrine document is + unratified. A whole-document string or regex exemption misses this; + a clause-scoped one still catches it. This is a coverage-isolation + correction, not a claim that the current, already-scoped + implementation will fail it; the Coordinator has already separately + observed this exact counterexample RED against the prior, + unscoped implementation and GREEN against the current one. + """ + self.inject( + self.ANCHOR + + " This Doctrine revision is a draft not yet ratified or activated." + ) + result = self.check() + self.assert_fails(result, "markers") + self.assertIn( + "DOCTRINE.md still describes the revision with 'not yet ratified' " + "while DC.1 records it as ratified", + result.stdout, + ) + + class ArchiveProvenanceTests(DistributionTestCase): BLOB = "9cf9aa5f188a5351d4c12b53763b4c3c4688ba28efefb57a284a2fcf120e74ab" BASELINE = "6e165e585f907baf83a787ba5cc71270a5a4652e" @@ -1178,7 +1383,7 @@ def test_readme_banner_and_repository_chrome_are_release_ready(self): for chrome in ( "actions/workflows/ci.yml/badge.svg", "img.shields.io/github/v/release/HLLMR/writwall", - "doctrine-0.8", + "doctrine-0.9", "security-policy", 'href="#try-it-in-five-minutes">Five-minute start', 'href="#how-writwall-differs">How it differs', @@ -1381,18 +1586,26 @@ def test_inception_name_clearance_gate_is_public_and_evidence_backed(self): class RatifiedReleaseTests(DistributionTestCase): - """Every ratification marker, and the package name, must agree.""" + """Every ratification marker, and the package name, must agree. + + Expectations are derived from this fixture's own current document + control (revision, footer, ratifying record path, effective date) + rather than a hardcoded revision string, so they remain meaningful + across a future ratified transition instead of silently going stale. + """ def test_all_markers_agree(self): + control = self.current_control() doctrine = (self.repo / "DOCTRINE.md").read_text(encoding="utf-8") self.assertIn("| Status | Ratified |", doctrine) - row = next(l for l in doctrine.splitlines() if l.startswith("| 0.8 |")) + row = next(l for l in doctrine.splitlines() + if l.startswith(f"| {control['revision']} |")) self.assertTrue(row.rstrip().endswith("| Yes |"), row) - self.assertIn("*Revision 0.8. Ratified 2026-08-21 by DR-005.", doctrine) + self.assertIn(control["footer_line"], doctrine) - record = (self.repo / "decisions" / "DR-005.md").read_text(encoding="utf-8") + record = (self.repo / control["ratifying_path"]).read_text(encoding="utf-8") self.assertIn("HLLMR", record) - self.assertIn("2026-08-21", record) + self.assertIn(control["effective_date"], record) self.assertNotIn("DRAFT — NO AUTHORITY", record) for name in ("README.md", "ADOPTING.md"): @@ -1400,17 +1613,23 @@ def test_all_markers_agree(self): self.assertNotIn("ratification candidate", text, name) def test_builder_produces_the_final_release_name(self): + control = self.current_control() result = self.build() self.assertEqual(result.returncode, 0, result.stderr) archives = sorted((self.repo / "dist").glob("*.zip")) - self.assertEqual([a.name for a in archives], ["writwall-0.8.zip"]) + self.assertEqual([a.name for a in archives], + [f"writwall-{control['revision']}.zip"]) def test_final_archive_passes_the_archive_check(self): + control = self.current_control() self.build() - result = self.check("--archive", "dist/writwall-0.8.zip") + result = self.check("--archive", f"dist/writwall-{control['revision']}.zip") self.assertEqual(result.returncode, 0, result.stdout) def test_candidate_name_is_refused_once_ratified(self): + """Historical fixture: 0.6-rc is a fixed disposable archive name for + this negative case, independent of the fixture's actual current + revision, so it is deliberately not derived from current_control().""" out = self.repo / "dist" out.mkdir(exist_ok=True) with zipfile.ZipFile(out / "writwall-0.6-rc.zip", "w") as archive: @@ -1420,11 +1639,13 @@ def test_candidate_name_is_refused_once_ratified(self): self.assert_fails(self.check("--archive", "dist/writwall-0.6-rc.zip"), "archive") def test_candidate_state_still_produces_rc(self): + control = self.current_control() self.make_candidate() result = self.build() self.assertEqual(result.returncode, 0, result.stderr) archives = sorted((self.repo / "dist").glob("*.zip")) - self.assertEqual([a.name for a in archives], ["writwall-0.8-rc.zip"]) + self.assertEqual([a.name for a in archives], + [f"writwall-{control['revision']}-rc.zip"]) def adopt_fixture(repo): @@ -1933,9 +2154,10 @@ def build_and_open(self): return archives[0] def test_candidate_name_while_unratified(self): + control = self.current_control() self.make_candidate() archive = self.build_and_open() - self.assertEqual(archive.name, "writwall-0.8-rc.zip") + self.assertEqual(archive.name, f"writwall-{control['revision']}-rc.zip") def test_single_top_level_directory(self): archive = self.build_and_open() @@ -2003,23 +2225,26 @@ def test_built_archive_passes_the_archive_check(self): self.assertEqual(result.returncode, 0, result.stdout) def test_final_release_name_only_when_both_markers_ratified(self): + control = self.current_control() self.make_candidate() self.set_dc1_status("Ratified") - self.set_dc2_ratified("Yes") + self.set_dc2_ratified("Yes", control["revision"]) archive = self.build_and_open() - self.assertEqual(archive.name, "writwall-0.8.zip") + self.assertEqual(archive.name, f"writwall-{control['revision']}.zip") def test_candidate_name_when_only_dc2_flipped(self): # DC.2 says ratified, DC.1 still a candidate: not a release. + control = self.current_control() self.set_dc1_status("Ratification candidate") archive = self.build_and_open() - self.assertEqual(archive.name, "writwall-0.8-rc.zip") + self.assertEqual(archive.name, f"writwall-{control['revision']}-rc.zip") def test_candidate_name_when_only_dc1_flipped(self): # DC.1 says ratified, DC.2 still pending: not a release. + control = self.current_control() self.set_dc2_ratified("Pending") archive = self.build_and_open() - self.assertEqual(archive.name, "writwall-0.8-rc.zip") + self.assertEqual(archive.name, f"writwall-{control['revision']}-rc.zip") class ArchiveCheckFailureTests(DistributionTestCase): diff --git a/tests/test_public_projection.py b/tests/test_public_projection.py index 040f29d..ae1dd71 100644 --- a/tests/test_public_projection.py +++ b/tests/test_public_projection.py @@ -496,6 +496,63 @@ def test_builder_qualifies_dr005_report_reference_in_candidate_only(self) -> Non encoding="utf-8") self.assertIn("private governed-source reference", projected) + def test_builder_qualifies_dr006_report_reference_in_candidate_only(self) -> None: + """Historically RED: `decisions/DR-006.md` was not yet in either + `PRIVATE_RETAINED_REFERENCE_FILES` set (builder and checker), so a + synthetic omitted-report reference inside a projected `DR-006.md` was + not qualified by the builder and the checker did not accept it; + coordinator-observed RED before the corresponding addition to both + sets. Now GREEN: `decisions/DR-006.md` is in both sets, and this + mirrors `test_builder_qualifies_dr005_report_reference_in_candidate_only` + exactly, using the existing synthetic builder/checker fixture + (`self.allow` / `self.run_builder` / `self.run_checker`) and a + synthetic reference string only -- never a real historical target or + DR-006's actual content, which this test does not read. The + canonical fixture source bytes are asserted unchanged; the checker + is required to accept the projected, qualified reference. + """ + source_text = ("See `governance/reports/WO-WW-099-SYNTHETIC-report.md` " + "for the underlying evidence.\n") + self.allow("decisions/DR-006.md", source_text) + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + self.assertEqual((self.source / "decisions" / "DR-006.md").read_text( + encoding="utf-8"), source_text) + projected = (self.output / "decisions" / "DR-006.md").read_text( + encoding="utf-8") + self.assertIn("private governed-source reference", projected) + + def test_builder_qualifies_state_report_reference_in_candidate_only(self) -> None: + """Historically RED: `governance/STATE.md` was not yet in either + `PRIVATE_RETAINED_REFERENCE_FILES` set (builder and checker), so a + synthetic omitted-report reference inside a projected `STATE.md` was + not qualified by the builder and the checker did not accept it; + coordinator-observed RED before the corresponding addition to both + sets. Now GREEN: `governance/STATE.md` is in both sets, and this + mirrors `test_builder_qualifies_dr006_report_reference_in_candidate_only` + exactly, using the existing synthetic builder/checker fixture + (`self.allow` / `self.run_builder` / `self.run_checker`) and a + synthetic reference string only -- never a real historical target or + this repository's actual STATE.md content, which this test does not + read. The canonical fixture source bytes are asserted unchanged, and + the existing state-snapshot note (WO-PL-029 B.3.2 item 1) is present + in the projection alongside the retained-reference qualification -- + this addition did not weaken or remove it. + """ + source_text = ("# State\n\nSee `governance/reports/WO-WW-099-SYNTHETIC-report.md` " + "for the underlying evidence.\n") + self.allow("governance/STATE.md", source_text) + self.assertEqual(self.run_builder().returncode, 0) + checked = self.run_checker() + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + self.assertEqual((self.source / "governance" / "STATE.md").read_text( + encoding="utf-8"), source_text) + projected = (self.output / "governance" / "STATE.md").read_text( + encoding="utf-8") + self.assertIn("snapshot of the private governed source", projected) + self.assertIn("private governed-source reference", projected) + def test_retained_archive_reference_with_target_project_note_passes(self) -> None: self.allow("NOTES.md", "Create `archive/project-history.md` " @@ -667,6 +724,70 @@ def test_projection_checker_runs_candidate_distribution_gate(self) -> None: self.assertNotEqual(checked.returncode, 0) self.assertIn("distribution", (checked.stdout + checked.stderr).lower()) + def test_real_source_projection_includes_dr006_and_the_08_to_09_guide_pair(self) -> None: + """A projection built from the actual current source must carry + `decisions/DR-006.md`, `migration-guides/0.8-to-0.9.md`, and its + bundled copy. This proves membership and payload presence only -- it + does not depend on `identity/legacy-references.json`'s digests being + refreshed yet, and it reads no excluded target. Uses the existing + real-source builder fixture (`source=REPO_ROOT`) with the controlled + synthetic private-pattern input already set up in `setUp` + (`self.patterns`), never the managed OS-local privacy profile. + + The two migration guides carry no retained-reference to an omitted + path, so their projected bytes are required to equal the canonical + source bytes exactly. `decisions/DR-006.md` is different: it is + already, correctly, subject to the just-approved retained-reference + qualification transform (its own "Candidate transcribed from" line + names a `governance/reports/` path the candidate omits), so the + projection is expected to differ from the canonical file by exactly + that already-tested qualification note, not to be byte-identical. + For DR-006 this test asserts file presence, manifest membership, and + the existing qualification note's presence in the projected file -- + the exact transformed-byte contract itself is already the builder's + and checker's own responsibility, proven by the existing synthetic + DR-006 regression; this test does not call any internal transform + helper to fabricate an expected value, which would duplicate and + could silently drift from that already-tested contract. + + Only these three files' own canonical source bytes are confirmed + unchanged afterward; this makes no claim about the rest of the + source tree. + """ + guide_paths = ( + "migration-guides/0.8-to-0.9.md", + "skills/writwall-adopt/references/migration-guides/0.8-to-0.9.md", + ) + dr006_path = "decisions/DR-006.md" + canonical_paths = (*guide_paths, dr006_path) + source_bytes_before = { + relative: (REPO_ROOT / relative).read_bytes() for relative in canonical_paths + } + + built = self.run_builder(source=REPO_ROOT) + self.assertEqual(built.returncode, 0, built.stdout + built.stderr) + + for relative in guide_paths: + with self.subTest(path=relative): + projected = self.output / relative + self.assertTrue(projected.is_file(), f"{relative} missing from projection") + self.assertEqual(projected.read_bytes(), source_bytes_before[relative]) + + dr006_projected = self.output / dr006_path + self.assertTrue(dr006_projected.is_file(), f"{dr006_path} missing from projection") + self.assertIn( + "private governed-source reference", + dr006_projected.read_text(encoding="utf-8"), + ) + + manifest = (self.output / "PROJECTION-MANIFEST.sha256").read_text(encoding="utf-8") + for relative in canonical_paths: + self.assertIn(f" {relative}", manifest) + + for relative in canonical_paths: + self.assertEqual( + (REPO_ROOT / relative).read_bytes(), source_bytes_before[relative]) + def test_real_public_surface_builds_and_passes_integrated_checks(self) -> None: built = self.run_builder(source=REPO_ROOT) self.assertEqual(built.returncode, 0, built.stdout + built.stderr) diff --git a/tests/test_start_writwall.py b/tests/test_start_writwall.py index 0675f7b..e998381 100644 --- a/tests/test_start_writwall.py +++ b/tests/test_start_writwall.py @@ -455,6 +455,221 @@ def test_unnamed_idea_emits_complete_unratified_architect_packet_set(self): text = (self.output / relative).read_text(encoding="utf-8") self.assertIn("unratified", text.lower(), relative) + def test_generated_packets_state_the_full_role_coordination_contract(self): + """The generated role-packet set expresses the ratified Doctrine 0.9 + coordination contract that the independent Reviewer's B1/B2/B3 and + R2/R3/R5 findings identified as missing, proven through the actual + emitted bytes of one ordinary public `writwall start` invocation -- + never an internal constant or a mocked collaborator. + + Markdown packet text is checked whitespace-normalized (as the + delegation-visibility test above already does for CLI stdout), + because Markdown line-wrapping is immaterial public formatting, not + required content; a phrase that happens to wrap across an emitted + line must still be found. `discovery.json` and `intake.json` are + checked on their raw bytes and parsed as JSON, so contamination and + validity are both verified against the actual machine-readable + output, not a normalized copy of it. + """ + result = self.run_idea_start() + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + + def flat(relative): + text = (self.output / relative).read_text(encoding="utf-8") + return " ".join(text.split()) + + architect = flat("ARCHITECT.md") + general = flat("GENERAL.md") + operator = flat("OPERATOR.md") + reviewer = flat("REVIEWER.md") + + # B1: Doctrine 7.12 reporting headers, with the status enum + # actually named, bind the Architect, General, Operator, and + # Reviewer whenever addressing the Owner directly (7.12.4). + for label, text in ( + ("ARCHITECT.md", architect), ("GENERAL.md", general), + ("OPERATOR.md", operator), ("REVIEWER.md", reviewer), + ): + with self.subTest(packet=label): + self.assertIn("one-line header", text) + self.assertIn("no active work order", text) + self.assertIn("proposed", text) + + # B1 negative: the header is instruction for Owner-facing replies, + # never a line inside machine-readable output (7.12.4), and the + # JSON it might have contaminated must still parse cleanly, checked + # on raw bytes rather than a normalized copy. + discovery_text = (self.output / "discovery.json").read_text(encoding="utf-8") + self.assertNotIn("one-line header", discovery_text) + json.loads(discovery_text) + intake_text = (self.output / "intake.json").read_text(encoding="utf-8") + self.assertNotIn("one-line header", intake_text) + json.loads(intake_text) + + # B2: Reviewer independence (7.6.4) -- the brief is addressed to + # the Owner and only conveyed, never filtered, through the + # Architect, with the Owner retaining standing access to the + # complete original findings. + self.assertIn("conveyed", reviewer) + self.assertIn( + "may not suppress, rewrite, condition, delay, or waive", reviewer) + self.assertIn("standing access", reviewer) + + # B3: a finite execution mandate, never standing authority + # (7.10.1, 7.10.4, 7.10.7), as the explicit counterweight to + # "perform every mechanically available authorized step." + self.assertIn("is not execution approval", general) + self.assertIn("fresh Owner approval", general) + self.assertIn("never activate, expand, or manufacture", general) + + # R2: RFI severity classes (7.11.1) and blocking-dependency + # treatment (7.11.2), on the function that actually files RFIs. + self.assertIn("informational clarification", operator) + self.assertIn("resolvable execution problem", operator) + self.assertIn( + "blocking scope, authority, or safety contradiction", operator) + + # R3: delegated conforming-completion disposition (2.33, 7.10.6) + # -- acceptance stays the Owner's absent a separately ratified + # policy, and rework/deviation ratification are never delegable. + self.assertIn("delegated conforming-completion disposition", general) + self.assertIn("never delegable", general) + + # R5: the five distinguishable handoff states (7.11.5) and + # relayed-message provenance (7.11.6). + for state in ("prepared", "sent", "acknowledged", "returned", "reviewed"): + with self.subTest(handoff_state=state): + self.assertIn(state, general) + self.assertIn("relayed", general) + + def test_direct_continuation_prompts_name_the_reporting_header_for_their_own_role(self): + """The family of directly-continuing/re-entering role prompts -- the + recovery coordinator (partial bootstrap), the Implementer (active + work order), and the re-entering Architect (`inspect --role + architect` on an already-adopted project) -- each instructs ITS OWN + invoked role to open Owner-facing replies with the Doctrine 7.12.1 + header, proven from the actual emitted prompt text for that + lifecycle state. + + Each fixture is checked independently and each assertion targets + only that state's own emitted prompt text, never aggregate stdout + that could also contain an unrelated role's own prompt. This + deliberately avoids the "prepared-intake trap": the clean/new + Architect prepared-intake prompt previews the General's own prompt + text at its end, so an assertion against that aggregate stdout could + be satisfied by the General's instructions rather than the + Architect's own -- none of the three fixtures below embed another + role's full prompt, so no such collision is possible here. + """ + # 1. partial_bootstrap -> recovery-coordinator prompt (standalone). + settings = self.project / ".claude" / "settings.json" + settings.parent.mkdir(parents=True) + settings.write_text("{}\n", encoding="utf-8") + recovery_result = self.run_lifecycle_start() + self.assertEqual( + recovery_result.returncode, 0, + recovery_result.stdout + recovery_result.stderr) + self.assertIn("Act as a fresh recovery coordinator", recovery_result.stdout) + self.assertIn("one-line header", recovery_result.stdout) + + # 2. active_work_order -> Implementer prompt (standalone). + implementer_project = self.temp / "active-work-order-project" + implementer_project.mkdir() + work_order = (implementer_project / "governance" / "work-orders" + / "WO-001.md") + work_order.parent.mkdir(parents=True) + work_order.write_text( + "---\nid: WO-001\nstatus: ACTIVE\n---\n# Work\n", encoding="utf-8") + pointer = implementer_project / ".claude" / "active-wo.txt" + pointer.parent.mkdir(parents=True) + pointer.write_text( + "governance/work-orders/WO-001.md\n", encoding="utf-8") + implementer_result = self.run_lifecycle_start(implementer_project) + self.assertEqual( + implementer_result.returncode, 0, + implementer_result.stdout + implementer_result.stderr) + self.assertIn( + "Act as a fresh Implementer for the active work order only", + implementer_result.stdout) + self.assertIn("one-line header", implementer_result.stdout) + + # 3. adopted_lockout -> re-entering Architect via `inspect --role + # architect` (standalone; does not embed the General's own prompt). + adopted_project = self.temp / "adopted-lockout-project" + adopted_project.mkdir() + governance = adopted_project / "governance" + governance.mkdir() + for name in ("PLAN.md", "STATE.md", "ROUTING.md"): + (governance / name).write_text(f"# {name}\n", encoding="utf-8") + decision = governance / "decisions" / "DR-001.md" + decision.parent.mkdir() + decision.write_text(ratified_adoption_record(), encoding="utf-8") + architect_result = self.run_inspect("architect", adopted_project) + self.assertEqual( + architect_result.returncode, 0, + architect_result.stdout + architect_result.stderr) + self.assertIn("Selected role: Fresh Architect", architect_result.stdout) + self.assertIn("one-line header", architect_result.stdout) + + def test_empty_project_architect_prompts_place_the_header_before_the_invitation(self): + """For a genuinely empty project, both `ARCHITECT_EMPTY_PROJECT_PROMPT` + (the zero-flag `writwall start` conversation-first handoff) and the + empty-project branch of `_architect_inspection_prompt` (`writwall + inspect --role architect`) instruct the invoked Architect to open + with the exact invitation "Tell me what you are thinking." AND to + begin every Owner-facing reply with the Doctrine 7.12.1 header. + Neither instruction exempts the other: the reconciliation keeps the + invitation as the opening conversational QUESTION, stated explicitly + as coming after the required header, rather than merely relying on + sentence order elsewhere in the text. This asserts the actual + reconciling phrase joining the two instructions, not just that a + header substring happens to appear before an invitation substring + somewhere unrelated in the same text. + + The two surfaces use two separate, genuinely empty project fixtures. + `inspect` runs on its own untouched fixture (never one `start` has + already written a `.writwall-bootstrap/` into, which would reclassify + it as `partial_bootstrap` and route to the recovery coordinator + instead of the intended empty-project Architect branch); each result + confirms the observed lifecycle and branch before checking sequence. + """ + reconciling_phrase = ( + 'After that required status header, begin the conversational body ' + 'as follows. Open with exactly: "Tell me what you are thinking."' + ) + + # Surface 1: zero-flag `writwall start` on a genuinely empty project + # writes the conversation-first prompt into HANDOFF.md. + start_result = self.run_lifecycle_start() + self.assertEqual( + start_result.returncode, 0, start_result.stdout + start_result.stderr) + handoff = self.handoff() + self.assertIn("Tell me what you are thinking.", handoff) + self.assertIn("one-line header", handoff) + self.assertIn(reconciling_phrase, handoff) + + # Surface 2: `writwall inspect --role architect` on a distinct, + # untouched empty project -- run first on that fixture, never after + # `start` has already created a bootstrap there. + inspect_project = self.temp / "empty-inspect-project" + inspect_project.mkdir() + inspect_result = self.run_inspect("architect", inspect_project) + self.assertEqual( + inspect_result.returncode, 0, + inspect_result.stdout + inspect_result.stderr) + self.assertIn("Observed lifecycle state: clean_new", inspect_result.stdout) + self.assertIn( + "Act as the Architect for a new, empty project.", inspect_result.stdout, + "expected the empty-project branch, not the existing-project branch", + ) + self.assertIn("Tell me what you are thinking.", inspect_result.stdout) + self.assertIn("one-line header", inspect_result.stdout) + self.assertIn(reconciling_phrase, inspect_result.stdout) + self.assertFalse( + (inspect_project / starter_module.OUTPUT_NAME).exists(), + "inspect must remain zero-write even on an empty project", + ) + def test_observed_boundaries_select_different_smallest_credible_topologies(self): local = self.run_idea_start() self.assertEqual(local.returncode, 0, local.stdout + local.stderr) @@ -1119,6 +1334,38 @@ def test_adopted_lockout_routes_to_fresh_general(self): self.assertIn("Do not ask for the same decision again", flat) self.assertIn("perform every mechanically available authorized step", flat) + def test_general_handoff_announces_delegation_visibility_contract(self): + """RED: the emitted fresh-General handoff must make delegation visible. + + Doctrine 0.9 7.11.5 defines distinguishable handoff states (prepared/ + sent/acknowledged/returned/reviewed) and states plainly that a status + not actually observed is reported as unknown, never inferred as + favorable. The Owner separately identified invisible delegation as a + usability gap: within the existing handoff surface, the General must + announce the delegated role and bounded task, name a discoverable + monitoring location or state that none exists, identify the last + verified execution/handoff state, and name the result/question + return route. This is existing-surface instruction clarity (7.11.5, + 7.12), not a new task UI or scheduler, so it is proven the same way + every other generated-prompt behavior here is proven: through the + emitted bytes of the existing public generator/inspect interface. + """ + governance = self.project / "governance" + governance.mkdir() + for name in ("PLAN.md", "STATE.md", "ROUTING.md"): + (governance / name).write_text(f"# {name}\n", encoding="utf-8") + decision = governance / "decisions" / "DR-001.md" + decision.parent.mkdir() + decision.write_text(ratified_adoption_record(), encoding="utf-8") + result = self.run_lifecycle_start() + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + self.assertIn("Act as a fresh General", result.stdout) + flat = " ".join(result.stdout.split()) + self.assertIn("announce the delegated role and bounded task", flat) + self.assertIn("monitoring location", flat) + self.assertIn("last verified execution/handoff state", flat) + self.assertIn("result/question return route", flat) + def test_inspect_architect_reenters_adopted_lockout_without_writes(self): governance = self.project / "governance" governance.mkdir()