@polycode-projects/the-mechanical-code-talker 1.9.2 → 1.10.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.
Files changed (80) hide show
  1. package/README.md +441 -202
  2. package/bin/tmct.mjs +126 -1
  3. package/package.json +4 -2
  4. package/src/answer-variants.mjs +8 -36
  5. package/src/ask-browser-entry.mjs +5 -23
  6. package/src/ask-browser.bundle.js +1 -2
  7. package/src/ask-nlp.mjs +9 -23
  8. package/src/ask-vocab.mjs +139 -589
  9. package/src/ask.mjs +627 -1729
  10. package/src/chat.mjs +1684 -2872
  11. package/src/cli-args.mjs +14 -28
  12. package/src/codegraph.mjs +236 -644
  13. package/src/completions/complete.mjs +18 -62
  14. package/src/completions/graph-adapter.mjs +14 -60
  15. package/src/completions/group.mjs +12 -68
  16. package/src/completions/infer.mjs +38 -126
  17. package/src/completions/prune.mjs +17 -70
  18. package/src/completions/rank.mjs +16 -69
  19. package/src/completions/search.mjs +8 -31
  20. package/src/concept.mjs +32 -88
  21. package/src/conformance.mjs +11 -15
  22. package/src/corpus/conceptnet.mjs +31 -89
  23. package/src/corpus/templates.mjs +19 -45
  24. package/src/corpus/unknown-ingest.mjs +31 -92
  25. package/src/embed.mjs +10 -22
  26. package/src/extensions.mjs +50 -154
  27. package/src/finish.mjs +35 -91
  28. package/src/grammar/ace.mjs +16 -40
  29. package/src/grammar/assert.mjs +1 -1
  30. package/src/grammar/lexicon-core.json +1 -1
  31. package/src/grammar/lexicon.mjs +9 -27
  32. package/src/graph-merge.mjs +2 -3
  33. package/src/hash.mjs +6 -14
  34. package/src/index.mjs +6 -10
  35. package/src/init.mjs +38 -125
  36. package/src/interpret/fuzzy.mjs +10 -29
  37. package/src/interpret/merge.mjs +9 -27
  38. package/src/interpret/normalize.mjs +137 -585
  39. package/src/interpret/pipeline.mjs +23 -71
  40. package/src/interpret/strategies/ace.mjs +7 -31
  41. package/src/interpret/strategies/constructions.mjs +14 -41
  42. package/src/interpret/strategies/grammar.mjs +21 -60
  43. package/src/interpret/strategies/keywords.mjs +42 -131
  44. package/src/interpret/strategies/noise-strip.mjs +18 -89
  45. package/src/memory/bias.mjs +11 -54
  46. package/src/memory/blocks.mjs +18 -69
  47. package/src/memory/core.mjs +171 -591
  48. package/src/memory/fold.mjs +0 -0
  49. package/src/memory/inspect.mjs +7 -25
  50. package/src/memory/shacl.mjs +10 -39
  51. package/src/memory/trust.mjs +26 -127
  52. package/src/memory-ask-browser-entry.mjs +7 -30
  53. package/src/memory-ask-browser.bundle.js +1 -1
  54. package/src/paraphrase.mjs +20 -53
  55. package/src/planning.mjs +15 -157
  56. package/src/prose-nlp.mjs +4 -17
  57. package/src/prose.mjs +19 -67
  58. package/src/providers/bootstrap.mjs +1 -2
  59. package/src/providers/fixture.mjs +1 -2
  60. package/src/providers/graph-service.mjs +28 -59
  61. package/src/repository-interface.mjs +6 -8
  62. package/src/router/drive.mjs +183 -0
  63. package/src/router/goal-reasoner.mjs +66 -231
  64. package/src/router/guardrail.mjs +20 -58
  65. package/src/router/planner.mjs +15 -46
  66. package/src/router/registry.mjs +13 -43
  67. package/src/router/resolver.mjs +46 -131
  68. package/src/router/results.mjs +231 -0
  69. package/src/schema-docs.mjs +10 -27
  70. package/src/server-http.mjs +10 -19
  71. package/src/server.mjs +22 -28
  72. package/src/sessions.mjs +15 -30
  73. package/src/source-slice.mjs +5 -7
  74. package/src/source.mjs +10 -20
  75. package/src/syllogise.mjs +187 -575
  76. package/src/telemetry.mjs +3 -3
  77. package/src/toml-config.mjs +4 -4
  78. package/src/tui/app.mjs +9 -19
  79. package/src/viz.mjs +66 -123
  80. package/src/wink-model.mjs +10 -24
