Add generated persistence log event catalog with freshness + completeness gates
docs/persistence-catalog/log-events.md enumerates every SessionEventMap member — the owning dsh-session vocabulary plus the dsh-compact and dsh-hook-protocol declaration merges — with payload, surface/log-only badge, JSDoc prose, and declaration site. scripts/gen-persistence-catalog.ts is a pure AST pass in the gen-cordis-catalog mold: verify-persistence-catalog (--check) joins doc-sync, so a stale committed catalog fails pre-push and CI. The walk enforces JSDoc completeness (every member needs description prose; @mode is rejected as a category error — log events do not dispatch on the cordis bus), derives the surface badge from the SurfaceEventType union with a stale-member cross-check, and hard-errors on duplicate declarations. Payloads render through the TypeScript printer so newline-separated multi-line type literals still emit valid one-line fragments. Documented the five previously JSDoc-less core events (turn/step boundaries, tool/call), removed the two stray @mode tags on the hook/* merges, and replaced the hand-restated event enumerations (session.md hook/* table, compact README table, hook-protocol README bullets, session README name-list — whose merge note had already drifted) with links to the catalog. RFC: docs/rfc/implemented/process/2026-07-04-persistence-log-catalog.md.
This commit is contained in:
@@ -9,13 +9,15 @@
|
||||
* opts out with an explicit ` ```ts ignore-check ` info string — the opt-out
|
||||
* is visible in the source, and this script reports the ratio so the escape
|
||||
* hatch can't quietly become the norm. A third info string,
|
||||
* doc-typecheck.ts recognizes two more fence variants and skips both (each is a
|
||||
* separately-checked category, not an unchecked sketch, so neither counts in the
|
||||
* opt-out ratio): ` ```ts type-equiv ` is a verbatim source-type paste that
|
||||
* `scripts/verify-type-equiv.ts` drift-checks, and ` ```ts cordis-catalog ` is a
|
||||
* doc-typecheck.ts recognizes three more fence variants and skips all three (each
|
||||
* is a separately-checked category, not an unchecked sketch, so none counts in
|
||||
* the opt-out ratio): ` ```ts type-equiv ` is a verbatim source-type paste that
|
||||
* `scripts/verify-type-equiv.ts` drift-checks, ` ```ts cordis-catalog ` is a
|
||||
* generated event/service signature fragment in the cordis catalog (a bare
|
||||
* signature is not standalone-compilable; the catalog is generated and frozen by
|
||||
* `scripts/gen-cordis-catalog.ts` + its `--check` freshness gate).
|
||||
* `scripts/gen-cordis-catalog.ts` + its `--check` freshness gate), and
|
||||
* ` ```ts persistence-catalog ` is a generated log-event payload fragment in the
|
||||
* persistence catalog (same reasoning, frozen by `scripts/gen-persistence-catalog.ts`).
|
||||
*
|
||||
* Run: `tsx scripts/doc-typecheck.ts`.
|
||||
*/
|
||||
@@ -43,8 +45,12 @@ const root = resolve(import.meta.dirname, '..')
|
||||
* (a bare signature fragment has no imports and does not stand alone) and
|
||||
* EXCLUDED from the opt-out ratio: the catalog is generated and frozen by
|
||||
* `scripts/gen-cordis-catalog.ts` + its `--check` freshness gate.
|
||||
* - `persistence-catalog` (` ```ts persistence-catalog `) — a generated
|
||||
* log-event payload fragment in the persistence catalog. Same treatment for
|
||||
* the same reason; frozen by `scripts/gen-persistence-catalog.ts` + its
|
||||
* `--check` freshness gate.
|
||||
*/
|
||||
type BlockKind = 'check' | 'ignore' | 'type-equiv' | 'cordis-catalog'
|
||||
type BlockKind = 'check' | 'ignore' | 'type-equiv' | 'cordis-catalog' | 'persistence-catalog'
|
||||
|
||||
/** One extracted code block. */
|
||||
interface Block {
|
||||
@@ -55,7 +61,8 @@ interface Block {
|
||||
code: string
|
||||
}
|
||||
|
||||
/** Extract every ts / ts ignore-check / ts type-equiv / ts cordis-catalog block from one Markdown file. */
|
||||
/** Extract every ts / ts ignore-check / ts type-equiv / ts cordis-catalog /
|
||||
* ts persistence-catalog block from one Markdown file. */
|
||||
function extractBlocks(absPath: string): Block[] {
|
||||
const text = readFileSync(absPath, 'utf8')
|
||||
const lines = text.split('\n')
|
||||
@@ -82,7 +89,8 @@ function extractBlocks(absPath: string): Block[] {
|
||||
: info === 'ts ignore-check' ? 'ignore'
|
||||
: info === 'ts type-equiv' ? 'type-equiv'
|
||||
: info === 'ts cordis-catalog' ? 'cordis-catalog'
|
||||
: null
|
||||
: info === 'ts persistence-catalog' ? 'persistence-catalog'
|
||||
: null
|
||||
if (kind) open = { line: i + 1, kind, body: [] }
|
||||
})
|
||||
return blocks
|
||||
@@ -131,11 +139,11 @@ files.sort()
|
||||
const all = files.flatMap(extractBlocks)
|
||||
const checked = all.filter(b => b.kind === 'check')
|
||||
const ignored = all.filter(b => b.kind === 'ignore')
|
||||
// `type-equiv` and `cordis-catalog` blocks are verified elsewhere
|
||||
// (verify-type-equiv.ts and the gen-cordis-catalog `--check` freshness gate),
|
||||
// not here: neither compiled nor counted toward the opt-out ratio (each is a
|
||||
// separate fully-checked category, not an unchecked sketch). The ratio's
|
||||
// denominator is therefore the compile-eligible blocks only.
|
||||
// `type-equiv`, `cordis-catalog`, and `persistence-catalog` blocks are verified
|
||||
// elsewhere (verify-type-equiv.ts and each catalog generator's `--check`
|
||||
// freshness gate), not here: neither compiled nor counted toward the opt-out
|
||||
// ratio (each is a separate fully-checked category, not an unchecked sketch).
|
||||
// The ratio's denominator is therefore the compile-eligible blocks only.
|
||||
const ratioDenominator = checked.length + ignored.length
|
||||
|
||||
if (checked.length === 0) {
|
||||
@@ -171,7 +179,7 @@ try {
|
||||
|
||||
const ratio = ignored.length / ratioDenominator
|
||||
const skipped = all.length - ratioDenominator
|
||||
console.log(`doc-typecheck: ${checked.length} block(s) compiled, ${ignored.length} ignored (${(ratio * 100).toFixed(0)}% opt-out), ${skipped} type-equiv/cordis-catalog (checked elsewhere).`)
|
||||
console.log(`doc-typecheck: ${checked.length} block(s) compiled, ${ignored.length} ignored (${(ratio * 100).toFixed(0)}% opt-out), ${skipped} type-equiv/catalog (checked elsewhere).`)
|
||||
// Guard against the escape hatch becoming the norm.
|
||||
if (ratioDenominator >= 4 && ratio > 0.5) {
|
||||
console.error(`doc-typecheck: too many blocks opt out of checking (${ignored.length}/${ratioDenominator}). Make them compile or delete them.`)
|
||||
|
||||
Reference in New Issue
Block a user