scan: promote to a verb (CLI + MCP) + shared Zod type contracts (types.mjs) - #41
Merged
Conversation
…s.mjs)
Two halves of one change — productionize the typing:
1. types.mjs — the per-type symbol contracts as ONE Zod source (headline ≤65 + no
superlatives, cta = action-verb + ≤24, meta 70-160, body). The audit's deterministic
type-scoped checks now run these instead of hand-coded length tests (verified
behavior-preserving: 12/12 cases match the old checks, scores unchanged); claim stays
dynamic (grounding-aware) in claimFindings(). inferType() lives here too.
2. scan — promoted from spikes/scan.mjs to a real verb (verbs.mjs) → registry → CLI bin
(scan.mjs / string-audit-scan) + MCP. Walks the source, extracts every string literal
(acorn AST, optional; regex fallback), keeps the copy-like ones, infers a type and
Zod-validates each keeper against types.mjs — the SAME contracts audit uses. --emit
writes a DTCG content/strings.json (round-trips as a CATALOG= input).
registry = { audit, extract, scan }. test.mjs: scan keepers + the shared type contracts.
ci.yml: scan-verb smoke (acorn AST + emit + audit round-trip) + scan in the MCP toolset.
README/Surfaces gains Scan; spikes/README drops the (now-promoted) row.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9 tasks
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.
What — productionize the typing (the two halves you picked)
1.
types.mjs— the per-type contracts in ONE Zod sourceEach symbol type as a Zod schema —
headline(≤65, ≥15, no superlatives),cta(action-verb + ≤24),
meta(70–160),body.audit's deterministic type-scoped checksnow run these instead of hand-coded length tests.
claimstays dynamic (grounding-aware)in
claimFindings();inferType()lives here too. One place to change what aheadlineis.Behavior-preserving: verified the Zod contracts reproduce the old hand-coded checks
12/12 cases (same findings, same scores).
2.
scan— promoted from a spike to a real verbspikes/scan.mjs→ ascanVerbSpec inverbs.mjs→ registry → CLI bin (scan.mjs/string-audit-scan) + MCP. Walks the source, extracts every string literal (acornAST,optional; regex fallback), keeps the copy-like ones, infers a type and Zod-validates each
keeper against
types.mjs— the same contractsaudituses.--emitwrites a DTCGcontent/strings.json(round-trips as aCATALOG=input).The surfaces now
Test
test.mjs: scan keepers (subset, typed, Zod-validated) + the shared type contracts(clean headline passes, over-long headline / non-action-verb cta fail, grounded vs
ungrounded claim).
ci.yml: scan-verb smoke (acorn AST +--emit→ audit round-trip) +scanin the MCPtoolset. No new deps (
acornwas already optional).auditoutput unchanged on the brand catalog.🤖 Generated with Claude Code