@polycode-projects/the-mechanical-code-talker 0.4.0 → 0.6.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.
- package/README.md +64 -28
- package/ROADMAP.md +6 -6
- package/bin/tmct.mjs +56 -0
- package/corpus/README.md +77 -5
- package/corpus/conceptnet/README.md +54 -2
- package/corpus/conceptnet/quality-filter.mjs +95 -0
- package/corpus/conceptnet/slice.jsonl +0 -378
- package/corpus/seon/LICENSE-NOTICE +37 -0
- package/corpus/seon/README.md +121 -0
- package/corpus/seon/concepts.jsonl +238 -0
- package/corpus/seon/definitions.jsonl +288 -0
- package/corpus/tier2/aws.jsonl +39 -0
- package/corpus/tier2/generate.mjs +253 -0
- package/corpus/tier2/java.jsonl +31 -0
- package/corpus/tier2/manifest.json +48 -0
- package/corpus/tier2/python.jsonl +30 -0
- package/data/templates/grammar-rules.toml +18 -10
- package/data/templates/responses.jsonl +2 -0
- package/package.json +10 -2
- package/src/ask-vocab.mjs +19 -1
- package/src/ask.mjs +90 -6
- package/src/chat.mjs +647 -60
- package/src/codegraph.mjs +28 -5
- package/src/conformance.mjs +166 -0
- package/src/corpus/conceptnet.mjs +24 -6
- package/src/grammar/lexicon-core.json +8 -0
- package/src/memory/inspect.mjs +25 -0
- package/src/server.mjs +88 -7
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// corpus/tier2/generate.mjs — the TIER-2 specialised-corpus generator + manifest
|
|
3
|
+
// writer. NOT part of the product path — a maintainer tool. Offline, $0.
|
|
4
|
+
//
|
|
5
|
+
// Tier-2 corpuses are LANGUAGE- or DOMAIN-specific fact sets (aws, python,
|
|
6
|
+
// java, …) that tmct fetches/generates into `.tmct/` at init time so it can
|
|
7
|
+
// "expand into a concept for an applicable codebase". They are NOT shipped in
|
|
8
|
+
// the npm package the way the tier-1 ConceptNet slice is — they are opt-in,
|
|
9
|
+
// selected per repo. See ../README.md for the full tier-1/2/3 policy.
|
|
10
|
+
//
|
|
11
|
+
// Every tier-2 corpus is written in the EXACT tier-1 fact shape
|
|
12
|
+
// (corpus/conceptnet/slice.jsonl): one JSON object per line,
|
|
13
|
+
// {"start":"/c/en/<term>","rel":"/r/<Rel>","end":"/c/en/<concept>","weight":N,"surfaceText":"…"}
|
|
14
|
+
// with `rel` drawn ONLY from the mapped relations in
|
|
15
|
+
// src/corpus/conceptnet-map.toml, so a tier-2 file loads through the very same
|
|
16
|
+
// loadSlice()/toFacts() path as the tier-1 slice (this file's --verify proves
|
|
17
|
+
// it). The Wave-2 tier-2 SEEDER (see ../README.md) is what stamps the right
|
|
18
|
+
// provenance (`corpus:tier2:<id> /r/…`) instead of the conceptnet default.
|
|
19
|
+
//
|
|
20
|
+
// node corpus/tier2/generate.mjs # (re)write every <id>.jsonl + manifest.json
|
|
21
|
+
// node corpus/tier2/generate.mjs --verify # generate + assert each file loads & seeds cleanly
|
|
22
|
+
//
|
|
23
|
+
// To ADD a specialised corpus: add an entry to CORPUSES below (a list of
|
|
24
|
+
// [subject, relation, concept] triples, optionally [.., surfaceText]) and
|
|
25
|
+
// re-run. Curated sets are authored here so they stay reviewable and diffable;
|
|
26
|
+
// a corpus too large to curate by hand is a `fetch` manifest entry instead
|
|
27
|
+
// (network, opt-in — see fetchCorpus() and ../README.md).
|
|
28
|
+
|
|
29
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
30
|
+
import { createHash } from "node:crypto";
|
|
31
|
+
import { fileURLToPath } from "node:url";
|
|
32
|
+
import { dirname, join } from "node:path";
|
|
33
|
+
|
|
34
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
|
|
36
|
+
// A curated triple is [subject, rel, concept] or [subject, rel, concept, weight].
|
|
37
|
+
// `rel` MUST be a mapped (ace != "none") relation in conceptnet-map.toml so the
|
|
38
|
+
// fact actually seeds. Terms are lowercase snake_case; the loader's termText()
|
|
39
|
+
// turns "/c/en/hash_table" into "hash table". Keep terms <= 3 words (the tier-1
|
|
40
|
+
// quality-filter rule) — curated data is clean by construction.
|
|
41
|
+
export const CORPUSES = {
|
|
42
|
+
aws: {
|
|
43
|
+
kind: "domain",
|
|
44
|
+
description: "Amazon Web Services core services and primitives (S3, Lambda, DynamoDB, EC2, IAM, SQS) mapped to general cloud/CS concepts.",
|
|
45
|
+
facts: [
|
|
46
|
+
["aws", "/r/IsA", "cloud_platform"],
|
|
47
|
+
["aws", "/r/IsA", "cloud"],
|
|
48
|
+
["aws", "/r/CapableOf", "host_applications"],
|
|
49
|
+
// S3
|
|
50
|
+
["s3", "/r/IsA", "object_storage"],
|
|
51
|
+
["s3", "/r/IsA", "storage_service"],
|
|
52
|
+
["s3", "/r/PartOf", "aws"],
|
|
53
|
+
["s3", "/r/HasA", "bucket"],
|
|
54
|
+
["s3", "/r/UsedFor", "storing_files"],
|
|
55
|
+
["s3", "/r/CapableOf", "store_objects"],
|
|
56
|
+
["bucket", "/r/IsA", "container"],
|
|
57
|
+
["bucket", "/r/PartOf", "s3"],
|
|
58
|
+
["bucket", "/r/UsedFor", "storing_objects"],
|
|
59
|
+
// Lambda
|
|
60
|
+
["lambda", "/r/IsA", "compute_service"],
|
|
61
|
+
["lambda", "/r/IsA", "function"],
|
|
62
|
+
["lambda", "/r/PartOf", "aws"],
|
|
63
|
+
["lambda", "/r/UsedFor", "running_code"],
|
|
64
|
+
["lambda", "/r/CapableOf", "run_code"],
|
|
65
|
+
["lambda", "/r/HasProperty", "serverless"],
|
|
66
|
+
// DynamoDB
|
|
67
|
+
["dynamodb", "/r/IsA", "database"],
|
|
68
|
+
["dynamodb", "/r/IsA", "nosql_database"],
|
|
69
|
+
["dynamodb", "/r/PartOf", "aws"],
|
|
70
|
+
["dynamodb", "/r/HasA", "table"],
|
|
71
|
+
["dynamodb", "/r/UsedFor", "storing_data"],
|
|
72
|
+
["dynamodb", "/r/HasProperty", "managed"],
|
|
73
|
+
// EC2
|
|
74
|
+
["ec2", "/r/IsA", "compute_service"],
|
|
75
|
+
["ec2", "/r/IsA", "virtual_machine"],
|
|
76
|
+
["ec2", "/r/PartOf", "aws"],
|
|
77
|
+
["ec2", "/r/HasA", "instance"],
|
|
78
|
+
["ec2", "/r/UsedFor", "running_servers"],
|
|
79
|
+
// IAM
|
|
80
|
+
["iam", "/r/IsA", "access_control"],
|
|
81
|
+
["iam", "/r/PartOf", "aws"],
|
|
82
|
+
["iam", "/r/UsedFor", "managing_permissions"],
|
|
83
|
+
["iam", "/r/HasA", "role"],
|
|
84
|
+
["iam", "/r/HasA", "policy"],
|
|
85
|
+
// SQS + queue
|
|
86
|
+
["sqs", "/r/IsA", "message_queue"],
|
|
87
|
+
["sqs", "/r/IsA", "queue"],
|
|
88
|
+
["sqs", "/r/PartOf", "aws"],
|
|
89
|
+
["sqs", "/r/UsedFor", "decoupling_services"],
|
|
90
|
+
["queue", "/r/IsA", "data_structure"],
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
python: {
|
|
95
|
+
kind: "language",
|
|
96
|
+
description: "Python language constructs and stdlib types mapped to the shared CS concept vocabulary (list->array, dict->hash table, …).",
|
|
97
|
+
facts: [
|
|
98
|
+
["python", "/r/IsA", "programming_language"],
|
|
99
|
+
["python", "/r/HasProperty", "interpreted"],
|
|
100
|
+
["python", "/r/HasProperty", "dynamically_typed"],
|
|
101
|
+
["python", "/r/UsedFor", "scripting"],
|
|
102
|
+
// built-in types → shared concepts
|
|
103
|
+
["list", "/r/IsA", "array"],
|
|
104
|
+
["list", "/r/IsA", "sequence"],
|
|
105
|
+
["list", "/r/IsA", "data_structure"],
|
|
106
|
+
["dict", "/r/IsA", "hash_table"],
|
|
107
|
+
["dict", "/r/IsA", "dictionary"],
|
|
108
|
+
["dict", "/r/IsA", "mapping"],
|
|
109
|
+
["tuple", "/r/IsA", "sequence"],
|
|
110
|
+
["tuple", "/r/HasProperty", "immutable"],
|
|
111
|
+
["set", "/r/IsA", "collection"],
|
|
112
|
+
["set", "/r/HasProperty", "unordered"],
|
|
113
|
+
["str", "/r/IsA", "string"],
|
|
114
|
+
// language constructs
|
|
115
|
+
["decorator", "/r/IsA", "function"],
|
|
116
|
+
["decorator", "/r/UsedFor", "modifying_functions"],
|
|
117
|
+
["generator", "/r/IsA", "iterator"],
|
|
118
|
+
["generator", "/r/UsedFor", "lazy_evaluation"],
|
|
119
|
+
["comprehension", "/r/IsA", "expression"],
|
|
120
|
+
["comprehension", "/r/UsedFor", "building_collections"],
|
|
121
|
+
["exception", "/r/IsA", "error"],
|
|
122
|
+
["module", "/r/IsA", "file"],
|
|
123
|
+
["package", "/r/IsA", "module"],
|
|
124
|
+
["method", "/r/IsA", "function"],
|
|
125
|
+
// tooling / runtime
|
|
126
|
+
["pip", "/r/IsA", "package_manager"],
|
|
127
|
+
["pip", "/r/UsedFor", "installing_packages"],
|
|
128
|
+
["gil", "/r/IsA", "lock"],
|
|
129
|
+
["gil", "/r/PartOf", "interpreter"],
|
|
130
|
+
["cpython", "/r/IsA", "interpreter"],
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
java: {
|
|
135
|
+
kind: "language",
|
|
136
|
+
description: "Java language and JVM constructs mapped to the shared CS concept vocabulary (ArrayList->list, HashMap->hash table, …).",
|
|
137
|
+
facts: [
|
|
138
|
+
["java", "/r/IsA", "programming_language"],
|
|
139
|
+
["java", "/r/HasProperty", "compiled"],
|
|
140
|
+
["java", "/r/HasProperty", "statically_typed"],
|
|
141
|
+
["java", "/r/UsedFor", "building_applications"],
|
|
142
|
+
// types → shared concepts
|
|
143
|
+
["arraylist", "/r/IsA", "list"],
|
|
144
|
+
["arraylist", "/r/IsA", "data_structure"],
|
|
145
|
+
["hashmap", "/r/IsA", "hash_table"],
|
|
146
|
+
["hashmap", "/r/IsA", "dictionary"],
|
|
147
|
+
["hashmap", "/r/IsA", "map"],
|
|
148
|
+
["interface", "/r/IsA", "type"],
|
|
149
|
+
["interface", "/r/IsA", "contract"],
|
|
150
|
+
["class", "/r/IsA", "type"],
|
|
151
|
+
["object", "/r/IsA", "instance"],
|
|
152
|
+
// JVM / runtime
|
|
153
|
+
["jvm", "/r/IsA", "virtual_machine"],
|
|
154
|
+
["jvm", "/r/UsedFor", "running_bytecode"],
|
|
155
|
+
["jvm", "/r/CapableOf", "execute_bytecode"],
|
|
156
|
+
["bytecode", "/r/IsA", "code"],
|
|
157
|
+
["garbage_collector", "/r/PartOf", "jvm"],
|
|
158
|
+
["garbage_collector", "/r/UsedFor", "freeing_memory"],
|
|
159
|
+
// packaging / tooling
|
|
160
|
+
["jar", "/r/IsA", "archive"],
|
|
161
|
+
["jar", "/r/IsA", "file"],
|
|
162
|
+
["jar", "/r/UsedFor", "packaging_classes"],
|
|
163
|
+
["maven", "/r/IsA", "build_tool"],
|
|
164
|
+
["maven", "/r/IsA", "package_manager"],
|
|
165
|
+
["gradle", "/r/IsA", "build_tool"],
|
|
166
|
+
// language features
|
|
167
|
+
["thread", "/r/IsA", "process"],
|
|
168
|
+
["thread", "/r/UsedFor", "concurrency"],
|
|
169
|
+
["generics", "/r/UsedFor", "type_safety"],
|
|
170
|
+
["annotation", "/r/IsA", "metadata"],
|
|
171
|
+
["exception", "/r/IsA", "error"],
|
|
172
|
+
["method", "/r/IsA", "function"],
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const conceptUri = (term) => `/c/en/${term}`;
|
|
178
|
+
const humanize = (term) => term.replace(/_/g, " ");
|
|
179
|
+
|
|
180
|
+
/** One curated triple → a tier-1-shaped slice row. */
|
|
181
|
+
export function toRow([subject, rel, concept, weight = 1]) {
|
|
182
|
+
return {
|
|
183
|
+
start: conceptUri(subject),
|
|
184
|
+
rel,
|
|
185
|
+
end: conceptUri(concept),
|
|
186
|
+
weight,
|
|
187
|
+
surfaceText: `[[${humanize(subject)}]] ${rel.replace("/r/", "")} [[${humanize(concept)}]]`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Curated corpus id → its JSONL text (deterministic order = authored order). */
|
|
192
|
+
export function corpusJsonl(id) {
|
|
193
|
+
return CORPUSES[id].facts.map((f) => JSON.stringify(toRow(f))).join("\n") + "\n";
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const sha256 = (text) => createHash("sha256").update(text).digest("hex");
|
|
197
|
+
|
|
198
|
+
// ---- network-fetch path (opt-in, offline-by-default) -----------------------
|
|
199
|
+
// A tier-2 corpus too large to curate by hand is declared in the manifest with
|
|
200
|
+
// { "source": { "kind": "fetch", "url": "...", "sha256": "..." } } and pulled by
|
|
201
|
+
// a Wave-2 fetch step. This helper is the reference implementation — it is NEVER
|
|
202
|
+
// called without an explicit --allow-network flag (the product default is $0,
|
|
203
|
+
// offline). No sample corpus uses it; the three samples are all `curated`.
|
|
204
|
+
export async function fetchCorpus(url, expectedSha) {
|
|
205
|
+
const res = await fetch(url, { headers: { accept: "application/x-ndjson,application/jsonl" } });
|
|
206
|
+
if (!res.ok) throw new Error(`fetch ${url}: HTTP ${res.status}`);
|
|
207
|
+
const text = await res.text();
|
|
208
|
+
const got = sha256(text);
|
|
209
|
+
if (expectedSha && got !== expectedSha) throw new Error(`checksum mismatch for ${url}: ${got} != ${expectedSha}`);
|
|
210
|
+
return text;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function main() {
|
|
214
|
+
const verify = process.argv.includes("--verify");
|
|
215
|
+
const manifest = { version: 1, generated: "by corpus/tier2/generate.mjs", corpuses: [] };
|
|
216
|
+
|
|
217
|
+
for (const [id, spec] of Object.entries(CORPUSES)) {
|
|
218
|
+
const text = corpusJsonl(id);
|
|
219
|
+
await writeFile(join(HERE, `${id}.jsonl`), text);
|
|
220
|
+
manifest.corpuses.push({
|
|
221
|
+
id,
|
|
222
|
+
kind: spec.kind,
|
|
223
|
+
description: spec.description,
|
|
224
|
+
source: { kind: "curated", tool: "corpus/tier2/generate.mjs" },
|
|
225
|
+
file: `${id}.jsonl`,
|
|
226
|
+
facts: spec.facts.length,
|
|
227
|
+
bytes: Buffer.byteLength(text),
|
|
228
|
+
sha256: sha256(text),
|
|
229
|
+
license: "MPL-2.0",
|
|
230
|
+
});
|
|
231
|
+
console.error(` ${id}: ${spec.facts.length} facts, ${Buffer.byteLength(text)} bytes`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const manifestText = JSON.stringify(manifest, null, 2) + "\n";
|
|
235
|
+
await writeFile(join(HERE, "manifest.json"), manifestText);
|
|
236
|
+
console.error(`wrote manifest.json (${manifest.corpuses.length} corpuses)`);
|
|
237
|
+
|
|
238
|
+
if (verify) {
|
|
239
|
+
const { loadSlice, loadMap, toFacts } = await import("../../src/corpus/conceptnet.mjs");
|
|
240
|
+
const map = await loadMap();
|
|
241
|
+
for (const c of manifest.corpuses) {
|
|
242
|
+
const assertions = await loadSlice(join(HERE, c.file));
|
|
243
|
+
const facts = toFacts(assertions, map); // throws on any unmapped rel
|
|
244
|
+
if (assertions.length !== c.facts) throw new Error(`${c.id}: loadSlice count ${assertions.length} != ${c.facts}`);
|
|
245
|
+
if (facts.length !== c.facts) throw new Error(`${c.id}: ${c.facts - facts.length} fact(s) did not seed (ace=none rel?)`);
|
|
246
|
+
console.error(` verify ${c.id}: ${assertions.length} assertions load, all ${facts.length} seed cleanly`);
|
|
247
|
+
}
|
|
248
|
+
console.error("verify: OK — every tier-2 corpus loads and seeds through the tier-1 path");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const isMain = process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href;
|
|
253
|
+
if (isMain) await main();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{"start":"/c/en/java","rel":"/r/IsA","end":"/c/en/programming_language","weight":1,"surfaceText":"[[java]] IsA [[programming language]]"}
|
|
2
|
+
{"start":"/c/en/java","rel":"/r/HasProperty","end":"/c/en/compiled","weight":1,"surfaceText":"[[java]] HasProperty [[compiled]]"}
|
|
3
|
+
{"start":"/c/en/java","rel":"/r/HasProperty","end":"/c/en/statically_typed","weight":1,"surfaceText":"[[java]] HasProperty [[statically typed]]"}
|
|
4
|
+
{"start":"/c/en/java","rel":"/r/UsedFor","end":"/c/en/building_applications","weight":1,"surfaceText":"[[java]] UsedFor [[building applications]]"}
|
|
5
|
+
{"start":"/c/en/arraylist","rel":"/r/IsA","end":"/c/en/list","weight":1,"surfaceText":"[[arraylist]] IsA [[list]]"}
|
|
6
|
+
{"start":"/c/en/arraylist","rel":"/r/IsA","end":"/c/en/data_structure","weight":1,"surfaceText":"[[arraylist]] IsA [[data structure]]"}
|
|
7
|
+
{"start":"/c/en/hashmap","rel":"/r/IsA","end":"/c/en/hash_table","weight":1,"surfaceText":"[[hashmap]] IsA [[hash table]]"}
|
|
8
|
+
{"start":"/c/en/hashmap","rel":"/r/IsA","end":"/c/en/dictionary","weight":1,"surfaceText":"[[hashmap]] IsA [[dictionary]]"}
|
|
9
|
+
{"start":"/c/en/hashmap","rel":"/r/IsA","end":"/c/en/map","weight":1,"surfaceText":"[[hashmap]] IsA [[map]]"}
|
|
10
|
+
{"start":"/c/en/interface","rel":"/r/IsA","end":"/c/en/type","weight":1,"surfaceText":"[[interface]] IsA [[type]]"}
|
|
11
|
+
{"start":"/c/en/interface","rel":"/r/IsA","end":"/c/en/contract","weight":1,"surfaceText":"[[interface]] IsA [[contract]]"}
|
|
12
|
+
{"start":"/c/en/class","rel":"/r/IsA","end":"/c/en/type","weight":1,"surfaceText":"[[class]] IsA [[type]]"}
|
|
13
|
+
{"start":"/c/en/object","rel":"/r/IsA","end":"/c/en/instance","weight":1,"surfaceText":"[[object]] IsA [[instance]]"}
|
|
14
|
+
{"start":"/c/en/jvm","rel":"/r/IsA","end":"/c/en/virtual_machine","weight":1,"surfaceText":"[[jvm]] IsA [[virtual machine]]"}
|
|
15
|
+
{"start":"/c/en/jvm","rel":"/r/UsedFor","end":"/c/en/running_bytecode","weight":1,"surfaceText":"[[jvm]] UsedFor [[running bytecode]]"}
|
|
16
|
+
{"start":"/c/en/jvm","rel":"/r/CapableOf","end":"/c/en/execute_bytecode","weight":1,"surfaceText":"[[jvm]] CapableOf [[execute bytecode]]"}
|
|
17
|
+
{"start":"/c/en/bytecode","rel":"/r/IsA","end":"/c/en/code","weight":1,"surfaceText":"[[bytecode]] IsA [[code]]"}
|
|
18
|
+
{"start":"/c/en/garbage_collector","rel":"/r/PartOf","end":"/c/en/jvm","weight":1,"surfaceText":"[[garbage collector]] PartOf [[jvm]]"}
|
|
19
|
+
{"start":"/c/en/garbage_collector","rel":"/r/UsedFor","end":"/c/en/freeing_memory","weight":1,"surfaceText":"[[garbage collector]] UsedFor [[freeing memory]]"}
|
|
20
|
+
{"start":"/c/en/jar","rel":"/r/IsA","end":"/c/en/archive","weight":1,"surfaceText":"[[jar]] IsA [[archive]]"}
|
|
21
|
+
{"start":"/c/en/jar","rel":"/r/IsA","end":"/c/en/file","weight":1,"surfaceText":"[[jar]] IsA [[file]]"}
|
|
22
|
+
{"start":"/c/en/jar","rel":"/r/UsedFor","end":"/c/en/packaging_classes","weight":1,"surfaceText":"[[jar]] UsedFor [[packaging classes]]"}
|
|
23
|
+
{"start":"/c/en/maven","rel":"/r/IsA","end":"/c/en/build_tool","weight":1,"surfaceText":"[[maven]] IsA [[build tool]]"}
|
|
24
|
+
{"start":"/c/en/maven","rel":"/r/IsA","end":"/c/en/package_manager","weight":1,"surfaceText":"[[maven]] IsA [[package manager]]"}
|
|
25
|
+
{"start":"/c/en/gradle","rel":"/r/IsA","end":"/c/en/build_tool","weight":1,"surfaceText":"[[gradle]] IsA [[build tool]]"}
|
|
26
|
+
{"start":"/c/en/thread","rel":"/r/IsA","end":"/c/en/process","weight":1,"surfaceText":"[[thread]] IsA [[process]]"}
|
|
27
|
+
{"start":"/c/en/thread","rel":"/r/UsedFor","end":"/c/en/concurrency","weight":1,"surfaceText":"[[thread]] UsedFor [[concurrency]]"}
|
|
28
|
+
{"start":"/c/en/generics","rel":"/r/UsedFor","end":"/c/en/type_safety","weight":1,"surfaceText":"[[generics]] UsedFor [[type safety]]"}
|
|
29
|
+
{"start":"/c/en/annotation","rel":"/r/IsA","end":"/c/en/metadata","weight":1,"surfaceText":"[[annotation]] IsA [[metadata]]"}
|
|
30
|
+
{"start":"/c/en/exception","rel":"/r/IsA","end":"/c/en/error","weight":1,"surfaceText":"[[exception]] IsA [[error]]"}
|
|
31
|
+
{"start":"/c/en/method","rel":"/r/IsA","end":"/c/en/function","weight":1,"surfaceText":"[[method]] IsA [[function]]"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"generated": "by corpus/tier2/generate.mjs",
|
|
4
|
+
"corpuses": [
|
|
5
|
+
{
|
|
6
|
+
"id": "aws",
|
|
7
|
+
"kind": "domain",
|
|
8
|
+
"description": "Amazon Web Services core services and primitives (S3, Lambda, DynamoDB, EC2, IAM, SQS) mapped to general cloud/CS concepts.",
|
|
9
|
+
"source": {
|
|
10
|
+
"kind": "curated",
|
|
11
|
+
"tool": "corpus/tier2/generate.mjs"
|
|
12
|
+
},
|
|
13
|
+
"file": "aws.jsonl",
|
|
14
|
+
"facts": 39,
|
|
15
|
+
"bytes": 4802,
|
|
16
|
+
"sha256": "7ab3e656bc4bc717be3c50d97af030e8592d6597cde182b15390a1dfaca9755a",
|
|
17
|
+
"license": "MPL-2.0"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "python",
|
|
21
|
+
"kind": "language",
|
|
22
|
+
"description": "Python language constructs and stdlib types mapped to the shared CS concept vocabulary (list->array, dict->hash table, …).",
|
|
23
|
+
"source": {
|
|
24
|
+
"kind": "curated",
|
|
25
|
+
"tool": "corpus/tier2/generate.mjs"
|
|
26
|
+
},
|
|
27
|
+
"file": "python.jsonl",
|
|
28
|
+
"facts": 30,
|
|
29
|
+
"bytes": 3794,
|
|
30
|
+
"sha256": "009245d024357bc4285e967fba486e32349ccec8fbe2796ba13011cb2be4c19c",
|
|
31
|
+
"license": "MPL-2.0"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "java",
|
|
35
|
+
"kind": "language",
|
|
36
|
+
"description": "Java language and JVM constructs mapped to the shared CS concept vocabulary (ArrayList->list, HashMap->hash table, …).",
|
|
37
|
+
"source": {
|
|
38
|
+
"kind": "curated",
|
|
39
|
+
"tool": "corpus/tier2/generate.mjs"
|
|
40
|
+
},
|
|
41
|
+
"file": "java.jsonl",
|
|
42
|
+
"facts": 31,
|
|
43
|
+
"bytes": 3920,
|
|
44
|
+
"sha256": "d089426833c393f6f1574fe75c4ac94a1483ee80f72f79bd7fd32aaaa24a6e44",
|
|
45
|
+
"license": "MPL-2.0"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{"start":"/c/en/python","rel":"/r/IsA","end":"/c/en/programming_language","weight":1,"surfaceText":"[[python]] IsA [[programming language]]"}
|
|
2
|
+
{"start":"/c/en/python","rel":"/r/HasProperty","end":"/c/en/interpreted","weight":1,"surfaceText":"[[python]] HasProperty [[interpreted]]"}
|
|
3
|
+
{"start":"/c/en/python","rel":"/r/HasProperty","end":"/c/en/dynamically_typed","weight":1,"surfaceText":"[[python]] HasProperty [[dynamically typed]]"}
|
|
4
|
+
{"start":"/c/en/python","rel":"/r/UsedFor","end":"/c/en/scripting","weight":1,"surfaceText":"[[python]] UsedFor [[scripting]]"}
|
|
5
|
+
{"start":"/c/en/list","rel":"/r/IsA","end":"/c/en/array","weight":1,"surfaceText":"[[list]] IsA [[array]]"}
|
|
6
|
+
{"start":"/c/en/list","rel":"/r/IsA","end":"/c/en/sequence","weight":1,"surfaceText":"[[list]] IsA [[sequence]]"}
|
|
7
|
+
{"start":"/c/en/list","rel":"/r/IsA","end":"/c/en/data_structure","weight":1,"surfaceText":"[[list]] IsA [[data structure]]"}
|
|
8
|
+
{"start":"/c/en/dict","rel":"/r/IsA","end":"/c/en/hash_table","weight":1,"surfaceText":"[[dict]] IsA [[hash table]]"}
|
|
9
|
+
{"start":"/c/en/dict","rel":"/r/IsA","end":"/c/en/dictionary","weight":1,"surfaceText":"[[dict]] IsA [[dictionary]]"}
|
|
10
|
+
{"start":"/c/en/dict","rel":"/r/IsA","end":"/c/en/mapping","weight":1,"surfaceText":"[[dict]] IsA [[mapping]]"}
|
|
11
|
+
{"start":"/c/en/tuple","rel":"/r/IsA","end":"/c/en/sequence","weight":1,"surfaceText":"[[tuple]] IsA [[sequence]]"}
|
|
12
|
+
{"start":"/c/en/tuple","rel":"/r/HasProperty","end":"/c/en/immutable","weight":1,"surfaceText":"[[tuple]] HasProperty [[immutable]]"}
|
|
13
|
+
{"start":"/c/en/set","rel":"/r/IsA","end":"/c/en/collection","weight":1,"surfaceText":"[[set]] IsA [[collection]]"}
|
|
14
|
+
{"start":"/c/en/set","rel":"/r/HasProperty","end":"/c/en/unordered","weight":1,"surfaceText":"[[set]] HasProperty [[unordered]]"}
|
|
15
|
+
{"start":"/c/en/str","rel":"/r/IsA","end":"/c/en/string","weight":1,"surfaceText":"[[str]] IsA [[string]]"}
|
|
16
|
+
{"start":"/c/en/decorator","rel":"/r/IsA","end":"/c/en/function","weight":1,"surfaceText":"[[decorator]] IsA [[function]]"}
|
|
17
|
+
{"start":"/c/en/decorator","rel":"/r/UsedFor","end":"/c/en/modifying_functions","weight":1,"surfaceText":"[[decorator]] UsedFor [[modifying functions]]"}
|
|
18
|
+
{"start":"/c/en/generator","rel":"/r/IsA","end":"/c/en/iterator","weight":1,"surfaceText":"[[generator]] IsA [[iterator]]"}
|
|
19
|
+
{"start":"/c/en/generator","rel":"/r/UsedFor","end":"/c/en/lazy_evaluation","weight":1,"surfaceText":"[[generator]] UsedFor [[lazy evaluation]]"}
|
|
20
|
+
{"start":"/c/en/comprehension","rel":"/r/IsA","end":"/c/en/expression","weight":1,"surfaceText":"[[comprehension]] IsA [[expression]]"}
|
|
21
|
+
{"start":"/c/en/comprehension","rel":"/r/UsedFor","end":"/c/en/building_collections","weight":1,"surfaceText":"[[comprehension]] UsedFor [[building collections]]"}
|
|
22
|
+
{"start":"/c/en/exception","rel":"/r/IsA","end":"/c/en/error","weight":1,"surfaceText":"[[exception]] IsA [[error]]"}
|
|
23
|
+
{"start":"/c/en/module","rel":"/r/IsA","end":"/c/en/file","weight":1,"surfaceText":"[[module]] IsA [[file]]"}
|
|
24
|
+
{"start":"/c/en/package","rel":"/r/IsA","end":"/c/en/module","weight":1,"surfaceText":"[[package]] IsA [[module]]"}
|
|
25
|
+
{"start":"/c/en/method","rel":"/r/IsA","end":"/c/en/function","weight":1,"surfaceText":"[[method]] IsA [[function]]"}
|
|
26
|
+
{"start":"/c/en/pip","rel":"/r/IsA","end":"/c/en/package_manager","weight":1,"surfaceText":"[[pip]] IsA [[package manager]]"}
|
|
27
|
+
{"start":"/c/en/pip","rel":"/r/UsedFor","end":"/c/en/installing_packages","weight":1,"surfaceText":"[[pip]] UsedFor [[installing packages]]"}
|
|
28
|
+
{"start":"/c/en/gil","rel":"/r/IsA","end":"/c/en/lock","weight":1,"surfaceText":"[[gil]] IsA [[lock]]"}
|
|
29
|
+
{"start":"/c/en/gil","rel":"/r/PartOf","end":"/c/en/interpreter","weight":1,"surfaceText":"[[gil]] PartOf [[interpreter]]"}
|
|
30
|
+
{"start":"/c/en/cpython","rel":"/r/IsA","end":"/c/en/interpreter","weight":1,"surfaceText":"[[cpython]] IsA [[interpreter]]"}
|
|
@@ -16,14 +16,22 @@
|
|
|
16
16
|
# chosen to commute so finish() is idempotent: finish(finish(x)) === finish(x).
|
|
17
17
|
#
|
|
18
18
|
# SEQUENCING (PLAN_RESPONSE_FINISHING.md, "one grammar rule per tuning cycle"):
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
19
|
+
# LIVE as of cycle 005: ARTICLE-SELECTION (cycle 4), plus the two SAFE defect
|
|
20
|
+
# fixes TERMINAL-PUNCTUATION and SUBJECT-VERB-AGREEMENT — each byte-stable when
|
|
21
|
+
# neutral, no product-voice change. CAPITALISATION and LIST are fully implemented
|
|
22
|
+
# and golden-tested IN ISOLATION but remain PARKED (enabled=false). The cycle-006
|
|
23
|
+
# judged A/B was assessed and DROPPED: `capitalise` rewrites the sentence-initial
|
|
24
|
+
# char, which regresses ~10 frozen v1 cases.jsonl whose case-sensitive answerMatch
|
|
25
|
+
# pins lowercase openers ("can't count", "no symbol matching", "assuming you meant",
|
|
26
|
+
# …) — the same sacred-case collision that reverted the voice-nit; and `list` has
|
|
27
|
+
# zero 3-item "X and Y and Z" targets in the judged set (a no-op). Deferred to a
|
|
28
|
+
# post-arc case-set refresh where the openers can be re-pinned deliberately. They
|
|
29
|
+
# rewrite established product bytes (tmct's
|
|
30
|
+
# lowercase openers and repeated "and" joins are an intentional VOICE, not a
|
|
31
|
+
# grammar defect), so activating them is a per-rule tuning-cycle decision with
|
|
32
|
+
# its own bench + showcase reconcile, not a blanket flip. `enabled=false` keeps
|
|
33
|
+
# them inert in finish(); the goldens force-enable each rule to prove its
|
|
34
|
+
# behaviour independent of the live flag.
|
|
27
35
|
|
|
28
36
|
# 1. Article selection — a/an by the following word's phonetic onset. The live
|
|
29
37
|
# defect this fixes: the assert echo "every module is a artifact" -> "an
|
|
@@ -48,7 +56,7 @@ vowel_sound_consonants = ["hour", "honest", "honour", "honor", "heir", "herb"]
|
|
|
48
56
|
[[rule]]
|
|
49
57
|
id = "subject-verb-agreement"
|
|
50
58
|
kind = "agreement"
|
|
51
|
-
enabled =
|
|
59
|
+
enabled = true # LIVE (cycle 005) — structure-driven existential agreement, byte-stable when neutral
|
|
52
60
|
registers = []
|
|
53
61
|
description = "existential copula agrees with the following count/plurality"
|
|
54
62
|
singular = ["is", "was", "has"]
|
|
@@ -83,7 +91,7 @@ separator = ", "
|
|
|
83
91
|
[[rule]]
|
|
84
92
|
id = "terminal-punctuation"
|
|
85
93
|
kind = "terminal"
|
|
86
|
-
enabled =
|
|
94
|
+
enabled = true # LIVE (cycle 005) — pure defect fix, narrowest blast radius (trailing doubled stop)
|
|
87
95
|
registers = []
|
|
88
96
|
description = "collapse a run of trailing sentence stops to a single stop"
|
|
89
97
|
stops = [".", "!", "?"]
|
|
@@ -62,6 +62,8 @@
|
|
|
62
62
|
{"id":"conversational-farewell","class":"conversational","register":"friendly","template":"Bye — flushing the session log. Come back with a question any time."}
|
|
63
63
|
{"id":"orientation-friendly","class":"orientation","register":"friendly","template":"I answer questions about THIS codebase's structure — imports, calls, definitions,\nhistory and counts. For example:\n which modules import walk.mjs\n what calls buildContextBundle\n how many classes are there\n/help for commands, /stats for an overview of the graph."}
|
|
64
64
|
{"id":"miss-no-previous-answer","class":"miss","register":"friendly","template":"No previous answer to expand yet — ask me a question first, then say \"why\" or \"say more\"."}
|
|
65
|
+
{"id":"conversational-greeting-empty","class":"conversational","register":"friendly","template":"Hi. There's no code graph loaded here yet — point me at your code with `--repo <path>` or run `tmct init`. Meanwhile I know some general vocabulary — try \"what is a cache\". /help for commands."}
|
|
66
|
+
{"id":"orientation-empty","class":"orientation","register":"friendly","template":"There's no code graph loaded here, so I can't answer structure questions (imports, calls, definitions) yet.\nPoint me at your code with `--repo <path>` or run `tmct init` to index this repo.\nI do know some general vocabulary — try \"what is a cache\". /help for commands, /memory for what I remember."}
|
|
65
67
|
{"id":"technical-density","class":"count","register":"technical","template":"{subject} carries {count} {noun} across {scope} — a concentration well above what a codebase of this size typically sustains ({provenance})."}
|
|
66
68
|
{"id":"technical-comparison","class":"count","register":"technical","template":"At {count} {noun}, {subject} sits {comparison} the comparable-project baseline, a divergence that reflects deliberate structure rather than measurement noise ({provenance})."}
|
|
67
69
|
{"id":"technical-superlative","class":"count","register":"technical","template":"No {noun} in {scope} is more {metric} than {subject}; it leads the next candidate by a clear margin of {count} ({provenance})."}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polycode-projects/the-mechanical-code-talker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The Mechanical Code Talker (tmct) — a tolerant, offline, $0 chat surface that guides you toward precision queries about a software repository. ELIZA/PARRY-style but domain-obsessed with code. No model calls; no codebase index of its own.",
|
|
@@ -48,7 +48,12 @@
|
|
|
48
48
|
"./relationKind": "./src/codegraph.mjs",
|
|
49
49
|
"./impactClosure": "./src/codegraph.mjs",
|
|
50
50
|
"./dispatchTool": "./src/server.mjs",
|
|
51
|
-
"./fetchEntities": "./src/source.mjs"
|
|
51
|
+
"./fetchEntities": "./src/source.mjs",
|
|
52
|
+
"./repository-interface": "./src/repository-interface.mjs",
|
|
53
|
+
"./graph-service": "./src/providers/graph-service.mjs",
|
|
54
|
+
"./providers/fixture": "./src/providers/fixture.mjs",
|
|
55
|
+
"./providers/bootstrap": "./src/providers/bootstrap.mjs",
|
|
56
|
+
"./conformance": "./src/conformance.mjs"
|
|
52
57
|
},
|
|
53
58
|
"files": [
|
|
54
59
|
"bin/",
|
|
@@ -72,6 +77,9 @@
|
|
|
72
77
|
"scripts": {
|
|
73
78
|
"test": "node --test \"test/**/*.test.mjs\"",
|
|
74
79
|
"chat": "node bin/tmct.mjs",
|
|
80
|
+
"chat:repo": "node bin/tmct.mjs chat --repo",
|
|
81
|
+
"example:mini": "node bin/tmct.mjs chat --repo examples/mini-webapp",
|
|
82
|
+
"example:polyglot": "node bin/tmct.mjs chat --repo examples/polyglot",
|
|
75
83
|
"chatbench:run": "node chatbench/run.mjs",
|
|
76
84
|
"chatbench:judge": "node chatbench/judge.mjs",
|
|
77
85
|
"audit": "npm audit --audit-level=high",
|
package/src/ask-vocab.mjs
CHANGED
|
@@ -529,7 +529,14 @@ export const AGGREGATE_TRIGGERS = Object.freeze([
|
|
|
529
529
|
// CONTENT_VOCAB and blocks the article's own noise-strip)
|
|
530
530
|
"how many", "how much", "how many of", "number of",
|
|
531
531
|
"total number of", "quantity of",
|
|
532
|
-
//
|
|
532
|
+
// "<measure> of <kind>" cardinality forms (widened net, cycle W2P): count = sum = total
|
|
533
|
+
// = tally = number of. The bare single words (sum/total/tally) stay CASCADE_SYNONYMS-
|
|
534
|
+
// mapped to "count" (identifier-fragment risk without the "of" anchor — see that table's
|
|
535
|
+
// note); the multi-word "of" forms are safe to promote to direct triggers because the
|
|
536
|
+
// trailing "of <kind>" pins them to a cardinality question, not a stray identifier.
|
|
537
|
+
"tally of", "sum of", "total of", "amount of",
|
|
538
|
+
// neutral / imperative (bare "tally"/"sum"/"total" stay CASCADE_SYNONYMS-mapped so the
|
|
539
|
+
// "tally the classes" relaxation path — pinned by a cascade test — is preserved).
|
|
533
540
|
"count", "count up", "count of", "tot up",
|
|
534
541
|
]);
|
|
535
542
|
|
|
@@ -593,6 +600,17 @@ export const EDGE_NOUN_TO_METRIC = Object.freeze({
|
|
|
593
600
|
connections: { kind: "*", dir: "both" },
|
|
594
601
|
edges: { kind: "*", dir: "both" },
|
|
595
602
|
connected: { kind: "*", dir: "both" },
|
|
603
|
+
// participle degree-nouns (widened net, cycle W2P): "the most imported / most
|
|
604
|
+
// depended-on / most used <module>" ranks by IN-degree — how many things import/depend
|
|
605
|
+
// on/use it — the ARGMAX-by-degree intent a developer expresses with a passive
|
|
606
|
+
// participle rather than the noun ("importers"). "depended" catches "depended-on" /
|
|
607
|
+
// "depended on" (both tokenize to a bare "depended"); "used" folds the symbol-grain
|
|
608
|
+
// callsSymbol callers in alongside importers so "most used" reads as most-relied-upon.
|
|
609
|
+
imported: { kind: "imports", dir: "in" },
|
|
610
|
+
"depended-on": { kind: "imports", dir: "in" },
|
|
611
|
+
depended: { kind: "imports", dir: "in" },
|
|
612
|
+
used: { kind: "imports", dir: "in", sibling: "callsSymbol" },
|
|
613
|
+
called: { kind: "calls", dir: "in", sibling: "callsSymbol" },
|
|
596
614
|
});
|
|
597
615
|
|
|
598
616
|
/** Anaphora triggers over the PREVIOUS result set (ask()'s `prev` id array):
|