Capabilities audit foundations: validateCapabilities lints + auto-generated /v3/capabilities + CONTRIBUTING#267
Merged
Conversation
Adds a structural lint suite for V3 catalog frontmatter and a new
auto-generated capabilities index page at /v3/capabilities, both backed
by a shared `isV3CatalogEntry` predicate so the lint scope and emitter
inclusion logic can't drift.
bin/emitters.mjs (new module):
- `isV3CatalogEntry(doc)` — shared predicate (catalog path patterns +
`exclude_from_v3_catalog` opt-out); used by both emitters and the new
lint so they share a single source of truth.
- `emitV3LibraryCatalog` — moved from build-agent-indexes.mjs; behaviour
unchanged (byte-identical output for existing 39-entry manifest;
emits new optional `category` field when present).
- `emitCapabilitiesIndex(docs)` — new emitter. Reads frontmatter
`category:` and renders one section per ALLOWED_CATEGORIES value
(data / identity / communications / media / native / commerce /
integration / automation / analytics / meta). Sorted bullet list per
section. Byte-stable across runs (no timestamps).
- `ALLOWED_CATEGORIES` + Set — exported enum (10 values).
- `parseListFrontmatter`, `deriveV3Package` — moved here too; re-exported
from build-agent-indexes.mjs for test back-compat.
bin/build-agent-indexes.mjs:
- `validateCapabilities(docs)` — new strict-mode lint. Scope: V3 catalog
entries only. Six rules:
* empty/absent `capabilities[]`
* non-lowercase token
* duplicate token within one entry
* token >40 chars
* WARN: token starts with `[` (bracket-mismatch parse footgun)
* `category:` not in ALLOWED_CATEGORIES_SET
Plus a WARN-level missing-category rule so the field can land in
staged commits without breaking CI mid-rollout.
Errors carry `{ relPath, field, message, hint, docUrl }`; the runner
prints hint + see-also URL on each failure so contributors know how
to fix.
- main(): wires `validateCapabilities` after `validateFrontmatter` and
emits the new capabilities.md page after the catalog manifest.
Frontmatter backfill across all 39 catalog entries:
- 14 installable docs (`API/fliplet-*.md`) gain a `category:` value.
- 25 ambient core docs (`API/core/*.md`) likewise.
- Distribution: data 4, identity 6, communications 5, media 3, native 1,
commerce 2, integration 2, automation 3, analytics 1, meta 12. The
`meta` bucket trails because framework-level APIs (App, Apps, Encode,
Env, Registry, Studio, Widget, Navigate, Screens, Misc, Error, Locale)
are genuinely framework-level rather than residual.
Tests: 127 (was 98). 29 new cases cover isV3CatalogEntry (5),
validateCapabilities (10), emitCapabilitiesIndex (7), and the
ALLOWED_CATEGORIES enum shape (3).
Verification:
- `node bin/build-agent-indexes.mjs --strict` passes
- `npm run test:unit` → 127/127 pass
- Catalog manifest byte-identical to pre-refactor (modulo timestamp +
new optional `category` field on each entry)
- Generated v3/capabilities.md is byte-stable across runs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the contributor checklist that lint errors link to so a new package
PR has a single page to follow instead of scattered tribal knowledge.
`docs/CONTRIBUTING.md` (new):
- 10-item "Adding a new package doc" checklist covering template, the
full frontmatter schema (incl. the new `category:` enum), capability
tagging guidance with worked examples, when to use
`exclude_from_v3_catalog`, signature verification against api repo
source, the `--strict` local check, and PR + CF Pages preview.
- "Updating an existing doc" cautions about renaming titles and
reordering capabilities[] (both ripple through the V3 builder's
prompt and SHA-pinned downstream artifacts).
- File-location map so contributors know which directory a new doc
belongs in.
`docs/CLAUDE.md`:
- "Optional fields for V3 library catalog" section gains `category:`
with the full enum, a cross-cutting-API guidance note, and a pointer
to CONTRIBUTING.md.
- Build pipeline diagram now shows the v3/capabilities.md output and
notes the validateCapabilities lints.
- "What NOT to add" §5 ("No second taxonomy") gets a documented
exception for the auto-generated capabilities page: re-derived from
catalog on every build, can't drift, serves a distinct audience.
`docs/bin/build-agent-indexes.mjs`:
- Lint `docUrl` for capability errors now points at
developers.fliplet.com/CONTRIBUTING.html (matching the `.html`
convention in urlForPath).
Verification:
- npm run test:unit → 127/127 pass
- node bin/build-agent-indexes.mjs --strict → exit 0
- Three injected violations (empty capabilities, bad category value,
uppercase token) all caught by --strict with hint + docUrl printed
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deploying fliplet-cli with
|
| Latest commit: |
6a8e479
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://1c8f81d7.fliplet-cli.pages.dev |
| Branch Preview URL: | https://v3-capabilities-audit-founda.fliplet-cli.pages.dev |
…v3/capabilities-audit-foundations
3 tasks
The `meta` bucket was trending toward catch-all status (12 entries already, projected 16-18 after upcoming doc work). Splits into three sized-for-purpose categories and adds `observability` to give logs + error tracking a home that's distinct from `analytics` (event tracking). ALLOWED_CATEGORIES (10 → 13): - ADD: `observability` — logs, error capture, audit trails (app health). Distinct from `analytics` which is user behaviour. - ADD: `framework` — runtime, registry, environment, widget, locale, dynamic loading (framework-level glue). - ADD: `navigation` — screen navigation, URL routing, screen listing. - KEEP: `meta` — residual catch-all only (App, Apps, Encode, parseError, common functions). 5 entries post-split. Relabels 7 existing docs out of `meta`: - `core/widget.md`, `core/localization.md`, `core/environment.md`, `core/registry.md`, `core/studio.md` → `framework` - `core/navigate.md`, `core/screens.md` → `navigation` Distribution after split (39 entries total): data 4 · identity 6 · communications 5 · media 3 · native 1 · commerce 2 · integration 2 · automation 3 · analytics 1 · observability 0 · framework 5 · navigation 2 · meta 5 `observability` ships empty — the emitter skips categories with 0 entries, so the rendered page shows 12 sections currently. Future docs (fliplet-error-tracking, App.Logs, Organizations.Logs) populate it. Updates: - bin/emitters.mjs: ALLOWED_CATEGORIES enum, HEADERS map - bin/__tests__/build-agent-indexes.test.mjs: enum length + order assertions updated for 13 values - docs/CLAUDE.md: documents the 13-value enum + the "if meta exceeds 6-8 entries, split rather than absorb" rule - docs/CONTRIBUTING.md: per-category guidance for new docs (incl. the analytics/observability distinction) Verification: - node bin/build-agent-indexes.mjs --strict → exit 0 - npm run test:unit → 127/127 pass - v3/capabilities.md regenerates with 12 sections in correct order (Framework between Analytics and Meta, Navigation following) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Foundations for the V3 JS API capabilities audit. Lands the tooling + schema without touching the contested package inventory (that's gated on the spreadsheet review). Three things ship here:
bin/emitters.mjs(new module) with a sharedisV3CatalogEntry(doc)predicate that both the V3 library catalog manifest and the new capabilities page consume — they can't drift.validateCapabilitieslints inbin/build-agent-indexes.mjs— six deterministic rules (empty/lowercase/dupes/length-boundcapabilities[]+category:enum check) + one bracket-mismatch warn. Errors includehintanddocUrlso the build pipeline teaches the contributor what to fix./v3/capabilitiespage grouping all 39 catalog entries bycategory:(10-value enum: data / identity / communications / media / native / commerce / integration / automation / analytics / meta). Byte-stable (no timestamps); re-derives from frontmatter every build.Plus
docs/CONTRIBUTING.mdwith the 10-item "Adding a new package doc" checklist that lint errors deep-link to, anddocs/CLAUDE.mdschema documentation for the newcategory:field.Reviewer focus
The 39
category:assignments are the only judgment-heavy piece — please eyeball that each doc is in the right bucket. Distribution:metais the biggest at 12 — these are genuinely framework-level (Env, Registry, Widget, etc.), not "stuff that didn't fit." If a specific assignment looks wrong, flag it in a comment and I'll move it.Out of scope (deferred to subsequent PRs)
fliplet-chart,fliplet-native, the 5 V3 SPA infra packages, ambient surface gaps infliplet-core) — gated on the V3 capabilities review spreadsheet which Tony is currently annotating with V3-relevance decisions.fliplet-nativePhase A scope review — separate workstream after spreadsheet review.docs/v3/coverage-decisions.md— written after spreadsheet review, fossilizing the V3-relevance decisions.Test plan
npm run test:unit→ 127/127 pass (98 existing + 29 new acrossisV3CatalogEntry,validateCapabilities,emitCapabilitiesIndex,ALLOWED_CATEGORIES)node bin/build-agent-indexes.mjs --strict→ exit 0 with current state (all 39 entries have validcategory:andcapabilities[])capabilities: [], (b)category: badvalue, (c)Stripeuppercase token — all three caught by--strictwithhint+docUrlprinted.well-known/llms-v3-libraries.json) byte-identical to master modulo timestamp + new optionalcategoryfield per entrydocs/v3/capabilities.mdis byte-stable across two consecutive build runs (no timestamp drift)/v3/capabilitiespage renders cleanly and each category section contains the expected entries🤖 Generated with Claude Code