Skip to content

Commit d5338c6

Browse files
ChanMeng666claude
andcommitted
chore(release): v1.25.0 — orientation & openings
Core 1.24.0 -> 1.25.0. MINOR: 9 new diagnostic codes, 11 new keywords and new public describe() fields across 67 commits, with no breaking change — every new form carries a byte-identity law verified by SHA-256 sweep over all fourteen shipped examples. packages/mcp 0.2.3 -> 0.2.4, and this is the pack-time law working as designed: the shim's SHIPPED sources did not change at all (git diff v1.24.0..main -- packages/mcp/src is empty), but its spec/context/GBNF/schema resources are baked into the tarball at pack time, and the language surface moved a long way. Only a version bump ships refreshed resources. Re-pinned ^1.24.0 -> ^1.25.0, which is what the lockstep string-equality test reddens for on every core release, and rebuilt dist/ so check-dist-resources is green. AGENTS.md: version column, mcp row, tags row, and the "Latest release:" line — the one the checklist warns goes stale, and which sat wrong through two releases before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent debe55a commit d5338c6

5 files changed

Lines changed: 51 additions & 10 deletions

File tree

AGENTS.md

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,46 @@ not a work-in-progress. Treat the live artifacts below as the source of truth
1919

2020
| Thing | Current | Where |
2121
|-------|---------|-------|
22-
| **Core package** | `@chanmeng666/archlang@1.24.0` (published, `latest`, with provenance — released tokenlessly via `.github/workflows/release.yml` OIDC trusted publishing) | npmjs.com/package/@chanmeng666/archlang |
22+
| **Core package** | `@chanmeng666/archlang@1.25.0` (published, `latest`, with provenance — released tokenlessly via `.github/workflows/release.yml` OIDC trusted publishing) | npmjs.com/package/@chanmeng666/archlang |
2323
| **Agent interface** | the `arch` **CLI** (`--json`, exit codes, stdin — incl. `ast`/`complete`/`fix`/`suggest`, `compile --from-json`/`-f txt`, `validate --graph`, v1.14's `validate --intent`/`--feedback` + `score --brief`, and the v1.17 **self-describing + bounded-output** layer: manifest-rendered per-command `--help` with worked examples, `--version`, exit-3 did-you-mean on an unknown flag/verb, `describe --room/--select`, `lint\|validate --code/--severity`, `context --section`, `fix --dry-run/--backup` + unified diff) + `SKILL.md` + `spec.llm.md` + **`llms-full.txt` / `arch context`** + **`schemas/plan.schema.json`** + **`schemas/intent.schema.json`** + **`grammars/archlang.gbnf`**. Primary interface stays the CLI; an **optional MCP shim** (`packages/mcp`) is a discoverability channel, not a replacement | `src/cli.ts`, `SKILL.md`, `spec.llm.md`, `llms-full.txt`, `packages/mcp` |
24-
| **MCP server** | `@chanmeng666/archlang-mcp@0.2.3` (published, `latest`; registry entry `io.github.ChanMeng666/archlang-mcp` v0.2.3 live on registry.modelcontextprotocol.io; `packages/mcp/`; stdio shim over the library; tools compile/describe/lint/validate (incl. `intent`)/**score**/repair/fix/suggest/complete + spec/context/schema/**intent-schema**/grammar resources; SDK dep quarantined here, core stays zero-dep). **Its context resources are baked in at pack time and only a version bump ships fresh ones** — the staleness itself is no longer silent: CI's `builds` job runs `packages/mcp/scripts/check-dist-resources.mjs` (byte-compares every baked `dist/` resource against its repo source) and `packages/mcp/test/lockstep.test.ts` pins the core dep range as a **string** equal to `^` + the root version, so every core release turns this package RED on purpose until someone re-pins, rebuilds the resources and bumps the shim in both `package.json` and both of `server.json`'s version fields (don't relax it to a semver-satisfies check). History, one clause: 0.2.2 served the v1.19 spec *and a v1.19 GBNF grammar that could not decode* `paper`/`level`/`place`/`zone`/`polygon`/`arc` while its `^1.14.0` range resolved to a current core; 0.2.3 refreshes all five, pins the range to `^1.24.0`, returns every storey of a multi-storey `compile` in `pages[]` (+ a `level` selector) instead of the ground floor alone, and derives the handshake version from `package.json` (the old hardcoded `"0.2.0"` drift, now test-pinned) | `packages/mcp/`, `server.json` |
24+
| **MCP server** | `@chanmeng666/archlang-mcp@0.2.4` (published, `latest`; registry entry `io.github.ChanMeng666/archlang-mcp` v0.2.4 live on registry.modelcontextprotocol.io; `packages/mcp/`; stdio shim over the library; tools compile/describe/lint/validate (incl. `intent`)/**score**/repair/fix/suggest/complete + spec/context/schema/**intent-schema**/grammar resources; SDK dep quarantined here, core stays zero-dep). **Its context resources are baked in at pack time and only a version bump ships fresh ones** — the staleness itself is no longer silent: CI's `builds` job runs `packages/mcp/scripts/check-dist-resources.mjs` (byte-compares every baked `dist/` resource against its repo source) and `packages/mcp/test/lockstep.test.ts` pins the core dep range as a **string** equal to `^` + the root version, so every core release turns this package RED on purpose until someone re-pins, rebuilds the resources and bumps the shim in both `package.json` and both of `server.json`'s version fields (don't relax it to a semver-satisfies check). History, one clause: 0.2.2 served the v1.19 spec *and a v1.19 GBNF grammar that could not decode* `paper`/`level`/`place`/`zone`/`polygon`/`arc` while its `^1.14.0` range resolved to a current core; 0.2.3 refreshes all five, pins the range to `^1.24.0`, returns every storey of a multi-storey `compile` in `pages[]` (+ a `level` selector) instead of the ground floor alone, and derives the handshake version from `package.json` (the old hardcoded `"0.2.0"` drift, now test-pinned); **0.2.4** re-pins to `^1.25.0` and rebakes all five resources for the `site` layer and the door kinds — the shipped sources did not change at all, and the bump exists purely to ship those refreshed resources, which is exactly the case the pack-time law describes | `packages/mcp/`, `server.json` |
2525
| **VS Code extension** | `ChanMeng.archlang@0.13.0` **live on the Marketplace** — verified 2026-08-01 via the gallery API (`extensionquery`, `filterType: 7` = `ChanMeng.archlang`): **0.13.0 is the only version the gallery returns**, even with `IncludeAllVersions`; its `lastUpdated` is 2026-07-26T11:51:11Z, so the upload landed that day, shortly after the query that still saw 0.10.0. It bundles core 1.24.0 (`arc`/`radius`/`circle`/`cw`/`ccw`/`major`, `E_ARC_RADIUS`/`E_ROOM_RADIUS`/`E_DIM_CURVE_REF`, exact πR² areas and arc-length opening attribution in the bundled analysis) and carried in one upload the three tiers that were packaged but never uploaded: 0.12.0 (core 1.23.0 — `polygon`), 0.11.0 (core 1.22.0 — `zone`/`place`/`mirror`) and 0.9.0 (core 1.20.0 — sheet/datum). Durable mechanics: the extension **bundles the core at build time** (a stale bundle ships a stale language — `editors/vscode/test/` pins bundle freshness), `.vsix` files are gitignored so the artifact is local to whoever ran `npm run package`, and **upload stays a human web step** at marketplace.visualstudio.com/manage/publishers/ChanMeng — there is no CI publish | marketplace.visualstudio.com/items?itemName=ChanMeng.archlang |
2626
| **Playground** | deployed, redesigned (**"The Compile Boundary"** one-light-world UI — see below · TypeScript app · pan/zoom · autocomplete · history · click-to-source · format · repair · error-explain · embeddable `embed.html` · circulation Paths toggle · **Copy-for-LLM** · inline diagnostic fixes) | https://playground.archlang.uk |
2727
| **Docs site** | deployed, redesigned (**"The Compile Boundary"** one-light-world UI · compiler-as-hero · VitePress · live editable `<ArchLive>` examples · plain ```` ```arch ```` fences auto-live · serves `/llms.txt` + `/llms-full.txt` + **raw `/<page>.md`** + **`/plan.schema.json`** + **`/archlang.gbnf`**) | https://archlang.uk |
28-
| **Git** | `main`, tags `v1.0.0``v1.24.0` (latest; a `v*` tag push triggers the tokenless OIDC release workflow) | github.com/ChanMeng666/archlang |
28+
| **Git** | `main`, tags `v1.0.0``v1.25.0` (latest; a `v*` tag push triggers the tokenless OIDC release workflow) | github.com/ChanMeng666/archlang |
2929
| **Dataset** | HF `ChanMeng666/archlang-repair-trajectories` (**published, live 2026-07-13** — repair 1200 + authoring 400 rows) — two splits, fully synthetic, self-verifying, CC0-1.0, deterministic from seed `20260712`; generator `dataset/` (`npm run dataset:gen`), permanent CI leakage guard `test/dataset.test.ts` | `dataset/`, huggingface.co/datasets/ChanMeng666/archlang-repair-trajectories |
3030
| **Tests** | 2257 passing (156 files, incl. the fault-injection L1 gate, the G1 oracle-isolation guards, the L2 protocol tests, the judge byte-equivalence fixture, the intent-channel suites, the vocabulary-equivalence classification pin, the dataset contamination/determinism guard, and v1.17's CLI-surface suites — FLAG_KEYS↔manifest bidirectional drift, per-command help/examples, filters-never-gate, the `context --section` splitter-to-generator weld, and `test/docs-flags.test.ts`, the docs↔manifest gate that fails if any hand-written doc names a flag its command doesn't declare, plus v1.19's drawing-quality suites — fixture orientation, `flush` placement, the openings render pass, and `test/repair-coverage.test.ts`, whose postcondition is that every piece a lint pass flags gets a change entry or an `unresolved` entry, never nothing, plus v1.20's sheet-and-datum suites — `test/axes.test.ts` (GB/T numbering incl. the `I`/`O`/`Z` skip and the descending-`y` lettering), `test/sheet.test.ts` (the paper/scale size table, closed-form auto-fit, `W_SCALE_OVERFLOW`, and a pin that a plan with no `paper` is byte-identical) and `test/schedule.test.ts` (schedule rows equal `describe()`'s own areas, legend lists only what is drawn), plus v1.21's vertical suites — `test/levels.test.ts` (either/or level nesting, per-storey id scoping, one-building paper/scale) and `test/cli-levels.test.ts` (`<stem>.L<n>.<ext>` fan-out, `outputs[]`/`pages[]`, `--level` as a display filter that never moves an exit code), `test/vertical.test.ts` (registry dispatch for the three new elements, the drawn symbols, the obstruct-except-the-entry-edge nav-grid rule, same-id shaft identity in `describe().vertical`, upper-storey reachability ± its counterexample, `W_STAIR_UNMATCHED` ±, and cross-level `checkGraph`), and `test/nav-grid-scale.test.ts` (the grid-resolution formulas, large-plan bottleneck discrimination, and the threshold carve), plus v1.22's composition suites — `test/zones.test.ts` (the byte-identity law that a zoned plan renders exactly like its unzoned twin, nesting/roll-up in `describe().zones`, `--zone` as a display filter that never moves an exit code, and the grouped `schedule rooms` subtotals partitioning the total) and `test/place.test.ts` (instance id namespacing and order-independence, dotted refs allowed only in reference positions, `rotate`/`mirror` as exact composing isometries incl. mirrored door swings, whole-file `import … as`, and the imported-fix span guard that keeps `applyFixes` from splicing a component's offsets into the importer), plus v1.23's geometry suites — `test/polygon-rooms.test.ts` (exact shoelace area and centroid labelling, the byte-identity law that an all-rectangle plan is unchanged, boundary-run adjacency and by-distance opening attribution at any angle, the occupancy/nav grids dropping out-of-ring cells, exact `W_ROOM_OVERLAP`, and every rectangle-only clause refusing rather than approximating — `E_PLACE_POLY`, `E_ROOM_POLY_SELF_INTERSECT`, `E_ROOM_POLY_DEGENERATE`, `W_ROOM_LABEL_OUTSIDE`) and `test/miter-limit.test.ts` (the `Paint.miterLimit` cap reaching SVG, PDF and the clipper2 offset alike), plus v1.24's `test/curves.test.ts` (the two-endpoints-and-a-radius arc solve incl. all four `cw`/`major` branches and the `E_ARC_RADIUS` floor, arc-length opening attribution and tangent-derived swings, exact πR² against the 48-gon it is *not* measured from, the dedup that gives a two-semicircle drum one `R` leader, and **both determinism laws** — byte-identical output with the optional clipper2 backend registered *and* cleared, which is what per-segment lowering buys), plus v1.25's orientation-and-openings suites — `test/site.test.ts` (the `site` grammar, the five derived names, the byte-identity law that a plan with no `site` is unchanged everywhere, and the pin that `north` is **deliberately absent** from `KEYWORDS.enum` so nobody "fixes" the three-of-four asymmetry into the first word in two categories), `test/window-facing-probe.test.ts` (the outward-face probe, incl. the two courtyard reproductions the bbox midpoint answered backwards, and both tie-break branches) and `test/doors.test.ts` (the four door kinds, `doorSwing()` returning `null` per kind, both `E_DOOR_KIND_CLAUSE` directions, `W_POCKET_RUN` ± its reverse-slide fix, and the mirrored-`place` pin that `slide`'s flip is the identity while `swing`'s is not)) + offline authorability eval (26 briefs, judge v2, `npm run eval:ci`, in CI) **and the separately-reported intent-fidelity slice** (`npm run eval:fidelity`, `eval/corpus-fidelity.json` — infeasible briefs where declaring infeasibility is correct, plus a deterministic judge-free laundering detector; it shares no ruler with the 26-brief rate and never touches `judge-fixture.json`), plus the 2026-08 cross-surface layer — lockstep drift guards (`test/site-lockstep.test.ts` token-block/`--syn-*` byte pins, `test/brand-assets.test.ts`, `test/share-codec.test.ts` — the `#z=` codec's three implementations held behaviourally equal, `test/docs-sync-list.test.ts`, `test/docs-table-pipes.test.ts` — the GFM `\|`-in-table tripwire, now scanning `docs/archive/` too since its one real offender was escaped, and `test/docs-fences.test.ts` — the live-fence gate: every published ```` ```arch ```` fence the docs site turns into a running `<ArchLive>` widget must compile clean, or carry the `static` opt-out), `test/escape-fuzz.test.ts` (hostile-string properties over SVG/ASCII/DXF via `src/text-safe.ts`), full MCP tool/resource/lockstep/fuzz coverage in `packages/mcp/test/`, VS Code LSP handler + stdio + bundle-freshness tests in `editors/vscode/test/`, and **Playwright E2E**: 50 playground specs (`playground/e2e/`) + 33 docs specs (`docs-site/e2e/`) against the built sites; typecheck (`noUncheckedIndexedAccess` on, full-repo via `typecheck:all`) + build + `npm run lint` (Biome) clean | — |
3131

32-
**Latest release: v1.24.0 (2026-07-26)** — Batch-2's final sub-release **"geometry II"**, which
33-
**closes the large-building roadmap**: `arc (x,y) radius R [cw|ccw] [major]` inside a `wall` body makes
32+
**Latest release: v1.25.0 (2026-08-11)****"orientation & openings"**, the Batch-3 release. Two new
33+
language surfaces and the closure of a whole defect class. `site { street north|south|east|west
34+
[hemisphere north|south] }` is a plan-level setting that **draws nothing** and names five directions on
35+
`describe --json`'s new `site` key — `street`, `back`, `equator_side`, `sunrise_side`, `sunset_side`
36+
assertable by name in an intent's `windows.facing` (`E_INTENT_NO_SITE` when the plan declares no site,
37+
never a silent pass) and read by one advisory rule, `W_ROOM_NOT_EQUATOR_FACING`. **The `_side` names are
38+
a drafting heuristic for an aspect, not a daylight measurement** — there is still no sun model, no
39+
latitude and no date, and the 2026-07 daylight refusal is upheld, not superseded; `good_sun` was
40+
deliberately REJECTED for exactly that reason (a token must not claim more than the check verifies,
41+
least of all to a model that will map "sunny" onto whatever token exists). A bare **door kind** may now
42+
lead a `door` statement — `sliding`, `barn`, `bifold`, `pocket` beside the default `hinged` — plus
43+
`slide left|right` and a drawing-only `open <0..1>`; a non-hinged leaf sweeps nothing, so `doorSwing()`
44+
returns `null` and `W_SWING_OBSTRUCTED` stops applying while every doorway rule is unchanged, and
45+
`W_POCKET_RUN` measures the wall a pocket panel must slide into (truncated at any intervening opening)
46+
against `width + max(50 mm, width x 5%)` — the two-term threshold deliberately chosen over the cited
47+
1.05 ratio, which is wrong on narrow doors. The other half of the release is **six instances of one
48+
defect class**: a position derived from a shape's *bounding box or centroid* rather than the shape
49+
itself, silent every time (`arch lint` reported none of them) — the room label point, the circulation
50+
routing anchor (a 10.9 m walk was reported as 5.6 m), `dims auto` witness lines floating metres off a
51+
sloped facade, `swing into <room>`, `furniture ... against wall`, and `windows[].facing` on a courtyard
52+
plan. The search that finds them is *a room-shape consumer reading `r.at`/`r.size` without branching on
53+
`r.poly`*, recorded in `docs/research/2026-08-06-competitor-borrowing-roadmap.md` §9.1. Also new:
54+
`W_DIM_OVERLAP` + a tier-bump fix, staggered dimension numbers on crowded chains, measured-deficit
55+
diagnostic prose on four rules, lint fixes finally carrying `file` provenance (an imported module's fix
56+
was rewriting the *importer's* source), and the judge-free **intent-fidelity eval slice**
57+
(`npm run eval:fidelity`) that catches a repair loop satisfying the validator by quietly rewriting the
58+
requirement it could not meet. **Every new form obeys a byte-identity law** — a plan that does not use
59+
it renders, describes and lints exactly as before, verified by SHA-256 sweeps over all fourteen shipped
60+
examples. (The five prior Batch-2 sub-releases, all 2026-07-26: **v1.24.0 "geometry II"**, which
61+
**closed the large-building roadmap**: `arc (x,y) radius R [cw|ccw] [major]` inside a `wall` body makes
3462
that edge a circular arc, and `room [id=…] circle at (cx,cy) radius R` makes a floor round. The visible
3563
faces are **true arcs** (SVG `A`, native DXF `ARC`) at `r ± t/2`, never faceted at any zoom — only the
3664
poché fill tessellates — and a circular room's area is **exact πR²** in closed form, not the 48-gon the

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.25.0] - 2026-08-11
11+
12+
**Orientation, openings, and the end of a defect class.** Two new language surfaces — a `site`
13+
block that names the four compass directions a brief actually speaks in, and four door kinds
14+
beside the default `hinged` — plus the closure of a whole family of silent bugs: a position
15+
derived from a shape's *bounding box or centroid* rather than from the shape itself. Six
16+
instances of that class were found and fixed this cycle; the search that locates them is
17+
recorded in `docs/research/2026-08-06-competitor-borrowing-roadmap.md` §9.1.
18+
19+
Every new form obeys a byte-identity law: a plan that does not use it renders, describes and
20+
lints exactly as before. `site`, `door hinged …`, and every unchanged plan are byte-identical,
21+
verified by SHA-256 sweeps over all fourteen shipped examples.
22+
1023
### Added (the two P2 language features)
1124

1225
- **Site & orientation**`site { street north|south|east|west [hemisphere north|south] }`, a

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@chanmeng666/archlang",
3-
"version": "1.24.0",
3+
"version": "1.25.0",
44
"description": "A small declarative language that compiles to professional SVG floor plans — like Typst/LaTeX, but for architecture.",
55
"keywords": [
66
"architecture",

packages/mcp/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@chanmeng666/archlang-mcp",
3-
"version": "0.2.3",
3+
"version": "0.2.4",
44
"mcpName": "io.github.ChanMeng666/archlang-mcp",
55
"description": "Model Context Protocol (MCP) server for ArchLang — compile, describe, lint, validate, score, repair, fix and suggest floor plans over stdio, plus the intent channel (gate + continuous score against a brief). Covers the whole current language: multi-storey `level` plans with stairs, `place`d components, zones, scaled paper with dimension chains and room schedules, and non-rectilinear `room polygon` / `room circle` / `arc` walls. A thin shim over @chanmeng666/archlang; the CLI stays the primary, token-cheaper interface.",
66
"keywords": [
@@ -42,7 +42,7 @@
4242
"prepack": "npm run build"
4343
},
4444
"dependencies": {
45-
"@chanmeng666/archlang": "^1.24.0",
45+
"@chanmeng666/archlang": "^1.25.0",
4646
"@modelcontextprotocol/sdk": "^1.29.0",
4747
"zod": "^3.25.76"
4848
},

packages/mcp/server.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
33
"name": "io.github.ChanMeng666/archlang-mcp",
44
"description": "Compile, describe, lint, validate, score and repair multi-storey and curved ArchLang floor plans.",
5-
"version": "0.2.3",
5+
"version": "0.2.4",
66
"repository": {
77
"url": "https://github.com/ChanMeng666/archlang",
88
"source": "github",
@@ -14,7 +14,7 @@
1414
"registryType": "npm",
1515
"registryBaseUrl": "https://registry.npmjs.org",
1616
"identifier": "@chanmeng666/archlang-mcp",
17-
"version": "0.2.3",
17+
"version": "0.2.4",
1818
"runtimeHint": "npx",
1919
"transport": {
2020
"type": "stdio"

0 commit comments

Comments
 (0)