Skip to content

Commit 71376e3

Browse files
committed
docs: testing map, backlog and contributing after the v1.28/v1.29 releases
- testing.md: nine generators now produce twenty-three artifacts (the gen:grammars generator gained arch-highlight.js and gen:example-svgs grew to thirteen README SVGs); documents the new roof/void byte- identity gate, the fixture-symbol snapshot layer's three differently-promised groups, and the v1.29 cross-feature gate that neither parallel branch could prove alone. - CONTRIBUTING.md: mirrors the twenty-three-artifact count and the worktree build-refusal / dep-range lockstep guards for the VS Code extension. - backlog.md: 3.11/3.12 marked done (v1.27.0, was already shipped but still read FIXED/unreleased); re-measured the spec.llm.md character budget (cap raised to 26,000 in v1.29.0, file is 25,636 as of 2026-08-27, 364 to spare); adds Wave 5 (six items deferred by name in v1.28.0/v1.29.0: curved roof offset, polygonal void, void area subtraction, glyph-aware mirroring, overhead-dash syntax, angled furniture) and re-scopes P2-7 against the widened fixture catalog. - README.md: furniture-symbol blurb updated to the measured 59 words / 36 families and the roof/void drawing-only annotations. All counts re-measured directly against the working tree (fixture family/category counts, generator/artifact counts, Playwright spec counts, error/warning catalog counts) rather than carried forward.
1 parent ec21b01 commit 71376e3

4 files changed

Lines changed: 165 additions & 20 deletions

File tree

CONTRIBUTING.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,20 @@ diagnostics, or error/lint codes — republish the extension so its bundled serv
146146
> — run `npm run vscode:build:only && npx vitest run editors/vscode` (CI's `builds` job does exactly
147147
> this). That replaced the old by-hand "count new keywords in `dist/server.js`" probe.
148148
149+
> **Build and package in the PRIMARY checkout only — the build now refuses otherwise.** A
150+
> `git worktree` checkout has no `node_modules`, so esbuild resolves the core by walking **up** and
151+
> bundles the *shared* repo's, and the `__CORE_VERSION__` stamp cannot catch it because both stamp
152+
> the same version. `editors/vscode/resolve-core.mjs` compares the resolved core's real path against
153+
> the repo root of the tree being built and throws naming both paths. Junctioning the worktree's
154+
> `node_modules` does **not** make it safe (npm links a workspace package by absolute path to the
155+
> main tree), and the guard fires there too — correctly.
156+
157+
> **Its `@chanmeng666/archlang` range is pinned by a test, and every core release turns that test
158+
> red on purpose.** `editors/vscode/test/lockstep.test.ts` asserts the range is a *string* equal to
159+
> `^` + the root version; re-pin it as step 2, never relax the check. It is distinct from the
160+
> freshness stamp above — that one says the BUNDLE is current, this one says the MANIFEST is honest,
161+
> and the range once sat two releases stale while the stamp stayed green throughout.
162+
149163
A repack can also be **non-language** — the icon, `galleryBanner`, or other marketplace metadata
150164
(e.g. `0.4.1` was an icon-only repack of `0.4.0`). Same steps 1–4 above (skip step 2 when the core
151165
did not move); the `.vsix` still needs a manual web upload.
@@ -245,21 +259,22 @@ low.
245259

246260
### CI drift gates (regenerate before you push)
247261

248-
**Nine generators** produce **twenty-one artifacts**, and CI drift-checks all of them in a single
249-
`npm run check:drift` step. The authoritative list is the `GENERATORS` table in
250-
`scripts/check-drift.ts` — this table mirrors it:
262+
**Nine generators** produce **twenty-three artifacts**, and CI drift-checks all of them in a single
263+
`npm run check:drift` step. The run prints its own total (`✓ all 23 generated artifacts are in sync
264+
with their sources`), so read the count there rather than from this page. The authoritative list is
265+
the `GENERATORS` table in `scripts/check-drift.ts` — this table mirrors it:
251266

252267
| Generated artifact | Generator | Source of truth |
253268
|--------------------|-----------|-----------------|
254-
| `editors/archlang.tmLanguage.json`, `playground/src/arch-language.js` | `gen:grammars` | `src/grammar/tokens.ts` |
269+
| `editors/archlang.tmLanguage.json`, `playground/src/arch-language.js`, `docs-site/.vitepress/theme/arch-highlight.js` | `gen:grammars` | `src/grammar/tokens.ts` |
255270
| `docs/error-codes.md` | `gen:errors` | `src/error-catalog.ts` |
256271
| `docs/cli-reference.md` | `gen:cli` | `src/manifest.ts` |
257272
| `spec.llm.md` | `gen:spec` | `src/grammar/tokens.ts` + `examples/` |
258273
| `llms-full.txt` | `gen:llms` | `spec.llm.md` + `SKILL.md` + `src/manifest.ts` + `src/error-catalog.ts` |
259274
| `grammars/archlang.gbnf` | `gen:gbnf` | `src/grammar/tokens.ts` |
260275
| `schemas/plan.schema.json` | `gen:plan-schema` | `PLAN_JSON_SCHEMA` |
261276
| `schemas/intent.schema.json` | `gen:intent-schema` | `INTENT_JSON_SCHEMA` |
262-
| the twelve `examples/*.svg` the README embeds | `gen:example-svgs` | the matching `examples/*.arch` (list: `README_SVGS`) |
277+
| the thirteen `examples/*.svg` the README embeds | `gen:example-svgs` | the matching `examples/*.arch` (list: `README_SVGS`) |
263278

