Skip to content

D1.24: remove the Rust tree from main - #166

Merged
Hafeok merged 15 commits into
mainfrom
claude/lucid-hamilton-jxk6pv
Nov 3, 2026
Merged

Hafeok merged 15 commits into
mainfrom
claude/lucid-hamilton-jxk6pv

Conversation

@Hafeok

@Hafeok Hafeok commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #165

The first rewrite pull request, as D1.24`` rules. It carries out the approved plan.

The Rust tree stays readable at rust-final

Everything this PR removes stays readable at the tag rust-final (tag object d0cf1f1ec40eb55c271b8d4dadfefcd260c03312, commit 70395dfe317cb9a00665433813766ca763f3c58a, verified by GitHub). Nothing at the tag changes, and the published Rust releases, up to v0.7.0, keep working.

The removal is one commit, 95bb957, made before anything was moved, renamed or edited. It deletes 1,937 files:

  • every crate;
  • the workspace files;
  • schema/, spec/, conventions/, examples/, scripts/ and docs/;
  • the .product/, .decisions/ and .ddd/ stores;
  • .claude/, .mcp.json, .htmlvalidate.json and .stylelintrc.json;
  • the three Rust workflows;
  • CLAUDE.md;
  • two files beyond the brief's list, as the plan said: .gitignore and .github/copilot-instructions.md.

There was no Cargo.lock to remove. LICENSE and README.md are replaced in their own commits.

No decision is lost. docs/decisions/hafeok.ddd.nt and hafeok.ledger.nt are the Rust ledger's exports, and they leave with the tree. writ import reads the ledger (.decisions/) at rust-final.

The licence

LICENSE is now Apache-2.0: the apache.org text, unedited and byte-identical to Writ's (sha256 cfc7749b…bc523d30). It replaces MIT, and a NOTICE is added.

The MIT text stays at the tag and governs everything there: every commit up to rust-final, and the releases built from them.

