|
1 | 1 | # Changelog |
2 | 2 |
|
3 | | -## Unreleased |
| 3 | +## 1.5.0 · 2026-09-14 |
| 4 | + |
| 5 | +### Added |
| 6 | + |
| 7 | +- **`decision-number-duplicate`** (error): `leji validate` reports two decision records |
| 8 | + that carry the same leading number, so a renumbering or a copied record cannot leave |
| 9 | + "0017" pointing at two files; padding does not hide it, `0017-a.md` and `17-b.md` are the |
| 10 | + same number. Additive, with no change to any existing rule name or severity. |
| 11 | +- **`link-unresolved`** (error): `leji validate` now walks the markdown links of every |
| 12 | + governed document (the boot profile, every indexed document, the agent profiles, the |
| 13 | + decision records) and fails one whose target the layer does not carry, so a rename or a |
| 14 | + move cannot leave a dangling reference. Relative targets resolve against the linking |
| 15 | + document, a leading `/` against `rootPath`, and a directory passes when it holds a |
| 16 | + `README.md`; URLs, `mailto:`, and bare fragments are never judged; a target that leaves |
| 17 | + the layer, by `..` or through a symlink, does not resolve. Links inside fenced blocks and |
| 18 | + code spans are code. Always on, not behind `--content`. Additive, with no change to any |
| 19 | + existing rule name or severity. |
| 20 | +- **A set-read guardrail in the scaffolded agent guidance**: the boot profile and core |
| 21 | + profile that `leji init` and `leji adopt` write now tell an agent that when one change |
| 22 | + introduces two or more decision records, the set is read together before it lands, for |
| 23 | + overlap, contradiction, and any record that narrates a state the landed tree will not |
| 24 | + show. Existing layers can copy the sentence; nothing rewrites them. |
| 25 | +- **`viewer.theme.link`**: an optional manifest field that colors the viewer's body links |
| 26 | + and inline code, applied only when it reaches 4.5:1 against the inline-code ground, the |
| 27 | + narrower of the two backgrounds those land on. A malformed or too-pale value emits nothing |
| 28 | + and warns (`viewer-theme-link-contrast`), so the fixed accessible tone stays; a layer that |
| 29 | + sets no `link` renders byte-identically to 1.4.1. Additive schema field, `$id` unchanged. |
| 30 | +- **A build marker on source-checkout builds**: `--version`, `-v`, and `version` print |
| 31 | + `X.Y.Z+dev.<short-sha>` from a checkout, bare `X.Y.Z` from an installed copy. Released |
| 32 | + binaries stay bare: the Go release build stamps a release flag. |
| 33 | +- **A generated decisions index**: a layer that declares a decisions category gets a |
| 34 | + `_decisions.md` page beside the Manifest page, listing every decision record with its |
| 35 | + number, title, status, date, and supersession, all read from the records' own |
| 36 | + frontmatter, so no layer maintains a summary table that lags its records. The sidebar's |
| 37 | + decisions group links it first and `leji export` carries it into the static site. |
| 38 | +- **leji.org in five more languages.** Every prose page, the specification pages, and the |
| 39 | + schema reference pages now ship in Spanish, Brazilian Portuguese, Vietnamese, Japanese, and |
| 40 | + Simplified Chinese beside the English page of record, with `hreflang` alternates, a |
| 41 | + language selector, language-aware navigation and footer, and a translation page that says |
| 42 | + how the translations are made and how to report a correction. The specification pages are |
| 43 | + informative renderings: the English text stays the only normative one, and a check on every |
| 44 | + site build fails if any translation has fallen behind its English source. |
| 45 | +- **Japanese and Chinese emphasis renders without Markdown's padding space.** In the Japanese |
| 46 | + and Simplified Chinese specification pages, the site's markdown pipeline deletes the |
| 47 | + half-width space Markdown forces around emphasis at a boundary between two CJK characters, |
| 48 | + so the text reads as the language writes it. Headings, links, and code spans keep their |
| 49 | + spaces, and the sources are unchanged. |
| 50 | +- **A release-date check on the release path.** `node scripts/version.ts --check --release` |
| 51 | + asserts, on top of version coherence, that the `CHANGELOG.md` heading for the declared |
| 52 | + version is dated `YYYY-MM-DD` and that the matching `CHANGELOG.json` entry, when present, |
| 53 | + names the same day. The pre-publish smoke and the rehearsal run it, so a tag cannot be cut |
| 54 | + past an undated heading, and `RELEASING.md` makes the bump and the stamp one release-day |
| 55 | + step. |
| 56 | + |
| 57 | +### Changed |
| 58 | + |
| 59 | +- **Sidebar groups follow authored `leji-index` order**: a non-alphabetical index reorders |
| 60 | + on upgrade; alphabetizing its entries keeps the previous appearance. |
| 61 | +- **The ecosystem scan proves the entry it judged is the entry it reads**, in all three |
| 62 | + SDKs. Each manifest and lockfile directly under a root is judged on its own directory |
| 63 | + entry, then opened through the verified-source chokepoint, and the descriptor must be the |
| 64 | + same regular file a fresh `lstat` of the name reports; the bytes that decide come from that |
| 65 | + descriptor. A name retargeted between the judgment and the open is refused rather than |
| 66 | + read, while a manifest that is merely unopenable stays unreadable as before; the Python |
| 67 | + CLI now takes those bytes from the descriptor too, so its line handling matches the other |
| 68 | + two SDKs. |
| 69 | +- **Path order is byte order in the TypeScript SDK.** The scans behind the index check, the |
| 70 | + sidebar, the decisions page, the agent profiles, and the freshness report sort repository |
| 71 | + paths by byte order, as the Python and Go SDKs already did, so a name carrying a character |
| 72 | + above the Basic Multilingual Plane orders the same in all three. No fixture's output |
| 73 | + changes; only such a name could have ordered differently. |
| 74 | +- **The CLI reference says what the commands do.** `adopt` names its `--wire-adapters` |
| 75 | + exception; `start` launches from the repository root; `mounts hydrate` no longer claims to |
| 76 | + be the only writer of the witness namespace; `export --strict` says the export destination |
| 77 | + is what stays untouched. Help output moves with it. |
| 78 | +- **Three clarifications on the frozen 1.0 specification line, no requirement changed.** |
| 79 | + `conformance.md` states what the boot-profile item's machine check covers (the identity, |
| 80 | + loading, and posture headings, reported as a `boot-profile-sections` warning on every |
| 81 | + `validate`) and what rides the opt-in content lint; `context-layer.md` requirement 4 and |
| 82 | + the manifest schema's `rootPath` description name the viewer's `homepage`, `logo`, and |
| 83 | + `favicon` as the one path convention written relative to the context root; `governance.md` |
| 84 | + reads "the owner tends the system's health". Every translation follows. |
| 85 | + |
| 86 | +### Fixed |
| 87 | + |
| 88 | +- **The site builds from any working directory.** Pages find the repository by walking up to |
| 89 | + `leji.json` instead of assuming Astro's working directory, so `astro build` from the |
| 90 | + repository root reads the same schemas and specification as a build from the site package. |
| 91 | + |
| 92 | +## 1.4.1 · 2026-08-26 |
4 | 93 |
|
5 | 94 | A hardening release. The CLI keeps its own generated tree out of git, the viewer takes the |
6 | 95 | brand's typography, the federation commands say which act failed and how to recover, and the |
|
0 commit comments