@@ -1,39 +1,16 @@
1
- // memory/blocks.mjs — text blocks + the relevance index (ROADMAP item 9).
2
- //
3
- // The memory graph (core.mjs) holds STRUCTURE; this module holds TEXT: cleaned
4
- // session transcripts (fold.mjs writes one block per session) and, later,
5
- // corpus documents. Storage under <repo>/.tmct/memory/blocks/:
6
- // <block-id>.txt — the plain block text
7
- // index.json — per-block prose tokens (prose.mjs tokenizer) + a static rank
8
- //
9
- // Ranking is two signals, combined at query time:
10
- // 1. STATIC rank — a genuine iterative PageRank over the block-similarity
11
- // graph (an undirected edge wherever two blocks share ≥ OVERLAP_MIN
12
- // tokens; damping 0.85, 20 iterations — cheap at this scale). A block that
13
- // shares vocabulary with many other blocks is "well-connected": it covers
14
- // ground the corpus keeps returning to, so it wins ties.
15
- // 2. QUERY-time IDF match — each query token is weighted by rarity across
16
- // blocks (idf = log(1 + N/(1+df)), the codegraph.mjs locate discipline),
17
- // so a whole-question query is not dominated by its ubiquitous words.
18
- // retrieveBlocks() scores idf-sum × (1 + rank) ÷ sqrt(1 + degree): the IDF
19
- // match decides topic, the static rank breaks ties toward well-connected
20
- // blocks, and the degree divisor (hub dampening, ported from codegraph.mjs's
21
- // spiralExpand degree-quantile gate; on by default here) stops a block that
22
- // merely shares vocabulary with disproportionately many others — a generic
23
- // "boilerplate" hub — from winning on inflated rank alone.
24
- //
25
- // All writes are temp+rename atomic; saveBlock is an upsert (same id replaces —
26
- // what makes fold.mjs's re-fold idempotent).
1
+ // memory/blocks.mjs — text blocks + the relevance index. core.mjs holds
2
+ // STRUCTURE; this holds TEXT (cleaned session transcripts, corpus docs) under
3
+ // .tmct/memory/blocks/. retrieveBlocks scores idf-sum × (1 + PageRank) ÷
4
+ // sqrt(1 + degree) a hub-dampened IDF match. Writes are atomic; saveBlock
5
+ // upserts by id (fold.mjs's re-fold idempotency rests on this).
27
6
 
28
7
  import { mkdir, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
29
8
  import { join } from "node:path";
30
9
  import { splitIdentifierWords, tokenizeProse } from "../prose.mjs";
31
10
  import { SOURCE_PRIOR } from "./trust.mjs";
32
11
 
33
- // A block inherits the trust of the Source it was folded from: a session block
34
- // is operator-chat (1.0), a corpus block its corpus Source (0.7). Retrieval
35
- // weights relevance × trust via a BOUNDED factor (≈ 0.5 + trust → ~[0.5, 1.5]),
36
- // a capped nudge so a weakly-trusted but perfectly-relevant block still surfaces.
12
+ // A block inherits its Source's trust (operator 1.0, corpus 0.7); retrieval
13
+ // weights relevance × trust via a bounded factor (0.5 + trust, ~[0.5, 1.5]).
37
14
  const DEFAULT_BLOCK_SOURCE_TYPE = "operator";
38
15
  const blockTrust = (sourceType) => SOURCE_PRIOR[sourceType] ?? SOURCE_PRIOR.operator;
39
16
  const trustFactorOf = (trust) => 0.5 + (typeof trust === "number" ? trust : SOURCE_PRIOR.operator);
@@ -82,17 +59,8 @@ export async function loadBlockIndex(dir) {
82
59
  }
83
60
  }
84
61
 
