@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 +51 -32
- package/ROADMAP.md +212 -92
- package/package.json +1 -1
- package/src/ask-vocab.mjs +125 -1
- package/src/ask.mjs +510 -17
- package/src/chat.mjs +1216 -78
- package/src/codegraph.mjs +1 -1
- package/src/interpret/normalize.mjs +137 -3
- package/src/interpret/strategies/grammar.mjs +44 -11
- package/src/interpret/strategies/keywords.mjs +15 -1
- package/src/memory/core.mjs +15 -1
- package/src/syllogise.mjs +0 -0
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
|
-
|
|
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.
|
|
37
|
-
fit the grammar still gets the tolerant strategies; nothing
|
|
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
|
|
63
|
-
receipts
|
|
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
|
|
71
|
-
class", "what about imports", "what calls are there"
|
|
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
|
|
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
|
|
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
|
|
87
|
-
tmct genuinely knows the concept *and* has instances of it
|
|
88
|
-
miss stands. The effect is a conversation that drills down from a vague
|
|
89
|
-
a useful answer without ever hitting a wall. Natural phrasings are
|
|
90
|
-
capability you meant: *"what functions are in Task"* → its
|
|
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
|
|
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)
|
|
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
|
|
115
|
-
web scrape, a rule-derived entailment
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
260
|
-
ConceptNet slice is **CC-BY-SA 4.0
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- **Operator-found bugs, fixed as they
|
|
56
|
-
specific vocabulary filtering ("what is a tree used for" was dumping every known
|
|
57
|
-
instead of filtering to UsedFor); a teach-lane "did you mean" suggestion that could
|
|
58
|
-
the user's own input byte-
|
|
59
|
-
("what time is it") hitting the raw grammar wall instead of an honest nudge; a
|
|
60
|
-
teach-lane gap that could silently store a bogus fact ("he is a module"); a
|
|
61
|
-
existence-question recognizer
|
|
62
|
-
|
|
63
|
-
"what
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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. **
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
2. **
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
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.",
|