@polycode-projects/the-mechanical-code-talker 2.3.0 → 2.5.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.
Files changed (152) hide show
  1. package/README.md +127 -28
  2. package/ROADMAP.md +3 -2
  3. package/bin/tmct.mjs +17 -90
  4. package/corpus/LICENSES.json +19 -4
  5. package/corpus/README.md +48 -0
  6. package/corpus/generated/README.md +24 -9
  7. package/corpus/generated/ace-surface-variants.jsonl +4 -1
  8. package/corpus/generated/manifest.json +4 -4
  9. package/corpus/prose/manifest.json +512 -0
  10. package/corpus/prose/sqlite/LICENSE-NOTICE +53 -0
  11. package/corpus/prose/sqlite/arch.txt +213 -0
  12. package/corpus/prose/sqlite/atomiccommit.txt +1117 -0
  13. package/corpus/prose/sqlite/faq.txt +473 -0
  14. package/corpus/prose/sqlite/fileformat.txt +1589 -0
  15. package/corpus/prose/sqlite/lang_createtable.txt +1339 -0
  16. package/corpus/prose/sqlite/lang_insert.txt +580 -0
  17. package/corpus/prose/sqlite/lang_select.txt +3293 -0
  18. package/corpus/prose/sqlite/optoverview.txt +908 -0
  19. package/corpus/prose/sqlite/queryplanner.txt +447 -0
  20. package/corpus/prose/sqlite/transactional.txt +41 -0
  21. package/corpus/prose/sqlite/wal.txt +567 -0
  22. package/corpus/prose/sqlite/whentouse.txt +300 -0
  23. package/corpus/prose/wikipedia/Apple.txt +4 -0
  24. package/corpus/prose/wikipedia/Attempto_Controlled_English.txt +169 -0
  25. package/corpus/prose/wikipedia/Automated_planning_and_scheduling.txt +67 -0
  26. package/corpus/prose/wikipedia/Bee.txt +7 -0
  27. package/corpus/prose/wikipedia/Bird.txt +8 -0
  28. package/corpus/prose/wikipedia/Bone.txt +4 -0
  29. package/corpus/prose/wikipedia/Book.txt +7 -0
  30. package/corpus/prose/wikipedia/Bread.txt +6 -0
  31. package/corpus/prose/wikipedia/Butterfly.txt +6 -0
  32. package/corpus/prose/wikipedia/Car.txt +1 -0
  33. package/corpus/prose/wikipedia/Cat.txt +1 -0
  34. package/corpus/prose/wikipedia/Child.txt +3 -0
  35. package/corpus/prose/wikipedia/City.txt +2 -0
  36. package/corpus/prose/wikipedia/Clock.txt +2 -0
  37. package/corpus/prose/wikipedia/Cooking.txt +1 -0
  38. package/corpus/prose/wikipedia/Description_logic.txt +660 -0
  39. package/corpus/prose/wikipedia/Doctor.txt +6 -0
  40. package/corpus/prose/wikipedia/Dog.txt +4 -0
  41. package/corpus/prose/wikipedia/Eagle.txt +4 -0
  42. package/corpus/prose/wikipedia/Emotion.txt +9 -0
  43. package/corpus/prose/wikipedia/Eye.txt +5 -0
  44. package/corpus/prose/wikipedia/Family.txt +3 -0
  45. package/corpus/prose/wikipedia/Farm.txt +4 -0
  46. package/corpus/prose/wikipedia/Fear.txt +4 -0
  47. package/corpus/prose/wikipedia/First-order_logic.txt +1518 -0
  48. package/corpus/prose/wikipedia/Fish.txt +10 -0
  49. package/corpus/prose/wikipedia/Flower.txt +3 -0
  50. package/corpus/prose/wikipedia/Food.txt +10 -0
  51. package/corpus/prose/wikipedia/Grass.txt +9 -0
  52. package/corpus/prose/wikipedia/Hand.txt +2 -0
  53. package/corpus/prose/wikipedia/Happiness.txt +3 -0
  54. package/corpus/prose/wikipedia/Heart.txt +4 -0
  55. package/corpus/prose/wikipedia/Horse.txt +4 -0
  56. package/corpus/prose/wikipedia/House.txt +6 -0
  57. package/corpus/prose/wikipedia/Human.txt +4 -0
  58. package/corpus/prose/wikipedia/Insect.txt +6 -0
  59. package/corpus/prose/wikipedia/Interactive_fiction.txt +112 -0
  60. package/corpus/prose/wikipedia/Knowledge.txt +5 -0
  61. package/corpus/prose/wikipedia/Knowledge_representation_and_reasoning.txt +87 -0
  62. package/corpus/prose/wikipedia/LICENSE-NOTICE +94 -0
  63. package/corpus/prose/wikipedia/Language.txt +10 -0
  64. package/corpus/prose/wikipedia/Learning.txt +4 -0
  65. package/corpus/prose/wikipedia/Mammal.txt +3 -0
  66. package/corpus/prose/wikipedia/Memory.txt +5 -0
  67. package/corpus/prose/wikipedia/Milk.txt +1 -0
  68. package/corpus/prose/wikipedia/Mountain.txt +1 -0
  69. package/corpus/prose/wikipedia/Natural_language_processing.txt +211 -0
  70. package/corpus/prose/wikipedia/Ostrich.txt +2 -0
  71. package/corpus/prose/wikipedia/Owl.txt +2 -0
  72. package/corpus/prose/wikipedia/Penguin.txt +2 -0
  73. package/corpus/prose/wikipedia/Plant.txt +5 -0
  74. package/corpus/prose/wikipedia/Rain.txt +1 -0
  75. package/corpus/prose/wikipedia/Resource_Description_Framework.txt +184 -0
  76. package/corpus/prose/wikipedia/River.txt +1 -0
  77. package/corpus/prose/wikipedia/School.txt +8 -0
  78. package/corpus/prose/wikipedia/Sea.txt +1 -0
  79. package/corpus/prose/wikipedia/Semantic_Web.txt +114 -0
  80. package/corpus/prose/wikipedia/Semantic_reasoner.txt +29 -0
  81. package/corpus/prose/wikipedia/Snow.txt +5 -0
  82. package/corpus/prose/wikipedia/Sun.txt +5 -0
  83. package/corpus/prose/wikipedia/Teacher.txt +4 -0
  84. package/corpus/prose/wikipedia/Team.txt +3 -0
  85. package/corpus/prose/wikipedia/Text-based_game.txt +17 -0
  86. package/corpus/prose/wikipedia/Tool.txt +4 -0
  87. package/corpus/prose/wikipedia/Tree.txt +7 -0
  88. package/corpus/prose/wikipedia/Weather.txt +4 -0
  89. package/corpus/prose/wikipedia/Web_Ontology_Language.txt +133 -0
  90. package/corpus/prose/wikipedia/Wind.txt +8 -0
  91. package/corpus/prose/wikipedia/Writing.txt +5 -0
  92. package/corpus/seon/README.md +1 -0
  93. package/corpus/tier2/generate.mjs +18 -18
  94. package/corpus/tier2/manifest.json +3 -3
  95. package/data/games/hanoi-3.txt +8 -2
  96. package/package.json +24 -5
  97. package/src/adapters/corpus-lanes.mjs +13 -0
  98. package/src/adapters/graph-build.mjs +5 -7
  99. package/src/adapters/import-closure.mjs +28 -0
  100. package/src/adapters/memory/blocks.mjs +5 -4
  101. package/src/adapters/memory/core.mjs +78 -5
  102. package/src/adapters/memory/shacl.mjs +12 -0
  103. package/src/adapters/providers/graph-service.mjs +12 -5
  104. package/src/adapters/tracked-files.mjs +17 -0
  105. package/src/domain/ask-vocab.mjs +2 -0
  106. package/src/domain/ask.mjs +225 -13
  107. package/src/domain/cli-verbs.mjs +201 -0
  108. package/src/domain/codegraph.mjs +142 -56
  109. package/src/domain/completions/graph-adapter.mjs +1 -1
  110. package/src/domain/completions/group.mjs +3 -17
  111. package/src/domain/completions/infer.mjs +4 -13
  112. package/src/domain/completions/rank.mjs +6 -19
  113. package/src/domain/grammar/lexicon-core.json +1 -1
  114. package/src/domain/hash.mjs +36 -13
  115. package/src/domain/interpret/fuzzy.mjs +7 -2
  116. package/src/domain/interpret/normalize.mjs +9 -0
  117. package/src/domain/interpret/strategies/keywords.mjs +19 -9
  118. package/src/domain/memory/capability.mjs +22 -3
  119. package/src/domain/memory/touched-facts.mjs +17 -0
  120. package/src/domain/module-paths.mjs +9 -0
  121. package/src/domain/persona/tiers.mjs +1 -1
  122. package/src/domain/planning.mjs +37 -0
  123. package/src/domain/prose.mjs +10 -2
  124. package/src/domain/relative-specifiers.mjs +12 -0
  125. package/src/domain/router/registry.mjs +3 -2
  126. package/src/domain/router/results.mjs +5 -18
  127. package/src/domain/seeded-random.mjs +33 -0
  128. package/src/domain/syllogise.mjs +10 -7
  129. package/src/domain/text-stats.mjs +31 -0
  130. package/src/services/chat.mjs +720 -182
  131. package/src/services/extract-facts.mjs +155 -0
  132. package/src/services/import-file.mjs +2 -2
  133. package/src/services/ledger-viz.mjs +6 -1
  134. package/src/services/sentences.mjs +26 -0
  135. package/src/surfaces/web/memory-ask-browser.bundle.js +11390 -360
  136. package/src/tools/graph-load.mjs +7 -1
  137. package/src/tools/readme-docs.mjs +113 -0
  138. package/src/tools/schema-docs.mjs +2 -2
  139. package/corpus/namenet/generate.mjs +0 -309
  140. package/corpus/wordnet/generate.mjs +0 -332
  141. package/src/adapters/prose-tokens.mjs +0 -98
  142. package/src/adapters/wordnet-source.mjs +0 -70
  143. package/src/domain/corpus-matrix.mjs +0 -87
  144. package/src/domain/inflect.mjs +0 -67
  145. package/src/domain/licences.mjs +0 -68
  146. package/src/domain/markdown-links.mjs +0 -55
  147. package/src/domain/persona/codegen.mjs +0 -123
  148. package/src/domain/publish-gate.mjs +0 -41
  149. package/src/domain/schemaorg/turtle.mjs +0 -25
  150. package/src/domain/semcor/parse.mjs +0 -87
  151. package/src/domain/version-stamp.mjs +0 -36
  152. package/src/domain/wordnet/yaml.mjs +0 -133
