Skip to content

fix(insights): reconcile only defined words (M19c) - #43

Open
jgrodziski wants to merge 4 commits into
feat/m19c-function-wordsfrom
feat/m19c-glossary-defined
Open

jgrodziski wants to merge 4 commits into
feat/m19c-function-wordsfrom
feat/m19c-glossary-defined

Conversation

@jgrodziski

Copy link
Copy Markdown
Contributor

Eighth step of milestone M19c in PLAN.md §20 (word cloud / glossary, #6). Stacked on #42 (itself on #40, #39, #38, #37, #36 and #35): this PR's diff is the four commits after #42.

A module is no longer asked to reconcile a word that none of its types defined. This is fix (c) from the PetClinic findings.

Why

A module's glossary candidates are the words its types spell, cut at --terms. A type's answer can leave some of its words undefined. The module prompt still listed those words, with a line - birth: no type defined it. On PetClinic, 2 of the ~50 words the modules were asked to reconcile were in that state, and the model paid for an entry for both:

  • birth (Pet skipped birthDate's first word): the owner module wrote {"concern": "ambiguous", "sense": "undefined term", "meaning": "No type in this module's supplied explanations defines an independent meaning for birth."}.
  • base (BaseEntity skipped it): the model module wrote it a meaning anyway, "the superclass role of BaseEntity". No type had said so.

The first entry is paid noise; the second is an unsourced definition in a glossary that claims to reconcile what its types said.

The change

  • glossaryAsked(member) in context.ts keeps the candidates that have at least one type entry. One function states the rule, and it is used in two places:
    • the module prompt lists only those words, and the "no type defined it" line is gone;
    • on receipt, the module's glossary keeps only entries for those words. An entry for a word the prompt did not list is dropped, as a word not asked already was.
  • No glossary section when every candidate went undefined; the module then keeps an empty glossary. Modules whose types spell no word already worked this way.
  • GlossaryWord.pending marks a word that some type spelling it has no words for yet: not yet explained, or explained under prompt 1. The estimate needs this (below).

Worth a look in review

  • The fingerprint does not move. It still takes the cut candidate list. Which candidates a type defined is read when the prompt renders, like the summaries it quotes.
    • When a type is re-explained, the module's fingerprint already changes, because the type is part of the module.
    • No paid record goes stale. On a copy of the PetClinic store, --dry-run statuses match fix(vocabulary): no definitions of function words (M19c) #42's unit for unit (diff of status and id per line: identical).
  • Cut, then filter. --terms N still cuts the candidates first, so a module asks at most N words, and fewer when some went undefined.
    • Filtering first would ask a full N. But the hashed list would then depend on what the types said, which the fingerprint deliberately excludes.
    • The heaviest words are the ones types spell in their own names, so they are the least likely to go undefined.
  • What the estimate counts: a candidate counts unless every type that spells it has words and none of them defined it.
    • A type still to be explained may define the word, so a cold plan counts every candidate, as before.
    • On PetClinic's warm plan, the estimate is 250 completion tokens lower (birth and base, at 125 each).
    • A cold module prompt now prints no glossary lines at all. The plan's input is a little lower: the Java fixture's module prompts go from 5,328 to 4,990 tokens. The cold input gap §20.3 measured (quotes no run has written yet) grows by that much.
  • A fix carried over from fix(vocabulary): no definitions of function words (M19c) #42. docs/insights.md IN-5 still said a lexicon correction re-explains "exactly the units whose words it changed". fix(vocabulary): no definitions of function words (M19c) #42 corrected the same claim in fingerprint.ts but not here; it is corrected in this PR's docs commit.

Docs

  • docs/insights.md, docs/cli.md, the side-car reference and explain's --terms row all say a module reconciles the candidates a type defined.
  • The Java fixture's plan is reprinted on four website pages: 114,136 prompt tokens (module 4,990), 52,415 completion tokens, $0.0429.
  • PLAN §20.3:
    • an "As built — only defined words reconciled" note;
    • a pointer from the glossary-candidates bullet of layer 2's as-built note.

Verification

  • Red first.
    • The prompt test listed order, line, price, sort, unit, key where it now lists order, line. Its first version passed against the base: its line parser skipped - price: no type defined it. The parser was tightened until the test failed on the base.
    • The run test saw a "Words its types define" section with - total: no type defined it where none is expected now.
  • Mutants.
    • Putting back the old receipt filter (member.glossary) fails "asks a module about no word its types left undefined, and drops an entry for one".
    • Counting every candidate in the estimate fails the prompt test's asked assertions: 2 with both types explained, 4 with one pending or under prompt 1, 6 cold.
  • Gate.
  • Tests: insights 160 (+2, +1 skipped), cli 1,037, vocabulary 348, core 544, analyzer 614, viz 143, navigator-ui 114, city 94, extractor-typescript 66, scm 56, navigator 40, llm 34.
    • All green, except analyzer's scale.test.ts, which timed out under the full parallel run and passes alone (the known flake; the analyzer is untouched).
  • PetClinic. Measured on a copy of the store in the scratchpad. The paid store in ~/spring-petclinic was not opened by this branch.

Still owed for M19c:

  • (d) count a word as polysemous only with at least two distinct senses;
  • whether a words-only change should cascade to dependents (fix(vocabulary): no definitions of function words (M19c) #42);
  • docs/vocabulary.md and the README;
  • the live run on the Java fixture;
  • §20.4's definition of done restated on PetClinic.

Part of #6.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w

jgrodziski and others added 4 commits November 3, 2026 13:46
A module prompt listed every candidate word, with "no type defined it"
for those its types skipped, and the model paid for an entry anyway
(PetClinic: `birth` as an "undefined term", `base` given a meaning no
type had). glossaryAsked keeps the candidates a type defined: the prompt
lists those and the receipt keeps only those. The candidates stay what is
hashed, so no record goes stale. The estimate still counts a word a type
not yet explained may define.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
docs/insights.md, docs/cli.md, the side-car and explain references: a
module reconciles the candidates a type defined. IN-5 also stops saying a
lexicon correction re-explains exactly the units whose words it changed:
through the dependency fingerprints it reaches their dependents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
A cold module prompt no longer prints "no type defined it" lines: the
Java fixture's plan is 114 136 prompt tokens (module 4 990), completion
unchanged at 52 415, $0.0429.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
PLAN 20.3: asked = a type defined it, the candidates stay hashed, cut
then filter, and what the estimate counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
codegraph bac6f63 Commit Preview URL

Branch Preview URL
Nov 03 2026, 01:48 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant