Skip to content

docs: stop offering $DELVEWRIGHT_CAMPAIGNS_DIR — no code has ever read it - #344

Merged
stellarfeline merged 2 commits into
mainfrom
fix/campaigns-dir-phantom
Aug 9, 2026
Merged

docs: stop offering $DELVEWRIGHT_CAMPAIGNS_DIR — no code has ever read it#344
stellarfeline merged 2 commits into
mainfrom
fix/campaigns-dir-phantom

Conversation

@stellarfeline

Copy link
Copy Markdown
Owner

Two agent-facing docs offered an environment variable to redirect the campaigns checkout. Zero code reads it.

$ grep -rn DELVEWRIGHT_CAMPAIGNS_DIR --exclude-dir=.git .
.claude/skills/new-delve/SKILL.md:66
docs/reference/worktree-bootstrap.md:12

The path is constructed literally in five places — crates/compiler/tests/common/mod.rs, crates/compiler/src/main.rs's --prefabs default, crates/render/src/nbt.rs, crates/render/tests/gpu.rs, .github/workflows/release.yml.

Design level. This is the storybook-version defect (#342) one layer over: a reader-facing fact the reader acts on, bound to nothing, so it drifts and nobody finds out. It is sharper here because the false fix and the real symptom sit in the same paragraph — a worker who exported the variable instead of making the symlink got exactly the two analyze.rs failures the file exists to prevent, by following the file.

Corrected rather than implemented: making it true means all five sites, and a two-of-five implementation is a second half-bound fact rather than a fix. The bootstrap doc now states the symlink is the only mechanism and names the five sites for whoever implements it later.

What CI now proves. Nothing new — this removes a claim, it does not add one. Docs checks stay green; the skill-version gate still binds (27 delvec mentions, 9 subcommands, 13 long flags).

stellarfeline and others added 2 commits August 9, 2026 19:07
…d it

The worktree-bootstrap reference and the new-delve skill both told workers the
campaigns checkout could be redirected with an environment variable. Nothing
reads it. The path is constructed literally in five places, so the offer was a
fact a reader ACTS on, bound to nothing — the same shape as the storybook
version stamp closed in #342, and worse here because the false fix and the real
symptom live in the same paragraph: a worker who exported the variable got the
two analyze.rs failures this file exists to prevent.

Corrected rather than implemented: honouring it means all five sites or none,
and a two-of-five implementation would be a second half-bound fact. The
bootstrap doc now records why, and names the five sites for whoever does it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL
@stellarfeline
stellarfeline merged commit 4da5be8 into main Aug 9, 2026
12 checks passed
@stellarfeline
stellarfeline deleted the fix/campaigns-dir-phantom branch August 9, 2026 23:21
stellarfeline added a commit that referenced this pull request Aug 9, 2026
…the version header (#345)

* fix(docs): bind the compiler reference's version header to the build

`docs/reference/compiler.md` is the authoritative current-behaviour record and
its first factual claim — the version header — was bound to nothing. It read
`delvec 0.1.0`, `dsl 0.8.0` and listed `dsl_version 0.2.0 … 0.8.0` while the
build is at `delvec 1.1.0` / `dsl 0.9.0` and accepts `0.9.0`. The body of the
same file documented the v0.9 surface correctly; only the header a reader
consults first was wrong, and every gate was green, because no gate related the
two.

Second instance of the same defect, found while fixing the first: the `DW0102`
catalog row restates the supported set by hand and read `{0.2.0 … 0.8.0}`.
`tools/check-dw-codes.py` was green on it and always would be — it proves a code
exists in both source and doc and is asserted by a test, never that the
BEHAVIOUR the doc ascribes to it is the behaviour the code has.

`tools/check-reference-versions.py` binds both, by EQUALITY in both directions,
to `crates/compiler/Cargo.toml`, `crates/dsl/src/envelope.rs`
(`SUPPORTED_DSL_VERSION` + `SUPPORTED_DSL_VERSIONS`, compared as an ordered
sequence) and `versions.toml`. Equality is the point: a gate that only rejects a
version NEWER than the build is exactly what let a storybook ship a stale `v1.0`
marker through the whole `v1.1` release green (#342), and stale-older is the
direction that actually happens. Demonstrated red on the pre-fix header and on
the `DW0102` row independently, green after.

Runs as a step in the existing `docs (local link check)` job, so no branch-
protection context changes (`check-required-contexts.py` still resolves 12/12).

Also corrected against the source, not from memory:
- added the missing `task #179 / dsl_version 0.9.0` landed-bullet (drops[] +
  `collect.dropped_by`), semantics read off `crates/dsl/src/diagnostic.rs`
  `DW0490`–`DW0493`.
- pass-order row 11 listed two-tier `DW0359` only under exit 3; it is an
  `EclipseError` (hard) AND a `Diagnostic::warning` (advisory) in
  `crates/compiler/src/eclipse.rs`, and the file's own convention lists two-tier
  `DW0489` in both places. Its catalog row already described both tiers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

* docs(tools): make the tool inventory match the tool surface, both directions

`tools.md` claims to be the inventory of the whole tool surface — every binary,
script and flag. Audited bidirectionally against `tools/`, `validation/`,
`crates/*/src/main.rs` (clap derives, not `--help`), `prefabs/` and
`.github/workflows/`. ~150 claims checked, 6 corrected.

- `.github/scripts/mecha_crosscheck.py` was ENTIRELY absent (`grep -c mecha
  docs/reference/tools.md` -> 0). ADR-0011's independent cross-check, invoked by
  the `mecha cross-check (PR only)` required job, missing from the file that
  claims to be the whole surface.
- `tools/refimg.py`: `--chain-from` and `--style-note` undocumented; the
  provider parenthetical said `ideogram-v3` only while `PROVIDERS` has two keys
  and the same cell already named both.
- `packtest` profile: the CI extra-pass list was one fixture short
  (`souls-timed-gate-disarm`, ci.yml 670-686).
- `tools/check-reference-versions.py` row added (CLAUDE.md tooling-sync).

The env-forwarding claim was FALSE and the first count of it was also wrong.
`harness/src/` reads 15 `DELVEWRIGHT_*` variables; `validation/*.yaml` declares
10. The doc said all 15 were forwarded. The set difference is five, of which
FOUR are real defects — `ACTOR_FLOOR`, `RETRY_ON_DEATH`, `CUTSCENE_GRACE_MS`,
`ENTITY_SETTLE_TIMEOUT_MS` arrive unset in the container, so setting them on a
`bot-run.sh` command line is silently dropped. The fifth, `NOTE_TEXT`, is not a
defect: `playtest-note-flow.sh` runs the note-bot on the host. The first sweep
named two of the four; measuring the set difference rather than spot-checking
found the other two.

That is a defect in `validation/compose.yaml`, not in the doc, so it is recorded
here as an open finding and NOT fixed in this PR: `DELVEWRIGHT_ACTOR_FLOOR=0`
cannot be used through the ladder at all today. It is the general form of the
one-variable fix task #102 already applied by hand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

* test(tools): pin the reference version gate, both directions

`tools/check-reference-versions.py` had a red->green demonstration but no
regression test, and its five regexes are the part that rots: a renamed constant
must exit 2 loudly, never pass quietly.

14 tests over synthetic sources. Both directions are pinned as red — the
stale-OLDER one because that is what actually happens (docs are written once,
the build moves), and the ahead-of-the-build one because a gate that only
rejected "newer" is exactly what let a storybook ship a v1.0 marker through the
whole v1.1 release green (#342). Also pinned: same members in the wrong ORDER
(the list doubles as the reading order for the additive-superset claim), the
DW0102 row going stale while the header is right, that `[minecraft]`'s
`version` is read rather than another table's, and that every reshaped-source
path exits 2.

Verified non-vacuous by mutation: stubbing the gate's `problems` list to empty
turns 8 of the 14 red. 180 -> 194 tests in `tools/tests`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

* docs(worktree): §2 carried the same phantom §1 was fixed for

`worktree-bootstrap.md` exists to stop a worker acting on a mechanism nothing
implements, and #344 removed one from §1 today ($DELVEWRIGHT_CAMPAIGNS_DIR, an
override no code has ever read). §2 carried a parallel one and was not looked at.

It said the local config holds "validation ports, container tooling paths" and
that absence makes "validation compose runs inherit wrong defaults silently".
Measured: nothing in `validation/` reads `delvewright.local.toml`, no shell
script reads it, no Rust crate reads it. Exactly two Python tools do, each only
for its own section — `tools/i18n-translate.py` (`[i18n]`) and `tools/refimg.py`
(`[refimg]`) — and the real file has exactly those two sections. Validation gets
its ports from `ephemeral-port.yaml` and its pins from `versions.toml`.

The consequence was a false causal story: a worker who skipped the copy and then
blamed a red ladder run on it was chasing a cause that does not exist. Corrected
to say what absence actually breaks (those two tools, which exit non-zero naming
what to add — `i18n-translate.py` returns 2 on a missing `[i18n]`), and to name
the two readers so the next reader can check rather than believe.

§1's claims were re-verified rather than assumed: the five literal
path-construction sites all exist, and `analyze.rs` has exactly two
`prefabs_dir()` call sites, both `.unwrap()` — so "exactly two failures" is
right.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

* docs(reference): correct i18n, playtest-methodology and skill-workflow against the build

~88 claims checked across the three, 9 corrected. Each correction is measured;
the counts and the unverifiable residue are in the PR body.

Two are the exact defect class this sweep hunts — a claim a reader acts on,
bound to nothing:

- i18n.md promised a width diagnostic was "being added separately (engine task
  #110)". `DW0331` had landed 18 hours BEFORE that line was written (bf706ce,
  2026-08-03 03:44 vs the line at 21:41), and the same file already cited it as
  an enforced gate 165 lines earlier. A translator reading the option-label
  section would take a hard error for advice.
- skill-workflow.md §8 item 5 said ADR-0016's version line "exists on paper
  only" and that the skill's frontmatter "carries `name` and `description` and
  nothing else". It carries `version`, `requires` and `verified_with`, and
  `check-skill-version.py` binds all three to the CLI in both directions. Every
  word was false; the item is now marked closed with what the gate does and does
  not prove.

playtest-methodology.md was asserting the very vacuity it warns about:

- Rule 3 said `/new-delve` "requires all four" declarations. It requires three,
  and the compiler enforces those (`DW0460`/`DW0481`/`DW0480`). Nothing requires
  a combat TIER — `grep -n tier SKILL.md` finds it only under *Authoring
  pitfalls*, and `DW0477` fires on a tiered fight nobody can measure, the
  opposite direction. An untiered set-piece compiles green. That is the same
  unbound gate whose nineteen-round history the document exists to record.
- The findings table's `0` cell for round 16 read as "she played and found
  nothing". Round 16 WAS an owner playtest — four items, all already-open
  findings, ledgered under r12/r15, and it opened with the rebuke rule 4 comes
  from. The caption now says findings are counted by the round they were FIRST
  reported in, and the "no owner exposure" window is corrected from 16-21 to
  17-21.

Also: skill-workflow gate 4b described the design-alignment images as renders of
built prefabs; #334 (2026-08-07) made them reference images drawn BEFORE any
prefab exists, and this doc never received the update — a reader acting on the
old row does the expensive thing first. And "six stage JSONs" as the artifact of
record omits the optional stage-7 `world-edits.json`, so a campaign that used
`delvec edit` and committed only the six loses its landscape on rebuild.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

* docs(grammar): four claims a rule author would act on were false

~230 claims checked against `crates/grammar`, 4 corrected. Every correction was
measured, not reasoned about.

- **§3 described two different test suites with one sentence.** "double-export
  test over every library program at four seeds" — `tests/export.rs::cases()` is
  `temple`/`castle`/`church` and nothing else, while `tests/determinism.rs`
  carries all 17. The §5b staging rules and §5c zone programs are not in the
  byte-comparison suite at all; what covers them is the registry round trip
  (`crates/compiler/tests/grammar_prefab.rs`), which exports once and reads back
  rather than twice and compares. A reader trusting that line believes the
  staging rules have determinism cover they do not have.
- **§5b `store_room`'s smallest region was 5 × 5 × 3; the real one is 5 × 5 × 5.**
  `crates/grammar/tests/staging.rs:2469` asserts `[5,5,5]` expands and `[5,5,4]`
  does not. `MIN_LINE` is 3, but the frame puts local Z on the LARGER horizontal,
  so a 3-long row is unreachable — the same shape `boulder_stair`'s `MIN_DEPTH`
  already records.
- **§4's `Program::validate` list reads as exhaustive and named 9 of 11.**
  `RoundingWithoutRelative` and `SplitAxisOutsideSplit` were missing
  (`crates/grammar/src/ir.rs`, `pub enum ProgramError`).
- **"Two anchor names are shared across rules" — there are three.**
  `anchor/landing` is declared by both `drop_shaft` and `dumbwaiter`. A zone
  author composing a chute and a duct hits an `AnchorCollision` the doc told
  them not to expect. Nothing enumerates the collisions; the list is prose, and
  the third entry was missing until a sweep counted the stems.

`cargo test -p delvewright-grammar`: 198 tests, 197 passed, 1 ignored, 0 failed.

Not fixed, because it is a code change: `crates/grammar/src/library/store_room.rs:57`
carries the same false minimum ("Z >= 3") in its module docs, and
`tests/staging.rs:2467` comments "3 of row" beside a check of `[5,5,5]`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjQ5p1Kv5MrkGPumi7yXWL

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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