264279
Whenever a generator's source changes, run `npm run gen:all` to regenerate every artifact in
265280
dependency order (`gen:spec` before `gen:llms`, which consumes it) and commit the output;

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,13 @@ fence in your Markdown to images in one step.
250250

251251
Poché-hatched walls (by material), door **swing arcs**, window glazing, computed room areas,
252252
dimension lines, layers, line weights, a north arrow, a scale bar and a title block. **Real drawn
253-
symbols for every catalogued furniture kind** — the bathroom and kitchen fixtures, and the room
254-
furniture beside them, each with the detail that makes it readable at plan scale (see
255-
[Furniture & Fixtures](docs/furniture.md), or the
256-
[`furnished-flat`](examples/furnished-flat.arch) example) — plus `dims auto` to synthesize
257-
dimension strings for you.
253+
symbols for every catalogued furniture kind** — 59 words across 36 families, the bathroom and
254+
kitchen fixtures and the room furniture beside them, each with the detail that makes it readable at
255+
plan scale (see [Furniture & Fixtures](docs/furniture.md), or the
256+
[`furnished-flat`](examples/furnished-flat.arch) example) — plus the two **drawing-only**
257+
annotations a plan needs above and below the cut: `roof overhang 600` puts a dashed eaves line
258+
around the building (an exact mitred offset of the wall ring, at any angle), and `void` puts a stair
259+
well or an atrium on the floor plate. And `dims auto` synthesizes the dimension strings for you.
258260

259261
</details>
260262

docs/backlog.md

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ to prevent.
9999

100100
</details>
101101

102-
### 3.11 · `repair(repair(s)) !== repair(s)``FIXED` (unreleased)
102+
### 3.11 · `repair(repair(s)) !== repair(s)``done` (v1.27.0)
103103

104104
**`repair` is now idempotent, and it is asserted**`test/fuzz.test.ts`'s "is idempotent — a second
105105
call changes nothing", a property over 300 generated plans, plus two named regression specimens in
@@ -147,7 +147,7 @@ Honesty holds throughout: a piece parked mid-cycle gets an `unresolved` entry na
147147
it alternates between, and a change entry whose net effect is nothing is dropped rather than
148148
reported. All 27 shipped examples repair byte-identically to before (they are already at a fixpoint).
149149

150-
### 3.12 · `flush` and `grid` fight — `FIXED` (unreleased)
150+
### 3.12 · `flush` and `grid` fight — `done` (v1.27.0)
151151

152152
A fixture placed `flush` against a 100 mm partition lands on a `…50` coordinate; `grid 100` then
153153
snapped it back **into** the wall and raised `W_FURNITURE_WALL_COLLISION` on a plan that is correct.
@@ -171,8 +171,13 @@ The agent Skill — the loop a cold-start model follows — documents neither th
171171
layer nor the four non-default door kinds. `examples/bungalow.arch` now demonstrates both, but
172172
there is nowhere in `SKILL.md` to reference it from.
173173

174-
Note the constraint before starting: `SKILL.md` feeds `gen:llms`, and `spec.llm.md` sits at
175-
**24,940 of 25,000 characters** — 60 to spare. Any addition needs its budget worked out first.
174+
Note the constraint before starting: `SKILL.md` feeds `gen:llms`, and `spec.llm.md` is under a hard
175+
character cap asserted by `test/llm-spec-drift.test.ts`. **Re-measure both numbers rather than
176+
trusting this line** — they have moved twice since it was written (the cap was 25,000; v1.29.0
177+
raised it to **26,000** after trimming a redundant keyword bullet, and the file is **25,636** as of
178+
2026-08-27, leaving 364). The standing instruction is unchanged and is the point of the cap:
179+
`spec.llm.md` is injected verbatim into agent prompts, so its size is a recurring per-request token
180+
cost — **trim duplication before raising.**
176181

177182
### 3.15 · `W_FURNITURE_WALL_COLLISION` does not check a CURVED wall — `todo`
178183

@@ -354,6 +359,69 @@ anywhere. Same "a promise quietly not kept" class as v1.26.1. The fix is to incl
354359

355360
---
356361

