@polycode-projects/the-mechanical-code-talker 5.0.12 → 5.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,82 @@
10
10
  > The [GitHub repo](https://github.com/polycode-public/the-mechanical-code-talker) is a
11
11
  > read-only mirror, synced hourly. Issues and merge requests go to GitLab.
12
12
 
13
+ ## 30-second quickstart
14
+
15
+ Install it:
16
+
17
+ ```bash skip=network
18
+ npm install @polycode-projects/the-mechanical-code-talker
19
+ ```
20
+
21
+ Teach it a fact, then ask about it. This is the whole public API for a
22
+ one-off library call:
23
+
24
+ ```js
25
+ import { runTurn } from "@polycode-projects/the-mechanical-code-talker";
26
+ import { mkdtemp, rm } from "node:fs/promises";
27
+ import { tmpdir } from "node:os";
28
+ import { join } from "node:path";
29
+
30
+ const memoryDir = await mkdtemp(join(tmpdir(), "tmct-quickstart-"));
31
+ await runTurn("a dog is an animal", { memoryDir });
32
+ const { answer } = await runTurn("what is a dog", { memoryDir });
33
+ console.log(answer);
34
+ await rm(memoryDir, { recursive: true, force: true });
35
+ ```
36
+
37
+ Cloned the repo instead? The same engine runs as a chat over stdin:
38
+
39
+ ```bash skip=repo-state
40
+ printf 'hi\n/exit\n' | node bin/tmct.mjs
41
+ ```
42
+
43
+ That greets you and exits 0. It's the project's own smoke test. (This one is
44
+ marked `skip=` so the README suite doesn't run it. It would seed `.tmct/` in
45
+ whatever directory it runs from, and every other example here runs from a
46
+ disposable temp dir instead of your clone.)
47
+
48
+ ## Architecture
49
+
50
+ Four layers, top to bottom. A **surface** (CLI, HTTP, TUI, or the browser)
51
+ takes input. A **service** (chat, plan, research, ledger, adventure) runs
52
+ the use case. **Domain** logic decides what's true and does no I/O of its
53
+ own. An **adapter** sits at the seam. It is the only layer that touches
54
+ disk, reading and writing the **graph store**, the OWL-labelled `.tmct/`
55
+ graph.
56
+
57
+ ![tmct architecture: surfaces call services, services call domain, adapters sit at the seam between domain and the graph store](docs/architecture.svg)
58
+
59
+ <details>
60
+ <summary>Mermaid source (GitLab and GitHub render this natively; npm does not, which is why the image above is the diagram of record)</summary>
61
+
62
+ ```mermaid
63
+ flowchart TB
64
+ subgraph Surfaces
65
+ CLI
66
+ HTTP
67
+ TUI
68
+ Web[Web browser]
69
+ end
70
+ subgraph Services
71
+ chat
72
+ plan
73
+ research
74
+ ledger
75
+ adventure
76
+ end
77
+ Domain["domain — pure logic<br/>router · planner · codegraph · completions"]
78
+ Adapters["adapters — the seam<br/>I/O · storage · providers"]
79
+ Store[(".tmct/ graph store<br/>SQLite or in-memory")]
80
+
81
+ Surfaces --> Services
82
+ Services --> Domain
83
+ Domain -.->|interface| Adapters
84
+ Adapters --> Store
85
+ ```
86
+
87
+ </details>
88
+
13
89
  `@polycode-projects/the-mechanical-code-talker`
14
90
 
15
91
  A pure-JS, **no-LLM**, offline, **$0** chatbot in the ELIZA/PARRY lineage.
@@ -34,9 +34,16 @@
34
34
  // 7. opinion object — /r/IsA or /r/DefinedAs whose object is one of a
35
35
  // small, evidence-based OPINION set (adjectives /
36
36
  // value words that never name a class)
37
+ // 8. denied row — the exact (rel, start, end) triple is in a
38
+ // small, hand-curated DENIED_ROWS set: a claim
39
+ // read as demonstrably false in general English
40
+ // while reading the committed slice, too
41
+ // specific for any shape rule above to catch
42
+ // ("beta IsA programming_language")
37
43
  //
38
- // Rules 1-5 apply to every relation (they only ever remove junk); 6-7 are the
39
- // definitional band the sims flagged. Stats land on stderr; JSONL on stdout.
44
+ // Rules 1-5 and 8 apply to every relation (they only ever remove junk); 6-7
45
+ // are the definitional band the sims flagged. Stats land on stderr; JSONL on
46
+ // stdout.
40
47
 
41
48
  import { readFile, writeFile } from "node:fs/promises";
42
49
  import { createInterface } from "node:readline";
@@ -65,8 +72,18 @@ export const KNOWN_MISSPELLINGS = new Set([
65
72
  "vessle",
66
73
  ]);
67
74
 
75
+ // Rows whose claim is demonstrably false in general English, found by reading
76
+ // the committed slice. Keyed `rel start end` so a row is cut only when all
77
+ // three match — a re-fetch that changes the object leaves the new row alone.
78
+ export const DENIED_ROWS = new Set([
79
+ "/r/IsA /c/en/beta /c/en/programming_language",
80
+ "/r/IsA /c/en/psi /c/en/software",
81
+ "/r/Antonym /c/en/letter /c/en/email",
82
+ ]);
83
+
68
84
  /** Why this row is noise, or null to keep it. Pure function of the row shape. */
69
85
  export function cutReason(row) {
86
+ if (DENIED_ROWS.has(`${row.rel} ${row.start} ${row.end}`)) return "denied-row";
70
87
  const s = bareTerm(row.start);
71
88
  const e = bareTerm(row.end);
72
89
  for (const t of [s, e]) {