Polycode projects · pure JS · no LLM · offline by default · $0

tmct  

Ask tmct a question and you get an answer you can check against an open graph. It runs deterministically, offline, in your browser. When it doesn't know, it says so. Nothing calls a model, and it costs nothing to run.

$ npm install -g @polycode-projects/the-mechanical-code-talker

The mudiii demo: a fox and goblins meeting in a 3D town square.

nine easy pieces

the numbers

Every claim ships with its number

the map of the deck

What each demo demonstrates

Seven demos, twelve capabilities between them. A tick means the demo shows that capability. An eye means it is what the demo is for. Nothing in this table calls a model: every tick is deterministic code you can read in the repository, and each demo's own about page says which files back it.

Which capability each demo page demonstrates, and which one it focuses on
Demo page Natural language Class hierarchy RDF/OWL triples Provenance & trust Graph retrieval Fact synthesis Search backed Classical planning Multi-agent Partial knowledge Fact-driven scene 3D rendering
chat.html its focus yes yes yes its focus its focus yes
news.html yes yes yes yes its focus
sprites.html its focus yes
ledger.html yes yes its focus its focus yes yes
plan.html yes yes its focus yes
mudiii.html yes yes yes yes its focus its focus yes its focus
adventure.html yes yes yes its focus

demonstrates it it is what the demo is for

The real engine, in the page

This is the same chat engine as the CLI, running entirely in the browser: teach it something, ask it something, or run a scripted demo, and it answers from facts it can point at on the graph. The shot here is a real exchange with it; open the full page to try your own.

open chat.html → (opens in a new tab)
tmct chat page: the question 'what is a dog' answered with three facts, each naming its corpus source (opens in a new tab)
Plate I · chat.html

One question, more than one fact

Some questions do not answer from a single fact. Teach a rule with two branches, rule one branch out, and /prove works the other by cases. This is a real exchange with the engine, run before this page was built, not a mockup.

tmct> every pet is a cat or a dog
noted — remembered 4 facts: cat-or-dog rdf:type class; cat-or-dog owl:unionOf cat; cat-or-dog owl:unionOf dog; pet rdfs:subClassOf cat-or-dog
tmct> rex is a pet
noted — remembered: rex is a pet
tmct> rex is not a cat
noted — remembered: no rex is a cat
/prove is rex a dog
yes — you told me: cat-or-dog is either cat (source: ace:chat:<session-id>@<timestamp>); you told me: rex is a pet (source: teach:chat:<session-id>@<timestamp>); you told me: rex is not a cat (source: teach:chat:<session-id>@<timestamp>); you told me: pet is a kind of cat-or-dog (source: ace:chat:<session-id>@<timestamp>); you told me: cat-or-dog is either dog (source: ace:chat:<session-id>@<timestamp>); in every case — a cat or a dog — rex is a dog.

More on how /classify and /prove work on chat-about.html.

A feed built only from what grounds

Click start and it polls real sources on a timer: a Wikimedia featured-articles feed, Hacker News, USGS earthquakes, and two more you can switch on. Every source it can ground turns into a paragraph of grounded sentences with links back to where they came from. Every term it can't ground yet goes on a ranked list instead.

open news.html → (opens in a new tab)
tmct news page: the dashboard tiles, the ranked ungrounded-terms panel, and the newest feed items (opens in a new tab)
Plate II · news.html

The feed runs through the same /news command

news.html is a dashboard, but the feed underneath it is one chat command. Type /news poll in any chat session and it runs the same poll-ground-rank loop, then reports it as text. This is a real exchange with the engine, run before this page was built, not a mockup.

/news
no news items yet — poll a source or teach something first.

Goal (inferred): Surface or work the news feed built over this graph.

/news poll
polled 1 source: 2 new items, 1 fact stored, 0 derived, 0 failures, 0 evicted.

Goal (inferred): Surface or work the news feed built over this graph.

/news rank
1. wombat (2) — unknown word
2. marsupial (1) — unknown word
3. nocturnal (1) — unknown word

Goal (inferred): Surface or work the news feed built over this graph.

More on how polling, grounding and ranking work on news-about.html.

The sprite library

Every shape the sprite library can draw, mapped to the real ontology class it belongs to. A term without a sprite of its own borrows its nearest ancestor's, so a poodle draws as a dog.

poodledoganimal doganimal spiderarachnidanimal flyinsectanimal
open sprites.html → (opens in a new tab)
tmct sprite library page: sprite shapes mapped to the ontology classes they belong to (opens in a new tab)
Plate III · sprites.html

Grounding a question from Wikipedia

A term the graph has never seen gets an honest miss. Ask it to research the topic and it fetches Simple English Wikipedia, reads the article's opening passage, and stores what it can ground as a fact, cited back to the page it read. This is a real exchange with the engine, run before this page was built, not a mockup.

