@polycode-projects/the-mechanical-code-talker 1.0.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,12 +18,12 @@ tmct> /exit
18
18
  ```
19
19
 
20
20
  **[Try it live in your browser →](https://polycode-projects.gitlab.io/the-mechanical-code-talker/)**
21
- a real, interactive chat demo running client-side: your browser runs the
21
+ is a real, interactive chat demo running client-side. Your browser runs the
22
22
  actual query engine against a small example codebase, no server, no install.
23
23
 
24
24
  ## How it interprets you
25
25
 
26
- Every message runs through **multiple concurrent interpretation strategies** —
26
+ Every message runs through **multiple concurrent interpretation strategies**:
27
27
  a grammar parse, keyword picking, noise-word removal, fuzzy matching. Their
28
28
  results are grouped by class:
29
29
 
@@ -32,10 +32,20 @@ results are grouped by class:
32
32
  *"if you mean X then …"* so ambiguity is shown, never silently resolved.
33
33
 
34
34
  One of the strategies is an **ACE-inspired controlled grammar**: when your
35
- text fits the controlled fragment, tmct emits OWL-labelled triples from it
36
- statements it can store, retrieve, and answer from later. Text that doesn't
37
- fit the grammar still gets the tolerant strategies; nothing is rejected for
38
- being loose, fuzzy, or misspelled.
35
+ text fits the controlled fragment, tmct emits OWL-labelled triples from it.
36
+ Those triples are statements it can store, retrieve, and answer from later.
37
+ Text that doesn't fit the grammar still gets the tolerant strategies; nothing
38
+ is rejected for being loose, fuzzy, or misspelled.
39
+
40
+ **Everyday question shapes.** Bare "what is Commit" (no article) now resolves
41
+ like "what is a commit" for tmct's own vocabulary. "What's model.mjs for" and
42
+ "what's model.mjs about" answer like "what does model.mjs do". "Is Base a
43
+ superclass of Widget" is read as the reverse of "is Widget a subclass of
44
+ Base", the same relationship either way round. "Recent commits" and "the last
45
+ commit" resolve to real dated history, not a literal string miss. Polite or
46
+ indirect framing reaches the same capability as a direct request: "I'd like
47
+ you to remember X" teaches like bare "remember X"; "please tell me about X"
48
+ and "search for X" describe and find exactly as their direct forms do.
39
49
 
40
50
  **Negation and passive.** "Which modules do *not* import X?" computes a bounded
41
51
  **set complement** over the graph, and an honestly empty result stays a miss
@@ -59,36 +69,41 @@ breaks"). It flags a question whose premise doesn't hold, too: "why does X
59
69
  still import Y" when it no longer does.
60
70
 
61
71
  **Response finishing.** Before an answer is printed it is segmented into typed
62
- spans prose versus *protected* entities, paths, numbers, code, provenance, and
63
- receipts and a small data-driven grammar pass runs on the prose spans only,
72
+ spans: prose versus *protected* entities, paths, numbers, code, provenance, and
73
+ receipts. A small data-driven grammar pass then runs on the prose spans only,
64
74
  under a guard that proves the protected spans came through byte-for-byte. Today
65
75
  that pass fixes the a/an article defect; broader voice and agreement rules are
66
76
  implemented but parked until they earn their place on the benchmark.
67
77
 
78
+ A frozen regression suite plays out full multi-turn dialogues built from these
79
+ phrasings, at every complexity level this project defines, from a single
80
+ question up to a messy, typo-ridden real user. Tier-by-tier detail is in
81
+ `HANDOVER.md` and `ROADMAP.md`.
82
+
68
83
  ## How it guides you
69
84
 
70
- When you touch a **concept** without asking a precise question "what is a
71
- class", "what about imports", "what calls are there" tmct answers in three
85
+ When you touch a **concept** without asking a precise question, like "what is a
86
+ class", "what about imports", or "what calls are there", tmct answers in three
72
87
  bands instead of dead-ending:
73
88
 
74
89
  1. the **definition** (a plain-English one-liner: *"A class is a template that
75
90
  defines the structure and behaviour of objects."* / *"To import is to bring
76
91
  another module's definitions into the current one."*);
77
- 2. **real instances from your graph** *"In this codebase, for example: Record,
92
+ 2. **real instances from your graph**: *"In this codebase, for example: Record,
78
93
  Task and User (10 classes)"*, or actual edges *"src/core/store.mjs imports
79
94
  src/core/model.mjs (18 import edges)"*;
80
- 3. **guided follow-ups** two or three concrete next questions, each one
95
+ 3. **guided follow-ups**: two or three concrete next questions, each one
81
96
  *pre-checked against your graph* so every suggestion is guaranteed to resolve:
82
97
  *"Want to go deeper? Try: which classes inherit from Record / what does Task
83
98
  contain / where is User defined"*.
84
99
 
85
100
  It fires for both **noun** concepts (class, module, function, method) and
86
- **relation** concepts (imports, calls, contains, inherits, tests), and only when
87
- tmct genuinely knows the concept *and* has instances of it otherwise the honest
88
- miss stands. The effect is a conversation that drills down from a vague opener to
89
- a useful answer without ever hitting a wall. Natural phrasings are routed to the
90
- capability you meant: *"what functions are in Task"* → its members, *"what
91
- defined saveStore"* → where it's defined.
101
+ **relation** concepts (imports, calls, contains, inherits, tests), and only
102
+ when tmct genuinely knows the concept *and* has instances of it. Otherwise the
103
+ honest miss stands. The effect is a conversation that drills down from a vague
104
+ opener to a useful answer without ever hitting a wall. Natural phrasings are
105
+ routed to the capability you meant: *"what functions are in Task"* → its
106
+ members, *"what defined saveStore"* → where it's defined.
92
107
 
93
108
  ## How it remembers
94
109
 
@@ -100,22 +115,26 @@ by cleaned session logs:
100
115
  - **text blocks under a PageRank-style index**, pulled into context on
101
116
  relevance rather than loaded wholesale.
102
117
 
103
- With no graph at all, tmct starts empty and remembers what you tell it — the
118
+ With no graph at all, tmct starts empty and remembers what you tell it. The
104
119
  `.tmct/` graph is created from the conversation. On a first run it seeds the
105
120
  committed vocabulary so it knows what it's talking about from turn one: a curated
106
121
  **SEON** software ontology plus the whole filtered **ConceptNet slice**
107
- (CC-BY-SA 4.0) every term carries an English definition, so "what is a cache?"
122
+ (CC-BY-SA 4.0). Every term carries an English definition, so "what is a cache?"
108
123
  answers offline, from disk, on turn one. `--ephemeral` (used by the shipped
109
124
  `npm run example:*` demos) reads a graph but writes nothing back.
110
125
 
126
+ Teaching isn't limited to the ACE grammar's fixed shapes. Tell tmct an
127
+ arbitrary fact, like "margo eats ribs", and it mints a fact you can later ask
128
+ about directly: "what does margo eat", or "does margo eat ribs".
129
+
111
130
  ### Provenance and trust
112
131
 
113
132
  Every fact and text block records **where it came from and when**. Sources are
114
- first-class individuals operator chat, a curated corpus, a provider graph, a
115
- web scrape, a rule-derived entailment and a fact links back to *all* of them
133
+ first-class individuals: operator chat, a curated corpus, a provider graph, a
134
+ web scrape, a rule-derived entailment. A fact links back to *all* of them
116
135
  (`mgx:derivedFrom` / `mgx:statedBy` / `mgx:canonicalisedFrom`), timestamped with
117
136
  `mgx:createdAt`. From those links tmct computes a **deterministic, explainable
118
- trust score** a source-type prior combined with corroboration (how many
137
+ trust score**: a source-type prior combined with corroboration (how many
119
138
  independent sources agree) and recency. It is never hand-set, always traceable
120
139
  to its inputs. Retrieval then ranks by **relevance × trust**, so a corroborated,
121
140
  operator-stated fact outranks a lone web scrape on the same question. When two
@@ -126,7 +145,7 @@ provenance** rather than silently picking a winner.
126
145
 
127
146
  `tmct syllogise [--depth n] [--budget n]` is an offline, bounded, deterministic
128
147
  batch that forward-chains the memory's `rdfs:subClassOf` closure into new
129
- **entailed** facts pre-deriving what the trusted sources already imply. It runs
148
+ **entailed** facts, pre-deriving what the trusted sources already imply. It runs
130
149
  once automatically after seeding and on demand; the entailed facts are
131
150
  **low-trust and retractable** (never outranking a stated fact) and this never runs
132
151
  on the chat's hot path.
@@ -140,9 +159,9 @@ on the chat's hot path.
140
159
  *calculation* surfaced as prose ("there are a lot of tests for a codebase of
141
160
  that size"). It is deterministic, explainable, and cheap. Even its forward-chaining
142
161
  entailment (`tmct syllogise`) is mechanical OWL rule materialization applied
143
- offline, rule-by-rule and retractable not an LLM. There is **no LLM anywhere
162
+ offline, rule-by-rule and retractable, not an LLM. There is **no LLM anywhere
144
163
  in the product**. (An LLM-as-judge exists only in the offline eval harness
145
- that tunes tmct see `SKILL_TUNING_CYCLE.md` never in the product path.)
164
+ that tunes tmct, see `SKILL_TUNING_CYCLE.md`, never in the product path.)
146
165
  - **It never guesses silently.** When it cannot resolve your question it says
147
166
  so and nudges you toward a query it *can* answer.
148
167
 
@@ -162,7 +181,7 @@ Inside the chat: `/help` lists commands, `/memory` inspects what tmct remembers
162
181
 
163
182
  `tmct init` is the onboarding surface for the repository interface below: it
164
183
  creates the `.tmct/` directory, writes the externalized `tmct.toml`
165
- configuration, seeds the tier-1 corpus, and records provenance a host package
184
+ configuration, seeds the tier-1 corpus, and records provenance. A host package
166
185
  or a bare user gets a working install in one command.
167
186
 
168
187
  > Install-size note: tmct depends on wink-nlp's deterministic English language
@@ -170,7 +189,7 @@ or a bare user gets a working install in one command.
170
189
 
171
190
  ### Try it on an example graph
172
191
 
173
- tmct *consumes* a code graph at `<repo>/.tmct/graph.json` it does not build
192
+ tmct *consumes* a code graph at `<repo>/.tmct/graph.json`; it does not build
174
193
  one. Two ready-made example graphs ship in `examples/` so you can see it answer
175
194
  real questions with no setup:
176
195
 
@@ -190,7 +209,7 @@ which modules import src/core/model.mjs
190
209
  what tests cover src/handlers/tasks.mjs
191
210
  ```
