@polycode-projects/the-mechanical-code-talker 1.2.0 → 1.3.1
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 +9 -0
- package/ROADMAP.md +145 -6
- package/package.json +1 -1
- package/src/chat.mjs +845 -11
- package/src/memory/core.mjs +117 -1
- package/src/planning.mjs +227 -0
package/README.md
CHANGED
|
@@ -127,6 +127,15 @@ Teaching isn't limited to the ACE grammar's fixed shapes. Tell tmct an
|
|
|
127
127
|
arbitrary fact, like "margo eats ribs", and it mints a fact you can later ask
|
|
128
128
|
about directly: "what does margo eat", or "does margo eat ribs".
|
|
129
129
|
|
|
130
|
+
New vocabulary compounds as you teach it. "redis is a cache" mints "redis" as
|
|
131
|
+
a class-level concept even though it was never in the built-in lexicon, and a
|
|
132
|
+
later "every cache is a store" does the same for "store," the other way
|
|
133
|
+
round, as long as one side of the sentence is already grounded. tmct never
|
|
134
|
+
mints a fact between two totally ungrounded terms; it declines and nudges you
|
|
135
|
+
to ground one side first. Quantified teaching works too: "some functions are
|
|
136
|
+
risky" stores the quantifier, and a later "how many functions are risky"
|
|
137
|
+
answers "A few."
|
|
138
|
+
|
|
130
139
|
### Provenance and trust
|
|
131
140
|
|
|
132
141
|
Every fact and text block records **where it came from and when**. Sources are
|
package/ROADMAP.md
CHANGED
|
@@ -35,6 +35,126 @@ Test count across the session's later stretch:
|
|
|
35
35
|
| Tier 6 (the messy real user), 5 cycles, run alongside a background test-suite health pass | 1328 → 1345 |
|
|
36
36
|
| Compound-name resolution (multi-word queries to joined-token symbol names) | 1345 → 1352 |
|
|
37
37
|
| Vocabulary-growth mirror fix — known-subject/unknown-object mint (`unknownObjectFallback`), so new terms compound turn over turn | 1352 → 1355 |
|
|
38
|
+
| `findActionPath` (`src/planning.mjs`) — generic bounded on-demand-successor state-space search, `PLAN_HANOI.md`'s Phase 2 kernel, proven against a small toy graph; not wired into chat, Hanoi itself not started | 1355 → 1361 |
|
|
39
|
+
|
|
40
|
+
**INFBENCH re-measured against 1.2.0** (measurement-only dispatch, 2026-07-09): `INFBENCH_1.2.0.md`
|
|
41
|
+
confirms chat/INF-A2 now closes to 100% (the cax-sco/proof-chase win the STATUS banner above already
|
|
42
|
+
claimed) but also finds chat/INF-C1 has flipped from an honest ceiling to a genuine 93%-fabrication
|
|
43
|
+
regression, traced to the new general-verb-to-predicate query lane answering "no" on an absent fact
|
|
44
|
+
instead of declining — a real correctness bug, separate from and cheaper than the still-gating
|
|
45
|
+
INF-B1 (`cax-dw`) work.
|
|
46
|
+
|
|
47
|
+
**INF-C1 fabrication FIXED (2026-07-09, follow-up dispatch)**: `GENERAL_VERB_YESNO_RE`'s no-hit
|
|
48
|
+
branch (`src/chat.mjs`) now declines (`null`) instead of asserting a confident "no" when no taught
|
|
49
|
+
fact matches the queried subject/predicate/object triple, falling through to the ordinary
|
|
50
|
+
honest-miss cascade — same convention as `WHO_OWNS_RE`'s own no-hit branch. Re-ran `npm run
|
|
51
|
+
infbench`: chat/INF-C1 is back to **93% completion / 0% fabrication**, its `0.8.2`-era honest
|
|
52
|
+
ceiling, exactly as predicted (up from `1.2.0`'s 0% completion / 93% fabrication). Everything else
|
|
53
|
+
in the ladder is unchanged — still gated at INF-B1 (33% completion), unaffected by this fix.
|
|
54
|
+
`npm test` 1361 → 1362 (this fix's own contribution; see `HANDOVER.md` for the combined total
|
|
55
|
+
alongside the concurrent Rule-storage dispatch).
|
|
56
|
+
|
|
57
|
+
**`PLAN_TAUGHT_RELATIONS.md`** (research/design, 2026-07-09, nothing implemented): scopes teaching
|
|
58
|
+
tmct brand-new relations and rules through ordinary chat (a Prolog-style family tree — father,
|
|
59
|
+
parent, grandparent, descendant — none of it hardcoded, all of it taught), reusing
|
|
60
|
+
`findActionPath` for the hop-counted relation chase and a new sibling kernel, `findReachableSet`,
|
|
61
|
+
for open-ended enumeration. Live-testing while designing it surfaced real, already-shipped gaps:
|
|
62
|
+
the "is a kind of" teach phrasing isn't accepted anywhere today, a "parent" example in the original
|
|
63
|
+
scoping conversation only worked by an accidental lexicon collision, and a wrapped property-teach
|
|
64
|
+
shape (`TEACH_PROPERTY_RE`) has no groundedness check at all, unlike the newer subject/object
|
|
65
|
+
mint-fallback pair's explicit discipline. See `HANDOVER.md` for the full finding list; this is
|
|
66
|
+
next-session pickup material, not yet started.
|
|
67
|
+
|
|
68
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 3 — DONE (2026-07-09)**: the Rule storage foundation landed in
|
|
69
|
+
`src/memory/core.mjs` (`RULE_CLASS`, `appendRule`, `findRuleByName`) — pure plumbing, zero
|
|
70
|
+
`chat.mjs` change, reusing the existing Source/trust pipeline unmodified. `npm test` 1361 → 1371.
|
|
71
|
+
Phase 4 (compose2 query-side wiring) is next in that plan's build order.
|
|
72
|
+
|
|
73
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 1 — DONE (2026-07-09)**: Item 1 (relational fact teach,
|
|
74
|
+
`RELATION_FACT_TEACH_RE` — "ahab is the father of john" mints an ordinary Fact via
|
|
75
|
+
`generalVerbPredicate`, reused verbatim) and Item 5 (adjective-mint, `unknownAdjectiveFallback` —
|
|
76
|
+
"the cache is bespoke" / "TaskController is bespoke" mint `mgx:hasProperty`) both landed in
|
|
77
|
+
`src/chat.mjs`. Query-side readback for Item 1 needed zero new machinery ("what do you know about
|
|
78
|
+
X" / "does X <role> Y" both already confirm it); Item 5's own groundedness guard needed tightening
|
|
79
|
+
beyond the original design to avoid reopening the pinned "module is banana" regression — see
|
|
80
|
+
`PLAN_TAUGHT_RELATIONS.md`'s "Phase 1 — DONE" note for the full adjustment, plus a sharper,
|
|
81
|
+
live-confirmed restatement of that doc's Verification finding 4 (`isConversational`'s ≤3-word gate
|
|
82
|
+
pre-empts the teach lane entirely for a short bare sentence, not just its decline text — flagged,
|
|
83
|
+
not fixed, still out of scope). `npm test` 1371 → 1377.
|
|
84
|
+
|
|
85
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 6, KERNEL half — DONE (2026-07-09)**: `findReachableSet`
|
|
86
|
+
(`src/planning.mjs`), a sibling of `findActionPath` with no `isGoal` at all — every state reachable
|
|
87
|
+
from the start within `maxDepth` is a result, not just one goal. Shares only the frontier-seeding
|
|
88
|
+
step with `findActionPath`; the expand loops stayed independent (halting/accumulation semantics
|
|
89
|
+
differ enough to make a shared core more complex, not less). Proven against a toy graph with a real
|
|
90
|
+
cycle and a same-length two-path convergence. `test/planning.test.mjs`, 5 new tests. The WIRING half
|
|
91
|
+
(teach-shape recognizer + query-dispatcher branch, both in `chat.mjs`) is deliberately deferred,
|
|
92
|
+
kernel-only per this task's own scoping — see `PLAN_TAUGHT_RELATIONS.md`/`HANDOVER.md` for detail.
|
|
93
|
+
|
|
94
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 2 — DONE (2026-07-09)**: closes Item 1's own live-found
|
|
95
|
+
query-side gap ("is ahab the father of john" now resolves directly) and Item 2 (relation alias/union
|
|
96
|
+
query-side chase — a taught "father ⊑ parent" alias lets "is ahab a parent of john" resolve off the
|
|
97
|
+
father fact). One new recognizer (`RELATION_FACT_YESNO_RE`) and one new local helper
|
|
98
|
+
(`relationFactsFor`) in `factReadBack`, tried BEFORE `ISA_ASK_RE` gets a chance at the overlapping
|
|
99
|
+
shape. The teach-side "kind of"/"type of" fix (`stripKindOf`) is a genuine one-liner.
|
|
100
|
+
`test/chat-taught-relations.test.mjs` (new file), 4 tests. `npm test` 1382 → 1386. Phase 4 (compose2
|
|
101
|
+
rule, next in this plan's build order) reuses `relationFactsFor` as its own per-hop edge lookup.
|
|
102
|
+
|
|
103
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 4 — DONE (2026-07-09)**: Item 3 (fixed-hop `compose2` composition
|
|
104
|
+
rule — "a grandparent is a parent of a parent" teaches a Rule, and "is ahab a grandparent of
|
|
105
|
+
ishmael" resolves via a hop-counted `findActionPath` search over the taught father facts,
|
|
106
|
+
alias-chased through "parent" via Phase 2's own `relationFactsFor`). The hop-counting discipline
|
|
107
|
+
(`{ entity, hopsTaken }` state, `isGoal` requiring exactly 2 hops) is live-verified load-bearing: a
|
|
108
|
+
1-hop and a 3-hop path through the SAME father/parent edges both correctly decline in the same store
|
|
109
|
+
where the genuine 2-hop pair resolves yes. Full family-tree chain (two father facts + the alias + the
|
|
110
|
+
compose2 rule) live-verified end-to-end via the piped CLI. `test/chat-taught-relations.test.mjs`
|
|
111
|
+
extended with 5 more tests (9 total). `npm test` 1386 → 1391.
|
|
112
|
+
|
|
113
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 5 — DONE (2026-07-09)**: Item 4 (property-filtered composition
|
|
114
|
+
rule — "a grandfather is a grandparent who is male" teaches a `filter`-kind Rule). Required
|
|
115
|
+
refactoring Phase 2/4's `relAsk` dispatcher's three inline steps into one recursive closure,
|
|
116
|
+
`resolveRelationChase`, so a filter rule's base resolves GENERICALLY — the function calling itself —
|
|
117
|
+
whether the base is a plain taught relation or another Rule (e.g. compose2), never assuming which.
|
|
118
|
+
A hit requires both the base chase to resolve AND the subject to carry the taught property
|
|
119
|
+
(`mgx:hasProperty`); live-verified both failure modes separately (base fails outright vs. base holds
|
|
120
|
+
but the property filter correctly excludes the candidate) plus a filter whose base is a plain
|
|
121
|
+
relation (not a compose2 rule at all), proving the genericity. `test/chat-taught-relations.test.mjs`
|
|
122
|
+
extended with 4 more tests (13 total). `npm test` 1391 → 1395.
|
|
123
|
+
|
|
124
|
+
**`PLAN_TAUGHT_RELATIONS.md` Phase 6 — DONE (2026-07-09), WIRING half — the plan's build is now
|
|
125
|
+
COMPLETE, all six items.** Item 6 (recursive/reachability rule — "a descendant is a parent, or a
|
|
126
|
+
parent of a descendant" teaches a `recursive`-kind Rule; "list the descendants of ahab" enumerates
|
|
127
|
+
the full reachability set via `findReachableSet`, the kernel half already shipped, reused unchanged).
|
|
128
|
+
The query side is the one genuine kind-change among all six items (a reachability-SET enumeration,
|
|
129
|
+
not a yes/no chase), landed as a sibling of Phase 5's `resolveRelationChase` rather than a fourth
|
|
130
|
+
branch inside it — mirroring `findActionPath`/`findReachableSet`'s own sibling split at the kernel
|
|
131
|
+
level. Cycle safety (two individuals mutually taught as each other's parent) and a malformed
|
|
132
|
+
self-reference teach attempt (guarded for free by the teach regex's own backreference) both
|
|
133
|
+
live-verified. `test/chat-taught-relations.test.mjs` extended with 5 more tests, including one
|
|
134
|
+
comprehensive ALL-SIX-items integration test (18 total). `npm test` 1395 → 1400. **Nothing remains
|
|
135
|
+
outstanding from `PLAN_TAUGHT_RELATIONS.md`'s original six-item scope.**
|
|
136
|
+
|
|
137
|
+
**INFBENCH re-measured against 1.3.1** (measurement-only dispatch, 2026-07-09): `INFBENCH_1.3.1.md`
|
|
138
|
+
finds the ladder unchanged, byte-for-byte, since `1.3.0` — the four `PLAN_TAUGHT_RELATIONS.md`
|
|
139
|
+
phases that completed the plan (alias/union, `compose2`, property-filter, recursive/reachability
|
|
140
|
+
wiring) don't touch any band, confirmed by a zero-diff row comparison of both runs' raw product
|
|
141
|
+
files plus a direct check that no INFBENCH case's premises/query ever reach the new relational-teach
|
|
142
|
+
phrasing. Still gated at INF-B1 (33% completion), unchanged for a fourth consecutive measured
|
|
143
|
+
version — an honest, expected result given the new surface and the ladder measure different things.
|
|
144
|
+
|
|
145
|
+
**`PLAN_TAUGHT_RELATIONS.md` live-testing follow-up — DONE (2026-07-09)**: the operator live-tested
|
|
146
|
+
the full family-tree example end-to-end and found two real gaps, both fixed in `src/chat.mjs`. Gap 1:
|
|
147
|
+
a recognized-but-unsatisfied relational query used to fall to the GENERIC structural wall instead of
|
|
148
|
+
naming the relation — fixed by distinguishing "relation/rule name never taught" from "name known, this
|
|
149
|
+
pair's chase came up short" right in the `(a0)` block, each with its own specific decline text. Gap 2:
|
|
150
|
+
the REVERSE query shape ("who is the grandparent of john") didn't exist at all — new recognizer
|
|
151
|
+
`RELATION_WHO_ASK_RE` + a new `(a0.2)` block in `factReadBack`, re-deriving `resolveRelationChase`'s
|
|
152
|
+
same resolution logic (direct/alias/compose2/filter) walked backward from the object, reusing
|
|
153
|
+
`findReachableSet` unmodified for the compose2 reverse hop-chase. Live-verified the operator's own
|
|
154
|
+
repro exactly: "who is the grandparent of ishmael" → ahab (full 2-hop derivation cited); "who is the
|
|
155
|
+
grandparent of john" → an honest empty (never a wrong guess). `test/chat-taught-relations.test.mjs`
|
|
156
|
+
extended with 8 more tests (26 total). `npm test` 1400 → 1408, zero regressions. **Nothing remains
|
|
157
|
+
outstanding from `PLAN_TAUGHT_RELATIONS.md`.**
|
|
38
158
|
|
|
39
159
|
### Shipped this session
|
|
40
160
|
|
|
@@ -63,6 +183,17 @@ Test count across the session's later stretch:
|
|
|
63
183
|
hand-rolled copy of `WALL_MISS_RE` with the real export; and extracted a shared session-driver
|
|
64
184
|
helper (`test/helpers/session.mjs`), replacing 11 near-duplicate `drive()`/`driveSession()`
|
|
65
185
|
implementations. Full detail is in `HANDOVER.md`'s "Test-suite health pass" entry.
|
|
186
|
+
- **Vocabulary-growth mirror fix.** New vocabulary used to grow one-directionally only: "redis is
|
|
187
|
+
a cache" could mint the unknown subject "redis" because the object "cache" was already a known
|
|
188
|
+
noun, but the reverse ("every cache is a store," subject known, object unknown) declined
|
|
189
|
+
outright. Added `unknownObjectFallback`, gated on a genuine universal quantifier ("every"/"each"/
|
|
190
|
+
"all") so it can't reopen the general lexicon bypass the existing bare/"a" shapes rely on. A term
|
|
191
|
+
minted by either direction now grounds a later sentence exactly like a lexicon word, using
|
|
192
|
+
taught-only groundedness checks that deliberately exclude the bulk ConceptNet corpus seed (the
|
|
193
|
+
corpus mentions ordinary English words constantly and must never silently count as "grounded").
|
|
194
|
+
When both sides are totally ungrounded, tmct still declines, but now with an actionable grounding
|
|
195
|
+
nudge instead of a bare "I couldn't store that." New coverage in
|
|
196
|
+
`test/chat-teach-quantifier.test.mjs`.
|
|
66
197
|
- **Compound-name resolution**, from the operator's own worked example: "the payment system" now
|
|
67
198
|
finds `PaymentSystem`, `payment-system`, a compound path like
|
|
68
199
|
`westfield-payment-system/src/MyCode.cs`, and an interface-style name like
|
|
@@ -985,14 +1116,22 @@ minimal benchmark domains before anything domain-general is attempted:
|
|
|
985
1116
|
slot (`game`) threaded through `createSession`/`runTurn` exactly the way `focus` already is,
|
|
986
1117
|
kept deliberately separate from the `pending` pagination field since a game must survive an
|
|
987
1118
|
aside mid-play, unlike a listing remainder.
|
|
988
|
-
|
|
989
|
-
|
|
1119
|
+
- `PLAN_TAUGHT_RELATIONS.md` — teaching tmct brand-new relations and rules through ordinary chat
|
|
1120
|
+
(a taught Prolog-style family tree, none of the kinship vocabulary hardcoded), the first of the
|
|
1121
|
+
three to need a successor function SYNTHESIZED from data the user taught in an earlier turn,
|
|
1122
|
+
rather than hand-written per domain the way Hanoi's `legalMoves` and guess-number's
|
|
1123
|
+
interval-update rule are. Its own enumeration capability ("list the descendants of X," no fixed
|
|
1124
|
+
goal) needs a genuine new sibling kernel, `findReachableSet`, since `findActionPath` only ever
|
|
1125
|
+
searches toward one goal.
|
|
1126
|
+
|
|
1127
|
+
All three docs converged on the one genuinely new primitive none of them found already built
|
|
990
1128
|
anywhere in tmct: something that computes a SUCCESSOR STATE (apply a chosen action, produce the
|
|
991
1129
|
next graph/belief to reason over) — every existing traversal (`ancestorsOf`, `computeFind`,
|
|
992
|
-
`findIsaChain` itself) is read-only. That primitive
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1130
|
+
`findIsaChain` itself) is read-only. That primitive now exists (`findActionPath`, `src/planning.mjs`,
|
|
1131
|
+
shipped this session — see "Shipped this session" above), proven against a small toy graph but not
|
|
1132
|
+
wired into any of the three domains yet. The remaining next-session scope is that wiring, plus a
|
|
1133
|
+
still-open recognition question: how tmct notices "the user wants goal-directed action" at all, and
|
|
1134
|
+
whether multi-step execution needs confirmation before running.
|
|
996
1135
|
|
|
997
1136
|
### The design horizon
|
|
998
1137
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polycode-projects/the-mechanical-code-talker",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
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.",
|