@polycode-projects/the-mechanical-code-talker 0.9.8 → 0.9.9

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/ROADMAP.md CHANGED
@@ -27,8 +27,8 @@ the file has been deleted.
27
27
  - **Cluster C** — `PLAN_CHAT_FEEL.md` item 6, the pronoun/temporal/discourse-count trio
28
28
  (measured red sets from an earlier advisor tick; re-measured against the current graded pool
29
29
  before any fix).
30
- - **Cluster D** — `PLAN_CODE.md` Track 1 (GOAL_RULE/PHRASING_FRAMES synthesis) operator
31
- sign-off given this session; Tracks 2-4 remain unsigned-off and untouched.
30
+ - ~~**Cluster D** — `PLAN_CODE.md` Track 1~~ **shipped** (see "Now" below). Tracks 2-4 remain
31
+ unsigned-off and untouched.
32
32
  - **Cluster E** — `PLAN_INFERENCE_TESTING.md` Stage 1 (`cax-sco` rule) + Stage 2 (proof-chain
33
33
  receipts) in `src/syllogise.mjs`, targeting the measured chat-A2 50% ceiling.
34
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "0.9.8",
3
+ "version": "0.9.9",
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.",
@@ -164,9 +164,16 @@ export function backwardChainGoal(topic) {
164
164
  * The caller REFUSES on zero matches (the open-world goal-generation seam) and
165
165
  * on more than one (an ambiguous meta-goal — arbitration between meta-goals is
166
166
  * undeclared, so guessing one would be an invented goal). */
167
- export function applicableRules(declaredTools, focus, mode) {
167
+ // `ruleSet` defaults to the real, shipped GOAL_RULES — every existing caller
168
+ // (driver-goal.mjs, this module's own goalReason, every test) is unaffected.
169
+ // The override exists ONLY for PLAN_CODE.md Track 1 (§1.4): the synthesis
170
+ // oracle clones a CANDIDATE rule into its own array and runs it through this
171
+ // SAME trusted function — never a re-derivation — to check it decides
172
+ // applicability exactly like a hand-written rule would. synthbench/ is the
173
+ // only caller that ever passes a non-default ruleSet.
174
+ export function applicableRules(declaredTools, focus, mode, ruleSet = GOAL_RULES) {
168
175
  const declared = Array.isArray(declaredTools) ? declaredTools : [];
169
- return GOAL_RULES.filter((rule) =>
176
+ return ruleSet.filter((rule) =>
170
177
  rule.modes.includes(mode)
171
178
  && (mode !== "scoped" || (focus != null && focus.class === rule.focusClass))
172
179
  && rule.subGoals.every((topic) => {
@@ -255,8 +262,14 @@ export function dropCondition(intention, observed, mode, focus, focusClass) {
255
262
  * the keystone module globally) or an HONEST REFUSE at the open-world
256
263
  * goal-generation seam.
257
264
  *
258
- * ctx: { dispatch(name,input)->{ok,result}, resolve(term)->{match,ambiguous} }. */
259
- export async function goalReason(request, tools, ctx, { driver = "goal-0.8.1" } = {}) {
265
+ * ctx: { dispatch(name,input)->{ok,result}, resolve(term)->{match,ambiguous} }.
266
+ *
267
+ * `ruleSet` defaults to the real, shipped GOAL_RULES (every product call site
268
+ * omits it). PLAN_CODE.md Track 1's synthesis oracle (synthbench/rules/
269
+ * oracle.mjs) is the one caller that overrides it, with a CLONED array
270
+ * holding a candidate rule — the candidate then runs through this exact same
271
+ * meta-loop a hand-written rule does, never a parallel re-implementation. */
272
+ export async function goalReason(request, tools, ctx, { driver = "goal-0.8.1", ruleSet = GOAL_RULES } = {}) {
260
273
  const declared = Array.isArray(tools) ? tools : [];
261
274
 
262
275
  // STEP 1 — deduce the goal scope from the DECLARED model + a bound focus,
@@ -267,8 +280,8 @@ export async function goalReason(request, tools, ctx, { driver = "goal-0.8.1" }
267
280
 
268
281
  // The open-world goal-generation seam, named honestly: a resolved focus whose
269
282
  // class NO declared goal-rule scopes is REFUSED, never given an invented goal.
270
- if (focus && !GOAL_RULES.some((r) => r.focusClass === focus.class)) {
271
- const covered = [...new Set(GOAL_RULES.map((r) => r.focusClass))].join("/");
283
+ if (focus && !ruleSet.some((r) => r.focusClass === focus.class)) {
284
+ const covered = [...new Set(ruleSet.map((r) => r.focusClass))].join("/");
272
285
  return refuse(`open-world: no declared goal-rule covers a ${focus.class} focus (the declared goal-rules are ${covered}-scoped) — escalate`, driver);
273
286
  }
274
287
 
@@ -276,7 +289,7 @@ export async function goalReason(request, tools, ctx, { driver = "goal-0.8.1" }
276
289
  // 0 applicable rules => the same open-world seam (nothing declared grounds the
277
290
  // request's scope in this toolset); >1 => an AMBIGUOUS meta-goal (arbitration
278
291
  // between meta-goals is undeclared) — both are honest refusals, never a guess.
279
- const applicable = applicableRules(declared, focus, mode);
292
+ const applicable = applicableRules(declared, focus, mode, ruleSet);
280
293
 
281
294
  // THE GLOBAL-MODE DOMAIN GATE (Bug 8 fix, see the module header). SCOPED mode
282
295
  // already proved relevance via a bound graph entity; GLOBAL mode has not, so