feat(help): retire the 13 phantom help entries + HelpCorpusSpec corpus-walk anti-drift guard - #263
Merged
Conversation
…Spec corpus-walk guard (Story 20.7) - delete all thirteen phantom help docs + json/_index.json (untracked, archived first - no diff shows; the RED/GREEN record in the story spec is the evidence) - NEW core test HelpCorpusSpec: 8-assertion corpus walk, zero allow-lists - NEW SQLKeywords.functionWords (canonical + alias function spellings via wordsOf) - HelpJsonLoader: category lists hoisted to private[help] object vals (behaviour-neutral), asserted equal to the directories present - roadmap Epic 31's silent json-category skip is resolved by removal + guarded Closes #261 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Sep 2, 2026
Closed
fupelaqu
marked this pull request as ready for review
September 2, 2026 14:39
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.
Closes #261
What
Story 20.7 (Epic 20, BI venue enablement — Layer 0). Retires the thirteen phantom help documents (help entries for functions the SQL parser rejects) and adds
HelpCorpusSpec, a corpus-walk anti-drift guard that makes a fourteenth phantom — or the arming of an existing one — a red build.core/src/main/resources/help/functions/json/directory (json_extract,json_object,json_array+_index.json— indexed but dead:HelpJsonLoader.loadFunctionsnever enumeratedjson, and the roadmap item fixing that skip would have armed all three), plus the ten unwired legacy phantomsconditional/{if,ifnull,nvl},numeric/{ln,mod,truncate},string/{lpad,rpad,space,regexp_replace}. The deletions produce no git diff; the red/green evidence below is the record (all fourteen files are archived locally before deletion).coretestHelpCorpusSpec— 8 assertions, zero allow-lists: corpus locatable (neverassume-cancelled); tree exactly two levels deep; every function doc topic ∈SQLKeywords.functionWordsor one of four recorded non-function parser words (CASE,INTERVAL,PI,RANDOM); topic uniqueness (.toMapkeeps the last pair silently); escape-hatch integrity (checked against canonical clause/literalsqlspellings —IF/TRUNCATE/JSON_ARRAY(statementWords) and the compound fragmentOUTERare all rejected, so the hatch cannot launder a phantom); command topics word-checked againstallWords; index↔disk equality in both directions (a dangling_index.jsonentry is skipped silently today); loader category lists ≡ directories present.SQLKeywords.functionWords(sql): one new publiclazy val— the derived function-word set (canonical + 54 aliases via theprivate[sql]wordsOf, single owner of the\s+-before-uppercase normalisation). Deliberately notallWords(which would falsely clearIF,JSON_ARRAY,TRUNCATE) and notfunctionTokens.map(_.sql)(which would reject alias help pages likeSAFE_CAST).HelpJsonLoader: the two hard-coded category lists hoisted to object-levelprivate[help] val functionCategories / commandCategories— behaviour-neutral (same members, same order), so the spec can assert them against the directory tree. The roadmap Epic 31 item "fixHelpJsonLoadersilently skippinghelp/functions/json" is resolved by removal + guarded — the loader still enumerates a hard-coded list; what changed is that the list is now checked against reality.Red → green demonstration
RED (phantoms present, before any deletion) — exactly the three predicted failures, other five green:
GREEN (after archive + retirement; one
sbt core/cleanneeded — sbt's cached resource Sync pruned the deleted files but left the emptytarget/.../jsondirectory, and the union walk correctly went RED on it, never green-and-wrong):Corpus size, reproducibly
No release note, no downstream sweep
Zero references to any of the thirteen in
documentation/,README.md, or the website sources; the trio was never loaded, the ten were never indexed. Nothing customer-visible changes; the REPL.helpoutput for every surviving topic is unchanged.Honest statement of the guarantee
Every help document reachable by
HelpJsonLoaderis checked: a function document must name a parser-accepted function spelling or one of four recorded clause/literal words; a command document must be built from words the parser knows; every document must be indexed, unique, and two levels deep. Still possible, but only as review-visible source changes: a doc whosenameis real while itssyntaxbody advertises a rejected form (exactly whatJSON_ARRAYwas), or a deliberate addition toNonFunctionTopics.Verification
sbt "+ sql/compile" "+ core/compile"green (2.12.20 + 2.13.16).sbt "+ core/test" "+ sql/test"green — both Scala legs. The 2.12 leg earned its keep: the spec's original clue string used\"inside an s-interpolated string, which the 2.12 lexer rejects (2.13-only tolerance) — caught only by+ core/test, reworded without inner quotes.sbt scalafmtAll(new file staged first —.scalafmt.confhasproject.git = true; the formatter demonstrably rewrote it) andsbt headerCheckgreen.core/Test/headerCheckflags 21 pre-existing header-less test sources;HelpCorpusSpec.scalais not among them (it carries the Apache-2.0 header).IF/TRUNCATE/JSON_ARRAY/OUTERrejection machine-demonstrated), 2 LOW deferred (cosmetic message relabel; hypothetical whitespace split — both loud-RED failure modes, never false green).Story: 20.7 — spec
_bmad-output/implementation-artifacts/20-7-phantom-help-entries.md(local).🤖 Generated with Claude Code