Skip to content

feat(migrate): os migrate value-shapes —— 引用/结构化 JSON 值形态的按部署门禁(#3438 第 2 项) #2088

feat(migrate): os migrate value-shapes —— 引用/结构化 JSON 值形态的按部署门禁(#3438 第 2 项)

feat(migrate): os migrate value-shapes —— 引用/结构化 JSON 值形态的按部署门禁(#3438 第 2 项) #2088

name: Spec Liveness Check
# For a metadata-driven platform the spec is the product surface — a parsed-but-
# unenforced property is a silent no-op (and, for security props, false compliance).
# This gate reads the metadata-type registry (the authorable types) and requires every
# property of a GOVERNED type to declare a liveness status with evidence in
# packages/spec/liveness/<type>.json. A new unclassified property fails the check (the
# ratchet: no new undeclared surface). See packages/spec/liveness/README.md.
#
# ADR-0054 (prove-it-runs): bound high-risk 'live' properties must carry a `proof`
# pointing to a dogfood test that declares the matching `@proof:` tag. The gate also
# triggers on packages/qa/dogfood/** so deleting/renaming a proof re-runs this check and
# the dangling reference is caught (the proof files live outside packages/spec/).
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'packages/spec/**'
- 'packages/qa/dogfood/**'
# The variant/doc gate reads hand-written pages, so editing one can break it
# without touching packages/spec at all.
- 'content/docs/**'
permissions:
contents: read
jobs:
liveness:
name: Spec property liveness
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22'
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Check spec liveness
run: pnpm --filter @objectstack/spec check:liveness
# #3896 follow-up. The liveness ledger asks whether a property does anything;
# this asks what its EMPTY value MEANS. A restriction-shaped property whose
# empty state is permissive has to be classified on purpose — omission is the
# commonest authoring error, and it must not also be the widest grant.
- name: Check empty-state semantics
run: pnpm --filter @objectstack/spec check:empty-state
# #4165 follow-up. Those two gates ask what a property does and what its empty
# value means. This asks the inverse-drift question neither covers: does a variant
# the schema declares appear in the hand-written doc at all? references/ is
# generated and cannot drift; the hand-written pages are typed by humans and do.
# apps.mdx said the nav tree had "eight item types" while the schema had nine.
- name: Check discriminated-union variants are documented
run: pnpm --filter @objectstack/spec check:variant-docs