tmct> what is an aardvark
I don't know "aardvark" yet — teach me directly, e.g. "aardvark is an <thing>" or "remember aardvark is an <thing>".
tmct> research aardvark
aardvark — The aardvark is a mammal from Africa; its name means "earth pig" in the language Afrikaans. It is the only living member in its order, though some fossil genera have been found (source: research article "Aardvark", Simple English Wikipedia, CC BY-SA 4.0 — https://simple.wikipedia.org/wiki/Aardvark?oldid=10916573)
stored 1 fact from "Aardvark". queued 3 linked topics: Africa, Afrikaans, Binomial nomenclature — "research next" fetches the next one (the page's play button does this for you).
tmct> what is an aardvark
i learned: aardvark is a kind of mammal (source: research:aardvark@0)

More on where a live Wikipedia read's trust tier comes from on chat-about.html.

Facts as RDF/OWL triples

Browse the taught graph. Every fact shows its provenance and its trust tier, and every term inside a fact is a link, so you can drill from any answer down to what it rests on. A chat dock lets you teach and ask against the same store.

open ledger.html → (opens in a new tab)
tmct memory ledger page: fact counts, a predicate breakdown, and the taught facts for the term 'peg' (opens in a new tab)
Plate IV · ledger.html

Classical AI Planning

Teach it a game's rules, then ask it to solve one. The planner replays every move it made, one by one, and a side panel shows the plan as a PDDL artifact and as OWL facts, so you can read exactly what it searched over. Change the disk count and it solves again, live.

open plan.html → (opens in a new tab)
tmct plan page: a Tower of Hanoi board mid-solve, with the move list and the PDDL plan artifact alongside (opens in a new tab)
Plate V · plan.html
Live demo: the real engine, running right now in your browser
tmct>
wink-nlp: loading…
This box asks a real question of a small fixture repo's code graph (examples/mini-webapp) using the exact same query engine the CLI ships. It runs live, client-side. Nothing is precomputed on a server; this static site has no backend to run it on. The same question against a real repo, from a terminal:

      

Multiple competing agents

This page runs the same deterministic planner as the other game demos, rendered in three dimensions. A fox and a handful of goblins each plan their own next move across a shared town square. Every one of them only knows what it has personally seen, so a goblin can walk straight into a fox it hasn't spotted. Drop food on the square and watch it change what the goblins do next. A fourth scenario swaps the chase for a logic puzzle: the classic wolf-goat-cabbage river crossing, played here with a fox, solved by the same search, its "may not be left alone" rule derived from the cast's own drives rather than authored twice. No LLM plans any of it.

open mudiii.html → (opens in a new tab)
tmct mudiii page: a fox and goblins moving through a 3D town square, each reacting only to what it has personally seen (opens in a new tab)
Plate VI · mudiii.html

A room drawn from the text

Ashcombe Hall is a small manor built from its own facts. The room view shows exactly what the text says is there, and nothing else. An auto-player explores the house, infers its own goal, and plays toward it with the same planner the other pages use.

open adventure.html → (opens in a new tab)
tmct adventure page: a room of Ashcombe Hall drawn from its facts, with the map and satchel alongside (opens in a new tab)
Plate VII · adventure.html

Run the chat yourself

npm install -g @polycode-projects/the-mechanical-code-talker

Point it at a repo's graph and ask about the code. This runs against examples/mini-webapp, which ships in the repo:

tmct> what talks to store.mjs?
src/handlers/tasks.mjs and src/handlers/users.mjs.
tmct> which modules do not import logger?
…
tmct> /exit

Or start with nothing. tmct bootstraps an empty memory and remembers what you tell it. Use tmct chat --repo /path/to/repo to point it at your own.

tmct init         # scaffold .tmct/, tmct.toml, seed the default persona + provenance
tmct viz          # write the ledger page — see the link below
tmct syllogise    # offline: pre-derive entailed facts (a maintenance job)

Facts don't have to come entirely from teaching. tmct's own corpus already knows a dog can bark; teach it that Rover is a dog and it reasons the rest, citing both facts it chained through:

tmct> Rover is a dog.
noted — remembered 1 fact: rover rdf:type dog

Goal (inferred): Teach/remember a new fact.

Canonical: rover rdf:type dog — fact("rover", "rdf:type", "dog")

tmct> Does Rover bark?
yes — dog can bark (source: corpus:human /r/CapableOf) — via: rover is a dog (source: ace:chat:<session-id>@<timestamp>)

A chatbot in the ELIZA/PARRY lineage, obsessed with software the way PARRY was obsessed with the mafia. Interpretation is mechanical and memory is an OWL-labelled graph on disk. It starts stocked with an everyday vocabulary. Point it at a codebase and it reasons over that too.

Use it as a library

The chat surface is a function. Feed it lines, read the answers, and the same grounding and provenance rules apply.

import { Readable } from "node:stream";
import { runChat } from "@polycode-projects/the-mechanical-code-talker";

await runChat({
  repoPath: "./my-repo",
  input: Readable.from([
    "ahab is the father of john\n",
    "who is the father of john\n",
    "/exit\n",
  ]),
  output: process.stdout,
});

Full feature list, the detailed-answer pipeline, and the rest of the library API in the README.

the project family

Polycode projects

tmct grew out of two sibling Polycode projects, and the wider family is taking up the tmct library in return.