Skip to content

Commit 0093d01

Browse files
committed
fix: teach AXIOM to prune rules and close community issues
AXIOM's prompt only showed "type": "modify" for ruleUpdates — it didn't know "type": "remove" existed, so it never pruned rules despite analytics warnings. Added remove example + explicit pruning policy. Also, resolvedSelfTasks only checked nexus-self-task issue numbers, so AXIOM couldn't close nexus-input (community) issues like #24. Now merges both issue number sets into closeable list.
1 parent cfeac9c commit 0093d01

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/agent.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ interface InputData {
224224
issuesText: string;
225225
selfTasksText: string;
226226
selfTaskNumbers: number[];
227+
issueNumbers: number[];
227228
isWeekend: boolean;
228229
}
229230

@@ -254,8 +255,10 @@ export async function fetchAllInputData(): Promise<InputData> {
254255

255256
// ── Handle issues (optional) ──
256257
let issuesText = "";
258+
let issueNumbers: number[] = [];
257259
if (issuesResult.status === "fulfilled") {
258260
const issues = issuesResult.value;
261+
issueNumbers = issues.map((i) => i.number);
259262
if (issues.length > 0) {
260263
issuesText = formatIssuesForPrompt(issues);
261264
}
@@ -308,7 +311,7 @@ export async function fetchAllInputData(): Promise<InputData> {
308311
console.log(chalk.dim(" Open self-tasks: unavailable\n"));
309312
}
310313

311-
return { snapshots, macroText: "", issuesText, selfTasksText, selfTaskNumbers, isWeekend: true };
314+
return { snapshots, macroText: "", issuesText, selfTasksText, selfTaskNumbers, issueNumbers, isWeekend: true };
312315
}
313316

314317
// ── Weekday: full data fetch ──
@@ -342,8 +345,10 @@ export async function fetchAllInputData(): Promise<InputData> {
342345

343346
// ── Handle issues (optional) ──
344347
let issuesText = "";
348+
let issueNumbers: number[] = [];
345349
if (issuesResult.status === "fulfilled") {
346350
const issues = issuesResult.value;
351+
issueNumbers = issues.map((i) => i.number);
347352
if (issues.length > 0) {
348353
issuesText = formatIssuesForPrompt(issues);
349354
}
@@ -425,7 +430,7 @@ export async function fetchAllInputData(): Promise<InputData> {
425430
console.log(chalk.dim(" Open self-tasks: unavailable\n"));
426431
}
427432

428-
return { snapshots, macroText, issuesText, selfTasksText, selfTaskNumbers, isWeekend: false };
433+
return { snapshots, macroText, issuesText, selfTasksText, selfTaskNumbers, issueNumbers, isWeekend: false };
429434
}
430435

431436
export async function runAndValidateOracle(
@@ -496,7 +501,8 @@ export async function runAndValidateAxiom(
496501
snapshots: MarketSnapshot[],
497502
issuesText: string,
498503
selfTasksText: string,
499-
selfTaskNumbers: number[]
504+
selfTaskNumbers: number[],
505+
issueNumbers: number[] = []
500506
): Promise<{ reflection: AxiomReflection; forgeRequests: ForgeRequest[] }> {
501507
console.log(chalk.bold.yellow(" ── PHASE 3: AXIOM REFLECTION ──\n"));
502508
const axiomSpinner = ora({ text: "AXIOM reflecting on cognitive performance...", color: "magenta" }).start();
@@ -538,7 +544,8 @@ System prompt additions about this same topic do NOT count as action.`;
538544
try {
539545
const noChangeStreak = getNoChangeStreak();
540546
const setupOutcomes = buildSetupOutcomes(snapshots);
541-
axiomResult = await runAxiomReflection(client, oracle, sessionNumber, prevContext, issuesText, selfTasksText, selfTaskNumbers, noChangeStreak, setupOutcomes);
547+
const closeableNumbers = [...selfTaskNumbers, ...issueNumbers];
548+
axiomResult = await runAxiomReflection(client, oracle, sessionNumber, prevContext, issuesText, selfTasksText, closeableNumbers, noChangeStreak, setupOutcomes);
542549
reflection = axiomResult.reflection;
543550

544551
// Block system prompt additions when AXIOM is ruminating without real action
@@ -726,7 +733,7 @@ export async function runSession(force = false): Promise<void> {
726733
}
727734

728735
currentPhase = "oracle";
729-
const { snapshots, macroText, issuesText, selfTasksText, selfTaskNumbers, isWeekend: weekendMode } = await fetchAllInputData();
736+
const { snapshots, macroText, issuesText, selfTasksText, selfTaskNumbers, issueNumbers, isWeekend: weekendMode } = await fetchAllInputData();
730737

731738
// On weekends, inject last weekday session context so ORACLE knows where traditional markets left off
732739
const oracleContext = weekendMode ? buildWeekdayBridge() : macroText;
@@ -735,7 +742,7 @@ export async function runSession(force = false): Promise<void> {
735742
const oracle = await runAndValidateOracle(client, snapshots, sessionId, sessionNumber, issuesText, oracleContext, weekendMode);
736743

737744
currentPhase = "axiom";
738-
const { reflection, forgeRequests } = await runAndValidateAxiom(client, oracle, sessionNumber, snapshots, issuesText, selfTasksText, selfTaskNumbers);
745+
const { reflection, forgeRequests } = await runAndValidateAxiom(client, oracle, sessionNumber, snapshots, issuesText, selfTasksText, selfTaskNumbers, issueNumbers);
739746

740747
currentPhase = "forge";
741748
await runAndValidateForge(client, forgeRequests, sessionNumber);

src/axiom.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ Reflect deeply on this session. Then respond with ONLY a JSON object:
198198
"before": "old text",
199199
"after": "improved text",
200200
"reason": "why this change makes the analysis better"
201+
},
202+
{
203+
"ruleId": "r099",
204+
"type": "remove",
205+
"reason": "why this rule is no longer earning its place (low hit rate, redundant, or never triggered)"
201206
}
202207
],
203208
"newRules": [
@@ -234,12 +239,20 @@ Reflect deeply on this session. Then respond with ONLY a JSON object:
234239
]
235240
}
236241
237-
SELF-TASK POLICY — CRITICAL:
238-
- CLOSING existing self-tasks is ALWAYS higher priority than opening new ones.
239-
- You can close a self-task in THREE ways:
242+
RULE PRUNING POLICY:
243+
- You can REMOVE rules using ruleUpdates with "type": "remove". Foundational rules (r001-r010) cannot be removed.
244+
- Remove a rule when: its hit rate is poor, it overlaps with another rule, it has never triggered in 10+ sessions, or analytics data shows it adds noise rather than signal.
245+
- Pruning weak rules is as valuable as adding new ones. A lean, high-signal ruleset outperforms a bloated one.
246+
- When community input or analytics flags rule bloat, act on it — do not just philosophize about pruning.
247+
248+
ISSUE RESOLUTION POLICY — CRITICAL:
249+
- CLOSING existing issues (self-tasks AND community input) is ALWAYS higher priority than opening new ones.
250+
- resolvedSelfTasks can close ANY open issue — both nexus-self-task and nexus-input (community) issues.
251+
- You can close an issue in THREE ways:
240252
1. codeChanges — if it needs a code fix
241253
2. resolvedSelfTasks — if the gap is already addressed by an existing rule, prompt improvement, or this session's analysis
242254
3. Rule update — if you modified/added a rule that covers the gap
255+
- If a community issue challenges you to take action (e.g. prune rules, improve methodology), take the action AND close the issue via resolvedSelfTasks with a comment explaining what you did.
243256
- If an open self-task describes an analytical gap and a corresponding rule already exists (e.g. "build confidence template" → r014 exists), CLOSE IT via resolvedSelfTasks with a comment explaining which rule addresses it.
244257
- Before opening ANY new self-task, check if a similar one already exists in your open self-tasks list.
245258
- Only open a new self-task if it covers a genuinely NEW gap not already tracked.

0 commit comments

Comments
 (0)