362+
## Wave 5 — deferred by name in v1.28.0 / v1.29.0
363+
364+
Each of these was **named in `CHANGELOG.md` at the time it was skipped**, not quietly omitted, so
365+
nobody has to guess whether it was overlooked. Two v1.28 entries are already gone from this list:
366+
`rug`, `sofa_l`, `piano` and `sun_lounger` were deferred there and **shipped in v1.29.0**.
367+
368+
### 5.1 · An `arc` edge under `roof overhang``todo`
369+
370+
`roof overhang <mm>` mitres a closed wall ring outward in closed form (line–line intersection,
371+
orientation from the shoelace sign). A curved edge has no such offset in the same arithmetic, so
372+
`E_ROOF_CURVED` **refuses** rather than approximating, and the author writes `roof polygon …`
373+
instead. Same shape as the `arc`-inside-a-`room polygon` deferral below, and probably the same
374+
design pass: an offset ring that carries arcs is an offset ring whose whole consumer set has to
375+
learn arcs.
376+
377+
**Gate:** the refusal's own test in `test/roof.test.ts` inverts — an arc-bearing ring must produce
378+
a drawn eaves line at `R ± overhang` on the curved run, and the exact-coordinate assertions on the
379+
straight runs must not move.
380+
381+
### 5.2 · A polygonal `void``todo`
382+
383+
`void … size WxH` is rectangle-only in v1. A ring form needs the machinery `room polygon` already
384+
has, and **every consumer here is written on a rectangle**: the nav-grid obstacle, the poly-aware
385+
room attribution, and `frame.ts`'s `transformElement`. Cheap to add to the grammar, not cheap to
386+
add to those three.
387+
388+
### 5.3 · Area subtraction under a `void``todo`
389+
390+
A void deliberately does **not** reduce its room's area today; `describe --json`'s `voids[]` gives
391+
the extent so a consumer can subtract. That decision is *pinned* by `test/void.test.ts`, so
392+
changing it is an argument with a test rather than an oversight — which is the point. Before
393+
reopening it, decide what a subtracted area means to `schedule rooms`, to the room label's ``
394+
text, and to an intent's area assertion, because those three are what would silently disagree.
395+
396+
### 5.4 · Glyph-aware mirroring in the `place` transform — `todo`
397+
398+
**`sofa_l`'s return is always on the LEFT and there is no right-handed twin.** `place … mirror`
399+
will not produce one, because a reflection transforms a resolved element's *position* and not the
400+
symbol drawn inside it — so a mirrored wing draws a left-hand sofa. A `sofa_l_r` category was
401+
**rejected rather than forgotten**: it would put the fix in the vocabulary, where every future
402+
handed symbol then needs its own twin. The real fix is for `frame.ts` to hand the glyph its own
403+
chirality when `det < 0`, which is the same place the handed door/furniture rules already flip.
404+
405+
Note the standing rule it must obey: add a handed rule ⇒ add its flip to `transformElement`, never
406+
a frame parameter to the element ([ADR 0016](adr/0016-component-instances-and-frames.md)).
407+
408+
### 5.5 · A syntax for overhead dashes — `todo`
409+
410+
`upper_cabinet` is drawn dashed because of *what it is*, and there is no way for an author to say
411+
"draw this piece above the cut plane" about anything else. Any design has to decide whether it is a
412+
clause on `furniture`, a property of a category, or a plan-level convention — and a dashed overhead
413+
line is also what `roof` and `void` now draw, so the three should agree about what dashed *means*
414+
before a fourth spelling appears.
415+
416+
### 5.6 · Angled furniture — `todo`
417+
418+
A fixture still draws on an **axis-aligned footprint**, so a piece against a sloped wall is not
419+
turned to it. Deferred by name in v1.28.0. Related but not the same as 3.15 above (which is about
420+
*measuring* against a curved wall, not drawing at an angle); both are instances of the fixture
421+
layer knowing only rectangles.
422+
423+
---
424+
357425
## Wave 4 — P2 language features
358426

359427
Designed and evidenced in `docs/research/2026-08-06-competitor-borrowing-roadmap.md` §5. Each one
@@ -364,7 +432,7 @@ proven by a SHA-256 sweep over the shipped examples), and a corpus entry in the
364432

365433
| # | Feature | Status | Note |
366434
|---|---|---|---|
367-
| P2-7 | Four-sided authorable clearances + embedded-insert exemption | `todo` | Most contained — widens `clearanceMm` (`src/fixtures-catalog.ts:21`) to `{front,back,left,right}` plus a per-statement override |
435+
| P2-7 | Four-sided authorable clearances + embedded-insert exemption | `todo` | Most contained — widens `clearanceMm` (`src/fixtures-catalog.ts:21`) to `{front,back,left,right}` plus a per-statement override. **Re-scope before starting:** v1.28.0 took that catalog from 18 categories to **59 across 36 families** and gave `FixtureSpec` two more flags (`directional`, then v1.29's `underlay`), so "one default per category" is now a far larger table to be right about — and an underlay already has a stated exemption (it never blocks a fixture's use-space) that a four-sided rule must not re-litigate |
368436
| P2-10 | Feet-and-inches display formatting (`dimension_units standard`) | `todo` | **Display only** — millimetres stay the internal unit and the measured truth. Route through `fmt()` |
369437
| P2-9 | `outdoor <kind>` + floor-material hatches + auto legend | `todo` | Hatches must be **scale-aware**; do not copy `patternUnits="userSpaceOnUse"` with fixed pixel sizes, which does not scale with drawing scale |
370438
| P2-8 | Targeted dimension selection (dimensions on named walls/fixtures) | `todo` | Composes with the sheet layer |

0 commit comments

Comments
 (0)