192
211
 
193
- The **polyglot** graph shows the language-neutral idea Java, Python and C#
212
+ The **polyglot** graph shows the language-neutral idea: Java, Python and C#
194
213
  entities all typed to the same `seon:Class` / `seon:Method` / `seon:Module`
195
214
  concepts, so one query reasons across every language at once:
196
215
 
@@ -254,9 +273,9 @@ naming, license, and memory model were reset to the vision above. See
254
273
 
255
274
  **MPL-2.0.** Free for commercial use; if you modify the covered files and
256
275
  distribute them, you must publish those files' source under the MPL with
257
- attribution the copyleft is file-level, not project-level. See `LICENSE`.
276
+ attribution. The copyleft is file-level, not project-level. See `LICENSE`.
258
277
 
259
- Corpus data carries its own licenses, separate from the code: the planned
260
- ConceptNet slice is **CC-BY-SA 4.0** and will ship with its own notice.
278
+ Corpus data carries its own licenses, separate from the code: the shipped
279
+ ConceptNet slice is **CC-BY-SA 4.0**, with its own notice alongside it.
261
280
 
262
281
  © Polycode Limited.
package/ROADMAP.md CHANGED
@@ -14,101 +14,188 @@ the file has been deleted.
14
14
 
15
15
  ## Where we are now (2026-07-09)