85
- /**
86
- * Build the block-similarity adjacency shared by rankBlocks and degreeOf:
87
- * `tokensById` is a plain { id: tokens[] } map; an undirected edge joins two
88
- * blocks sharing at least `overlapMin` tokens. Returns { ids, neighbours }
89
- * (neighbours[i] is an array of adjacent indices into ids).
90
- *
91
- * Exported (as of Stage 0 of PLAN_COMPLETIONS.md) so src/completions/group.mjs can build
92
- * connected components over the same similarity graph rankBlocks/degreeOf already use,
93
- * rather than re-deriving the shared-token-overlap logic — this IS the clustering
94
- * primitive this graph was missing; grouping is layered on top of it, not duplicated.
95
- */
62
+ /** The block-similarity adjacency shared by rankBlocks/degreeOf: an edge
63
+ * joins two blocks sharing >= `overlapMin` tokens. Returns { ids, neighbours }. */
96
64
  export function buildNeighbours(tokensById, overlapMin) {
97
65
  const ids = Object.keys(tokensById || {});
98
66
  const N = ids.length;
@@ -114,13 +82,8 @@ export function buildNeighbours(tokensById, overlapMin) {
114
82
  return { ids, neighbours };
115
83
  }
116
84
 
117
- /**
118
- * Each block's degree (neighbour count) in the same block-similarity graph
119
- * rankBlocks runs PageRank over. Pure — returns { id: degree }. Used to
120
- * dampen retrieveBlocks' hub bias (a block linked to many others shouldn't
121
- * win purely by being well-connected — codegraph.mjs's spiralExpand applies
122
- * the same degree-quantile idea to module search).
123
- */
85
+ /** Each block's degree (neighbour count) in the similarity graph — used to
86
+ * dampen hub bias in retrieveBlocks. Pure returns { id: degree }. */
124
87
  export function degreeOf(tokensById, { overlapMin = OVERLAP_MIN } = {}) {
125
88
  const { ids, neighbours } = buildNeighbours(tokensById, overlapMin);
126
89
  const out = {};
@@ -128,12 +91,8 @@ export function degreeOf(tokensById, { overlapMin = OVERLAP_MIN } = {}) {
128
91
  return out;
129
92
  }
130
93
 
131
- /**
132
- * Iterative PageRank over the block-similarity graph. `tokensById` is a plain
133
- * { id: tokens[] } map; an undirected edge joins two blocks sharing at least
134
- * `overlapMin` tokens. Standard damped iteration (d=0.85, 20 rounds), dangling
135
- * mass redistributed evenly, ranks summing to ~1. Pure — returns { id: rank }.
136
- */
94
+ /** Iterative PageRank over the block-similarity graph (damped, dangling mass
95
+ * redistributed evenly). Pure returns { id: rank }. */
137
96
  export function rankBlocks(tokensById, {
138
97
  damping = PAGERANK_DAMPING, iterations = PAGERANK_ITERATIONS, overlapMin = OVERLAP_MIN,
139
98
  } = {}) {
@@ -190,7 +149,7 @@ export async function saveBlock(dir, { id, text, sourceType = DEFAULT_BLOCK_SOUR
190
149
  const prior = index.blocks[id];
191
150
  index.blocks[id] = {
192
151
  file, tokens: tokenizeBlock(text),
193
- // first-write-wins createdAt (step (a)) + the block's inherited source trust (step (d)).
152
+ // first-write-wins createdAt + the block's inherited source trust.
194
153
  createdAt: prior?.createdAt || createdAt || new Date().toISOString(),
195
154
  sourceType, trust: blockTrust(sourceType),
196
155
  };
@@ -211,14 +170,9 @@ export async function removeBlock(dir, id) {
211
170
  return true;
212
171
  }
213
172
 
214
- /**
215
- * The top-k blocks a question "touches": IDF-weighted token match (rarity-
216
- * weighted, so common words can't dominate) combined with the static PageRank
217
- * (score × (1 + rank), divided by sqrt(1 + degree) to dampen hubs — a block
218
- * that shares vocabulary with disproportionately many others doesn't win on
219
- * inflated rank alone). Returns [{ id, score, rank, file, text }], best
220
- * first; [] when nothing matches (never a guessed block).
221
- */
173
+ /** Top-k blocks matching `query`: IDF-weighted token overlap combined with
174
+ * PageRank, hub-dampened. Returns [{ id, score, rank, file, text }], best
175
+ * first; [] when nothing matches. */
222
176
  export async function retrieveBlocks(dir, query, k = 3) {
223
177
  const index = await loadBlockIndex(dir);
224
178
  const entries = Object.entries(index.blocks);
@@ -243,12 +197,7 @@ export async function retrieveBlocks(dir, query, k = 3) {
243
197
  if (idfSum <= 0) continue;
244
198
  const rank = b.rank ?? 0;
245
199
  const degree = b.degree ?? 0;
246
- // relevance × connectivity × TRUST a bounded trustFactor (~[0.5, 1.5]) so a
247
- // corroborated/operator block outranks a lone low-trust one on a relevance tie,
248
- // yet a weakly-trusted but perfectly-relevant block still surfaces. Divided by
249
- // sqrt(1 + degree) — hub dampening (the codegraph.mjs spiralExpand idea, ported
250
- // here): a block that shares vocabulary with disproportionately many others
251
- // shouldn't win purely by being well-connected.
200
+ // relevance × connectivity × trust, hub-dampened by sqrt(1 + degree).
252
201
  const trust = typeof b.trust === "number" ? b.trust : blockTrust(b.sourceType);
253
202
  const trustFactor = trustFactorOf(trust);
254
203
  scored.push({