Merge remote-tracking branch 'origin/codex/package-readme-limitations-audit-20260712' into codex/model-experience-readmes-20260712

# Conflicts:
#	docs/cookbook/adding-a-package.md
#	docs/rfc/INDEX.md
#	package.json
#	packages/AGENTS.md
#	packages/bash/bash-sandbox/README.md
#	packages/sandbox/sandbox-local/README.md
#	packages/sandbox/sandbox/README.md
#	packages/session-persistence/session-persistence-sqlite/README.md
#	packages/support/acp-snapshot/README.md
#	packages/ui/app-boot/README.md
#	packages/ui/user-approval/README.md
#	packages/workflow/tool-workflow/README.md
This commit is contained in:
Tianyi Cui
2026-07-12 02:48:49 +08:00
73 changed files with 623 additions and 58 deletions

View File

@@ -13,7 +13,10 @@ packages/<group>/<pkg>/
# you use Config, + ../../<group>/<dep> for each dsh dep)
src/index.ts # service default export or plugin (name/inject/apply/Config)
tests/<x>.spec.ts
README.md # contract plus the required Model Experience table
README.md # service API, events, extension points, design notes,
# + the required Model Experience table
# + the gated "Known Limitations and Deferred Work" section
# (or a whitelist entry in scripts/verify-readme-limitations.ts)
```
Fill the canonical [Model Experience table](../AGENTS.md#package-model-experience) from the implementation: name every direct request contribution and token-growth condition, or state zero direct tokens and the exact indirect path. Every package participates, including type-only libraries and backend seams.

View File

@@ -161,6 +161,7 @@ Generated by `pnpm run gen-rfc-index` from the RFC tree — never edit by hand;
| [Raise the Node LTS engine floor to 22.19](implemented/process/2026-07-06-node-engine-floor.md) | 2026-07-06 |
| [Parallel GitHub CI gates](implemented/process/2026-07-06-parallel-github-ci-gates.md) | 2026-07-06 |
| [Parallel pre-push gates](implemented/process/2026-07-06-parallel-pre-push-gates.md) | 2026-07-06 |
| [A gated Known-Limitations section in every package README](implemented/process/2026-07-10-readme-known-limitations-gate.md) | 2026-07-10 |
| [Package Model Experience contract](implemented/process/2026-07-12-package-model-experience-contract.md) | 2026-07-12 |
### Testing

View File

@@ -0,0 +1,28 @@
# RFC: A gated Known-Limitations section in every package README
Status: implemented
## Problem
The [documentation standard](../../../AGENTS.md) assigns limitations to the package-README tier ("the per-package contract: config, semantics, limitations, extension points"), but nothing enforced that the section exists or shares a shape. Ten READMEs carried the content under five ad-hoc headings — "What is NOT here (TODO)", "What is NOT here", "Deferred (faithful-but-degraded)", "Limitations (MVP, documented deliberately)", "Known limitations (tracked TODOs)" — and the other forty-odd carried nothing, so a reader could not distinguish "this package has no known limitations" from "nobody wrote them down", and no grep could enumerate the repo's known gaps.
## Decision
Every package manifest under `packages/<group>/<pkg>/package.json` has a sibling README carrying a canonical `## Known Limitations and Deferred Work` section: a condensed bullet list of consumer-visible gaps (unimplemented features, platform caveats, deliberate MVP cuts) and consciously postponed work (TODO markers, RFC deferrals still open). A `doc-sync` gate, `verify-readme-limitations` ([scripts/verify-readme-limitations.ts](../../../../scripts/verify-readme-limitations.ts)), derives the package set from those manifests, rejects a missing README, and enforces the shape per README: exactly one limitations-like heading, byte-equal to the canonical h2, with at least one top-level bullet. Near-miss headings at any level ("Limitations", "Deferred", "What is NOT here", "Non-goals", …) fail the gate, so variant sections cannot creep back beside — or instead of — the canonical one.
A package with genuinely nothing to declare is whitelisted (`NO_LIMITATIONS` in the script) and must NOT carry the section. The inverted check keeps the whitelist honest in both directions: an empty or boilerplate section cannot satisfy the gate, and giving a whitelisted package real limitations forces the whitelist edit in the same change. Whitelist entries are validated against the scanned package set, so a package rename or removal fails loud instead of silently un-gating a README.
The gate checks presence, shape, and the whitelist; the bullets' truthfulness and specificity are governed by review under the documentation standard, like the rest of the README tier. The standing rule lives in [packages/AGENTS.md](../../../../packages/AGENTS.md).
## Alternatives considered
- **Free-form headings, gate only that "something limitations-like" exists** — keeps the five variants, stays un-greppable, and needs the same near-miss heuristics anyway without buying uniformity.
- **Require the section in ALL READMEs, allowing an empty body or "None."** — boilerplate "None" rots silently as a package gains real limitations; the whitelist inversion turns "nothing declared" into an explicit, lintable claim that review can challenge.
- **A word-count ceiling on the section** — limitation lists are legitimately variable in length; package READMEs are deliberately unbudgeted (per the [budget policy](../../../AGENTS.md)) and review governs their prose.
## Consequences
- A new package cannot ship without either declaring its gaps or explicitly claiming it has none; a missing, drifted, or empty section fails `doc-sync` locally (pre-push) and in CI (`readme-limitations` in the run-gates doc-sync leaf set).
- The pre-existing variant sections are normalized to the canonical heading, and every package README now answers the limitations question one way or the other.
- One more fast tsx script in the `doc-sync` chain; no new dependency (plain `node:fs` glob + line scan).
- The canonical heading is enforced verbatim, so renaming it later is a mechanical one-script-plus-all-READMEs change guarded by the same gate.