LearnNewsExamplesServices
Frontmatter
id12899
titleJSDoc type parser chokes on TS-style syntax across ai/ — docs silently ship with dropped batches
stateClosed
labels
bugdocumentationaibuild
assigneesneo-fable
createdAtJun 11, 2026, 1:59 PM
updatedAtJun 11, 2026, 2:42 PM
githubUrlhttps://github.com/neomjs/neo/issues/12899
authorneo-fable
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 11, 2026, 2:42 PM

JSDoc type parser chokes on TS-style syntax across ai/ — docs silently ship with dropped batches

Closed v13.0.0/archive-v13-0-0-chunk-17 bugdocumentationaibuild
neo-fable
neo-fable commented on Jun 11, 2026, 1:59 PM

Context

Operator-flagged pre-release: agents (mostly inside the brain — ai/) have been writing JSDoc type expressions in TypeScript-flavored syntax that the docs type parser (catharsis, via buildScripts/docs/jsdocx.mjsjsdoc-x) cannot handle. build-all runs the parser by default (buildScripts/build/all.mjs parsedocs defaults to 'yes', and build-all -n takes defaults), and docs/app consumes the generated JSON — so every standard build bakes the damage into the shipped docs.

Release classification: ON the board — v13 is the brain release; its docs currently ship with brain files silently missing (see The Problem), and the generator masks the failure (exit 0).

The Problem

Full-run inventory (2026-06-11, node buildScripts/docs/jsdocx.mjs):

  • 121 type-expression parse errors across 21 files — all inside ai/.
  • 2 parse batches FAIL entirely → every file in those batches vanishes from the docs JSON (whole memory-core / knowledge-base service groups absent from the docs app).
  • The script exits 0 regardless — batch failures are logged and swallowed, so neither build-all nor any pipeline can ever detect the corruption. This silent-success is the durable bug riding on top of the syntax issue.

Error-class census (from the run log):

Count Class Example
96 TS optional property prop?: Type inside record types {action: String, drift?: Object}
4 bare union inside record property {instanceAddress:String|null}
~12 string-literal unions / multi-line type expressions 'clone'|'silent'|…; types spanning 3 source lines
4 misc ([-class) tuple-ish array syntax

Affected files (21): ai/daemons/wake/{daemon,wokenWatermark}.mjs, ai/mcp/server/knowledge-base/{config,config.template}.mjs, ai/scripts/benchmark/{helpers/stats,keep-alive-probe,setupClass-cold-start}.mjs, ai/scripts/diagnostics/{check-identity-facts,mcpHealthcheck}.mjs, ai/scripts/lifecycle/inflightLock.mjs, ai/scripts/lint/{lint-agents,lint-skill-manifest,lint-tree-json}.mjs, ai/scripts/maintenance/{backup,downloadKnowledgeBase}.mjs, ai/scripts/migrations/bootstrapWorktree.mjs, ai/scripts/setup/initServerConfigs.mjs, ai/services/knowledge-base/helpers/tenantRepoAccessContract.mjs, ai/services/memory-core/{GraphService,WakeSubscriptionService,helpers/harnessClassifier}.mjs.

The Architectural Reality

  • buildScripts/docs/jsdocx.mjs orchestrates; buildScripts/docs/jsdoc-x/runner.mjs runs parallel jsdoc batches and currently logs Batch N failed without propagating failure (index.mjs parse() resolves anyway).
  • The catharsis type grammar supports JSDoc record types {a: B}, parenthesized unions (A|null), nullable ?Type — but NOT TS optional-property ?, bare | inside record properties, string-literal types, or multi-line expressions.
  • Root cause of recurrence: agent training priors default to TS-flavored JSDoc; nothing in the repo's contextual-completeness guidance names the parseable subset, and no gate exists.

The Fix

Two parts, one PR:

  1. Fail loudly (the guard): jsdoc-x batch failures propagate — the script exits non-zero and prints a failure summary when any batch fails or any type expression errors. build-all then surfaces docs corruption instead of shipping it.
  2. Rewrite the 121 spots to the parseable JSDoc subset (comment-only edits, behavior-neutral):
    • prop?: Typeprop: Type (optionality noted in prose where load-bearing)
    • bare record-internal unions → parenthesized (A|null)
    • string-literal unions → String + prose enumeration
    • multi-line type expressions → single-line / simplified shapes
  3. Verification: full parser run → 0 errors, 0 failed batches; guard verified by reverting one fix locally.

Post-v13 follow-up (separate): a lint/CI gate running the parser in check-mode + one line in the JSDoc guidance naming the parseable subset (prevents recurrence at authoring time).

Acceptance Criteria

  • node buildScripts/docs/jsdocx.mjs completes with 0 type-expression errors and 0 failed batches.
  • The script exits non-zero when a batch fails (verified by injecting a known-bad type locally).
  • All 21 files' JSDoc rewritten to the parseable subset; no runtime code changes.
  • docs/app output JSON contains the previously-dropped memory-core / knowledge-base files.

Out of Scope

  • CI gating the parser (post-v13 follow-up).
  • JSDoc guidance/substrate update naming the parseable subset (post-v13 follow-up, pairs with the gate).
  • Any runtime behavior change — comment-only + build-script exit semantics.

Related

  • #12696 (v13 release epic — docs integrity feeds the cut)

Live latest-open sweep: checked latest open issues at 2026-06-11T12:00Z; no equivalent found. Operator-routed lane (in-session direct).

Origin Session ID: e605ce21-3668-445c-bc00-45896aa9a092

Retrieval Hint: "jsdocx catharsis TS-style optional properties silent batch drop exit 0"

tobiu referenced in commit e837120 - "fix(docs): heal jsdocx type-parser damage across ai/ + fail loudly on dropped batches (#12899) (#12900) on Jun 11, 2026, 2:42 PM
tobiu closed this issue on Jun 11, 2026, 2:42 PM