Relicensing confirmed by the copyright holder (recorded verbatim in the session record's addendum):

“As copyright holder I relicense this repository from MIT to Apache-2.0 from this PR onward; MIT continues to govern everything at rust-final and earlier.”

Licence. Apache-2.0, from the commit after rust-final that replaced the licence. MIT governs everything at rust-final and before it, and the Rust tool’s releases.

That commit is 59553ee. NOTICE states the same boundary, and nothing in it changed.

Question. The brief says Apache-2.0 is "as the definition requires", but Draft 4 at fcda5ed names no licence anywhere. decision-driven-design's own code is MPL-2.0 (DDD-dec-79). So NOTICE doesn't claim the definition requires Apache-2.0. If the requirement should be in the definition, it is a decision-driven-design change.

What main holds after this PR

One commit each, in this order:

  • AGENTS.md, the single source for agents (ADR-0007). It includes the ADR numbering rule: the Rust workspace's own ADRs are cited as rust-final:conventions/adr/ADR-NNNN. Its never list is built from your answers, the definition and the ADRs.
  • CLAUDE.md, one line.
  • README.md.
  • LICENSE and NOTICE.
  • docs/decisions/:
    • the collected file, byte-identical to the attachment (sha256 3dcf7e5b…c096faffd);
    • ADR-0001 to ADR-0012, split verbatim;
    • the four Draft 4 notes, in their own commit so they read as a diff;
    • README.md, with the interim rule.
  • .github/workflows/gates.yml and eng/gates/.
  • releases/v0.8.0-preview.1.yaml. It names rust-final, and that no Rust release follows. The edition is sdlc: edition 1, pending. accepted-by is left for you.
  • docs/traceability/2026-11-03-issue-165-rust-removal.md. The model is "not recorded (ADR-0007 D1)". Its addendum holds the relicensing confirmation.

git ls-tree -r --name-only HEAD:

.github/workflows/gates.yml
AGENTS.md
CLAUDE.md
LICENSE
NOTICE
README.md
docs/decisions/ADR-0001-decisions-in-embedded-writ.md
docs/decisions/ADR-0002-layers.md
docs/decisions/ADR-0003-native-aot-single-binary.md
docs/decisions/ADR-0004-package-policy.md
docs/decisions/ADR-0005-node-kind-source-generator.md
docs/decisions/ADR-0006-tests-observe-bytes.md
docs/decisions/ADR-0007-commit-discipline.md
docs/decisions/ADR-0008-exporters-over-canonical-graph.md
docs/decisions/ADR-0009-rust-migration-acceptance.md
docs/decisions/ADR-0010-workbench-blazor-webassembly.md
docs/decisions/ADR-0011-proposals-and-dpp-decision-records.md
docs/decisions/ADR-0012-adopting-on-the-fly.md
docs/decisions/README.md
docs/decisions/collected-2026-11-03.md
docs/traceability/2026-11-03-issue-165-rust-removal.md
eng/gates/adr-shape.sh
eng/gates/adr-text.sh
eng/gates/commits.sh
eng/gates/no-toolchain.sh
eng/gates/selftest.sh
eng/gates/signatures.sh
releases/v0.8.0-preview.1.yaml

The gates

  • CI kept: none.
  • CI added: gates.yml, six jobs, each a Bash script in eng/gates/:
    • commits;
    • signatures;
    • adr-shape;
    • adr-text, which rebuilds the twelve files from the collected file, notes included, and compares bytes;
    • no-toolchain;
    • selftest.
  • No .NET solution, project or SDK pin. Those come in slice 0.

selftest changed after the plan in one respect. Each plant now names the finding it must produce, so a check that fails for another reason counts as a self-test failure. The first local run caught exactly that: every commit plant was failing because the script ran in the wrong repository.

Current head a9df5c4: all six jobs green in run 41627148468. d4ea57b was green too, in run 41627089375. The table and the selftest output below are from the first run, 41620431044, on 9f14362.

Job Result Output
commits success every commit in 70395df..9f14362 passes
signatures success 12 commit(s) verified, each verified (valid)
adr-shape success 12 ADRs have the shape
adr-text success 12 ADRs equal their sections of the collected file
no-toolchain success no toolchain file at the root
selftest success 5 clean cases pass; 31 plants fail, each with its finding

The selftest run. It shows the finding line for each plant, with the diff bodies trimmed:

selftest: clean  commits: passes
selftest: plant  commits: no Refs line: fails as it should
    commits: 82e813f: no 'Refs #N' line
selftest: plant  commits: no sign-off: fails as it should
    commits: f61f861: no 'Signed-off-by:' line
selftest: plant  commits: malformed sign-off: fails as it should
    commits: b023b1c: malformed sign-off: Signed-off-by: Emil
selftest: plant  commits: sign-off by an agent address: fails as it should
    commits: 841c17d: sign-off does not name a person: Signed-off-by: Claude <noreply@anthropic.com>
selftest: plant  commits: model id in the message: fails as it should
    commits: 2b3fc9b: message names a model: 1:docs: written with gpt-9
selftest: plant  commits: model family in a trailer: fails as it should
    commits: 2718f3a: message names a model: 6:Co-Authored-By: Claude Opus 9.9 <someone@example.invalid>
selftest: plant  commits: co-author at a model vendor: fails as it should
    commits: b188024: co-author trailer names a model vendor: 6:Co-Authored-By: Claude <noreply@anthropic.com>
selftest: plant  commits: model id in the author name: fails as it should
    commits: 6ce2269: author or committer names a model: Bot gpt-9 <planted@example.invalid>
selftest: plant  commits: an empty range: fails as it should
    commits: no commits in e988407…..e988407…
selftest: clean  signatures: passes
selftest: plant  signatures: an unsigned commit: fails as it should
    signatures: cccccccccccc NOT verified (unsigned)
selftest: plant  signatures: a signature GitHub cannot verify: fails as it should
    signatures: dddddddddddd NOT verified (bad_email)
selftest: plant  signatures: no commits: fails as it should
    signatures: no commits to check
selftest: clean  adr-shape: passes
selftest: plant  adr-shape: no status: fails as it should
    adr-shape: ADR-0003-native-aot-single-binary.md: no '**Status:**' line with a status
selftest: plant  adr-shape: no alternatives: fails as it should
    adr-shape: ADR-0004-package-policy.md: no '## Alternatives considered' section
selftest: plant  adr-shape: no consequences: fails as it should
    adr-shape: ADR-0005-node-kind-source-generator.md: no '## Consequences' section
selftest: plant  adr-shape: a number that is not the file's: fails as it should
    adr-shape: ADR-0006-tests-observe-bytes.md: first line is not '# ADR-0006: <title>'
selftest: plant  adr-shape: two ADRs with one number: fails as it should
    adr-shape: ADR-0007-commit-discipline.md: number 0007 is also ADR-0007-commit-discipline-again.md
selftest: plant  adr-shape: a file that is not an ADR: fails as it should
    adr-shape: notes.md: not an ADR file name (ADR-NNNN-<slug>.md)
selftest: clean  adr-text: passes
selftest: plant  adr-text: one word edited: fails as it should
    adr-text: …/ADR-0002-layers.md differs from its section of …/collected-2026-11-03.md:
    -# ADR-0002: Fixed layers, dependencies strictly downward
    +# ADR-0002: Fixed layers, dependencies strictly downwards
selftest: plant  adr-text: a trailing newline added: fails as it should
    adr-text: …/ADR-0010-workbench-blazor-webassembly.md differs from its section of …
selftest: plant  adr-text: a note removed: fails as it should
    adr-text: …/ADR-0001-decisions-in-embedded-writ.md differs from its section of …
selftest: plant  adr-text: a note on an ADR the preamble does not list: fails as it should
    adr-text: …/ADR-0002-layers.md differs from its section of …
selftest: plant  adr-text: an ADR file missing: fails as it should
    adr-text: ADR-0012: expected one file, found 0
selftest: clean  no-toolchain: passes
selftest: plant  no-toolchain: Cargo.toml: fails as it should
selftest: plant  no-toolchain: rust-toolchain.toml: fails as it should
selftest: plant  no-toolchain: package.json: fails as it should
selftest: plant  no-toolchain: pnpm-lock.yaml: fails as it should
selftest: plant  no-toolchain: pyproject.toml: fails as it should
selftest: plant  no-toolchain: requirements.txt: fails as it should
selftest: plant  no-toolchain: .python-version: fails as it should
selftest: plant  no-toolchain: .cargo/: fails as it should
selftest: every check passes its clean case and fails every plant

The model ids above (gpt-9, Opus 9.9) are fictitious. selftest assembles them at run time from fragments, so neither the repository nor any commit in it contains one.

Commit verification, read through the REST API

SHA verified reason subject
95bb957052ff97d6b112b1a8eed921917021a9a0 true valid chore: remove the Rust tree from main (D1.24)
875a5130ea9bff45bc13e1523b6e58818d5ca0ab true valid docs: AGENTS.md, the single source for agents (ADR-0007)
48f5c9ad83971a3df49446660d7376ef547b6183 true valid docs: CLAUDE.md points to AGENTS.md
ed5008dfbe473bb2f8fc0ddc5741d0fb35065ad4 true valid docs: README.md for the rewrite
59553eee80d1660e0a1c5f03f55c009dc8b4c78b true valid licence: Apache-2.0 replaces MIT; add NOTICE
eb270d957e3fcdcab9eaef885ab71ee011e6584f true valid docs(decisions): the collected ADR text of 2026-11-03
cc827e09ee84bd461a6ca1bac767bf27a2c7dab0 true valid docs(decisions): ADR-0001 to ADR-0012, split from the collected file
3fd396b0b877a2aa5f4cc7e2484b15aff4d6e97a true valid docs(decisions): the Draft 4 notes on ADR-0001, 0008, 0009 and 0011
d3bdf88d127b3d71e8d01257c790f279a0f390dc true valid docs(decisions): README, the interim rule (D1.22)
2ffd36ae418562a3af303c2a89f37e9bd4189e9e true valid ci: gates.yml, the checks on every pull request
e14a897e3f780895f94dff40f8d069606d92b195 true valid releases: v0.8.0-preview.1, the rewrite begins
9f14362ef44dd0eb0f736a9f98c185672f2053c5 true valid docs(traceability): the session record for #165
d4ea57bf0a1535929619cac072152e6b694bc523 true valid docs(traceability): the relicensing confirmation, as an addendum
a9df5c4d21729357f12e7f22e1fb96292b8c87d7 true valid docs(traceability): the licence boundary, in the addendum

Disposition of the Rust tool's open work

I'll carry this out only after the merge, as approved on #165.

After your merge, the decision-driven-design PR opens as one commit with the row met and the merge SHA. It also carries step 0 and the D1.21 correction.

Developed with AI assistance under human review.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU

Hafeok and others added 15 commits November 3, 2026 10:24
The first rewrite pull request removes the Rust workspace from main, as
the product definition rules in D1.24 (Draft 4, decision-driven-design
fcda5ed). Every crate, the workspace files, schema/, spec/, conventions/,
examples/, scripts/, docs/, the .product/, .decisions/ and .ddd/ stores,
the agent configuration, the three Rust workflows, CLAUDE.md, .gitignore
and .github/copilot-instructions.md leave in this one commit; nothing was
moved, renamed or edited first.

Everything removed stays readable at the tag rust-final (tag object
d0cf1f1, commit 70395df). LICENSE and README.md stay here and are
replaced in their own commits.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
What the repository is, where the definition lives and the rule that a
definition change merges in decision-driven-design first, how ADRs are
numbered and cited, the gates, the commit and session rules, and the
never list.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
One line, which Claude Code also reads as an import of AGENTS.md.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
What the rewrite is, in two paragraphs from the definition's chapter 1;
that the Rust tool is frozen at rust-final and its releases keep working;
and a link to the definition.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
LICENSE is the Apache-2.0 text from apache.org, unedited (sha256
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30, the
same bytes as Writ's). NOTICE names the copyright holder and states that
the MIT licence keeps governing everything at rust-final and before. The
relicensing is confirmed in review by the copyright holder named in the
MIT file.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
product-cli-adrs.md as Emil supplied it, byte for byte (sha256
3dcf7e5b1a84363866b3f3abd198dfe7de721483a51810d75f50982c096faffd). It is
the source the adr-text check holds ADR-0001 to ADR-0012 against.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
One file per ADR, under the interim rule of D1.22. Each is its section of
docs/decisions/collected-2026-11-03.md with the heading promoted to # and
its subheadings to ##, outside code fences, and the separators between
sections dropped. The text is otherwise byte for byte. The Draft 4 notes
follow in their own commit.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
Each of the four ADRs whose rulings Draft 4 superseded or amended gets the
note that the collected file's preamble gives for it, as a blockquote
under its status lines headed "Note (2026-11-03, Draft 4)". The note is
the preamble's bullet with its ADR lead removed and its sub-bullets
de-indented one level. Nothing else in the four files changes.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
Review keeps ADR discipline until Writ #7; writ import reads these files
once it exists; every package entry carries Adr=. Also how ADRs are
numbered and cited, their shape, and how ADR-0001 to ADR-0012 are held
against the collected file.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
Six jobs, each a Bash script in eng/gates/ that runs locally the same way:

- commits: every commit carries Refs #N and a DCO sign-off naming a
  person, and names no model in its message, trailers, author or
  committer;
- signatures: GitHub reports every commit of the pull request verified;
- adr-shape: every file under docs/decisions/ is an ADR with its number,
  status, alternatives and consequences, or one of the two allowed files;
- adr-text: ADR-0001 to ADR-0012 equal their sections of the collected
  file, with the Draft 4 notes, byte for byte;
- no-toolchain: no Rust, Node or Python toolchain file at the root;
- selftest: each check fails on its plant, with the finding the plant is
  for, and passes its clean case.

The plants are built on the runner and never committed. No .NET
solution, project or SDK pin: those come in slice 0.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
The release descriptor, in Varve's shape. It names rust-final and that
no Rust release follows it, and the sdlc: edition this repository will
pin, edition 1, stated as pending until decision-driven-design tags it.
It ships no binary and is cut once slice 0 brings a release path.
accepted-by is left for the maintainer.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
The prompt and the approval, verbatim; what was read; what the session
found; the commits; the checks; and the deviations from the plan. In the
shape of Writ's records, with the model written as not recorded
(ADR-0007 D1).

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
The maintainer's statement, as copyright holder, that the repository is
relicensed from MIT to Apache-2.0 from this pull request onward, with MIT
governing everything at rust-final and earlier. Verbatim; nothing above
the addendum changes.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
The maintainer's exact statement of the boundary: Apache-2.0 from the
commit that replaced the licence (59553ee), MIT for everything at
rust-final and before it and for the Rust tool's releases. NOTICE already
states it.

Refs #165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
Signed-off-by: Emil Klein -  Claude Code AI <emil@okkels-klein.dk>
@Hafeok

Hafeok commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Approved at 53bd54758ba71f7a810f91ddf3a6c83d5e653145. As copyright holder I relicense this repository from MIT to Apache-2.0 from this PR onward; MIT continues to govern everything at rust-final and earlier.

This was referenced Nov 3, 2026
Hafeok added a commit to mindovermachine-dev/decision-driven-design that referenced this pull request Nov 3, 2026
…corrected, the licence (chapter 8)

The cross-repository table: the rust-final row is met, at tag object
d0cf1f1ec40eb55c271b8d4dadfefcd260c03312, and a new row records the Rust
tree removed from product-cli's main, met by
mindovermachine-dev/product-cli#166, merged at 53bd547. The README row is
unchanged.

D1.25 adds step 0 to chapter 7's order of work: slice 0, the repository
skeleton (ADR-0002, ADR-0003, ADR-0004), which needs no sdlc: edition.
The header now reads D1.16 to D1.25.

D1.21, the lift map: the "Attribute blank nodes" bullet is replaced. All
32 blank nodes become elements, keyed by owning subject, predicate and
their own sorted description; the 15 pf:hasAttribute nodes become
sdlc:Field and the 7 pf:offers and 10 pf:surfaces nodes become
sdlc:Interaction. The ULIDs and adopted wire names are stored in the map,
so lifting again reproduces the golden bytes.

The licence (chapter 8): a bullet under "Boundaries and decisions taken",
after Scope. Apache-2.0 from the commit after rust-final that replaced the
licence (59553ee, merged at 53bd547); MIT for everything at rust-final and
before it, and for the Rust tool's releases.

Basis: DDD-dec-72
Refs mindovermachine-dev/product-cli#165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU

Hafeok commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

The licence question is answered. This PR asked whether the definition should name the licence, because the brief said Apache-2.0 is "as the definition requires" and Draft 4 named none.

The definition now carries the answer as a bullet in chapter 8, "Boundaries and decisions taken", after Scope. The bullet arrives with mindovermachine-dev/decision-driven-design#57, commit a052ed94875c7a237929eb03ccaee9f77c52571d:

  • Licence. Apache-2.0, from the commit after rust-final that replaced the licence (59553ee, merged at 53bd547). MIT governs everything at rust-final and before it, and the Rust tool's releases.

It states the same boundary as this repository's NOTICE, so nothing here changes.


Generated by Claude Code

Hafeok added a commit to mindovermachine-dev/decision-driven-design that referenced this pull request Nov 3, 2026
…corrected, the licence (chapter 8)

The cross-repository table: the rust-final row is met, at tag object
d0cf1f1ec40eb55c271b8d4dadfefcd260c03312, and a new row records the Rust
tree removed from product-cli's main, met by
mindovermachine-dev/product-cli#166, merged at 53bd547. The README row is
unchanged.

D1.25 adds step 0 to chapter 7's order of work: slice 0, the repository
skeleton (ADR-0002, ADR-0003, ADR-0004), which needs no sdlc: edition.
The header now reads D1.16 to D1.25.

D1.21, the lift map: the "Attribute blank nodes" bullet is replaced. All
32 blank nodes become elements, keyed by owning subject, predicate and
their own sorted description; the 15 pf:hasAttribute nodes become
sdlc:Field and the 7 pf:offers and 10 pf:surfaces nodes become
sdlc:Interaction. The ULIDs and adopted wire names are stored in the map,
so lifting again reproduces the golden bytes.

The licence (chapter 8): a bullet under "Boundaries and decisions taken",
after Scope. Apache-2.0 from the commit after rust-final that replaced the
licence (59553ee, merged at 53bd547); MIT for everything at rust-final and
before it, and for the Rust tool's releases.

Basis: DDD-dec-72
Refs #58
Refs mindovermachine-dev/product-cli#165

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Claude-Session: https://claude.ai/code/session_01NbWSYSVJASSN4tw4nMJ9kU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant