@polycode-projects/the-mechanical-code-talker 3.0.5 → 3.0.7

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 (68) hide show
  1. package/README.md +41 -16
  2. package/bin/tmct.mjs +1 -1
  3. package/corpus/child/README.md +2 -2
  4. package/corpus/child/index.json.gz +0 -0
  5. package/corpus/child/manifest.json +74 -74
  6. package/corpus/child/shards/child-00.jsonl.gz +0 -0
  7. package/corpus/child/shards/child-01.jsonl.gz +0 -0
  8. package/corpus/child/shards/child-02.jsonl.gz +0 -0
  9. package/corpus/child/shards/child-03.jsonl.gz +0 -0
  10. package/corpus/child/shards/child-04.jsonl.gz +0 -0
  11. package/corpus/child/shards/child-05.jsonl.gz +0 -0
  12. package/corpus/child/shards/child-06.jsonl.gz +0 -0
  13. package/corpus/child/shards/child-07.jsonl.gz +0 -0
  14. package/corpus/child/shards/child-08.jsonl.gz +0 -0
  15. package/corpus/child/shards/child-09.jsonl.gz +0 -0
  16. package/corpus/child/shards/child-0a.jsonl.gz +0 -0
  17. package/corpus/child/shards/child-0b.jsonl.gz +0 -0
  18. package/corpus/child/shards/child-0c.jsonl.gz +0 -0
  19. package/corpus/child/shards/child-0d.jsonl.gz +0 -0
  20. package/corpus/child/shards/child-0e.jsonl.gz +0 -0
  21. package/corpus/child/shards/child-0f.jsonl.gz +0 -0
  22. package/corpus/child/shards/child-10.jsonl.gz +0 -0
  23. package/corpus/child/shards/child-11.jsonl.gz +0 -0
  24. package/corpus/child/shards/child-12.jsonl.gz +0 -0
  25. package/corpus/child/shards/child-13.jsonl.gz +0 -0
  26. package/corpus/child/shards/child-14.jsonl.gz +0 -0
  27. package/corpus/child/shards/child-15.jsonl.gz +0 -0
  28. package/corpus/child/shards/child-16.jsonl.gz +0 -0
  29. package/corpus/child/shards/child-17.jsonl.gz +0 -0
  30. package/corpus/child/shards/child-18.jsonl.gz +0 -0
  31. package/corpus/child/shards/child-19.jsonl.gz +0 -0
  32. package/corpus/child/shards/child-1a.jsonl.gz +0 -0
  33. package/corpus/child/shards/child-1b.jsonl.gz +0 -0
  34. package/corpus/child/shards/child-1c.jsonl.gz +0 -0
  35. package/corpus/child/shards/child-1d.jsonl.gz +0 -0
  36. package/corpus/child/shards/child-1e.jsonl.gz +0 -0
  37. package/corpus/child/shards/child-1f.jsonl.gz +0 -0
  38. package/corpus/conceptnet/quality-filter.mjs +28 -4
  39. package/corpus/tier2/generate.mjs +4 -8
  40. package/corpus/tier2/human-large.jsonl +0 -2
  41. package/corpus/tier2/human-medium.jsonl +0 -2
  42. package/corpus/tier2/manifest.json +6 -6
  43. package/data/templates/constructions/digest-sentence-structures.toml +146 -1
  44. package/package.json +18 -15
  45. package/src/adapters/corpus/digest-bank.mjs +15 -3
  46. package/src/domain/answer-variants.json +1 -1
  47. package/src/domain/ask-vocab.mjs +4 -0
  48. package/src/domain/ask.mjs +101 -12
  49. package/src/domain/codegraph.mjs +25 -8
  50. package/src/domain/digest/compose.mjs +142 -10
  51. package/src/domain/digest/config.json +5 -0
  52. package/src/domain/digest/structures.mjs +39 -14
  53. package/src/domain/interpret/normalize.mjs +2 -2
  54. package/src/domain/reference-pack.mjs +12 -3
  55. package/src/domain/router/call-validator.mjs +1 -1
  56. package/src/domain/router/drive.mjs +2 -2
  57. package/src/domain/router/set-algebra.mjs +1 -1
  58. package/src/services/adventure.mjs +34 -19
  59. package/src/services/chat-page-viz.mjs +16 -5
  60. package/src/services/chat.mjs +290 -88
  61. package/src/services/extract-facts.mjs +46 -4
  62. package/src/services/index.mjs +6 -3
  63. package/src/services/ledger-viz.mjs +1 -1
  64. package/src/services/research.mjs +80 -3
  65. package/src/surfaces/web/chat-browser-entry.mjs +23 -3
  66. package/src/surfaces/web/digest-client.mjs +8 -3
  67. package/src/surfaces/web/graph-ask-browser-entry.mjs +41 -0
  68. package/src/surfaces/web/memory-ask-browser.bundle.js +113 -113
package/README.md CHANGED
@@ -17,6 +17,30 @@ Teach it a fact in plain English and it mints a node. Ask it a question and
17
17
  it answers from what it was seeded with, what you taught it, and what it can
18
18
  derive by rule from both. Every answer is either grounded or an honest miss.
19
19
 
20
+ ## Repository layout
21
+
22
+ | directory | contains |
23
+ |---|---|
24
+ | `bin/` | the CLI entrypoint (`tmct.mjs`) |
25
+ | `src/` | the shipped product: `domain/` (pure logic), `adapters/` (I/O, storage, providers), `services/` (chat, adventure, research, ledger, plan), `surfaces/` (CLI, HTTP, TUI, web), `index/` (repo indexing) |
26
+ | `corpus/` | committed corpus and template data (ConceptNet, WordNet, NameNet, the generated persona vocab) |
27
+ | `data/` | seed data assets: sprites, phrasebook, games, response templates |
28
+ | `ontology/` | the software ontology (`tmct-core.ttl`) and memory shapes, in Turtle |
29
+ | `scripts/` | build, check, and maintenance scripts (`npm run` targets live here) |
30
+ | `examples/` | runnable example scripts and fixture repos used by the README's own examples and the test suite |
31
+ | `demo/` | standalone demo scripts (e.g. the agentic-loop demo) |
32
+ | `electron/` | the Electron desktop app wrapper |
33
+ | `docs/` | reference docs: the adapter/repository-interface contracts, bibliography |
34
+ | `test/` | the unit, corpus, and estate-guard test suite (`npm test`) |
35
+ | `test-e2e/` | the end-to-end suite: real CLI/TUI spawns and Playwright browser journeys (`npm run test:e2e`) |
36
+ | `test-benchmarks/` | the benchmark harnesses (agentbench, chatbench, idxbench, infbench, ingestbench, researchbench, synthbench) and their shared `benchlib/` |
37
+ | `reports/` | benchmark write-ups (`BENCHMARK_*.md`) and `PAGE_WEIGHTS.md` — see the root `STATUS.md` for the one-page summary these feed |
38
+ | `playtests/` | numbered playtest session logs, one edge found and fixed per entry |
39
+ | `archive/` | delivered `PLAN_*.md`/`BENCHMARK_*.md` docs, kept for history |
40
+ | `public/` | the built demo site — a gitignored output of `npm run demo:build`, never hand-edited |
41
+
42
+ `node_modules/` (dependencies) and dotfiles/hidden tooling directories are omitted above.
43
+
20
44
  ## Teach it, then ask it to reason
21
45
 
22
46
  This is real, runnable output. No cherry-picking, no model anywhere in the