package/README.md CHANGED
@@ -2,9 +2,8 @@
2
2
 
3
3
  `@polycode-projects/the-mechanical-code-talker`
4
4
 
5
- A pure-JS, **no-LLM**, offline, **$0** chatbot in the ELIZA/PARRY lineage:
6
- pattern-driven, best-efforts, and focused on software as its subject matter.
7
- It makes no model calls.
5
+ A pure-JS, **no-LLM**, offline, **$0** chatbot in the ELIZA/PARRY lineage.
6
+ It is pattern-driven and focused on software, and it makes no model calls.
8
7
 
9
8
  tmct turns natural language directly into a graph database. On first run it
10
9
  seeds an everyday **human-world persona**: people, places, objects, nature,
@@ -100,8 +99,12 @@ parts are real provenance receipts. Every fact tmct stores records where it
100
99
  came from and when (more on that below).
101
100
 
102
101
  The test suite replays every runnable example in this README against the
103
- live product, this transcript included. If the chat behavior ever drifts
104
- from the output above, the suite fails and says so.
102
+ live product, this transcript included. Every line shown must be a line the
103
+ product prints, in the order shown, so if the chat behavior drifts from the
104
+ output above, the suite fails and says so. Two blocks below are marked `skip=`
105
+ and never run: one would touch the network, the other needs an LLM judge.
106
+ `docs/public-examples.md` maps every example on every public surface to the
107
+ test that holds it.
105
108
 
106
109
  Point it at a codebase's graph and the same engine answers structural questions.
107
110
  `examples/mini-webapp` ships in this repo, so this runs as written:
@@ -160,7 +163,7 @@ Text that doesn't fit the grammar still gets the tolerant strategies. Nothing
160
163
  is rejected for being loose, fuzzy, or misspelled.
161
164
 
162
165
  On top of that base, tmct reads the shapes people actually use, and each one
163
- resolves to a real graph traversal or declines honestly:
166
+ resolves to a real graph traversal or declines cleanly:
164
167
 
165
168
  - everyday question forms: "what is Commit", "what's model.mjs for",
166
169
  "recent commits" as real dated history;
