Skip to content

Commit 66d5cd6

Browse files
ci(check-links): widen lychee's inputs to docs/** and the root history pages (#26313)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi97jMShinfrgwb8tLuAanQ3t)_ Fixes #26087 Clause-②: no Metadata-protocol: none ## What `check-links.yml` handed lychee only `content/**`, `README.md` and `ARCHITECTURE.md`, so a dead relative link anywhere in `docs/` or in the root history pages was checked by nothing. This PR widens the **same job's** input (no new workflow, no new gate, no path filter) and fixes every link the wider run reports. - `LYCHEE_ARGS` gains `'docs/**/*.md'`, `CHANGELOG.md`, `RELEASE_NOTES.md`, `CONTRIBUTING.md`, `ROADMAP.md`, `LICENSING.md`, `CODE_OF_CONDUCT.md`. - `docs/adr/` is taken back out with `--exclude-path '^docs/adr/'`: the `Check ADR cross-links` step in the same job owns that registry, with its own shrink-only baseline, so one link gets one verdict. The workflow's comment above the argv is rewritten to say that (it previously justified the exclusion by "8 broken ADR links today", which no longer holds, see Acceptance notes). - `AGENTS.md` is not added and not edited (other cards hold it). Measured separately: its 2 links resolve, 0 errors. - `lychee.toml` is unchanged. ## Link fixes (6) | Where | Dead target | Why it is gone | Fix | |---|---|---|---| | `CHANGELOG.md` (org-scoping entry) | `packages/plugins/plugin-org-scoping/README.md` | package retired from this repo (54e43db) | link removed, "(since retired from this repository)" added | | `CHANGELOG.md` (M9 formula entry) | `content/docs/guides/formula.mdx` | same page renamed to `content/docs/data-modeling/formulas.mdx` (f7606a1) | path updated | | `CHANGELOG.md` (remote API commands entry) | `./REMOTE_API_COMMANDS.md` | deleted as obsolete (e9ba126) | "See … for full documentation" bullet removed | | `RELEASE_NOTES.md` (v0.2.0 package list) | `packages/plugins/driver-memory/CHANGELOG.md` | same file moved to `packages/drivers/driver-memory/` (06ba036) | path updated | | `RELEASE_NOTES.md` (v0.2.0 docs list) | `internal/planning/DEVELOPMENT_ROADMAP.md` | deleted (9d9460b) | bullet removed | | `RELEASE_NOTES.md` (v0.2.0 docs list) | `QUICK_START_IMPLEMENTATION.md` | deleted (9f9a4a2) | bullet removed | Deleted-on-purpose targets lose the sentence; nothing is pointed at a different document. Two moves (same content, new path) get the new path. The card's sampled `docs/NEXT_STEP.md` and `docs/releases-maintenance.md` links are already gone on `main` (#26271, #26021): `docs/**` reports 0 errors before this PR. ## Acceptance lychee **0.24.2** (the pinned version, built from crates.io in the card container), CI's argv read out of the workflow YAML with `github.workspace` substituted, cache file removed before each run, tree = `origin/main` 69aa630 for "before" and fceddfe for "after": | Run | Inputs | Result | |---|---|---| | before, current CI set | 4 globs | 2520 total · 0 errors (exit 0) | | **before, widened set** | 11 globs, `docs/adr/` excluded | 2887 total · **6 errors** (exit 2): 3 in `CHANGELOG.md`, 3 in `RELEASE_NOTES.md`, 0 in `docs/**` | | **after, this PR's argv** | 11 globs, `docs/adr/` excluded | 2883 total · **0 errors** (exit 0) | - Exclusion syntax measured: `--exclude-path '^docs/adr/'` drops every `docs/adr/` input and nothing else, and `lychee.toml`'s own `exclude_path` (meta.json) keeps applying alongside it (`--dump-inputs` with and without the flag). - Negative control on fceddfe: a dead link planted in `docs/HARDENING.md`, `ROADMAP.md` and an ADR → exit 2 with exactly 2 errors (the `docs/` and `ROADMAP.md` ones; the ADR one is not read). Restored from `HEAD`, `git diff HEAD` empty. - Time: lychee itself 63–66 ms → 70–94 ms locally (3 runs each). The job's recent wall time on PRs is 31–36 s (runs 40393608080, 40393580234, 40393044766, 40392691453, 40392656950, 40391655111), almost all of it checkout and the binary download, so no measurable growth is expected; this PR's own `Check Links` run is the after reading. - `node scripts/check-adr-links.mjs --self-test && node scripts/check-adr-links.mjs` → exit 0, 807 destinations resolve. - `pnpm check:doc-authoring` → exit 0. ## Gates `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on fceddfe derived 37 commands; all 37 ran locally with stdin from `/dev/null`, every exit 0 (incl. `pnpm check:pm-dispatch-gates`, fast tier, 243 s). `--ran` reconciliation: **37 derived, 37 run, 0 NOT-MEASURED** (a derived zero). Every other family is CI's, read from this PR's check-runs. ## Acceptance notes - The ⛔ comment this PR replaces said adding `docs/adr/**` would report 8 broken links; measured today it reports **0** (the widened run with no exclusion: 4217 total, the same 6 errors, none under `docs/adr/`), and `check-adr-links.mjs`'s `KNOWN_DEAD_TARGETS` is empty. The exclusion is kept on ownership grounds, not on rot. `scripts/check-adr-links.mjs`'s header still says lychee runs "exactly three globs"; that prose is now stale (observation only; outside this card's file surface). - `docs/NORTH-STAR.md` is inside `docs/**` and is a governed file; it reports 0 errors, so the widened glob reads it but this PR does not edit it. ## Changeset None: the diff touches a workflow and two root history files, which no package publishes. `skip-changeset` is set at creation. ## 维护者速读(草稿) **改了什么**:链接检查原来只看 `content/`、README 和 ARCHITECTURE,现在同一个任务也检查 `docs/` 下的文档(ADR 除外,ADR 已有自己的检查)和 6 个根目录文档(CHANGELOG、RELEASE_NOTES、CONTRIBUTING、ROADMAP、LICENSING、CODE_OF_CONDUCT)。顺手修掉扩大范围后查出的 6 个坏链,都在 CHANGELOG 和 RELEASE_NOTES 的历史条目里。 **为什么改**:读者从发布说明或路线图点链接会落到 404,而本该发现它的检查从来没看过这些文件。 **风险与代价(含回滚)**:这条检查是建议性的,不在必过集合里,不会挡合并。用时几乎不变(lychee 本身多几十毫秒)。将来有人在 `docs/` 或这些根文件里写坏链,这条检查会变红。回滚就是撤掉 `check-links.yml` 里新增的几行。 **席位意见**: **你要做的**:这是受管文件(`.github/workflows/`)的改动,需要你审批后才能落地。PR 保持 draft,席位不会自己转 ready 或开自动合并。 --- _Generated by [Claude Code](https://claude.ai/code/session_019PqtBRVkBPJHnCXGWvUQED)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7e6fca0 commit 66d5cd6

3 files changed

Lines changed: 28 additions & 22 deletions

File tree

‎.github/workflows/check-links.yml‎

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,30 +62,39 @@ jobs:
6262
# green at all: 1286 root-relative links fail as "Cannot resolve
6363
# root-relative link ... provide a root dir".
6464
#
65-
# ⛔ Do NOT add `docs/adr/**/*.md` here. It looks like the one-line fix
66-
# for #6592 and it is not: measured on the pinned lychee 0.24.2, that
67-
# glob reports 8 broken links today, every one a pre-existing ADR →
68-
# source-tree link whose target moved out of this repo. This job would
69-
# be red on every PR from the moment it merged, which is how an
70-
# advisory lane becomes a lane nobody reads (#6028 landed it
71-
# advisory-first specifically to earn a green streak). `docs/adr/` is
72-
# checked by the `Check ADR cross-links` step below instead, which can
73-
# freeze those 8 on a shrink-only baseline and fail on a NEW one --
74-
# something neither `exclude` nor `.lycheeignore` can express, because
75-
# neither ever tells you an entry stopped being needed.
76-
# `ARCHITECTURE.md` joined this glob in #6867: unlike `docs/adr/**`, it
77-
# carried no pre-existing rot once its 10 dead links + 2 stale path
78-
# references were fixed in the same PR, so -- unlike the ADR directory
79-
# above -- it needs no KNOWN_DEAD_TARGETS-style baseline to land clean.
65+
# ⛔ `docs/adr/` stays OUT of lychee's reach: `'docs/**/*.md'` below
66+
# would sweep it in, so `--exclude-path '^docs/adr/'` takes it back out
67+
# (a regex over the input path as globbed, measured to drop exactly that
68+
# directory on the pinned 0.24.2 while `lychee.toml`'s own `exclude_path`
69+
# entries keep applying -- the CLI flag adds to them, it does not replace
70+
# them). The decision registry has ONE link owner, the `Check ADR
71+
# cross-links` step below, which can freeze a pre-existing break on a
72+
# shrink-only baseline and fail on a NEW one -- something neither
73+
# `exclude` nor `.lycheeignore` can express, because neither ever tells
74+
# you an entry stopped being needed. Checking the same files twice, under
75+
# two rule sets, would put two verdicts on one link.
76+
# `ARCHITECTURE.md` joined this glob in #6867; `docs/**` and the root
77+
# history/governance pages (CHANGELOG, RELEASE_NOTES, CONTRIBUTING,
78+
# ROADMAP, LICENSING, CODE_OF_CONDUCT) joined in #26087, each landing
79+
# clean once its dead links were fixed in the same PR, so none needs a
80+
# KNOWN_DEAD_TARGETS-style baseline.
8081
LYCHEE_ARGS: >-
8182
--offline
8283
--root-dir ${{ github.workspace }}/content
8384
--fallback-extensions mdx,md
8485
--config lychee.toml
86+
--exclude-path '^docs/adr/'
8587
'content/**/*.md'
8688
'content/**/*.mdx'
8789
'README.md'
8890
'ARCHITECTURE.md'
91+
'docs/**/*.md'
92+
'CHANGELOG.md'
93+
'RELEASE_NOTES.md'
94+
'CONTRIBUTING.md'
95+
'ROADMAP.md'
96+
'LICENSING.md'
97+
'CODE_OF_CONDUCT.md'
8998
9099
# ⛔ Pin the lychee binary explicitly rather than inheriting the action's
91100
# default (#8238). Three comments in this file already reason about "the

‎CHANGELOG.md‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ the `organization_id` auto-stamp middleware, the `sys_organization`
160160
post-create seed-replay pipeline, the default-organization bootstrap,
161161
and the `cloneTenantSeedData` export.
162162

163-
**New package**: [`@objectstack/plugin-org-scoping`](packages/plugins/plugin-org-scoping/README.md)
164-
ships the row-level Organization scoping primitives — `organization_id`
163+
**New package**: `@objectstack/plugin-org-scoping` (since retired from this
164+
repository) ships the row-level Organization scoping primitives — `organization_id`
165165
auto-stamp, per-org seed replay, default-org bootstrap, orphan-row
166166
claim, and a new `org-scoping` service that `plugin-security` probes at
167167
start time to decide whether to keep wildcard `tenant_isolation` RLS
@@ -1027,7 +1027,7 @@ Followup to M10.30a. Walked every Setup menu in a real tenant; produced verdict
10271027
- **Dynamic seed values** (`@objectstack/runtime` SeedLoader) — `Dataset.records` now accepts `cel\`...\`` expressions for fields whose value depends on the install-time clock or identity. SeedLoader walks records and evaluates expressions through `ExpressionEngine` with a single per-load pinned `now`, so package authors can ship `close_date: cel\`daysFromNow(45)\`` without baking their laptop's timestamp into the artifact. Determinism gate enforced via SHA-1 comparison of two consecutive `objectstack build` runs. Resolves D11.
10281028
- **CRM example migrated to CEL** (`examples/app-crm`) — All 4 formula fields (`lead.full_name`, `contact.full_name`, `campaign.response_rate`, `campaign.roi`) re-written in CEL using the `coalesce()` / ternary patterns. 48 dynamic-date seed values migrated from `new Date()` (compile-time) to `cel\`daysFromNow(N)\`` / `cel\`daysAgo(N)\`` (install-time). Browser-verified end-to-end via `pnpm dev:crm`: `Lead.full_name` renders "Lisa Thompson", `Campaign.roi` renders `1907.04` in the dashboard.
10291029
- **`planFormulaProjection` evaluates on default REST projection** (`@objectstack/objectql`) — Previously formulas were only computed when the caller passed an explicit `?fields=` projection. The REST default returns all columns but no formulas, so `Field.type === 'formula'` columns came back as `null` in the dashboard's auto-generated views. Fix: when `requestedFields` is empty/undefined, target every field in the schema for formula evaluation while leaving `projected` undefined so the driver still returns the default column set.
1030-
- **New `objectstack-formula` skill** ([`skills/objectstack-formula/SKILL.md`](skills/objectstack-formula/SKILL.md)) and rewritten [`content/docs/guides/formula.mdx`](content/docs/guides/formula.mdx) — Author-facing documentation of the canonical CEL contract: stdlib reference, mandatory patterns for AI emission, mechanical translation table from the legacy Salesforce-flavor DSL, and the determinism contract.
1030+
- **New `objectstack-formula` skill** ([`skills/objectstack-formula/SKILL.md`](skills/objectstack-formula/SKILL.md)) and rewritten [`content/docs/data-modeling/formulas.mdx`](content/docs/data-modeling/formulas.mdx) — Author-facing documentation of the canonical CEL contract: stdlib reference, mandatory patterns for AI emission, mechanical translation table from the legacy Salesforce-flavor DSL, and the determinism contract.
10311031

10321032
### Removed — M9 Expression Unification
10331033
- **Custom Salesforce-flavor formula engine** (`@objectstack/objectql`) — Deleted `packages/objectql/src/formula.ts` (433 LoC hand-written recursive-descent parser exposing 22 functions: `CONCAT`/`UPPER`/`IF`/`AND`/`OR`/`ISBLANK`/`TODAY`/…) and its companion `packages/spec/docs/formula-functions.md`. The engine had no formal grammar, no public training corpus, no AST persistence, and was a single-vendor surface. **Salesforce compatibility is not pursued** — see [north-star §8](content/docs/concepts/north-star.mdx) "No private expression DSL". Authors targeting Salesforce semantics rewrite their formulas in CEL using the translation table in the formula skill. Resolves D9.
@@ -1352,7 +1352,6 @@ Followup to M10.30a. Walked every Setup menu in a real tenant; produced verdict
13521352
- All commands support `--url` and `--token` flags, or use stored credentials from `~/.objectstack/credentials.json`
13531353
- Multiple output formats: `--format json|table|yaml` (yaml available on all commands)
13541354
- Environment variable support: `OBJECTSTACK_URL`, `OBJECTSTACK_TOKEN`
1355-
- See [REMOTE_API_COMMANDS.md](./REMOTE_API_COMMANDS.md) for full documentation
13561355

13571356
### Changed
13581357
- **i18n: `I18nLabelSchema` now accepts `string` only** — `label`, `description`, `title`,

‎RELEASE_NOTES.md‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ See individual CHANGELOG.md files in each package:
286286
- [packages/client/CHANGELOG.md](packages/client/CHANGELOG.md)
287287
- [packages/objectql/CHANGELOG.md](packages/objectql/CHANGELOG.md)
288288
- [packages/runtime/CHANGELOG.md](packages/runtime/CHANGELOG.md)
289-
- [packages/plugins/driver-memory/CHANGELOG.md](packages/plugins/driver-memory/CHANGELOG.md)
289+
- [packages/drivers/driver-memory/CHANGELOG.md](packages/drivers/driver-memory/CHANGELOG.md)
290290
- [packages/plugins/plugin-hono-server/CHANGELOG.md](packages/plugins/plugin-hono-server/CHANGELOG.md)
291291
- [packages/types/CHANGELOG.md](packages/types/CHANGELOG.md)
292292

@@ -321,9 +321,7 @@ Version tag `v0.2.0` has been created for this release.
321321
## 📚 Documentation
322322

323323
Full documentation is available at:
324-
- Development Roadmap: [DEVELOPMENT_ROADMAP.md](internal/planning/DEVELOPMENT_ROADMAP.md)
325324
- Architecture: [ARCHITECTURE.md](ARCHITECTURE.md)
326-
- Quick Start: [QUICK_START_IMPLEMENTATION.md](QUICK_START_IMPLEMENTATION.md)
327325

328326
## 🛠️ Build Status
329327

0 commit comments

Comments
 (0)