Skip to content

Commit d41a173

Browse files
committed
ci(check-links): 恢复 pull_request 断链门,仅检仓内链接 (#6028)
按维护者 2026-08-07 裁决恢复 `Check Links`:重新启用 `pull_request` 触发(branches: main),保留 `workflow_dispatch`,`fail: true` 不变; 方向②(留空壳写注释)已被否决,故被注释掉的 `push:` 残骸按 「declared = enforced」直接删除,而不是留在文件里继续误导读者。 ⛔ advisory-first:不进 required 集,也不加 `merge_group` —— advisory 车道不该消耗合并队列容量。日后若晋级 required,必须按 #6121 的教训在 同一次改动里补上 `merge_group`,否则队列会卡在一个永不上报的必需检查上。 仅检仓内链接的机制选 `--offline`,写在调用处而不是 lychee.toml: 实测 `offline = true` 这个配置键在 lychee 0.19.1 上被静默忽略、在 action 当前钉住的 0.24.2 上才生效,确定性保证不能取决于 action 恰好 装了哪个版本。`^https?://` 这类 exclude 也不够 —— 它要逐个枚举远程 scheme,漏一个就重新引入外网依赖。 门休眠半年期间配置已经漂移到跑不起来,这次一并修好(否则恢复触发器 只会让门以 exit 3 直接死掉,连链接都不检): - `follow_redirects` 在 0.24.2 上根本不是合法键 —— 硬解析错误; - `include_fragments` 已从 bool 变成枚举,裸 `false` 同样硬报错, 改为 `"none"` 保持原语义(不检 fragment)。 root-relative 链接是 content/** 的主力写法,而 lychee 在没有 root-dir 时对它们直接报错。补 `--root-dir <workspace>/content` + `--fallback-extensions mdx,md` 之后,1286 条此前完全没被检查的 `/docs/*` 链接首次纳入检查面(134 → 1476 条被检)。原来的 `remap` 块一次都没生效过(URI 构造在 remap 之前就失败),已按 declared = enforced 删除,能力由真正生效的 root-dir 承接。 修掉门首次真正运行后暴露的 22 条既有真断链(仅改链接目标,不改散文): - 14 条 ADR 链接归一到仓内既有约定(29 处在用的 GitHub blob URL): `/adr/*` 站点路由并不存在,apps/docs 只有 /[lang]/docs 与 /[lang]/blog 两条路由,也没有任何 /adr 重定向 —— 这些链接在线上 就是 404; - quick-reference 三行指向已退役 schema 的表项删除(audit.zod 按 ADR-0056 移除、registry.zod 按 #4939 退役、graphql.zod 全仓无踪), 并同步修正两处小节计数;connector-auth 有 schema 无页面,改为不带 链接保留信息;plugin-security 页面在 references/kernel 而非 cloud; - README 两处:`@objectstack/account` 已迁到 packages/apps/account; `service-feed` 已在 #1955 删除,整行移除。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
1 parent 6131d90 commit d41a173

9 files changed

Lines changed: 104 additions & 65 deletions

File tree

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

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
name: Check Links
22

3+
# Repo-internal link gate (#6028).
4+
#
5+
# `pull_request` was commented out in a59dc59e (2026-01-28) as a rider on an
6+
# unrelated commit, with no rationale recorded; the gate then sat dormant for
7+
# six months while `lychee.toml` and `fail: true` kept it looking alive.
8+
# Maintainer ruling 2026-08-07: restore the trigger, check REPO-INTERNAL links
9+
# only, and land it advisory-first (NOT in the required set) until it has shown
10+
# a stable green streak.
11+
#
12+
# ⛔ No `merge_group` trigger on purpose: this is an advisory lane, and an
13+
# advisory gate does not get to consume merge-queue capacity. If it is ever
14+
# promoted into the required set, `merge_group` MUST be added in the same
15+
# change or the queue stalls on a required check that never reports (#6121).
316
on:
417
workflow_dispatch:
5-
# push:
6-
# branches:
7-
# - main
8-
# pull_request:
9-
# branches:
10-
# - main
18+
pull_request:
19+
branches:
20+
- main
1121

1222
jobs:
1323
link-checker:
1424
name: Check Documentation Links
1525
runs-on: ubuntu-latest
26+
# Least privilege: the job only reads the tree and runs lychee offline.
27+
# There is no issue-filing step, and `--offline` makes zero network
28+
# requests, so neither `issues: write` nor a GITHUB_TOKEN is needed.
1629
permissions:
1730
contents: read
18-
issues: write
1931

2032
steps:
2133
- name: Checkout repository
@@ -24,14 +36,32 @@ jobs:
2436
- name: Check links with lychee
2537
uses: lycheeverse/lychee-action@v2
2638
with:
27-
# Use configuration file for path remapping and settings
39+
# `--offline` is the internal-only mechanism, and it lives HERE rather
40+
# than in lychee.toml on purpose: the equivalent `offline = true`
41+
# config key is silently ignored by older lychee (measured: ignored on
42+
# 0.19.1, honoured on the 0.24.2 this action pins). A determinism
43+
# guarantee must not depend on which lychee the action happens to
44+
# install, so it is asserted at the invocation site.
45+
#
46+
# Offline means only `file://` targets are resolved -- every http(s)
47+
# link is reported EXCLUDED, never requested. That is what makes this
48+
# gate deterministic and free of external-network flake.
49+
#
50+
# --root-dir is what makes ROOT-RELATIVE links checkable. Most internal
51+
# links in content/** are site routes (`/docs/permissions`), and lychee
52+
# hard-errors on those unless it is told which directory `/` means.
53+
# The Fumadocs content root is `content/`, so `/docs/x` resolves to
54+
# content/docs/x -- and --fallback-extensions supplies the .mdx/.md
55+
# suffix that a site route omits. Without this pair the gate cannot go
56+
# green at all: 1286 root-relative links fail as "Cannot resolve
57+
# root-relative link ... provide a root dir".
2858
args: >-
59+
--offline
60+
--root-dir ${{ github.workspace }}/content
61+
--fallback-extensions mdx,md
2962
--config lychee.toml
3063
'content/**/*.md'
3164
'content/**/*.mdx'
3265
'README.md'
3366
# Fail the job if broken links are found
3467
fail: true
35-
env:
36-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37-

‎README.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ For the browser, the typed client SDK and React hooks (`useQuery` / `useMutation
321321
| [`@objectstack/service-analytics`](packages/services/service-analytics) | Analytics — aggregations, time series, funnels, dashboards |
322322
| [`@objectstack/service-automation`](packages/services/service-automation) | Automation engine — flows, triggers, and workflow state machines |
323323
| [`@objectstack/service-cache`](packages/services/service-cache) | Cache — in-memory, Redis, multi-tier |
324-
| [`@objectstack/service-feed`](packages/services/service-feed) | Activity feed / chatter |
325324
| [`@objectstack/service-i18n`](packages/services/service-i18n) | Internationalization service |
326325
| [`@objectstack/service-job`](packages/services/service-job) | Cron & interval job scheduler |
327326
| [`@objectstack/service-package`](packages/services/service-package) | Package registry — publish, version, retrieve metadata packages |
@@ -343,7 +342,7 @@ For the browser, the typed client SDK and React hooks (`useQuery` / `useMutation
343342
| [`@objectstack/cli`](packages/cli) | CLI binary (`os` / `objectstack`) — `init`, `dev`, `start`, `serve`, `compile`, `publish`, `validate`, `generate`, `lint`, `doctor` |
344343
| [`create-objectstack`](packages/create-objectstack) | Project scaffolder (`npx create-objectstack`) |
345344
| [`@object-ui/console`](https://github.com/objectstack-ai/objectui/tree/main/apps/console) | Fork-ready runtime console SPA (lives in objectstack-ai/objectui, served via `@object-ui/console` on npm) |
346-
| [`@objectstack/account`](apps/account) | Account & identity portal — sign in, organizations, connected apps |
345+
| [`@objectstack/account`](packages/apps/account) | Account & identity portal — sign in, organizations, connected apps |
347346
| [`@objectstack/docs`](apps/docs) | Documentation site (Fumadocs + Next.js) |
348347

349348
### Examples

‎content/blog/metadata-driven-architecture.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,4 +583,4 @@ ObjectStack is our answer.
583583

584584
---
585585

586-
*Want to dive deeper? Explore our [technical specifications](/docs/specifications) or join the discussion on [GitHub](https://github.com/objectstack-ai/spec/issues).*
586+
*Want to dive deeper? Explore our [technical specifications](/docs/references) or join the discussion on [GitHub](https://github.com/objectstack-ai/spec/issues).*

‎content/docs/ai/connect-mcp.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ full-authority local agent, mint the key on a platform-admin or dedicated
113113
**service** identity; for a scoped one, mint it on a user with exactly the
114114
access it should have. See
115115
[environment variables](/docs/deployment/environment-variables#mcp-server) for
116-
the switches and [ADR-0101](/adr/0101-mcp-stdio-principal-admission) for the
116+
the switches and [ADR-0101](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0101-mcp-stdio-principal-admission.md) for the
117117
decision.
118118

119119
## What the agent gets

‎content/docs/getting-started/quick-reference.mdx‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,12 @@ Plugin architecture, manifests, and kernel runtime.
7676
| **[Metadata Loader](/docs/references/kernel/metadata-loader)** | `metadata-loader.zod.ts` | MetadataLoaderContract | Metadata loading |
7777
| **[Package Registry](/docs/references/kernel/package-registry)** | `package-registry.zod.ts` | InstalledPackage, InstallPackageRequest | Package resolution |
7878

79-
## System Protocol (19 schemas)
79+
## System Protocol (18 schemas)
8080

8181
Runtime environment, logging, jobs, caching, and observability.
8282

8383
| Protocol | Source File | Key Schemas | Purpose |
8484
|:---------|:-----------|:------------|:--------|
85-
| **[Audit](/docs/references/system/audit)** | `audit.zod.ts` | AuditEvent, AuditConfig | Audit trail logging |
8685
| **[Auth Config](/docs/references/system/auth-config)** | `auth-config.zod.ts` | AuthConfig | Authentication configuration |
8786
| **[Cache](/docs/references/system/cache)** | `cache.zod.ts` | CacheConfig | Caching layer |
8887
| **[Change Management](/docs/references/system/change-management)** | `change-management.zod.ts` | ChangeRequest, RollbackPlan | Change tracking |
@@ -120,7 +119,7 @@ AI/ML capabilities - agents, skills, tools, MCP exposure, RAG, and cost tracking
120119
| **[Usage](/docs/references/ai/usage)** | `usage.zod.ts` | AIUsageRecord, TokenUsage | AI usage and cost tracking |
121120
| **[Solution Blueprint](/docs/references/ai/solution-blueprint)** | `solution-blueprint.zod.ts` | BlueprintObject, BlueprintApp | Blueprint format for AI app generation |
122121

123-
## API Protocol (19 schemas)
122+
## API Protocol (17 schemas)
124123

125124
REST/GraphQL endpoints, real-time subscriptions, and discovery.
126125

@@ -130,7 +129,6 @@ REST/GraphQL endpoints, real-time subscriptions, and discovery.
130129
| **[Endpoint](/docs/references/api/endpoint)** | `endpoint.zod.ts` | ApiEndpoint, ApiMapping | REST endpoint configuration |
131130
| **[Router](/docs/references/api/router)** | `router.zod.ts` | Router, Route | API routing rules |
132131
| **[OData](/docs/references/api/odata)** | `odata.zod.ts` | ODataQuery | OData protocol support |
133-
| **[GraphQL](/docs/references/api/graphql)** | `graphql.zod.ts` | GraphQLConfig, FederationEntity | GraphQL API config |
134132
| **[Realtime](/docs/references/api/realtime)** | `realtime.zod.ts` | Subscription, RealtimeEvent | WebSocket subscriptions |
135133
| **[WebSocket](/docs/references/api/websocket)** | `websocket.zod.ts` | WebSocketConfig | WebSocket protocol |
136134
| **[Discovery](/docs/references/api/discovery)** | `discovery.zod.ts` | Discovery, ServiceInfo | API discovery and metadata |
@@ -143,7 +141,6 @@ REST/GraphQL endpoints, real-time subscriptions, and discovery.
143141
| **[Analytics](/docs/references/api/analytics)** | `analytics.zod.ts` | Analytics | API usage analytics |
144142
| **[Documentation](/docs/references/api/documentation)** | `documentation.zod.ts` | Documentation | API docs generation |
145143
| **[Metadata](/docs/references/api/metadata)** | `metadata.zod.ts` | Metadata | API metadata endpoints |
146-
| **[Registry](/docs/references/api/registry)** | `registry.zod.ts` | Registry | API registry |
147144
| **[Storage](/docs/references/api/storage)** | `storage.zod.ts` | Storage | API storage operations |
148145

149146
## Automation Protocol (5 schemas)
@@ -188,7 +185,7 @@ Environments, marketplace, licensing, and multi-tenancy.
188185
| **[Environment](/docs/references/cloud/environment)** | `environment.zod.ts` | Environment, EnvironmentType | Deployment environments |
189186
| **[Marketplace](/docs/references/cloud/marketplace)** | `marketplace.zod.ts` | MarketplaceListing, PackageSubmission | Plugin marketplace |
190187
| **[Plugin Registry](/docs/references/kernel/plugin-registry)** | `plugin-registry.zod.ts` | PluginRegistryEntry, PluginVendor | Plugin registry entries and quality metrics |
191-
| **[Plugin Security](/docs/references/cloud/plugin-security)** | `plugin-security.zod.ts` | PluginSecurityProtocol, SBOM | Plugin security policies |
188+
| **[Plugin Security](/docs/references/kernel/plugin-security)** | `plugin-security.zod.ts` | PluginSecurityProtocol, SBOM | Plugin security policies |
192189
| **[Tenant](/docs/references/cloud/tenant)** | `tenant.zod.ts` | Tenant | Multi-tenancy isolation |
193190

194191
## Integration Protocol (1 schema)
@@ -214,7 +211,7 @@ Common utilities used across all protocols.
214211
| **[HTTP](/docs/references/shared/http)** | `http.zod.ts` | HttpRequest, HttpMethod, CorsConfig | HTTP utilities |
215212
| **[Identifiers](/docs/references/shared/identifiers)** | `identifiers.zod.ts` | SystemIdentifier, SnakeCaseIdentifier | Standard ID patterns |
216213
| **[Mapping](/docs/references/shared/mapping)** | `mapping.zod.ts` | FieldMapping | Field mapping utilities |
217-
| **[Connector Auth](/docs/references/shared/connector-auth)** | `connector-auth.zod.ts` | ConnectorAuthConfig | Connector auth patterns |
214+
| **Connector Auth** | `connector-auth.zod.ts` | ConnectorAuthConfig | Connector auth patterns |
218215

219216
## QA Protocol (1 schema)
220217

‎content/docs/permissions/attachments-access.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ an auth service is wired, and stamp `owner_id` on the new `sys_file`.
103103

104104
Deleting attachments does not immediately delete the underlying bytes (a file
105105
can be shared across records). Reclamation is handled by the platform LifecycleService via declarative
106-
[reap guards](/adr/0057-system-data-lifecycle-and-retention):
106+
[reap guards](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0057-system-data-lifecycle-and-retention.md):
107107

108108
- **`sys_file`** — when the last `sys_attachment` referencing an
109109
attachments-scope file is deleted, the file is tombstoned; a reap guard

‎content/docs/permissions/authorization.mdx‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -409,16 +409,16 @@ The complete, prioritized gap map lives in issue **#2561** (the production
409409

410410
| ADR | Owns |
411411
|---|---|
412-
| [0049](/adr/0049-no-unenforced-security-properties) | No unenforced security properties (enforce / mark / remove) |
413-
| [0054](/adr/0054-runtime-proof-for-authorable-surface) | Prove-it-runs — high-risk classes need runtime proofs |
414-
| [0056](/adr/0056-permission-model-landing-verification) | Permission-model landing: OWD, anonymous deny default, D10 matrix |
415-
| [0057](/adr/0057-erp-authorization-core-business-units-and-scope-depth) | Business units, scope depth, declarative RBAC seeding, platform-owned assignment |
416-
| [0066](/adr/0066-unified-authorization-model) | Unified model: capability registry, posture, precedence, future refinements |
417-
| [0068](/adr/0068-unified-user-context-and-built-in-identity-roles) | Built-in identity positions (formerly "identity roles"), `EvalUser` |
418-
| [0069](/adr/0069-enterprise-authentication-hardening) | Enterprise authentication hardening (phased) |
419-
| [0078](/adr/0078-no-silently-inert-metadata) | No inert declarable metadata |
420-
| [0086](/adr/0086-authz-metadata-config-boundary-and-cross-package-composition) | Metadata↔config boundary, package provenance, cross-package composition |
412+
| [0049](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0049-no-unenforced-security-properties.md) | No unenforced security properties (enforce / mark / remove) |
413+
| [0054](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0054-runtime-proof-for-authorable-surface.md) | Prove-it-runs — high-risk classes need runtime proofs |
414+
| [0056](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0056-permission-model-landing-verification.md) | Permission-model landing: OWD, anonymous deny default, D10 matrix |
415+
| [0057](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md) | Business units, scope depth, declarative RBAC seeding, platform-owned assignment |
416+
| [0066](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0066-unified-authorization-model.md) | Unified model: capability registry, posture, precedence, future refinements |
417+
| [0068](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0068-unified-user-context-and-built-in-identity-roles.md) | Built-in identity positions (formerly "identity roles"), `EvalUser` |
418+
| [0069](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0069-enterprise-authentication-hardening.md) | Enterprise authentication hardening (phased) |
419+
| [0078](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0078-no-silently-inert-metadata.md) | No inert declarable metadata |
420+
| [0086](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0086-authz-metadata-config-boundary-and-cross-package-composition.md) | Metadata↔config boundary, package provenance, cross-package composition |
421421
| 0090 | Permission Model v2: position rename + vocabulary freeze, profile removal, fail-closed OWD default + external dial, audience anchors, principal taxonomy, publish linter, delegated administration, explain engine + access matrix |
422422
| 0091 | Grant lifecycle: validity windows + resolution-time filtering (L1, landed), delegation, break-glass, recertification substrate |
423-
| [0096](/adr/0096-execution-surface-identity-admission) | Execution-surface identity admission — no data-engine call without an explicit principal (the MCP HTTP surface admits identity here) |
424-
| [0101](/adr/0101-mcp-stdio-principal-admission) | MCP stdio principal admission — env-supplied API-key identity, fail-closed, no `system` bypass |
423+
| [0096](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0096-execution-surface-identity-admission.md) | Execution-surface identity admission — no data-engine call without an explicit principal (the MCP HTTP surface admits identity here) |
424+
| [0101](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0101-mcp-stdio-principal-admission.md) | MCP stdio principal admission — env-supplied API-key identity, fail-closed, no `system` bypass |

‎content/docs/references/automation/state-machine.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The ledger carried these shapes as `authorable (p)` — provisional, because
2121

2222
nobody had checked. Checking matters here more than usual, because
2323

24-
[ADR-0020](../../../docs/adr/0020-state-machine-converge-and-enforce.md)
24+
[ADR-0020](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0020-state-machine-converge-and-enforce.md)
2525

2626
**retired this shape as a record-lifecycle declaration**: the top-level
2727

0 commit comments

Comments
 (0)