@@ -353,8 +356,13 @@ Goal (inferred): Plan a move sequence from the current state to the goal (7 move
353
356
  ```
354
357
 
355
358
  "next" executes one move at a time, writing each board state into memory as
356
- facts; the final step re-reads those facts and confirms the goal from them,
357
- never assuming success. The search is genuine and domain-general: the test
359
+ facts stamped with the step that produced them ("disk-1@step1 rests on peg-c",
360
+ sourced to the plan). The final step re-reads the store and confirms the goal
361
+ from those written facts, never assuming success. The stamp is what makes each
362
+ step a separate record; a question about the piece itself ("where does disk-1
363
+ rest?", "is disk-1 clear?") reads the current board — the latest step's facts,
364
+ not every step at once. The search is
365
+ domain-general: the test
358
366
  suite teaches Towers of Hanoi purely as sentences for 1 to 8 disks and
359
367
  asserts the plan is exactly 2^n − 1 moves every time, and a second game
360
368
  (`crates.txt`, stacking crates with different rules and a two-goal
@@ -417,14 +425,15 @@ nudges you to ground one side first. Quantified teaching stores the
417
425
  quantifier ("some functions are risky" … "how many functions are risky" →
418
426
  "A few."), and "how many facts are there" counts the store back.
419
427
 
420
- Teaching doesn't have to be typed, either. `npm run extract:facts` (from a
421
- clone) runs a plain text file through the same recognizer the chat's teach
422
- lane uses. Sentences the recognizer grounds become fact rows; everything
423
- else is skipped and counted, never paraphrased:
428
+ Teaching doesn't have to be typed, either. `tmct extract` runs a plain text
429
+ file through the same recognizer the chat's teach lane uses. Sentences the
430
+ recognizer grounds become fact rows; everything else is skipped and counted,
431
+ never paraphrased. Add `--repo <abs>` to write them into that repo's own
432
+ memory; without it nothing on disk is mutated and the facts print as JSONL:
424
433
 
425
434
  ```bash cwd=repo
426
435
  printf 'We deployed redis last week. a cache is a kind of store. Why was it slow?\n' > /tmp/notes.txt
427
- node scripts/extract-facts-from-text.mjs /tmp/notes.txt
436
+ node bin/tmct.mjs extract /tmp/notes.txt
428
437
  ```
429
438
 
430
439
  ```output
@@ -537,13 +546,13 @@ provenance record. Most of its flags choose what gets seeded and where config is
537
546
  [--corpus <id|path>] also seed a corpus — a tier-2 manifest id (aws|python|java|
538
547
  general) or a jsonl file path — opt-in, offline, $0
539
548
  [--ontology <name|path>] activate+seed an ontology bundle (a recognized name or a path)
540
- [--lexicon <name|path>] activate a lexicon bundle (recognized name or a path;
549
+ [--lexicon <name|path>] activate a lexicon bundle (recognized name or a path;
541
550
  merged read-time, never seeded — see mergedLexiconExtra)
542
551
  [--graph <path>] set graph_file/graph_files in tmct.toml (repeatable)
543
552
  [--config <path>] write to an alternate tmct.toml location
544
553
  [--detect] suggest a tier-2 corpus from the repo's manifests
545
554
  (pyproject.toml → python, pom.xml → java); never seeds unasked
546
- [--with-persona <name>] write an explicit [extensions]/[bias] preset into tmct.toml
555
+ [--with-persona <name>] write an explicit [extensions]/[bias] preset into tmct.toml
547
556
  ("code" — today's implicit default, made explicit)
548
557
  [--persona-size <medium|large>] grow the default "human" persona's fact count
549
558
  beyond Small (the default): "medium" activates
@@ -564,7 +573,7 @@ already set up. Its `--graph` flag works differently from the others: it appends
564
573
  tmct import [--repo <abs>] activate+seed into an ALREADY-initialized repo (any
565
574
  [--corpus <id|path>] combination of these flags in one call). --graph is a
566
575
  [--ontology <name|path>] DIFFERENT operation from the others: it APPENDS to
567
- [--lexicon <name|path>] tmct.toml's graph_files array (multi-graph growth),
576
+ [--lexicon <name|path>] tmct.toml's graph_files array (multi-graph growth),
568
577
  [--graph <path>] never an extensions-bundle activation.
569
578
  [--file <definition.txt>] teach a plain-text definition file sentence by
570
579
  sentence (# lines are comments); any declined
@@ -573,12 +582,24 @@ already set up. Its `--graph` flag works differently from the others: it appends
573
582
  [--config <path>]
574
583
  ```
575
584
 
585
+ `tmct extract` is the document route into memory described under "Teach it"
586
+ above — the same teach recognizer, reading a file instead of your typing:
587
+
588
+ ```output:help:extract
589
+ tmct extract <text-file> read a plain text file's sentences through the chat's own
590
+ [--file <text-file>] teach recognizer and keep the facts it grounds; every
591
+ other sentence is skipped and counted, never paraphrased
592
+ [--repo <abs>] write the facts into that repo's own tmct memory; without
593
+ it nothing on disk is mutated and the facts print as JSONL
594
+ [--out <file.jsonl>] write that JSONL to a file instead of stdout
595
+ ```
596
+
576
597
  `tmct extend --validate` checks a third-party extension pack's declared resources
577
598
  before you switch any repo's `tmct.toml` over to it:
578
599
 
579
600
  ```output:help:extend
580
601
  tmct extend --validate <dir> validate a third-party extension pack's declared
581
- [--config <path>] resources (corpus/lexicon/templates) before activating
602
+ [--config <path>] resources (corpus/lexicon/templates) before activating
582
603
  it in any repo's tmct.toml; exits non-zero on failure
583
604
  ```
584
605
 
@@ -586,9 +607,9 @@ before you switch any repo's `tmct.toml` over to it:
586
607
  inference" above:
587
608
 
588
609
  ```output:help:syllogise
589
- tmct syllogise [--repo <abs>] speculative inference (offline maintenance job): forward-
610
+ tmct syllogise [--repo <abs>] speculative inference (offline maintenance job): forward-
590
611
  [--depth <n>] [--budget <n>] chain the memory's rdfs:subClassOf closure, materialising
591
- [--config <path>] bounded, low-trust, retractable entailed facts (never on the chat path)
612
+ [--config <path>] bounded, low-trust, retractable entailed facts (never on the chat path)
592
613
  ```
593
614
 
594
615
  `tmct viz` renders the memory graph as the ledger explorer — a single,
@@ -596,11 +617,11 @@ self-contained HTML file you can open in a browser:
596
617
 
597
618
  ```output:help:viz
598
619
  tmct viz [--repo <abs>] write one self-contained HTML page: the memory graph as a
599
- [--focus <term>] readable ledger of fact-sentences around one focus term,
600
- [--term <word>] with segments, a two-hop minimap, and an in-page chat dock
601
- [--limit <n>] that answers from the embedded graph. Focuses on the newest
602
- [--output <path>] taught fact's subject by default (--focus <term> or
603
- [--config <path>] --term <word> override it); --output defaults to
620
+ [--focus <term>] readable ledger of fact-sentences around one focus term,
621
+ [--term <word>] with segments, a two-hop minimap, and an in-page chat dock
622
+ [--limit <n>] that answers from the embedded graph. Focuses on the newest
623
+ [--output <path>] taught fact's subject by default (--focus <term> or
624
+ [--config <path>] --term <word> override it); --output defaults to
604
625
  ledger.html in the cwd; --limit caps the embedded fact
605
626
  rows; --term resolves via the same normalization chat uses.
606
627
  ```
@@ -927,7 +948,7 @@ node bin/tmct.mjs cli tmct_untested '{"repo_path":"examples/mini-webapp"}'
927
948
  ## The repository interface
928
949
 
929
950
  tmct is not an indexer, so it consumes a graph through a typed contract any
930
- producer can implement. That contract is first-class: a **versioned (1.0.0),
951
+ producer can implement. That contract is first-class: a **versioned (1.1.0),
931
952
  OWL-grounded, machine-readable service definition** (`docs/repository-interface.md`
932
953
  plus a JSON schema) of every service, its arguments, result types, and error
933
954
  contract. The interface returns a miss as a normal value. It never throws to
@@ -942,6 +963,19 @@ service. The LLM agent stays outside tmct, as the no-LLM ethos requires.
942
963
 
943
964
  ## Measuring it
944
965
 
966
+ What the 2.0.3 cycle measured, on 2026-07-16. Each figure links to its method
967
+ and carries, in the same row, the caveat that changes what it means. The full
968
+ tables, judge scores, and transcripts are in the linked write-ups.
969
+
970
+ | What it does | Result (2.0.3) | Read the number with this | Method |
971
+ |---|---|---|---|
972
+ | Multi-hop entailment | 219/219 chat cases and 80/80 kernel cases, 0% fabrication, all six bands pass | 50 of the 219 greens (23%) are graded against a declared floor, not the classical answer. INF-C2's 20/20 grades that the engine answers contradictory memory without fabricating, never that it detects the clash. | `BENCHMARK_INFERENCE_2.0.3.md` |
973
+ | Tool-call planning | 56/56 cases, 100% plan-completion, 100% result-completion, 0% hallucination, every rung A0→C2 | Goal driver. All 11 C2 cases pass, so the ladder now has more headroom than the case set exercises. | `BENCHMARK_AGENT_2.0.3.md` |
974
+ | Groundedness | Every answer carries a source, and an empty graph reports itself empty (`bootstrap-empty` 2.000/2). Judge-scored groundedness 1.857/2 over 98 cases. | The 1.857 is judged (`claude-haiku-4-5-20251001`, `judge-prompt-v1`) at N=1 over 9 of 23 construction shapes, so read it as indicative. The judge runs in the offline eval harness, never in the product. | `BENCHMARK_CEFR_ENGLISH_2.0.3.md` |
975
+ | Abstention (the honest miss) | 0% fabrication across 299 inference rows and 0% hallucination across 168 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.0.3.md`, `BENCHMARK_AGENT_2.0.3.md` |
976
+ | Determinism | Byte-identical on rerun, 0 verdict changes across 299 inference rows against the prior cycle, a 109-case replay in 877ms at $0 per turn | A property of the no-model pipeline. | `BENCHMARK_INFERENCE_2.0.3.md`, `CAPABILITIES_2.0.3.md` |
977
+ | Dialogue robustness (role and polarity) | An adversarial persona sweep could not force a single role or polarity inversion in 55 probes — active/passive, forward/reverse, negation and the converse trap all compiled to the correct canonical shape | The same five-frame sweep (~200 probes) surfaced 25 dialogue dead-ends, eight of them confidently wrong, all from words dropped before the parser rather than from the reasoning. | `BENCHMARK_CONVERSATION_2.0.3.md` |
978
+
945
979
  Three offline benchmark rigs live in a clone (they are not in the npm
946
980
  package). Each replays a committed case set through the real product and
947
981
  writes graded rows you can diff between runs:
@@ -971,9 +1005,6 @@ one place an LLM is allowed, never the product:
971
1005
  npm run chatbench:judge -- --product /tmp/chatbench-smoke/product.jsonl
972
1006
  ```
973
1007
 
974
- The headline numbers and their conditions live in the `BENCHMARK_*.md`
975
- write-ups.
976
-
977
1008
  ## Security and supply chain
978
1009
 
979
1010
  tmct is $0 to run and meant to be trusted offline, so the supply chain is
@@ -995,6 +1026,74 @@ fallback, the code-extraction stack, and the MCP server were all removed. The
995
1026
  naming, license, and memory model were reset to the vision above. See
996
1027
  `ROADMAP.md` for the phase plan.
997
1028
 
1029
+ ## Standards and bibliography
1030
+
1031
+ tmct's vocabulary is grounded in published standards where they exist, and says where they don't.
1032
+ Each alignment below is a triple in `ontology/tmct-core.ttl` and a test in
1033
+ `test/adapters/grammar-ontology.test.mjs`. `docs/references/` holds an entry per source: the
1034
+ edition, the retrieval date, the terms tmct uses, and what could not be verified.
1035
+ `PLAN_NORMATIVE.md` holds the reconciliation, one verdict per term.
1036
+
1037
+ ### The data model
1038
+
1039
+ | source | edition | what tmct uses it for |
1040
+ |---|---|---|
1041
+ | [W3C OWL 2 Primer](https://www.w3.org/TR/owl2-primer/) · [Profiles](https://www.w3.org/TR/owl2-profiles/) | Recommendation, 2012-12-11 | The triple model. The grammar emits `rdfs:subClassOf`, `owl:Restriction`, `owl:someValuesFrom`, `owl:disjointWith` and cardinality axioms. The inference engine implements OWL 2 RL/RDF rules and uses their names: `scm-sco`, `cax-sco`, `cax-dw`, `cls-svf1`, `scm-svf1`. |
1042
+ | [RDF 1.1 Semantics](https://www.w3.org/TR/rdf11-mt/) | Recommendation, 2014-02-25 | Facts are reified statements. Appendix D.1 endorses reification for provenance, which is what tmct uses it for. [RDF 1.2](https://www.w3.org/TR/rdf12-concepts/) (Candidate Recommendation, 2026-04-07) reclassifies that vocabulary as legacy and points new systems at triple terms and `rdf:reifies`. tmct has not moved, and `docs/references/schemas/rdf-reification-and-rdf-star.md` says why. |
1043
+ | [W3C PROV-O](https://www.w3.org/TR/prov-o/) | Recommendation, 2013-04-30 | Provenance. A fact's source links sit under `prov:wasInfluencedBy`; a fact cleaned from a raw utterance is a `prov:wasDerivedFrom`; a session is a `prov:Activity` and the utterances in it are `prov:Entity`s it generated. |
1044
+ | [W3C SKOS](https://www.w3.org/TR/skos-reference/) | Recommendation, 2009-08-18 | Read, and mostly not used. `skos:related` needs `skos:Concept` at both ends, and tmct's corpus terms are bare strings. `docs/references/schemas/skos.md` records what a concept-identity pass would need. |
1045
+ | [SEON](http://se-on.org/) `code.owl` | 2012/02 | Code-graph vocabulary: `seon:hasSuperType`, `seon:containsCodeEntity`, `seon:declaresMethod`, `seon:invokesMethod` and 15 more. Where SEON has no term, tmct coins under its own `mgx:` prefix rather than borrowing SEON's. |
1046
+
1047
+ ### Language
1048
+
1049
+ | source | edition | what tmct uses it for |
1050
+ |---|---|---|
1051
+ | [Attempto Controlled English](http://attempto.ifi.uzh.ch/site/docs/) | ACE 6.7, 2013 | The controlled-English fragment. tmct implements 9 of ACE's declarative sentence patterns. |
1052
+ | Kuhn, "A Survey and Classification of Controlled Natural Languages" | *Computational Linguistics* 40(1), 2014 | Where ACE sits among controlled languages. |
1053
+ | [ConceptNet](https://github.com/commonsense/conceptnet5/wiki/Relations) | slice pins 5.7.0 | The commonsense corpus. 25 relations are mirrored into `mgx:` and each cites its `/r/` origin. |
1054
+ | Damerau, *CACM* 7(3), 1964 · Levenshtein, *Soviet Physics Doklady* 10(8), 1966 | — | Fuzzy matching. `fuzzy.mjs` implements **Optimal String Alignment** — restricted Damerau-Levenshtein, which allows adjacent transposition but edits no substring twice. |
1055
+
1056
+ ### Reasoning and planning
1057
+
1058
+ | source | edition | what tmct uses it for |
1059
+ |---|---|---|
1060
+ | Fikes & Nilsson, "STRIPS" | *Artificial Intelligence* 2(3–4), 1971 | The action model: operator, precondition, effect. |
1061
+ | McDermott et al., PDDL | Yale CVC TR-98-003, 1998 | The action-rule vocabulary. |
1062
+ | Doyle, "A Truth Maintenance System" | *Artificial Intelligence* 12(3), 1979 | Justification and premise. tmct records which rule entailed a fact; it does not yet record which facts fed the rule. |
1063
+ | Meszaros, *xUnit Test Patterns* | Addison-Wesley, 2007 | The test-double taxonomy — stub, spy, mock, fake, dummy — and the fixture patterns. `docs/references/testing-vocabulary.md` records where tmct's own tiers depart from the standard taxonomy, and that "blast radius" is an ops metaphor for what the literature calls Regression Test Selection. |
1064
+ | Aristotle, *Prior Analytics* I.1 (24b18–20) · Bobzien, "Ancient Logic", *SEP* | — | **Why the command is called `syllogise`.** The word is used in the older, broader sense of *sullogismos* — Aristotle's own definition is "discourse in which, certain things being stated, something other than what is stated follows of necessity", with no mention of three terms or two premises, and the Stoics used the same word for a system in which modus ponens is a *sullogismos*. Two of tmct's rules are the narrow thing exactly: `scm-sco` is **Barbara**, `cax-sco` is the **Socrates syllogism**. The others reach past term logic. The operation's own names are **forward chaining** and **materialisation**, and the code uses those. |
1065
+
1066
+ ### Storage
1067
+
1068
+ | source | edition | what tmct uses it for |
1069
+ |---|---|---|
1070
+ | Jensen et al., "A Consensus Glossary of Temporal Database Concepts" | *SIGMOD Record* 23(1), 1994 | The time vocabulary. `mgx:utteranceTs` is valid time; `mgx:createdAt` is a transaction-time start. tmct is **not** bitemporal: `mgx:updatedAt` is an audit stamp, so tmct cannot answer what it believed last Tuesday. |
1071
+ | RFC 9923, "The FNV Non-Cryptographic Hash Algorithm" | Informational, 2026 | FNV hashes the narrow non-fact-id pools (paraphrase keys, per-URL source ids, corpus dedupe). Fact ids are content-addressed with a **64-bit truncation of SHA-256**, so a fact id is collision-resistant at tmct's corpus sizes; tmct is still **not** a Merkle tree and offers no tamper-evidence. |
1072
+ | Green, Karvounarakis, Tannen, "Provenance Semirings" | PODS 2007 | The distinction tmct's docs keep: it records source annotation and PROV-style attribution, not how-provenance. |
1073
+
1074
+ ### Measuring it
1075
+
1076
+ | source | edition | what tmct uses it for |
1077
+ |---|---|---|
1078
+ | 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. |
1079
+ | 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". |
1080
+ | 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. |
1081
+ | 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. |
1082
+
1083
+ ### Where no standard fits
1084
+
1085
+ - **Trust.** PROV records who said a thing, not whether to believe them, and no W3C Recommendation
1086
+ covers trust. `mgx:trustScore` and its inputs are tmct's own. Candidate literature: Artz & Gil,
1087
+ "A survey of trust in computer science and the Semantic Web", *Journal of Web Semantics* 5(2),
1088
+ 2007.
1089
+ - **Negation.** tmct negates with its own `mgxneg:` prefix, which applies to any predicate.
1090
+ `owl:disjointWith` would over-claim, since "john is not a man" denies one membership rather than
1091
+ a class axiom, and OWL 2's `negativePropertyAssertion` needs a reified shape the flat JSON store
1092
+ has no room for.
1093
+ - **Dialogue acts.** tmct has no intent vocabulary. ISO 24617-2 (SemAF) is the standard for one, and
1094
+ `docs/references/schemas/iso-24617-2-dialogue-acts.md` maps tmct's behaviour onto it so that if
1095
+ one is built it uses the standard's names.
1096
+
998
1097
  ## Licensing
999
1098
 
1000
1099
  **MPL-2.0.** Free for commercial use. If you modify the covered files and
package/ROADMAP.md CHANGED
@@ -112,14 +112,15 @@ status in its opening lines — read it there, because a status quoted here woul
112
112
  | [PLAN_CLASS_QUERY.md](PLAN_CLASS_QUERY.md) | "list/count all X of class Y", reconciled against what already shipped |
113
113
  | [PLAN_CODE.md](PLAN_CODE.md) | program synthesis over tmct's closed DSLs, plus JS/HTML/CSS fragments and goal-directed program repair |
114
114
  | [PLAN_CONSISTENCY_CHECK.md](PLAN_CONSISTENCY_CHECK.md) | tmct as a consistency service for an LLM tool loop |
115
+ | [PLAN_DIALOGUE_ACTS.md](PLAN_DIALOGUE_ACTS.md) | naming tmct's turn types to ISO 24617-2 dialogue acts, deterministically |
115
116
  | [PLAN_EMBEDDINGS.md](PLAN_EMBEDDINGS.md) | the semantic-similarity axis, and the way back to it |
116
117
  | [PLAN_GRAPH_SCAN.md](PLAN_GRAPH_SCAN.md) | seed and query cost at `init:xl`/`init:xxl` corpus scale |
117
118
  | [PLAN_GUESS_NUMBER.md](PLAN_GUESS_NUMBER.md) | closed-loop planning over hidden state, via belief-interval bisection |
118
119
  | [PLAN_MUD.md](PLAN_MUD.md) | persistent, shared tmct worlds over a `server:` memory backend |
119
120
  | [PLAN_NLU_BENCHMARKS.md](PLAN_NLU_BENCHMARKS.md) | scoring tmct on the CLINC150 and HWU64 intent sets |
120
- | [PLAN_OPEN_ITEMS.md](PLAN_OPEN_ITEMS.md) | the build order closing the backlog `HANDOVER.md` carries |
121
+ | [PLAN_OPEN_ITEMS.md](archive/PLAN_OPEN_ITEMS.md) | delivered — the 2.0.3-cycle build order, archived |
121
122
  | [PLAN_PARAPHRASE_VERIFICATION.md](PLAN_PARAPHRASE_VERIFICATION.md) | checking a paraphrase against the graph before it prints |
122
- | [PLAN_PURGE.md](PLAN_PURGE.md) | promote the load-bearing code, delete the dead weight |
123
+ | [PLAN_PURGE.md](archive/PLAN_PURGE.md) | delivered — promoted the load-bearing code, deleted the dead weight, archived |
123
124
  | [PLAN_REPO_INDEX.md](PLAN_REPO_INDEX.md) | tmct grows its own code parsers, ported from seonix |
124
125
  | [PLAN_SYLLOGIST.md](PLAN_SYLLOGIST.md) | the reasoning engine's incrementality and retraction horizon |
125
126
  | [PLAN_SYLLOGIST_EL_DL.md](PLAN_SYLLOGIST_EL_DL.md) | beyond OWL 2 RL: an EL classifier, then a DL tableau prover |
package/bin/tmct.mjs CHANGED
@@ -28,100 +28,19 @@
28
28
  // shape and the green test suite. See README.md for what tmct is and
29
29
  // deliberately is NOT, and ROADMAP.md for where it is going.
30
30
 
31
+ // The verb list itself is data (src/domain/cli-verbs.mjs) and both the Usage
32
+ // block below and the unknown-invocation line read it, so a new verb is one
33
+ // entry rather than two edits that drift. It is pure and imports nothing, so a
34
+ // static import here costs `tmct --help` nothing.
35
+ import { renderUsage, unknownInvocationMessage } from "../src/domain/cli-verbs.mjs";
36
+
31
37
  const HELP = `tmct — The Mechanical Code Talker
32
38
 
33
39
  A tolerant, offline, $0 chat that guides you toward precision queries about a
34
40
  software repository. No model calls; no codebase index of its own.
35
41
 
36
42
  Usage:
37
- tmct interactive chat (the headline surface)
38
- tmct chat [--repo <abs>] chat over a specific repo's graph
39
- [--graph <path>] explicit graph file (repeatable — multiple graphs merge;
40
- see src/adapters/graph-merge.mjs); wins over --repo/TMCT_GRAPH_FILE/tmct.toml
41
- [--config <path>] an alternate tmct.toml location (a file or a directory)
42
- [--ephemeral] read the graph but write nothing back (demo/read-only)
43
- [--prompt "<text>"] one-shot: run the prompt's sentences as turns and print
44
- the final answer (teach state first, trigger last)
45
- [--render blocks] with --prompt: when the final turn produced a plan,
46
- write it as a self-contained animated page
47
- [--output <path>] the rendered page's path (default plan.html)
48
- [--narrate] start with narrate mode on — a verbose, developer-facing
49
- trace of decision points/matched pattern/results/goal per
50
- turn, appended under a "--- narrate ---" marker (also
51
- TMCT_NARRATE=1; toggle mid-session with /narrate on|off)
52
- [--plain] force the plain readline shell (the default when
53
- stdin/stdout is not a terminal)
54
- [--memory-backend <default|memory|sqlite>] storage backend for taught facts this
55
- session (CLI flag > TMCT_MEMORY_BACKEND env > tmct.toml's
56
- [memory] backend > "default", the flat .tmct/ JSON file)
57
- tmct memory [--repo <abs>] what tmct remembers: facts, utterances, sessions,
58
- [--config <path>] folded blocks (the /memory chat command, from the shell)
59
- [--verbose]
60
- tmct init [--repo <abs>] initialize a repo for tmct (default: cwd): .tmct/,
61
- [--force] tmct.toml, .tmct/TOOLS.md (the cold-tool catalog),
62
- tier-1 corpus seed, provenance record
63
- [--corpus <id|path>] also seed a corpus — a tier-2 manifest id (aws|python|java|
64
- general) or a jsonl file path — opt-in, offline, $0
65
- [--ontology <name|path>] activate+seed an ontology bundle (a recognized name or a path)
66
- [--lexicon <name|path>] activate a lexicon bundle (recognized name or a path;
67
- merged read-time, never seeded — see mergedLexiconExtra)
68
- [--graph <path>] set graph_file/graph_files in tmct.toml (repeatable)
69
- [--config <path>] write to an alternate tmct.toml location
70
- [--detect] suggest a tier-2 corpus from the repo's manifests
71
- (pyproject.toml → python, pom.xml → java); never seeds unasked
72
- [--with-persona <name>] write an explicit [extensions]/[bias] preset into tmct.toml
73
- ("code" — today's implicit default, made explicit)
74
- [--persona-size <medium|large>] grow the default "human" persona's fact count
75
- beyond Small (the default): "medium" activates
76
- human-medium.jsonl (~1,608 facts total), "large" also
77
- activates human-large.jsonl (~13,600 facts total,
78
- with genuine multi-hop hypernym chains) — additive
79
- size tiers of the SAME bundle, not separate personas
80
- [--memory-backend <default|memory|sqlite>] write tmct.toml's [memory] backend
81
- (same flag name as \`tmct chat\`) — a later \`tmct chat\`
82
- in this repo picks it up with no flag needed
83
- tmct import [--repo <abs>] activate+seed into an ALREADY-initialized repo (any
84
- [--corpus <id|path>] combination of these flags in one call). --graph is a
85
- [--ontology <name|path>] DIFFERENT operation from the others: it APPENDS to
86
- [--lexicon <name|path>] tmct.toml's graph_files array (multi-graph growth),
87
- [--graph <path>] never an extensions-bundle activation.
88
- [--file <definition.txt>] teach a plain-text definition file sentence by
89
- sentence (# lines are comments); any declined
90
- sentence exits non-zero with the sentence named
91
- [--memory-backend <default|memory|sqlite>] same knob as \`tmct init\`
92
- [--config <path>]
93
- tmct extend --validate <dir> validate a third-party extension pack's declared
94
- [--config <path>] resources (corpus/lexicon/templates) before activating
95
- it in any repo's tmct.toml; exits non-zero on failure
96
- tmct syllogise [--repo <abs>] speculative inference (offline maintenance job): forward-
97
- [--depth <n>] [--budget <n>] chain the memory's rdfs:subClassOf closure, materialising
98
- [--config <path>] bounded, low-trust, retractable entailed facts (never on the chat path)
99
- tmct viz [--repo <abs>] write one self-contained HTML page: the memory graph as a
100
- [--focus <term>] readable ledger of fact-sentences around one focus term,
101
- [--term <word>] with segments, a two-hop minimap, and an in-page chat dock
102
- [--limit <n>] that answers from the embedded graph. Focuses on the newest
103
- [--output <path>] taught fact's subject by default (--focus <term> or
104
- [--config <path>] --term <word> override it); --output defaults to
105
- ledger.html in the cwd; --limit caps the embedded fact
106
- rows; --term resolves via the same normalization chat uses.
107
- tmct serve [--repo <abs>] run the Anthropic Messages API-compatible endpoint
108
- [--host <h>] [--port <n>] (POST /v1/messages) over the graph — a deterministic,
109
- [--graph <path>] no-LLM "model" a tool-loop client can call; $0 usage.
110
- [--config <path>] Defaults: host 127.0.0.1, port 8787. Ctrl+C to stop.
111
- tmct plan "<request>" the capability router: compose/execute read-only graph-
112
- [--repo <abs>] query tool calls for a compound or maintenance-goal
113
- [--graph <path>] request ("of the modules impacted by X, which are
114
- [--config <path>] untested", "what most needs a test") — a real STRIPS/
115
- [--tools <a,b,...>] PDDL planner (src/domain/router/*), never a guessed call.
116
- [--json] Prints the grounded step sequence + composed answer,
117
- or an honest "no plan found". --tools restricts the
118
- declared toolset; --json prints the full loop result.
119
- tmct cli <tool> '{…}' invoke a graph tool directly (carry-over, de-emphasized)
120
- [--repo <abs>] the repo to answer from; the payload's "repo_path" says
121
- [--graph <path>] the same thing. --graph names the graph file outright
122
- [--config <path>] (repeatable), --config an alternate tmct.toml
123
- tmct cli digest '{…}' architecture map + per-module context bundles
124
- tmct --help show this help
43
+ ${renderUsage()}
125
44
 
126
45
  On a terminal, chat opens the full-screen TUI; piped input gets the plain shell.
127
46
  In chat: /help lists slash-commands; /exit leaves. Session log → <repo>/.tmct/session-<id>.log.
@@ -1117,6 +1036,15 @@ async function main() {
1117
1036
  return;
1118
1037
  }
1119
1038
 
1039
+ if (mode === "extract") {
1040
+ // `tmct extract` — run a text file's sentences through the chat's own teach
1041
+ // recognizer and keep what it grounds. Lazily imported: it pulls the whole
1042
+ // chat stack, which `tmct --help` and chat startup must not pay for.
1043
+ const { main: extractFacts } = await import("../src/services/extract-facts.mjs");
1044
+ await extractFacts(process.argv.slice(3));
1045
+ return;
1046
+ }
1047
+
1120
1048
  if (mode === "viz") {
1121
1049
  // `tmct viz` — the ledger explorer: one self-contained HTML page rendering
1122
1050
  // the memory graph as readable fact-sentences around a focus term, with
@@ -1336,8 +1264,7 @@ async function main() {
1336
1264
 
1337
1265
  // An unknown mode gets the instructive usage line and exit 2. (A bare invocation
1338
1266
  // never lands here — the argv splice above rewrote it to `chat`.)
1339
- process.stderr.write(`tmct: unknown invocation "${process.argv.slice(2).join(" ")}". ` +
1340
- "Use `chat`, `memory`, `init`, `import`, `extend --validate`, `syllogise`, `serve`, `plan`, `cli digest …`, or `cli <tool> …`.\n");
1267
+ process.stderr.write(unknownInvocationMessage(process.argv.slice(2).join(" ")));
1341
1268
  process.exit(2);
1342
1269
  }
1343
1270
 
@@ -101,11 +101,26 @@
101
101
  "notice": "corpus/tier2/manifest.json"
102
102
  },
103
103
  {
104
- "path": "corpus/generated/ace-surface-variants.jsonl",
105
- "upstream": "mechanically generated from Open English WordNet / SemCor example sentences and this repository's own docs prose",
106
- "license": "CC-BY-4.0",
104
+ "path": "corpus/prose/sqlite/",
105
+ "upstream": "SQLite documentation (sqlite.org), plain-text extractions of 12 pages",
106
+ "license": "public-domain",
107
107
  "shareAlike": false,
108
- "notice": "corpus/generated/manifest.json"
108
+ "notice": "corpus/prose/sqlite/LICENSE-NOTICE"
109
+ },
110
+ {
111
+ "path": "corpus/prose/wikipedia/",
112
+ "upstream": "Wikipedia — simple.wikipedia.org lead sections (56 everyday-concept articles) and en.wikipedia.org full articles (12 in tmct's technical domain), fetched via the MediaWiki extracts API",
113
+ "license": "CC-BY-SA-4.0",
114
+ "shareAlike": true,
115
+ "notice": "corpus/prose/wikipedia/LICENSE-NOTICE"
116
+ },
117
+ {
118
+ "path": "corpus/generated/ace-surface-variants.jsonl",
119
+ "upstream": "mechanically generated from Open English WordNet / SemCor example sentences (CC-BY-4.0) and corpus/prose/, which includes CC-BY-SA-4.0 Wikipedia text",
120
+ "license": "CC-BY-SA-4.0",
121
+ "shareAlike": true,
122
+ "notice": "corpus/generated/manifest.json",
123
+ "note": "CC-BY-SA-4.0, not CC-BY-4.0: the rescue rows quote and word-substitute Wikipedia sentences from corpus/prose/wikipedia/, so this published file is a modified derivative of CC-BY-SA-4.0 text and inherits its viral share-alike. It carried CC-BY-4.0 while the prose corpus was this repository's own docs; adding Wikipedia is what changed it. See corpus/prose/wikipedia/LICENSE-NOTICE."
109
124
  },
110
125
  {
111
126
  "path": "data/",
package/corpus/README.md CHANGED
@@ -45,6 +45,9 @@ notice}), guarded by `test/estate/corpus-licences.test.mjs`.
45
45
  | `tier2/{aws,python,java,general}.jsonl` | tier-2 SAMPLE corpuses — same fact shape as the tier-1 slice, loadable via the same path (`general` is the one deliberately non-code-domain bundle) | ~4-6 KB each | MPL-2.0 |
46
46
  | `tier2/human.jsonl` | the DEFAULT active bundle: the everyday "human-world" persona, Small tier (664 facts) — hand-curated from Open English WordNet, bridged to Schema.org's top-level classes | ~80 KB | MPL-2.0 (hand-authored fact set; not a verbatim WordNet/Schema.org excerpt — see `tier2/generate.mjs`'s own header comment) |
47
47
  | `tier2/human-medium.jsonl` / `tier2/human-large.jsonl` | SIZE tiers of the SAME `human` bundle — each holds ONLY the facts that size adds beyond the previous one; both shipped INACTIVE by default, activated via `tmct init --persona-size medium\|large`. Built by `scripts/build-persona-tiers.mjs` from the same WordNet source, automatically curated (sense-ranked, blocklist/denylist-filtered) rather than hand-typed one at a time, given the scale (944 / ~12,000 facts) | ~111 KB / ~1.4 MB | MPL-2.0 (same "hand-authored in homage to the source's shape" basis as `human.jsonl`) |
48
+ | `prose/sqlite/*.txt` | the frozen prose corpus, code half: plain-text extractions of 12 SQLite documentation pages | ~375 KB | **public domain** (see `prose/sqlite/LICENSE-NOTICE`) |
49
+ | `prose/wikipedia/*.txt` | the frozen prose corpus, English half: 56 simple-English lead sections (everyday concepts) + 12 en.wikipedia full articles (NLP/OWL/logic) | ~356 KB | **CC-BY-SA 4.0** (see `prose/wikipedia/LICENSE-NOTICE`) |
50
+ | `prose/manifest.json` | provenance for the above: source URL, byte count and sha256 per file, plus the fetch date | — | MPL-2.0 |
48
51
  | `tier2/human-examples.jsonl` / `tier2/human-examples-medium.jsonl` / `tier2/human-examples-large.jsonl` | the example-sentence corpus — real natural-language sentences mapped to the same curated vocabulary, NOT fact triples. Small/Medium tiers are 100% WordNet's own inline `example:` field (same CC-BY-4.0 basis as the fact bundles). Large tier ALSO includes a SemCor-filtered supplement (real Brown Corpus text, re-tagged to modern OEWN senses) for categories where WordNet's own inline coverage is thin (`human-nature` especially — `noun.animal.yaml`'s inline rate is under 1%) | ~11 KB / ~43 KB / ~257 KB | **The WordNet-inline entries**: CC-BY-4.0 (Princeton WordNet + Open English WordNet team), reproduced verbatim (these ARE the source's own example sentences, not a paraphrase). **The `source: "semcor:…"` entries**: CC-BY-4.0 per this SemCor fork's own `LICENSE.md` (a local uncommitted checkout of `globalwordnet/semcor`, real Brown Corpus text re-tagged to modern senses — the original 1960s Brown Corpus permissions aren't independently re-verified beyond that fork's own license statement; proceeding with attribution was an explicit operator decision) — each entry's own `source` field names its origin file (`semcor:<genre>/<file>.yaml`) for exactly this reason |
49
52
 
50
53
  And alongside (same phase, different directory because it is tmct-original
@@ -55,6 +58,51 @@ data, not a derived corpus):
55
58
  | `../data/templates/responses.jsonl` | ~56 response templates ({id, class, template, register}) | MPL-2.0 |
56
59
  | `../data/phrasebook/software-phrases.txt` | ~170 SE phrase patterns + 31 synonym families | MPL-2.0 |
57
60
 
61
+ ## The prose corpus (`prose/`) — external and frozen, on purpose
62
+
63
+ `prose/` is plain English text. It is not seeded and holds no facts. It exists
64
+ to be *measured against*: `scripts/template-coverage.mjs` asks how much of it
65
+ tmct's ACE grammar parses, and the rescue pass in
66
+ `scripts/generate-template-variants.mjs` mines it for near-misses.
67
+
68
+ It used to be this repository's own root `*.md` docs, and both reasons it moved
69
+ are worth stating, because both were real bugs:
70
+
71
+ - **A doc edit could drift a shipped artifact.** The corpus was globbed from
72
+ every root `*.md`, so editing a README or a plan changed
73
+ `generated/ace-surface-variants.jsonl` — a file npm ships. A rescue row could
74
+ be, and once was, a sentence someone had written into a plan that morning.
75
+ Committed text fetched from a recorded URL cannot do that.
76
+ - **The coverage metric was not comparable across versions.** A hit rate only
77
+ means something against a fixed corpus. When the corpus moves with every doc
78
+ edit, two versions' numbers are not measuring the same thing, and a change in
79
+ the number says nothing about a change in the grammar.
80
+
81
+ So the corpus is external (nothing in this repo can edit it), frozen (a
82
+ snapshot, checksummed per file in `prose/manifest.json`), and re-fetched only
83
+ when someone deliberately runs `npm run gen:prose-corpus`. `test/estate/prose-corpus.test.mjs`
84
+ checks the committed bytes against the manifest, so a hand-edit fails loudly.
85
+
86
+ **Licensing picked the sources, not preference.** The rescue pass substitutes
87
+ words and commits the result to a file npm publishes, so this corpus is
88
+ republished as a *modified derivative*. Only sources that permit derivatives
89
+ qualify. IETF RFCs and W3C specifications — including the OWL 2 Primer, the
90
+ best domain match there is — permit redistribution but **not** modification, so
91
+ they are unusable here and must not be added. SQLite's documentation is public
92
+ domain; Wikipedia is CC BY-SA 4.0. Adding Wikipedia is what makes
93
+ `generated/ace-surface-variants.jsonl` CC-BY-SA-4.0 rather than CC-BY-4.0:
94
+ share-alike is viral, and it reaches the generated file.
95
+
96
+ **Why simple-English lead sections for the everyday half.** Measured, on the
97
+ metric the rescue pass actually consumes (sentences with exactly one undeclared
98
+ word): simple.wikipedia.org lead sections yield ~0.33 rescue candidates per KB
99
+ against ~0.12 for technical prose. Lead sections are dense definitional English
100
+ ("A penguin is a bird that cannot fly"), which is the shape the ACE grammar was
101
+ built to parse; later article sections drift into history and citations. The
102
+ titles cover the same everyday concepts the persona clumps model
103
+ (`scripts/build-persona-tiers.mjs`'s `CLUMP_FILES`). The technical half stays
104
+ because tmct's own domain is code.
105
+
58
106
  ## How seeding works
59
107
 
60
108
  `src/adapters/corpus/conceptnet.mjs` turns the slice into tmct memory facts:
@@ -17,7 +17,7 @@ measurement: `node scripts/template-coverage.mjs` (baseline) and
17
17
 
18
18
  | `kind` | What | Fields |
19
19
  |---|---|---|
20
- | `rescue` | A real docs-corpus sentence that almost fit the ACE grammar (exactly one undeclared word), rescued by substituting a WordNet synonym of that word that's ALSO already declared in `src/domain/grammar/lexicon-core.json` | `sentence`, `rescued`, `from`, `to`, `pos`, `synsetId`, `sourceFile` |
20
+ | `rescue` | A real sentence from the frozen prose corpus (`corpus/prose/`) that almost fit the ACE grammar (exactly one undeclared word), rescued by substituting a WordNet synonym of that word that's ALSO already declared in `src/domain/grammar/lexicon-core.json` | `sentence`, `rescued`, `from`, `to`, `pos`, `synsetId`, `sourceFile` |
21
21
  | `variant` | A real WordNet/SemCor example sentence (`corpus/tier2/human-examples*.jsonl`) that already hits `parseAce`, with one content word swapped for a same-synset sibling (both ends independently declared in tmct's own lexicon) | `seed`, `generated`, `from`, `to`, `pos`, `synsetId`, `sourceCorpus` |
22
22
  | `alt-phrasing` | A possessive-pattern (#7) hit rewritten in the ACE grammar's OTHER declared surface form for the same triple (`"X's Y is Z"` <-> `"the Y of X is Z"`, both routed through `buildPossessive` in `src/domain/grammar/ace.mjs`) | `seed`, `generated`, `pattern`, `form` |
23
23
 
@@ -31,12 +31,27 @@ product code — it is committed raw material, verified by
31
31
  `scripts/template-coverage.mjs`. Wiring it into live answer rendering is a
32
32
  separate, future phase.
33
33
 
34
- ## Licence
34
+ ## Licence — CC-BY-SA-4.0
35
35
 
36
- Open English WordNet content (synset `members`/`example` fields) is
37
- CC-BY-4.0; SemCor-derived sentences (`corpus/tier2/human-examples-large.jsonl`)
38
- are CC-BY-4.0 per that fork's own `LICENSE.md` (same basis `corpus/README.md`
39
- already documents for that file). A `variant`/`rescue` row is a one-word
40
- derivative of that material — CC-BY-4.0. An `alt-phrasing` row is a pure
41
- grammar-level rephrasing of the same source sentence CC-BY-4.0 also, no new
42
- creative content introduced either way.
36
+ **`ace-surface-variants.jsonl` is CC-BY-SA-4.0**, and this file ships in the npm
37
+ package. It is not under this repository's MPL-2.0.
38
+
39
+ Two source licences meet in this file:
40
+
41
+ - Open English WordNet content (synset `members`/`example` fields) is CC-BY-4.0;
42
+ SemCor-derived sentences (`corpus/tier2/human-examples-large.jsonl`) are
43
+ CC-BY-4.0 per that fork's own `LICENSE.md` (the same basis `corpus/README.md`
44
+ already documents for that file). `variant` and `alt-phrasing` rows derive
45
+ from this material.
46
+ - `corpus/prose/` feeds the `rescue` rows, and it includes Wikipedia text under
47
+ **CC-BY-SA-4.0** (`corpus/prose/wikipedia/LICENSE-NOTICE`). A `rescue` row
48
+ quotes such a sentence and substitutes one word into it, so the row is a
49
+ published, modified derivative of CC-BY-SA-4.0 text.
50
+
51
+ Share-alike is viral, so the combined file takes the stricter licence:
52
+ **CC-BY-SA-4.0**. Redistributing it, modified or not, means doing so under
53
+ CC-BY-SA 4.0 with the attribution in `corpus/prose/wikipedia/LICENSE-NOTICE`.
54
+
55
+ This file was labelled CC-BY-4.0 while the rescue corpus was this repository's
56
+ own MPL-2.0 docs. Repointing the corpus at Wikipedia is what changed it.
57
+ `corpus/prose/sqlite/` is public domain and adds no condition of its own.
@@ -1,4 +1,7 @@
1
- {"kind":"rescue","sentence":"Code search is a retrieval task","rescued":"Code hunt is a retrieval task","from":"search","to":"hunt","pos":"noun","synsetId":"00947217-n","sourceFile":"PLAN_EMBEDDINGS.md","provenance":"wordnet:00947217-n"}
1
+ {"kind":"rescue","sentence":"The claim of the previous paragraph is extensively checked in the SQLite regression test suite using a special test harness that simulates the effects on a database file of operating system crashes and power failures","rescued":"The claim of the old paragraph is extensively checked in the SQLite regression test suite using a special test harness that simulates the effects on a database file of operating system crashes and power failures","from":"previous","to":"old","pos":"adjective","synsetId":"00128009-s","sourceFile":"sqlite/transactional.txt","provenance":"wordnet:00128009-s"}
2
+ {"kind":"rescue","sentence":"The meaning of sentences is described as a small set of interpretation rules","rescued":"The significance of sentences is described as a small set of interpretation rules","from":"meaning","to":"significance","pos":"noun","synsetId":"06613680-n","sourceFile":"wikipedia/Attempto_Controlled_English.txt","provenance":"wordnet:06613680-n"}
3
+ {"kind":"rescue","sentence":"The difficulty of planning is dependent on the simplifying assumptions employed","rescued":"The trouble of planning is dependent on the simplifying assumptions employed","from":"difficulty","to":"trouble","pos":"noun","synsetId":"00625102-n","sourceFile":"wikipedia/Automated_planning_and_scheduling.txt","provenance":"wordnet:00625102-n"}
4
+ {"kind":"rescue","sentence":"The consumption of food is normally enjoyable to humans","rescued":"The intake of food is normally enjoyable to humans","from":"consumption","to":"intake","pos":"noun","synsetId":"00839759-n","sourceFile":"wikipedia/Food.txt","provenance":"wordnet:00839759-n"}
2
5
  {"kind":"variant","seed":"the ace of trumps is a sure winner","generated":"the one of trumps is a sure winner","from":"ace","to":"one","pos":"noun","synsetId":"13764713-n","sourceCorpus":"corpus/tier2/human-examples-large.jsonl","provenance":"wordnet:13764713-n"}
3
6
  {"kind":"variant","seed":"the ace of trumps is a sure winner","generated":"the single of trumps is a sure winner","from":"ace","to":"single","pos":"noun","synsetId":"13764713-n","sourceCorpus":"corpus/tier2/human-examples-large.jsonl","provenance":"wordnet:13764713-n"}
4
7
  {"kind":"variant","seed":"the ace of trumps is a sure winner","generated":"the unity of trumps is a sure winner","from":"ace","to":"unity","pos":"noun","synsetId":"13764713-n","sourceCorpus":"corpus/tier2/human-examples-large.jsonl","provenance":"wordnet:13764713-n"}
@@ -2,8 +2,8 @@
2
2
  "version": 1,
3
3
  "generated": "by scripts/generate-template-variants.mjs",
4
4
  "file": "ace-surface-variants.jsonl",
5
- "rows": 18,
6
- "bytes": 5012,
7
- "sha256": "28fae5a3353f5dd1df365b4407e0ac2a5c66b98b232d8bf454fe3573f2c16760",
8
- "license": "CC-BY-4.0 (WordNet-derived synonym substitutions of Open English WordNet / SemCor example sentences and this repo's own MPL-2.0 docs prosesee corpus/generated/README.md)"
5
+ "rows": 21,
6
+ "bytes": 6417,
7
+ "sha256": "6e1daca10e43455608e5ee91ca41e20c5a1c5b0127f14ffd087c85580fe1f0ad",
8
+ "license": "CC-BY-SA-4.0 (WordNet-derived synonym substitutions of Open English WordNet / SemCor example sentences (CC-BY-4.0) and corpus/prose/, which includes CC-BY-SA-4.0 Wikipedia text. Share-alike is viral and the rescue rows quote and modify that text, so the combined file is CC-BY-SA-4.0 the stricter of the two. See corpus/prose/wikipedia/LICENSE-NOTICE and corpus/generated/README.md)"
9
9
  }