16
16
 
17
- `npm test` green (**1245**). **v1.0.7, pushed** (0.9.11 1.0.0 1.0.7 across this session —
18
- see `HANDOVER.md` for the exact release chain and file:line detail).
19
-
20
- ### Now: shipped this session
21
-
22
- - **1.0.0 — the first-run chat experience, rewritten.** The original trigger: a brand-new
23
- `npm install` + bare `tmct chat` led with a "no code graph loaded" apology for *any* input,
24
- including plain greetings and identity questions, even though the seeded ontology/lexicon
25
- could already answer them. Root-caused to a 0.6.0-era design that over-applied its own honest
26
- empty-graph orientation. Fixed: identity/capability-led responses (`I'm tmct — ...` before any
27
- caveat), a real self-description + a distinct "no LLM involved" answer for the identity/AI-ID
28
- family, provably-correct "try this" examples (a `vocabExampleHint` that only ever offers a term
29
- confirmed to resolve in the session's actual seed state — the prior hint could silently lie
30
- under `TMCT_NO_SEED=1`), and substantially broadened conversational recognition (dialect,
31
- register, slang, elongation, a bounded-fuzzy-match typo layer) — all via curated closed-set
32
- additions, not a generalized grammar rule, per the project's standing preference.
33
- - **The `SKILL_CHAT_PLAYTEST.md` dialogue-flow loop, run for real across 5 tiers.** Tier 0
34
- (bootstrap/identity), Tier 1 (single touch + one drill-down), Tier 2 (drill-down chains with
35
- anaphora), and Tier 4 (compositional & comparative) each closed in one pass; **Tier 3
36
- (cross-concept & relation touches) took 7 passes** cycles 3-9 progressively found and fixed a
37
- recurring `resolveObject` substring-match weakness (a missing minimum-length floor let short
38
- staccato connectives like "and"/"it" silently hijack the conversation's focus, producing
39
- confidently WRONG answers on a *later* turn while looking honest) — patched three times
40
- point-by-point before cycle 9 found and fixed the actual root cause in one place. Tier 5/6 not
41
- yet started. The skill doc itself gained two new rules from real incidents this run: always
42
- `mktemp -d` + exact-path cleanup for scratch fixtures (a wildcard `rm -rf /tmp/pt-*` cleanup
43
- step got flagged by the harness's own safety policy no damage, but a real cross-agent risk),
44
- and never `chat --repo` the committed example fixture directly (dirties a checked-in file).
45
- - **A live, client-side chat demo on the GitLab Pages homepage.** Not a scripted/pre-recorded
46
- fake the real `src/ask.mjs` query engine runs in the visitor's browser (wink-nlp loaded from
47
- `esm.sh`, an import-map shim working around 3 leaf files' Node-only static imports, zero
48
- changes needed to the engine itself since it was already browser-clean pure JS). Boots with a
17
+ The full `SKILL_CHAT_PLAYTEST.md` dialogue-flow tier ladder is complete, tiers 0 through 6.
18
+ Tiers 0, 1, 2, and 4 each closed in one pass. Tier 3 took 7 passes to track down a recurring
19
+ `resolveObject` substring-match weakness. Tiers 5 and 6 each ran the full 5-cycle cap and each
20
+ turned up one genuinely important correctness bug alongside a batch of routing fixes. Full
21
+ per-cycle detail is in `HANDOVER.md`'s "The dialogue-flow playtest loop" section.
22
+
23
+ `npm test` is green at **1355** (up from 1258 at the start of this session). v1.0.7 is
24
+ published (0.9.11 1.0.0 1.0.7 across an earlier session; the exact release chain and
25
+ file:line detail are in `HANDOVER.md`). Nothing has pushed since, so the local version sits at
26
+ 1.0.9 per the bump-at-push-time policy.
27
+
28
+ Test count across the session's later stretch:
29
+
30
+ | Work | `npm test` |
31
+ | --- | --- |
32
+ | Playtest-freeze verification pass (Tiers 0/1/2/4 + operator bugs A-F, chat-tested live and frozen as regressions) | 1299 → 1303 |
33
+ | `resolveObject` tier-3 derivational-stem bridge, closing the one dead-end the freeze pass found | 1303 → 1307 |
34
+ | Tier 5 (teach + recall + reasoning in dialogue), 5 cycles | 1307 → 1328 |
35
+ | Tier 6 (the messy real user), 5 cycles, run alongside a background test-suite health pass | 1328 → 1345 |
36
+ | Compound-name resolution (multi-word queries to joined-token symbol names) | 1345 1352 |
37
+ | Vocabulary-growth mirror fix — known-subject/unknown-object mint (`unknownObjectFallback`), so new terms compound turn over turn | 1352 → 1355 |
38
+
39
+ ### Shipped this session
40
+
41
+ - **Tier 5** found 12 routing/recognition fixes across teach and recall: article/head-word gaps
42
+ in "what do you know about X", an adverb mis-parsed as a verb in general-verb teach, passive
43
+ ownership phrasing, a quantified-property mis-teach, missing yes/no readers for taught facts, a
44
+ silently-null teach path, past-tense property support, a leading hedge-adverb gap. The final
45
+ cycle also caught a real correctness bug: "is the validate module deprecated" confidently
46
+ answered off an unrelated "logger module" fact, through a word-overlap fallback with no
47
+ exclusion for common code-noun suffixes like "module". New `test/chatflow-tier5.test.mjs` (21
48
+ cases).
49
+ - **Tier 6**, the last rung of the ladder, found 23 routing/recognition fixes: a grain-word
50
+ resolution ambiguity ("the logger module" tying a Module against a same-stem Class); five new
51
+ closed preamble frames in `interpret/normalize.mjs` for topic-switch, self-interruption,
52
+ acknowledgement, hedge-adverb, and browsing discourse markers, chaining correctly when several
53
+ stack together; bare "inherits"/"inherit" alongside its sibling "extends"; a dozen more
54
+ vague-opener idioms; dialect and register gaps like "yeah nah", "howdy pardner", "aight", "no
55
+ worries". It also caught one important bug: "is the logger module tested" answered a
56
+ fabricated "I don't know that yet" even though the structural engine had already computed the
57
+ real, honest answer. An over-eager property-adjective matcher discarded it whenever a real
58
+ graph-computed parse already existed. New `test/chatflow-tier6.test.mjs` (17 cases).
59
+ - **A test-suite health pass**, run in the background alongside Tier 6: batched `syllogise()`'s
60
+ per-fact writes via `appendFacts`; let two chatbench plumbing tests opt out of the corpus seed
61
+ (`TMCT_NO_SEED`); added a shared once-per-process seeded-fixture builder
62
+ (`test/helpers/seeded-fixture.mjs`) for tests that only consume seeded content; replaced a
63
+ hand-rolled copy of `WALL_MISS_RE` with the real export; and extracted a shared session-driver
64
+ helper (`test/helpers/session.mjs`), replacing 11 near-duplicate `drive()`/`driveSession()`
65
+ implementations. Full detail is in `HANDOVER.md`'s "Test-suite health pass" entry.
66
+ - **Compound-name resolution**, from the operator's own worked example: "the payment system" now
67
+ finds `PaymentSystem`, `payment-system`, a compound path like
68
+ `westfield-payment-system/src/MyCode.cs`, and an interface-style name like
69
+ `IPaymentSystemImpl.cs`. `resolveObject` (`src/ask.mjs`) gained a multi-word compound-term
70
+ tier, the same shape as the existing single-word basename-exact/prefix-suffix (`9dde2b3`) and
71
+ derivational-stem (`6e2d96b`) tiers, gated to require an explicit separator in the candidate
72
+ label so a pure-camelCase identifier still falls to tier 4's prose fallback unaffected (this
73
+ protects a frozen "total price" → `calculateTotalPrice` test). New
74
+ `test/ask-compound-resolve.test.mjs` (7 cases). Full detail is in `HANDOVER.md`'s
75
+ "Compound-name resolution addendum" entry.
76
+ - **The first-run chat experience, rewritten (1.0.0).** A brand-new `npm install` plus a bare
77
+ `tmct chat` used to lead with a "no code graph loaded" apology for any input, including plain
78
+ greetings, even though the seeded ontology/lexicon could already answer them. This was a
79
+ 0.6.0-era design over-applying its own honest empty-graph orientation. The fix: identity/
80
+ capability-led responses ("I'm tmct — ..." before any caveat), a real self-description and a
81
+ distinct "no LLM involved" answer for the identity/AI-ID family, provably-correct "try this"
82
+ examples (a `vocabExampleHint` that only offers a term confirmed to resolve in the session's
83
+ actual seed state), and broadened conversational recognition (dialect, register, slang,
84
+ elongation, a bounded-fuzzy typo layer). All of it landed as curated closed-set additions, per
85
+ the project's standing preference over general grammar rules.
86
+ - **The dialogue-flow playtest loop, tiers 0-4.** Tier 0 (bootstrap/identity), Tier 1 (single
87
+ touch plus one drill-down), Tier 2 (drill-down chains with anaphora), and Tier 4
88
+ (compositional and comparative) each closed in one pass. Tier 3 (cross-concept and relation
89
+ touches) took 7 passes: cycles 3-9 progressively found and fixed a recurring `resolveObject`
90
+ substring-match weakness, where a missing minimum-length floor let short staccato connectives
91
+ like "and"/"it" silently hijack the conversation's focus and produce confidently wrong answers
92
+ on a later turn while the triggering turn still looked honest. It took three point-by-point
93
+ patches before cycle 9 found and fixed the actual root cause in one place. The skill doc itself
94
+ gained two rules from real incidents this run: always `mktemp -d` plus exact-path cleanup for
95
+ scratch fixtures, and never `chat --repo` the committed example fixture directly.
96
+ - **A live, client-side chat demo on the GitLab Pages homepage.** The real `src/ask.mjs` query
97
+ engine runs directly in the visitor's browser as a live demo, not a scripted replay. wink-nlp
98
+ loads from `esm.sh`, an import-map shim works around 3 leaf files' Node-only static imports, and
99
+ the engine itself needed no changes since it was already browser-clean pure JS. It boots with a
49
100
  banner, replays a few real pre-verified Q&A turns as "history", asks one randomized (or
50
- `?q=`-primed) question live, and as of this session's last addition has a genuine
51
- interactive input box so a visitor can type their own questions and get real computed answers.
52
- `?compact=1` for a minimal primed-link view; `window.tmctAnswer`/`tmctAsk`/`tmctParseEntities`
53
- exposed for headless/Playwright consumers (curl/jq can never see it no backend on GitLab
54
- Pages, JS never executes for a plain HTTP client documented plainly, not oversold).
55
- - **Operator-found bugs, fixed as they were found by hand-testing the shipped CLI**: relation-
56
- specific vocabulary filtering ("what is a tree used for" was dumping every known relation
57
- instead of filtering to UsedFor); a teach-lane "did you mean" suggestion that could echo back
58
- the user's own input byte-identical (a missing a/an agreement check); out-of-domain small talk
59
- ("what time is it") hitting the raw grammar wall instead of an honest nudge; a pronoun-subject
60
- teach-lane gap that could silently store a bogus fact ("he is a module"); a closed-set
61
- existence-question recognizer ("is there a class called X anywhere" was silently mis-answering
62
- a *different* question a relationship check as if it were a verified existence negative);
63
- "what else is X" repeating the primary definition verbatim instead of surfacing more; bare
64
- "what is X" (no article) having no fact-lookup route at all, including for a fact the user had
65
- *just* taught; and general verb-to-predicate teaching ("remember margo eats ribs" mints its own
66
- predicate now, not just the closed is/has/are set — "has a" interoperates with the existing
67
- ConceptNet-sourced `mgx:hasA` data).
68
- - **New-term teaching + quantifiers.** "redis is a cache" (a genuinely new term, not previously
69
- in the closed ACE lexicon) is now teachable via a write-side-only fix the read path already
70
- worked generically over any subject string, including the existing 2-hop transitive `IsA` proof
71
- chase. Plus four new phrasings ("some/a few Xs are Ys", "your X is a Y", bare "X is Y" as a
72
- property assertion) and a stored-quantifier recall ("how many Xs are Ys" "A few.").
73
- - **An always-on, short "Goal (inferred): ..." line** on every real structural/vocabulary answer
74
- distinct from the pre-existing opt-in `/narrate` full-trace mode, which stays as the deeper
75
- debug tool. Two correctness bugs in the goal-deduction hook itself got fixed along the way
76
- (a confidently wrong goal shown on failed teach attempts; a missing goal on relation-force
77
- answers that resolve via a different path than the normal parse).
78
- - **Seonix's 17-round dogfooding backlog, triaged and Batch 1 shipped.** A sibling project
79
- (seonix, consuming tmct as a real dependency) ran extensive dogfooding against both a synthetic
80
- self-index and a real 27,929-module production estate, relaying findings via the inter-session
81
- inbox. Triaged into 5 priority batches (4 items were already fixed by intervening work); Batch 1
82
- (existence-query correctness) shipped. Batches 2-5 queued see "Next" below.
83
- - **The version-bump policy, set then revised.** Tried "bump immediately after every push, hold
84
- locally until the next batch" (to keep the published npm version always matching the last
85
- pushed commit); reverted after it produced confusing "referencing a version that doesn't exist
86
- yet" noise mid-session. Current policy: bump only at the moment of actually pushing, as part of
87
- that same push. Recorded in `CLAUDE.md`.
101
+ `?q=`-primed) question live, and gives the visitor a genuine interactive input box to type
102
+ their own questions and get real computed answers. `?compact=1` gives a minimal primed-link
103
+ view; `window.tmctAnswer`/`tmctAsk`/`tmctParseEntities` are exposed for headless/Playwright
104
+ consumers. There's no backend on GitLab Pages, so plain `curl`/`jq` never sees a computed
105
+ answer, which is stated plainly in the code rather than oversold.
106
+ - **Operator-found bugs, fixed as they turned up in hand-testing the shipped CLI.** Relation-
107
+ specific vocabulary filtering (an ask like "what is a tree used for" was dumping every known
108
+ relation instead of filtering to UsedFor); a teach-lane "did you mean" suggestion that could
109
+ echo the user's own input byte-for-byte (a missing a/an agreement check); out-of-domain small
110
+ talk ("what time is it") hitting the raw grammar wall instead of an honest nudge; a
111
+ pronoun-subject teach-lane gap that could silently store a bogus fact ("he is a module"); a
112
+ closed-set existence-question recognizer misreporting a relationship check as a verified
113
+ existence negative; "what else is X" repeating the primary definition instead of surfacing
114
+ more; bare "what is X" (no article) having no fact-lookup route at all, including for a fact
115
+ the user had just taught; and general verb-to-predicate teaching ("remember margo eats ribs"
116
+ mints its own predicate now, not just the closed is/has/are set, and "has a" interoperates with
117
+ the existing ConceptNet-sourced `mgx:hasA` data).
118
+ - **Six more operator-found bugs (A-F), from a later manual chat-testing pass.** A malformed
119
+ "haves soup" render for past-tense "had" (a lemma fix); a broken "count soup" message when no
120
+ code graph is loaded; "what is in your memory" (bare, and "... about X") falling to the
121
+ structural miss instead of the memory summary/fact-lookup lanes. The "about X" form now also
122
+ walks transitive subtypes of X over taught (never corpus-noise) isa facts; a closed-set
123
+ indirect-request wrapper ("I want you to search for Widget") that used to be swallowed whole by
124
+ the general-verb teach recognizer, now stripped centrally before dispatch, plus a "search for
125
+ X"/"tell me X" (no "about") phrasing fix; and a `GOAL_BY_COMMAND` table that gives every
126
+ slash-command dispatch its own honest "Goal (inferred): ..." line. Full detail per bug is in
127
+ `HANDOVER.md`'s "Operator-found bugs A-F" entry.
128
+ - **General verb-to-predicate teaching's query-side follow-up.** A taught general-verb fact now
129
+ answers direct questions too: "does margo eat ribs" → yes, "did margo eat ribs" yes, "does
130
+ margo eat cake" → an honest no, "what does margo eat" lists ribs. It reuses the same has/have
131
+ predicate bridge the teach side already had.
132
+ - **New-term teaching and quantifiers.** "redis is a cache" (a genuinely new term, not
133
+ previously in the closed ACE lexicon) is now teachable through a write-side-only fix; the read
134
+ path already worked generically over any subject string, including the existing 2-hop
135
+ transitive `IsA` proof chase. Plus four new phrasings ("some/a few Xs are Ys", "your X is a Y",
136
+ bare "X is Y" as a property assertion) and a stored-quantifier recall ("how many Xs are Ys" →
137
+ "A few.").
138
+ - **An always-on, short "Goal (inferred): ..." line** on every real structural or vocabulary
139
+ answer, distinct from the pre-existing opt-in `/narrate` full-trace mode. Two correctness bugs
140
+ in the goal-deduction hook itself got fixed along the way: a confidently wrong goal shown on
141
+ failed teach attempts, and a missing goal on relation-force answers that resolve through a
142
+ different path than the normal parse.
143
+ - **Seonix's 17-round dogfooding backlog, triaged and worked through.** Seonix, a sibling
144
+ project consuming tmct as a real dependency, ran extensive dogfooding against both a synthetic
145
+ self-index and a real 27,929-module production estate, and relayed the findings over the
146
+ inter-session inbox. The backlog was triaged into 5 priority batches (4 items were already
147
+ fixed by intervening work). **Batch 1** (existence-query correctness) shipped first. **Batch
148
+ 2**: bare "what is Commit" now parses (article optional, restricted to `ENTITY_TO_TYPE`'s
149
+ closed vocabulary); a reverse `inherits` verb family ("is X a superclass/parent class of Y")
150
+ swaps subject and object at parse time to agree with the existing forward phrasing; a curated
151
+ trailing-scope-filler strip ("what is a Module in this graph" → "Module") works at both the
152
+ grammar and chat-fact-lookup layers. **Batch 3**: purpose/identity phrasing ("whats X for/
153
+ about") joins "what does X do"; bare "recent/latest/newest commits" render a real dated list
154
+ instead of a false find-miss, and "the last/latest/most recent commit" as a query subject
155
+ substitutes the actual newest Commit before parsing; onboarding/closing phrasings beyond the
156
+ original closed set get the orientation nudge; present-tense cochange phrasing ("changes with")
157
+ joins the past-tense form. **Batch 4/5**: the cross-graph disambiguation-ranking weakness never
158
+ reproduced on tmct's own tiny example fixtures, so a new committed fixture graph
159
+ (`test/fixtures/large-scale/`, vendored commander.js + express.js source) was built to
160
+ reproduce it. It surfaced an exact basename match losing to a same-directory sibling that only
161
+ shared a component; fixed in `resolveObject`'s tier-3 scoring, where a new exact/prefix/suffix
162
+ basename tier now outranks the length-normalized overlap fallback. Separately, "which functions
163
+ call X and test Y" (two different, both-recognized relation verbs joined by "and") used to fall
164
+ to the legacy `ambiguousParse` path; the marker gate now also opens when every later
165
+ "and"-branch names its own single-word recognized verb, composing a real set intersection,
166
+ narrowly scoped so the pre-existing "which classes extends Base and couples to logging" compat
167
+ case stays exactly as closed as before. Still open: cochange phrasing variants, and a single,
168
+ not independently reverified "multi-root" substring over-match.
169
+ - **The Tier-4 "of X" membership gap, walked through inheritance.** "public methods of
170
+ TaskController" used to return a genuine-looking but incomplete empty when the class declared
171
+ no members of its own but inherited real ones from a superclass. `src/ask.mjs`'s membership
172
+ eval now tries the owner's own (qualifier-filtered) members first, and only walks
173
+ `ancestorsOf` nearest-first when that's empty and the class participates in `inherits`. An
174
+ inherited answer is disclosed out loud ("… has no own methods — inherited from Controller:
175
+ …"), never silently presented as the owner's own.
176
+ - **The version-bump policy, set then revised.** The session first tried bumping immediately
177
+ after every push and holding the bump locally until the next batch shipped, to keep the
178
+ published npm version matching the last pushed commit. That produced confusing "referencing a
179
+ version that doesn't exist yet" noise, so it was reverted mid-session. Current policy, recorded
180
+ in `CLAUDE.md`: bump only at the moment of actually pushing, as part of that same push.
88
181
 
89
182
  ### Next: the open follow-ups
90
183
 
91
- 1. **Tier 5 (teach + recall + reasoning in dialogue) and Tier 6 (the messy real user)** — the
92
- remaining two rungs of the dialogue-flow ladder, not yet run. Tier 5's territory substantially
93
- overlaps functionality shipped this session (new-term teaching, quantifier recall) but hasn't
94
- been run through the playtest loop's own dead-end-hunting discipline yet.
95
- 2. **Seonix Batches 2-5** (full detail relayed via the inbox, triage summary in this session's
96
- history): Batch 2 "what is X" vs "what is a X" grammar-level minimal pair (the chat-layer
97
- fact-lookup side is now fixed; the underlying `grammar.mjs` T5 template still requires the
98
- article, left alone deliberately pending a closer look at why), a missing reverse-direction
99
- "is X a superclass of Y" verb entry, "what is a `<noun phrase>`" swallowing the whole phrase
100
- instead of extracting the head noun. Batch 3 — recurring wall patterns (purpose/identity
101
- "whats X for/about", temporal qualifiers on Commit queries, onboarding/closing questions read
102
- as literal search strings). Batch 4/5 lower-priority, including a cross-graph disambiguation-
103
- candidate-ranking weakness seonix evidenced 5 times independently but that doesn't reproduce on
104
- tmct's own small fixture graph (needs a larger graph to chase).
105
- 3. **General verb-to-predicate teaching's natural follow-up**: dedicated direct-question
106
- recognition ("does margo eat ribs", "what does margo eat") — this session's work covers
107
- teaching + generic retrieval, not verb-specific query phrasings.
108
- 4. **The Tier-4 "of X" membership gap**: "public methods of TaskController" returns a genuine,
109
- receipted empty because the class declares no methods of its own (they're inherited) —
110
- extending membership queries to walk inheritance is a bigger structural change than a routing
111
- fix, deliberately deferred.
184
+ 1. **Judged CHATBENCH re-run.** Not run this session. This session's changes touch answer text
185
+ on judged surfaces again (onboarding/identity responses, teach-lane wording, new relation
186
+ phrasings), so the next judged pass needs to re-derive its stale set from answer-text diffs,
187
+ not assume anything carries over from the 0.8.2-era baseline still on record.
188
+ 2. **The reverse-`inherits` verb family's "the"-definite forms** from Seonix Batch 2 ("is the
189
+ superclass of") aren't wired into `VERB_TO_KIND` yet. Doing so leaked the bare word "the"
190
+ into `ask.mjs`'s CONTENT_VOCAB and broke the relaxation cascade's noise-strip tests, so it
191
+ needs a CONTENT_VOCAB fix first.
192
+ 3. **Seonix Batch 4/5's remaining items**: cochange phrasing variants, and the single,
193
+ not-independently-reverified "multi-root" substring over-match noted above.
194
+ 4. **Extend compound-symbol matching to `/describe`'s own resolver.** The compound-name
195
+ resolution above only covers `resolveObject` (`src/ask.mjs`); `/describe`'s own resolver
196
+ (`resolveSymbol` in `codegraph.mjs`) is a separate, stricter, pre-existing resolver that
197
+ doesn't share `resolveObject`'s tiered scoring, so "describe the payment system" doesn't
198
+ benefit yet. Not a regression, just not yet covered.
112
199
 
113
200
  ### Later: deferred by design, staged inside each plan
114
201
 
@@ -116,7 +203,9 @@ Each plan doc stages its own later phases; this list just points to them rather
116
203
  their tables.
117
204
 
118
205
  - **infbench stages 1-5** (`PLAN_INFERENCE_TESTING.md` §4). The disjointness proof rule (unlocks
119
- B1), proof-chain materialization, cardinality entailment, consistency checking.
206
+ B1), proof-chain materialization, cardinality entailment, consistency checking. The repeatable
207
+ measure/gate/advance cycle for this ladder is now also captured as an invokable skill,
208
+ `SKILL_INFERENCE_TESTING.md`.
120
209
  - **Advanced-grammar tracks b/d/e** (`PLAN_ADVANCED_GRAMMAR.md`). The constructions not landed
121
210
  this wave: stacked modality/passive, implicit arguments, and the rest of the CEFR inventory
122
211
  audit table.
@@ -874,6 +963,37 @@ Features we have deliberately shaped seams for but will not build until the phas
874
963
  earned them. **Not everything below is deferred for the same reason** — the design horizon,
875
964
  stated explicitly (2026-07-08 research pass):
876
965
 
966
+ ### Future direction: a genuine planning/agentic loop (flagged 2026-07-09, research pass done, not implemented)
967
+
968
+ The operator's own framing, explicitly out of scope for the routing-level `GOAL_BY_COMMAND`/
969
+ Goal-inference generalization this session shipped (HANDOVER's Bug F point 5, which only labels
970
+ an already-computed answer's intent — it never plans ahead of one): infer the goal, read the
971
+ relevant subgraph, reason about candidate action-paths and their effects, pick the next step,
972
+ execute, repeat.
973
+
974
+ Two companion research docs (2026-07-09, design only, zero code shipped) scope this against
975
+ minimal benchmark domains before anything domain-general is attempted:
976
+ - `PLAN_HANOI.md` — the OPEN-LOOP case (a whole solution path is computable up front from the
977
+ start state). Recommends representing state as taught facts in the memory store (not the
978
+ read-only, provider-owned code graph), a new `restsOn` edge encoding stack order, and genuine
979
+ bounded state-space search — reusing `syllogise.mjs`'s `findIsaChain` (already, in shape, a
980
+ bounded rooted BFS path search) — over hard-coding Hanoi's known closed-form recursive solution,
981
+ so the result is an actual generalizable planner, not a Hanoi-shaped trick.
982
+ - `PLAN_GUESS_NUMBER.md` — the CLOSED-LOOP case ("I am thinking of a number," both as guesser —
983
+ belief-interval bisection over repeated higher/lower observations — and as thinker — tmct holds
984
+ a secret and gives honest feedback, no search needed). Recommends a new parallel session-state
985
+ slot (`game`) threaded through `createSession`/`runTurn` exactly the way `focus` already is,
986
+ kept deliberately separate from the `pending` pagination field since a game must survive an
987
+ aside mid-play, unlike a listing remainder.
988
+
989
+ Both docs converge on the SAME one genuinely new primitive neither doc found already built
990
+ anywhere in tmct: something that computes a SUCCESSOR STATE (apply a chosen action, produce the
991
+ next graph/belief to reason over) — every existing traversal (`ancestorsOf`, `computeFind`,
992
+ `findIsaChain` itself) is read-only. That primitive, plus a still-open recognition question (how
993
+ tmct notices "the user wants goal-directed action" at all, and whether multi-step execution needs
994
+ confirmation before running) is the real next-session scope — a dedicated design/implementation
995
+ session, not a routing fix.
996
+
877
997
  ### The design horizon
878
998
 
879
999
  **Before the horizon — known-how, not-yet-built, no research risk.** Sequencing or engineering
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "1.0.8",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "The Mechanical Code Talker (tmct) — a tolerant, offline, $0 chat surface that guides you toward precision queries about a software repository. ELIZA/PARRY-style but domain-obsessed with code. No model calls; no codebase index of its own.",