@@ -227,7 +251,7 @@ resolves to a real graph traversal or declines cleanly:
227
251
  (*because/although/while*), conditionals, and false-premise flags ("why
228
252
  does X still import Y" when it no longer does).
229
253
 
230
- The full catalog with measured coverage lives in the `BENCHMARK_*.md`
254
+ The full catalog with measured coverage lives in the `reports/BENCHMARK_*.md`
231
255
  reports.
232
256
 
233
257
  **Response finishing.** Before an answer prints, it is segmented into typed
@@ -1179,18 +1203,20 @@ service. The LLM agent stays outside tmct, as the no-LLM ethos requires.
1179
1203
 
1180
1204
  ## Measuring it
1181
1205
 
1182
- What the 2.7.11/2.7.12 cycle measured, on 2026-07-19. Each figure links to its
1183
- method and carries, in the same row, the caveat that changes what it means.
1184
- The full tables, judge scores, and transcripts are in the linked write-ups.
1206
+ **For the latest measured numbers, see `STATUS.md`** a one-page summary of the most
1207
+ recent full sweep, citing its source reports by name. What follows here is what the 2.7.11/2.7.12
1208
+ cycle measured, on 2026-07-19, kept for its own detail. Each figure links to its method and
1209
+ carries, in the same row, the caveat that changes what it means. The full tables, judge scores,
1210
+ and transcripts are in the linked write-ups.
1185
1211
 
1186
1212
  | What it does | Result (2.7.12) | Read the number with this | Method |
1187
1213
  |---|---|---|---|
1188
- | Multi-hop entailment | 379/379 chat cases and 100/100 kernel cases, 0% fabrication, all bands pass | The case set is unchanged from 2.6.0 (same templates, same counts). The one real move this cycle is INF-4's ceiling-graded count dropping 35→30: five cases that now pass as genuine capability instead of against the declared honest-miss floor. | `BENCHMARK_INFERENCE_2.7.12.md` |
1189
- | Tool-call planning | 68/68 cases, 100% plan-completion, 100% result-completion, 0% hallucination, every rung A0→C2 | Goal driver. 2.6.0 gated at TOOL-7 (62/66, 94%). This cycle's router uplift (a guarded RECOVER step, a tied-candidate composer) cleared it: a real capability move, not a ruler change. | `BENCHMARK_AGENT_2.7.12.md` |
1190
- | Groundedness | Every answer carries a source, and an empty graph reports itself empty. Judge-scored mean 1.809/2 over 138 cases, 5 hard fails, 136/138 tier-1. | Judged (`claude-haiku-4-5-20251001`, `judge-prompt-v2`) at N=1. The judge prompt moved v1→v2 since 2.6.0, so this is a measurement, not a clean lever comparison against the prior cycle. The judge runs in the offline eval harness, never in the product. | `BENCHMARK_CEFR_ENGLISH_2.7.12.md` |
1191
- | Abstention (the honest miss) | 0% fabrication across 479 inference rows (379 chat + 100 kernel) and 0% hallucination across 272 agent rows | Structural, not a tuned threshold. tmct abstains because nothing matched, so the rows test a property of a no-model design rather than a score. | `BENCHMARK_INFERENCE_2.7.12.md`, `BENCHMARK_AGENT_2.7.12.md` |
1192
- | Determinism | Byte-identical on rerun: a 379-case `--replay` clean across 2 runs, no LLM, no network, $0 per turn | A property of the no-model pipeline. | `BENCHMARK_INFERENCE_2.7.12.md` |
1193
- | Dialogue robustness (persona sweep) | A 6-persona sweep (textbook logician, casual newcomer, new developer, adversarial sceptic, returning user, planning user) fixed 25 of the prior cycle's 29 routed findings (21 clean, 4 with a residual noted); 4 remain broken, 2 in a shape distinct from the original complaint | Free exploration across all six personas surfaced roughly 60 fresh findings beyond the ratchet check. The single highest-signal pattern: tmct's own suggested repair text was itself frequently broken when followed verbatim (since fixed, see `NEXT.md`). | `BENCHMARK_CONVERSATION_2.7.11.md` |
1214
+ | Multi-hop entailment | 379/379 chat cases and 100/100 kernel cases, 0% fabrication, all bands pass | The case set is unchanged from 2.6.0 (same templates, same counts). The one real move this cycle is INF-4's ceiling-graded count dropping 35→30: five cases that now pass as genuine capability instead of against the declared honest-miss floor. | `archive/BENCHMARK_INFERENCE_2.7.12.md` |
1215
+ | Tool-call planning | 68/68 cases, 100% plan-completion, 100% result-completion, 0% hallucination, every rung A0→C2 | Goal driver. 2.6.0 gated at TOOL-7 (62/66, 94%). This cycle's router uplift (a guarded RECOVER step, a tied-candidate composer) cleared it: a real capability move, not a ruler change. | `archive/BENCHMARK_AGENT_2.7.12.md` |
1216
+ | Groundedness | Every answer carries a source, and an empty graph reports itself empty. Judge-scored mean 1.809/2 over 138 cases, 5 hard fails, 136/138 tier-1. | Judged (`claude-haiku-4-5-20251001`, `judge-prompt-v2`) at N=1. The judge prompt moved v1→v2 since 2.6.0, so this is a measurement, not a clean lever comparison against the prior cycle. The judge runs in the offline eval harness, never in the product. | `archive/BENCHMARK_CEFR_ENGLISH_2.7.12.md` |
1217
+ | Abstention (the honest miss) | 0% fabrication across 479 inference rows (379 chat + 100 kernel) and 0% hallucination across 272 agent rows | Structural, not a tuned threshold. tmct abstains because nothing matched, so the rows test a property of a no-model design rather than a score. | `archive/BENCHMARK_INFERENCE_2.7.12.md`, `archive/BENCHMARK_AGENT_2.7.12.md` |
1218
+ | Determinism | Byte-identical on rerun: a 379-case `--replay` clean across 2 runs, no LLM, no network, $0 per turn | A property of the no-model pipeline. | `archive/BENCHMARK_INFERENCE_2.7.12.md` |
1219
+ | Dialogue robustness (persona sweep) | A 6-persona sweep (textbook logician, casual newcomer, new developer, adversarial sceptic, returning user, planning user) fixed 25 of the prior cycle's 29 routed findings (21 clean, 4 with a residual noted); 4 remain broken, 2 in a shape distinct from the original complaint | Free exploration across all six personas surfaced roughly 60 fresh findings beyond the ratchet check. The single highest-signal pattern: tmct's own suggested repair text was itself frequently broken when followed verbatim (since fixed, see `NEXT.md`). | `archive/BENCHMARK_CONVERSATION_2.7.11.md` |
1194
1220
 
1195
1221
  Three offline benchmark rigs live in a clone (they are not in the npm
1196
1222
  package). Each replays a committed case set through the real product and
@@ -1208,10 +1234,10 @@ The smallest real slice of each, the same invocations the test suite's
1208
1234
  bench-smoke lane replays:
1209
1235
 
1210
1236
  ```bash cwd=repo
1211
- node chatbench/run.mjs --stamp smoke --only g-a1-naming-1 --out /tmp/chatbench-smoke
1212
- node infbench/generate-cases.mjs --out /tmp/infbench-cases.jsonl
1213
- node infbench/run.mjs --cases /tmp/infbench-cases.jsonl --only inf-1-lookup-subClassOf-001 --stamp smoke --out /tmp/infbench-smoke
1214
- node agentbench/run.mjs --stamp smoke --driver stub --only ab-a0-describe-widget --out /tmp/agentbench-smoke
1237
+ node test-benchmarks/chatbench/run.mjs --stamp smoke --only g-a1-naming-1 --out /tmp/chatbench-smoke
1238
+ node test-benchmarks/infbench/generate-cases.mjs --out /tmp/infbench-cases.jsonl
1239
+ node test-benchmarks/infbench/run.mjs --cases /tmp/infbench-cases.jsonl --only inf-1-lookup-subClassOf-001 --stamp smoke --out /tmp/infbench-smoke
1240
+ node test-benchmarks/agentbench/run.mjs --stamp smoke --driver stub --only ab-a0-describe-widget --out /tmp/agentbench-smoke
1215
1241
  ```
1216
1242
 
1217
1243
  Grading beyond tier 1 uses an LLM as judge. The offline eval harness is the
@@ -1229,7 +1255,6 @@ hardened:
1229
1255
  - CI runs **SAST and secret detection**.
1230
1256
  - A nightly **`npm audit` + OSV-Scanner** job watches dependencies.
1231
1257
  - Releases are published with **npm provenance** (`--provenance`).
1232
- - A coordinated-disclosure `SECURITY.md` policy covers reports.
1233
1258
 
1234
1259
  The content-address hash is single-sourced in `src/domain/hash.mjs`, so the
1235
1260
  cross-version-stable fact-id contract has exactly one definition.
@@ -1291,7 +1316,7 @@ edition, the retrieval date, the terms tmct uses, and what could not be verified
1291
1316
 
1292
1317
  | source | edition | what tmct uses it for |
1293
1318
  |---|---|---|
1294
- | Council of Europe, CEFR — Companion volume | 2020, ISBN 978-92-871-8621-8 | The band labels A1–C2 the chat benchmark grades against. CEFR measures what a *person* can do communicatively; grading the difficulty of *prompts* by band is tmct's adaptation, not a CEFR-validated use. The band descriptions in `chatbench/GRADED.md` are tmct's own prose. |
1319
+ | Council of Europe, CEFR — Companion volume | 2020, ISBN 978-92-871-8621-8 | The band labels A1–C2 the chat benchmark grades against. CEFR measures what a *person* can do communicatively; grading the difficulty of *prompts* by band is tmct's adaptation, not a CEFR-validated use. The band descriptions in `test-benchmarks/chatbench/GRADED.md` are tmct's own prose. |
1295
1320
  | Reiter, "On Closed World Data Bases" | *Logic and Data Bases*, Plenum, 1978, pp. 55–76 | Both halves of the honest miss. The planner's operator model is **closed-world**, which is what makes a plan checkable. The chat layer is **open-world**: it will not read "no matching rule" as "the answer is no". |
1296
1321
  | Chow, "On optimum recognition error and reject tradeoff" | *IEEE Trans. Information Theory* 16(1), 1970 | Prior art for the goal. The literature calls a refusal **abstention**, or selective prediction, and Chow's reject option is its root. Those methods threshold a confidence score; tmct has none, and abstains because nothing matched — which is why the row above names the mechanism. |
1297
1322
  | Ji et al., "Survey of Hallucination in Natural Language Generation" | *ACM Computing Surveys* 55(12), 2023 | Groundedness, and what tmct is avoiding by having no model to hallucinate with. |
package/bin/tmct.mjs CHANGED
@@ -467,7 +467,7 @@ async function activatePluggableInput(repoRoot, resolved) {
467
467
  }
468
468
  if (resolved.manifestEntry) {
469
469
  // Preserve the ORIGINAL `--corpus <tier2-id>` wording byte-for-byte
470
- // (e2e/init-cli.test.mjs asserts on this exact shape).
470
+ // (test-e2e/init-cli.test.mjs asserts on this exact shape).
471
471
  return `seeded tier-2 corpus "${resolved.manifestEntry.id}" (${resolved.manifestEntry.kind}) — ${seeded.appended} fact(s) added`
472
472
  + `${seeded.skipped ? `, ${seeded.skipped} already present` : ""}. Source: corpus/tier2/${resolved.manifestEntry.file} (${resolved.manifestEntry.license}). `
473
473
  + `Activated in tmct.toml — future \`tmct init\`/chat sessions seed it automatically.\n`;
@@ -20,7 +20,7 @@ Layout (mirrors corpus/reference/):
20
20
  budgets, the acceptance metrics, and a sha256 for every emitted file.
21
21
  - `LICENSE-NOTICE` — CC-BY-SA 4.0; read it before reusing these files.
22
22
 
23
- 47267 terms, 93161 keyed facts. Built 2026-07-18.
23
+ 46883 terms, 92638 keyed facts. Built 2026-07-24.
24
24
 
25
25
  Predicates are already mapped into tmct's vocabulary
26
26
  (conceptnet-map.toml): `rdfs:subClassOf`, `mgx:capableOf`,
@@ -63,7 +63,7 @@ acceptance test — the plan's hand-counted baseline drifted once). Numbers belo
63
63
  are for this committed pack:
64
64
 
65
65
  ```
66
- Measured over this pack: 69620 facts
66
+ Measured over this pack: 69140 facts
67
67
  kinds of bird 1881 [abbott's booby, abyssinian woodpecker, acadian flycatcher, accipiter, acorn woodpecker, acridotheres, acrocephalus, actitis, adélie penguin, african black duck, african cuckoo hawk, african finfoot, african fish eagle, african marsh harrier, african penguin, african pygmy goose, african sacred ibis, african skimmer, aix, akiapola au]
68
68
  capabilities on birds 71 [bird can attempt to fly, chicken can become food, bird can build nest, bird can call with chirps, bird can chirp, bird can eat grasshopper, bird can experience flight, bird can eye fish, bird can fall from sky, bird can fly, bird can fly high, bird can head south, bird can kill fish, bird can land on beach, bird can land on branch, bird can land on tree, bird can learn to fly, bird can listen to insect, bird can person's pet, bird can pet]
69
69
  things that can fly 39 [animals, ants, bat, bats, bats and birds, bee, beetles, bird, butterfly, doves, dragon, dragonfly, flies, frisbee, geese, gnat, goose, helicoptors, hoatzins, insects]
Binary file
@@ -14,30 +14,30 @@
14
14
  "version": "5.7.0",
15
15
  "sha256": "accd65fe94038584295574ddc26e1500c1919c8c4532bf771811cafd0948af7e"
16
16
  },
17
- "built": "2026-07-18",
17
+ "built": "2026-07-24",
18
18
  "pack": "conceptnet",
19
19
  "shardCount": 32,
20
20
  "counts": {
21
- "terms": 47267,
22
- "facts": 93161,
21
+ "terms": 46883,
22
+ "facts": 92638,
23
23
  "shards": 32
24
24
  },
25
25
  "budgets": {
26
26
  "facts": {
27
- "used": 93161,
27
+ "used": 92638,
28
28
  "max": 120000
29
29
  },
30
30
  "shardsGzBytes": {
31
- "used": 1104132,
31
+ "used": 1097302,
32
32
  "max": 3145728
33
33
  },
34
34
  "indexGzBytes": {
35
- "used": 466600,
35
+ "used": 463262,
36
36
  "max": 716800
37
37
  }
38
38
  },
39
39
  "acceptance": {
40
- "totalFacts": 69620,
40
+ "totalFacts": 69140,
41
41
  "kindsOfBird": {
42
42
  "count": 1881,
43
43
  "sample": [
@@ -136,8 +136,8 @@
136
136
  "files": [
137
137
  {
138
138
  "file": "index.json.gz",
139
- "bytes": 466600,
140
- "sha256": "8c5940d2f888841a89a6d891c034a357d9f568175610d7ba723d82c0b3789375"
139
+ "bytes": 463262,
140
+ "sha256": "cfe726d696e7a3bd37a33171943b4cbee79f6be38441f0ba8425b8e303c97076"
141
141
  },
142
142
  {
143
143
  "file": "LICENSE-NOTICE",
@@ -147,167 +147,167 @@
147
147
  {
148
148
  "file": "README.md",
149
149
  "bytes": 4728,
150
- "sha256": "4bc27cc68ece52930fee4fc18fd65966ebdc1fe9e39d9c5497a579e9a7de7ebb"
150
+ "sha256": "b4a0916b8315b2276df7dc0c612136e241c8e24b3f4debbdbbce5ae4082a6de2"
151
151
  },
152
152
  {
153
153
  "file": "shards/child-00.jsonl.gz",
154
- "bytes": 32103,
155
- "sha256": "9ccb587b8bcbaf4cd250620b7455b347ad48632c9a74a58576ad53bea7661cba"
154
+ "bytes": 31885,
155
+ "sha256": "8fa0c70c391a7cd06262358fe32d52ac35d9e8ef40b976373f1b341cecf19758"
156
156
  },
157
157
  {
158
158
  "file": "shards/child-01.jsonl.gz",
159
- "bytes": 33579,
160
- "sha256": "72cc98f950493cd74c108275fc4fd2375673d4bb518ef5dc18a792e2e0dc4314"
159
+ "bytes": 33446,
160
+ "sha256": "7f33ec49bb0d1a33b1ed4e44d66609a72b88af16d48f7ccb354e2936af042081"
161
161
  },
162
162
  {
163
163
  "file": "shards/child-02.jsonl.gz",
164
- "bytes": 39506,
165
- "sha256": "66509505127314f56ba97d91bf8eb16f8041e79372967686fe4bd12f7836fa12"
164
+ "bytes": 39355,
165
+ "sha256": "56d731fad9aabc630c7d8794424513f99f4abbde84580f24a0aad6cbd6d57a73"
166
166
  },
167
167
  {
168
168
  "file": "shards/child-03.jsonl.gz",
169
- "bytes": 31952,
170
- "sha256": "718cf034eea6eedd8dfa28308b88707b783188096740493cfe9dcc2fc099715c"
169
+ "bytes": 31745,
170
+ "sha256": "b14ddc87a2fe7434701e8ada94673d9b20b2c0ccceb00e49168a33f198cadfce"
171
171
  },
172
172
  {
173
173
  "file": "shards/child-04.jsonl.gz",
174
- "bytes": 33426,
175
- "sha256": "789c98cac46582609bd0f8fe10714992b6142845ceef7595d1344817b3828a22"
174
+ "bytes": 33202,
175
+ "sha256": "7890d1a63601132a9fd1054a8b088065bd41d9e2a26ab908582b1858beae0c36"
176
176
  },
177
177
  {
178
178
  "file": "shards/child-05.jsonl.gz",
179
- "bytes": 35162,
180
- "sha256": "76145b77126d0ad589de1024036d56e363a205ae1d214407f377328adbb78e38"
179
+ "bytes": 34872,
180
+ "sha256": "0bb756c6e78d598a31fe7c57385785c26f7f7ddbab16f3a5143f715cfff76fb1"
181
181
  },
182
182
  {
183
183
  "file": "shards/child-06.jsonl.gz",
184
- "bytes": 36407,
185
- "sha256": "2eef507004137e8ce92d56e043e8c5e4065c9a03ae00022422ee36fbd3cfcbba"
184
+ "bytes": 36268,
185
+ "sha256": "bd150f3d13b0519cb97155657bd5edac4860b338d988db7c05c74e2d6b9dc440"
186
186
  },
187
187
  {
188
188
  "file": "shards/child-07.jsonl.gz",
189
- "bytes": 33893,
190
- "sha256": "9a889f73e18a800725333df87702642d658a442e5b957dfb40eb7c70127ae5cc"
189
+ "bytes": 33641,
190
+ "sha256": "797a5dd7a575c633ebae145b6811750b401f527e558b034d84761e9e8fa08df8"
191
191
  },
192
192
  {
193
193
  "file": "shards/child-08.jsonl.gz",
194
- "bytes": 34136,
195
- "sha256": "d8bb02bcc35d0303178f296ca47251fe0133227553b806ebda459377fdd57fcd"
194
+ "bytes": 34071,
195
+ "sha256": "2c39d8f05e5246a26efe84a479484f992a49eb2125d82ad01ad94c49e2a9a573"
196
196
  },
197
197
  {
198
198
  "file": "shards/child-09.jsonl.gz",
199
- "bytes": 35965,
200
- "sha256": "7d86341fedf002c8838bccd766e425b0a67f502d031fd53d4e07f1c6f12aa19f"
199
+ "bytes": 35865,
200
+ "sha256": "9d8363f3c04cfe80643b2c1e1cd4222544c8e80c347ea0042789df7b752287f8"
201
201
  },
202
202
  {
203
203
  "file": "shards/child-0a.jsonl.gz",
204
- "bytes": 34735,
205
- "sha256": "206a813208895488b15f4b57ae142472b23eedc98337c1960bc002247ab1ec19"
204
+ "bytes": 34618,
205
+ "sha256": "17a5cd9946fc6a19f69e51277f9486c92c8d43e3953439580adf71e90736376d"
206
206
  },
207
207
  {
208
208
  "file": "shards/child-0b.jsonl.gz",
209
- "bytes": 32343,
210
- "sha256": "13e94bddc1c1dfadb3d15f3cf437f8bc6fdee4aba34e146f855b592dfc3cb29e"
209
+ "bytes": 31978,
210
+ "sha256": "f447a23e7e3191f5247a0d2cbfc187ba707f347d4fca01c4fedd3ef6446e1996"
211
211
  },
212
212
  {
213
213
  "file": "shards/child-0c.jsonl.gz",
214
- "bytes": 32843,
215
- "sha256": "5004d2abe2a52616bad4b7b55989f3d4feea8c6bb156154be700d6d5102fc1a4"
214
+ "bytes": 32540,
215
+ "sha256": "d333ca1ca7167fa22f8af37fd0a493e735ff5b993f76d8f8d975c1f9bf2ef188"
216
216
  },
217
217
  {
218
218
  "file": "shards/child-0d.jsonl.gz",
219
- "bytes": 33100,
220
- "sha256": "fb16a8d7812e93f5d7b54792ae376f424c03cb67bb38205e9a352fd3761f862e"
219
+ "bytes": 32826,
220
+ "sha256": "f52920d032e74322750dd6420e6dc8cea57a023a515b81b7f77ade63e25e952d"
221
221
  },
222
222
  {
223
223
  "file": "shards/child-0e.jsonl.gz",
224
- "bytes": 37434,
225
- "sha256": "34ed35347c1e05d662791f547dc487a1ea106a144c6722105249113ae17144e0"
224
+ "bytes": 37216,
225
+ "sha256": "55688d2f5233345816403611cd9e9e9990a5566b1df08c061529bfa8fcf89575"
226
226
  },
227
227
  {
228
228
  "file": "shards/child-0f.jsonl.gz",
229
- "bytes": 33042,
230
- "sha256": "128fe45227c40a020b017d62ed267bbbc537308903a637bed7e3a730c77167a5"
229
+ "bytes": 32817,
230
+ "sha256": "f767faeb048dab56a018e1a547a8063b1bd907b256b8110f56b6da3b58c3a5a6"
231
231
  },
232
232
  {
233
233
  "file": "shards/child-10.jsonl.gz",
234
- "bytes": 36325,
235
- "sha256": "f464aa705b6f805e939d8b755e1b7459dfa1567d227d42fbb45966cca77911b2"
234
+ "bytes": 36194,
235
+ "sha256": "bd90001e185c2b84239d7362ad7765593c7f94fb422f60a35a86bb9330903f12"
236
236
  },
237
237
  {
238
238
  "file": "shards/child-11.jsonl.gz",
239
- "bytes": 37037,
240
- "sha256": "9d42260cd01eb000bfd05f3589162e02b473a8e0d67153164f6309a64161af1c"
239
+ "bytes": 36842,
240
+ "sha256": "f5a603e3290b29a463af799258838ec692933db492a0d372dd2dab32bbdc3868"
241
241
  },
242
242
  {
243
243
  "file": "shards/child-12.jsonl.gz",
244
- "bytes": 34979,
245
- "sha256": "007e234d9ef074bbf2ca01e974b78cf92275c395709d8ceca4f9143610db8a35"
244
+ "bytes": 34716,
245
+ "sha256": "daba6bd6859ded6d016418a01fe89699803b87d5f1629cd2ebca5e7fc97cb3f4"
246
246
  },
247
247
  {
248
248
  "file": "shards/child-13.jsonl.gz",
249
- "bytes": 35807,
250
- "sha256": "61157570ac6a5744c12852f8f918315efc388c099ca931f4ddd51ed7a968fd15"
249
+ "bytes": 35643,
250
+ "sha256": "914501ada0aa3cdd959603ec095597bed731b649e5c26477f390b3db4f8db93f"
251
251
  },
252
252
  {
253
253
  "file": "shards/child-14.jsonl.gz",
254
- "bytes": 34486,
255
- "sha256": "c06be6bfc64cfeb385b2e6654813b3bafc885242ff67157ef36f3cb319603fdf"
254
+ "bytes": 34171,
255
+ "sha256": "343285630b15e1b5a221dcc23770d2430c366ef320429f6ff38ef64e9c1b338b"
256
256
  },
257
257
  {
258
258
  "file": "shards/child-15.jsonl.gz",
259
- "bytes": 35086,
260
- "sha256": "684f17882e97c9a00008d7601ebce936e9acadea655ae79a84ade493db071da1"
259
+ "bytes": 34878,
260
+ "sha256": "8541b35ca94f56f49c58abcf99dbeaff5a576aaba11802fb9851239daee07b2f"
261
261
  },
262
262
  {
263
263
  "file": "shards/child-16.jsonl.gz",
264
- "bytes": 36486,
265
- "sha256": "a730cd4e15f0dd221a0b1de8a4f7d675dfb51aa330d4f5bd5d31362eb3261e04"
264
+ "bytes": 36348,
265
+ "sha256": "54139274ab7d073126f9bec37cc02c67fbaf41b62aa507c487096d98168966a8"
266
266
  },
267
267
  {
268
268
  "file": "shards/child-17.jsonl.gz",
269
- "bytes": 35087,
270
- "sha256": "f3aede1ef18acc53e96791eb05511ce7cd1e9fadc78901913026350c26ddb40a"
269
+ "bytes": 34902,
270
+ "sha256": "2874b45a1dc8dc829f960f9fafa05b15d7b8b5801cccdf9e490242c830466e93"
271
271
  },
272
272
  {
273
273
  "file": "shards/child-18.jsonl.gz",
274
- "bytes": 33768,
275
- "sha256": "ba858cd656f5e27c5a6afaf47d1932eb12a568abe24ab88103eea043051320ac"
274
+ "bytes": 33492,
275
+ "sha256": "e248f9137d314573917469b958bfbb1d3e6393feae119488976d9ce32d9707bf"
276
276
  },
277
277
  {
278
278
  "file": "shards/child-19.jsonl.gz",
279
- "bytes": 35857,
280
- "sha256": "30ab1d0dfb61decd5d43e7f30e5a7d35e4360d3fa4b8de2e2792d213fe0fa040"
279
+ "bytes": 35739,
280
+ "sha256": "f84e5b6584d5e46bb5566a39ba941c71e293ed9f8cc83f0eb627eff6dfddd32b"
281
281
  },
282
282
  {
283
283
  "file": "shards/child-1a.jsonl.gz",
284
- "bytes": 32457,
285
- "sha256": "835831e995b3457de2420e6980b4d32dd8dedeefeccfa9ad8437b709d7615260"
284
+ "bytes": 32215,
285
+ "sha256": "f59bc66d6b5dfe8c50e95636098c15afa2430c4bc1973a2a71855b41e87c191e"
286
286
  },
287
287
  {
288
288
  "file": "shards/child-1b.jsonl.gz",
289
- "bytes": 33232,
290
- "sha256": "cc703f2de00ce184271d75c54c199df6d0de5628386458001c97b1e440b2ff35"
289
+ "bytes": 32942,
290
+ "sha256": "0ab7e4649c448ef556b54384575ffdd112877444969f7634b4f6c5195b08ccce"
291
291
  },
292
292
  {
293
293
  "file": "shards/child-1c.jsonl.gz",
294
- "bytes": 34490,
295
- "sha256": "92ed3c10f60d74c5273734c3dd200977be3902c2afb2d53932e41419585ae1fa"
294
+ "bytes": 34145,
295
+ "sha256": "336e70ce7e06d55fbf97b306a65f817e424b5c0beada5921013d1b8fc80f43a4"
296
296
  },
297
297
  {
298
298
  "file": "shards/child-1d.jsonl.gz",
299
- "bytes": 32293,
300
- "sha256": "a02fd0b0c3167fd8ce2209338ca90700e48a133c0d7b169d7c5c87bdd85778ee"
299
+ "bytes": 31999,
300
+ "sha256": "880b79cff62cf3a3a1b8cc9f1a6c45c5a3e9dd5b88893740a59bd1574a6ba0a9"
301
301
  },
302
302
  {
303
303
  "file": "shards/child-1e.jsonl.gz",
304
- "bytes": 32991,
305
- "sha256": "bd631352a9abdc46fc4a2d79c0134bbbd235b4dc6cc5a6af598b21aaec1d7e55"
304
+ "bytes": 32844,
305
+ "sha256": "ddefecf98f3d44a41e0899db9794be105a509ffae02e56d2b83dc5c47819fba0"
306
306
  },
307
307
  {
308
308
  "file": "shards/child-1f.jsonl.gz",
309
- "bytes": 34125,
310
- "sha256": "23e47bef6b0c9e7671155b59a117e5c94701ea38665a602af024fbf1f443143d"
309
+ "bytes": 33887,
310
+ "sha256": "2b5abd6c51d20eedbba38c65e0679aea9842ba9f28ae4fb7b76cfabac1643301"
311
311
  }
312
312
  ]
313
313
  }
@@ -23,13 +23,19 @@
23
23
  // 3. sentence fragment — bare term is >= 4 underscore-words on EITHER
24
24
  // endpoint ("taloned_grip_of_owl",
25
25
  // "worlds_largest_interconnected_network_of_networks")
26
- // 4. definitional phrase /r/DefinedAs whose object is >= 3 words
26
+ // 4. trailing-preposition fragment bare term is a 2-3 underscore-word
27
+ // endpoint whose LAST word is a preposition
28
+ // ("pot_in") — a truncated crowd-sourced
29
+ // prepositional-phrase fragment, not a concept
30
+ // 5. known misspelling — bare endpoint is in a small, hand-curated
31
+ // KNOWN_MISSPELLINGS set ("vessle")
32
+ // 6. definitional phrase — /r/DefinedAs whose object is >= 3 words
27
33
  // (real DefinedAs is a synonym: cpu->processor)
28
- // 5. opinion object — /r/IsA or /r/DefinedAs whose object is one of a
34
+ // 7. opinion object — /r/IsA or /r/DefinedAs whose object is one of a
29
35
  // small, evidence-based OPINION set (adjectives /
30
36
  // value words that never name a class)
31
37
  //
32
- // Rules 1-3 apply to every relation (they only ever remove junk); 4-5 are the
38
+ // Rules 1-5 apply to every relation (they only ever remove junk); 6-7 are the
33
39
  // definitional band the sims flagged. Stats land on stderr; JSONL on stdout.
34
40
 
35
41
  import { readFile, writeFile } from "node:fs/promises";
@@ -46,6 +52,19 @@ export const OPINION_OBJECTS = new Set([
46
52
  "elegance", "evil", "gloom", "unreality", "universalism", "dumb", "free", "junk",
47
53
  ]);
48
54
 
55
+ // A short, closed preposition set. A 2-3 underscore-word endpoint ending in
56
+ // one of these ("pot_in") is a truncated crowd-sourced prepositional-phrase
57
+ // fragment, not a standalone concept.
58
+ const TRAILING_PREPOSITIONS = new Set(["in", "on", "at", "of", "for", "with", "to", "from", "by"]);
59
+
60
+ // Evidence-based: crowd-sourced misspellings seen in the committed slice.
61
+ // Kept explicit (not a spellcheck dependency — wink-nlp carries no spellcheck
62
+ // signal, so a general heuristic here would risk cutting a legitimate but
63
+ // unfamiliar word) so it never cuts anything but a confirmed typo.
64
+ export const KNOWN_MISSPELLINGS = new Set([
65
+ "vessle",
66
+ ]);
67
+
49
68
  /** Why this row is noise, or null to keep it. Pure function of the row shape. */
50
69
  export function cutReason(row) {
51
70
  const s = bareTerm(row.start);
@@ -53,7 +72,12 @@ export function cutReason(row) {
53
72
  for (const t of [s, e]) {
54
73
  if (/^\d+$/.test(t)) return "numeric-endpoint";
55
74
  if (t.length <= 1) return "single-char-endpoint";
56
- if (words(t) >= 4) return "sentence-fragment";
75
+ const parts = t.split("_").filter(Boolean);
76
+ if (parts.length >= 4) return "sentence-fragment";
77
+ if (parts.length >= 2 && parts.length <= 3 && TRAILING_PREPOSITIONS.has(parts[parts.length - 1])) {
78
+ return "trailing-preposition-fragment";
79
+ }
80
+ if (KNOWN_MISSPELLINGS.has(t)) return "known-misspelling";
57
81
  }
58
82
  if (row.rel === "/r/DefinedAs" && words(e) >= 3) return "definitional-phrase";
59
83
  if ((row.rel === "/r/IsA" || row.rel === "/r/DefinedAs") && OPINION_OBJECTS.has(e)) return "opinion-object";