Add a root-level contribution guide - #38
coderabbitai[bot] wants to merge 4 commits into
Conversation
D73-C ruled that `launcher-standard` converts to `.deed`, so this crate
needs to read the estate's live format. This commit adds the reader and
the evidence that it reads it correctly; nothing consumes it yet, so the
existing `.a2ml` path is untouched and the crate still builds standalone.
`deed.rs` is a hand-rolled recursive-descent parser over the DEED v1.0.0
ABNF — no `nom`, no `pest`. The grammar has exactly one ambiguity worth
naming: after a keyword, `(` opens a list (value position), while in a
clause body the same `(` opens a clause. Position resolves it, so the
parser never backtracks. Two other rules are easy to get wrong in the
permissive direction and are asserted rather than assumed:
- `symbol = ALPHA *( ... "=" ... )` — `=` is a legal symbol CHARACTER,
never a field separator, but a symbol must still start with a letter.
A parser that splits on `=` is reading TOML.
- order is not semantic. Precedence is an explicit `:priority` INTEGER
and consumers MUST sort ascending, so `children_by_priority` sorts
and the corpus carries a deliberately scrambled fixture to prove it.
The `:schema-version` rule lives in `parse()` rather than in any schema
layer, because the ABNF states it as a side condition on `form`: exactly
one field, STRING-valued. It need not be a semver — the upstream corpus
carries `:schema-version "not-string-issue"` as a VALID fixture.
The 15-file corpus is vendored from `standards` at c60abfaa with a
`MANIFEST.sha256` recording its provenance and refresh procedure, so
drift is detected rather than inherited. The manifest test compares the
SET of names, not a count, so an added or removed fixture is visible.
`every_invalid_fixture_is_rejected_for_the_right_reason` panics when a
new fixture has no expected-reason entry — "10 files are rejected" is
not the same claim as "10 files are rejected for their 10 named
reasons", and only the second is worth having.
Four mutants were reintroduced and each killed exactly the right test:
file-order `children_by_priority`, an unstable reversed sort, the tab
check disabled, and a permissive escape table. Green was restored after
each.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
Owner ruling D73-C converted `launcher-standard` to the estate's live
`.deed` format. The standards side merged as be6c9580, which opened a
silent-downgrade window: this crate still parsed the retired `.a2ml`,
so it could only ever see the baked copy. This closes it.
The vendored standard moves with the reader, and the retired
`launcher-standard.a2ml` is deleted in the same commit so no build can
resolve to it by accident.
Three defects are fixed rather than carried:
- `spec_version` now reads `:standard-version` ("0.4.0"). The document
also carries `:schema-version` ("1.0.0"), which is the version of
the DEED GRAMMAR. Reading it yields a confident wrong answer, and
because 1.0.0 sorts above 0.4.0 the mistake reads as an upgrade.
A test asserts the two are different values, so the trap cannot be
reintroduced silently.
- `resolve()` walked ONE hardcoded `/var/mnt/eclipse/...` path and
then fell through to the baked copy. On any host not using the
eclipse-mount layout that is a silent downgrade with no diagnostic.
It now walks the deed's own `(resolution)(standard-search)` ladder
in ascending `:priority`, and the baked fallback logs at `info!`
rather than `debug!` because it means the on-disk standard was not
found.
- An unset `$VAR` now SKIPS its rung. `unwrap_or_default()` would turn
`$HP_ESTATE_ROOT/standards/...` into `/standards/...` — a real
absolute path that could exist and is not what the standard named.
The single documented exception is `$XDG_DATA_HOME`, which the
deed's own `:note` says defaults to `$HOME/.local/share`; with
`$HOME` also unset that rung vanishes too.
`resolve()` delegates to `resolve_with(flag, env, exists)` so tests
inject closures. `std::env::set_var` is process-global while cargo runs
tests in parallel threads, so an env-mutating test corrupts its
neighbours instead of isolating itself.
A file that is still the old TOML is diagnosed by name and pointed at
standards#960, rather than reported as a deed syntax error — that would
send a reader hunting for a typo in a file that is simply the wrong
format. `include_str!` reaches outside this crate, so the vendored
standard is pinned by sha256; an edit in `standards/` would otherwise
change this binary with no diff here and no test naming it.
Three mutants were reintroduced and killed: reading `:schema-version`
(3 tests red), `unwrap_or_default()` on an unset var (1 test red), and
reading the ladder in file order (1 test red).
The third initially SURVIVED, and that is worth recording: the real
deed's rungs happen to be written 10, 20, 30, 40, 50, so sorting and
not-sorting are indistinguishable against it. The ordering test asserted
the right rule while being unable to detect its absence. The ladder
reader is now split out so the test can feed it a deliberately scrambled
document, and the test asserts the fixture is still scrambled so it
cannot lose its teeth to a later tidy-up.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
Commits 65d6893 and 7ab9fc5 converted the launcher standard to a praxis DEED and taught launch-scaffolder to read it. The documentation surface still described the old arrangement, and in two places was actively wrong rather than merely stale: - EXPLAINME.adoc linked to standards/launcher-standard.a2ml, which 7ab9fc5 deleted. That was a broken link. - README.adoc and EXPLAINME.adoc documented resolution as a three-step chain ending at one hardcoded absolute path. The tool now walks the search ladder the standard declares for itself, sorted by :priority. - README.adoc's "Why A2ML for inputs" promised a v0.2 migration TO A2ML "once a2ml-rs reaches feature parity". A2ML is retired estate-wide, so that is a plan to build on a dead format. META.a2ml records the change as ADR-010 and marks ADR-003 superseded rather than rewriting it; ADR-003 is the historical record of what was decided on 2026-04-10 and its text is left intact. ADR-010 also records the two hazards that are not visible from the code: the deed carries two version numbers (:schema-version is the grammar, :standard-version is the document), and the real deed lists its rungs already in ascending :priority order, so a consumer that ignores :priority cannot be detected by testing against it. Deliberately NOT converted here, and named so they read as deferred rather than missed: - the per-app <app>.launcher.a2ml config format -> standards#960 - the emitted @a2ml-metadata launcher header, a wire format shared by mint and realign; changing it strands launchers already on disk - docs/ruleset-audit-2026-04-10/ and docs/compliance-audit-2026-04-10.adoc, which are dated audit records and should not be rewritten References to launcher-standard.adoc are untouched: that prose spec still exists in standards and is a different file from the .a2ml that was retired. No behaviour change. 56 tests green, clippy -D warnings clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
|
Important Review skippedThis PR was authored by the user configured for CodeRabbit reviews. CodeRabbit does not review PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Essentials Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
Superseded by #39 — measured, not assumed.
Every other file is identical in both ( Both are currently 🤖 Generated with Claude Code |
Now superseded by
|
| file this PR adds | on main |
|---|---|
crates/launcher-common/src/deed.rs |
present, 39,081 B |
crates/launcher-common/tests/deed_corpus.rs |
present, and green (5 passed) |
standards/launcher-standard_praxis.deed |
present, 13,803 B |
standards/launcher-standard.a2ml (deleted here) |
already absent |
| a root contribution guide | CONTRIBUTING.adoc present |
This PR proposes CONTRIBUTING.md; main carries CONTRIBUTING.adoc, which is
the estate's format and what governance / Code quality + docs checks for — that
gate has been SUCCESS on main since 154b9b6 (09-22T11:53). The need this
PR addressed is met, and launch-scaffolder#37 is closed on that evidence.
The PR is CONFLICTING / DIRTY and cannot land as it stands.
⚠ Stated honestly: the three versions of deed.rs are not byte-identical
(this PR +984 lines, #39 +1050, main 39,081 B), so this is not a superset
proof. Nothing is lost by closing — refs/pull/38/head is permanent. If a
specific improvement here turns out to be missing from main, it should return
as a small focused PR against current main, not as this branch rebased.
Closing as superseded, not rejected.
🤖 Generated with Claude Code
Add CONTRIBUTING.md at the repository root with contribution steps, RSR conventions, and licensing terms.
The committed change only adds documentation; it does not modify CI configuration or demonstrate that PR #36’s CI failures are fixed.
Validation was not run.
View coding task