mirror of
https://github.com/lukaszraczylo/claude-adam.git
synced 2026-10-15 05:37:59 +00:00
feat(nudge): ReContext-grounded cue reactivation + analyst refinements
Analyse claude-adam through ReContext (arXiv:2607.02509): close the access!=utilization gap with query-conditioned nudge replay + analyst tweaks. - nudge: optional cue.cwd gates SessionStart replay (adam-nudge.mjs) and new mid-session reactivation on UserPromptSubmit (adam-observe.mjs, cwd-gated, once/session, ADAM_NO_MIDSESSION_NUDGE opt-out). - new adam-apply-nudge.mjs builds message + cue deterministically from proposal frontmatter (wired into SKILL.md, install.sh, pending-check). - adam-batch: optional --max-batches/--top-fraction output cap (default off), reports capped. - analyst: utility-lift rubric penalty + skill_utility_path fed to both stages; adaptive re-diagnose for unclear/top-severity clusters; cross-type associative pass (agents/adam.md, SKILL.md). - tests: 140 -> 144 (cue gate, batch cap, apply-nudge, mid-session).
This commit is contained in:
@@ -83,7 +83,7 @@ function clusterKey(entry) {
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = { input: null, minEntries: DEFAULT_MIN_ENTRIES, minSessions: DEFAULT_MIN_SESSIONS, help: false };
|
||||
const args = { input: null, minEntries: DEFAULT_MIN_ENTRIES, minSessions: DEFAULT_MIN_SESSIONS, maxBatches: null, topFraction: null, help: false };
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
const a = argv[i];
|
||||
if (a === "--input" && i + 1 < argv.length) args.input = argv[++i];
|
||||
@@ -95,6 +95,14 @@ function parseArgs(argv) {
|
||||
const n = Number(argv[++i]);
|
||||
if (!Number.isNaN(n) && n > 0) args.minSessions = n;
|
||||
}
|
||||
else if (a === "--max-batches" && i + 1 < argv.length) {
|
||||
const n = Number(argv[++i]);
|
||||
if (!Number.isNaN(n) && n > 0) args.maxBatches = n;
|
||||
}
|
||||
else if (a === "--top-fraction" && i + 1 < argv.length) {
|
||||
const n = Number(argv[++i]);
|
||||
if (!Number.isNaN(n) && n > 0 && n < 1) args.topFraction = n;
|
||||
}
|
||||
else if (a === "--help" || a === "-h") args.help = true;
|
||||
}
|
||||
return args;
|
||||
@@ -146,13 +154,28 @@ export function buildBatches(entries, opts = {}) {
|
||||
}
|
||||
|
||||
batches.sort((a, b) => b.entry_count - a.entry_count);
|
||||
return { batches, unbatched, total: (entries || []).length };
|
||||
|
||||
// Optional output cap (default: no cap — the full ranked list is returned).
|
||||
// ReContext P2: relevance is concentrated, so surfacing only the top head keeps
|
||||
// reviewer attention on the highest-value clusters. `topFraction` keeps the top
|
||||
// ceil(f * N) after ranking (so the survivor count tracks corpus volume);
|
||||
// `maxBatches` is a hard ceiling. The more restrictive of the two applies.
|
||||
// Never silent: `capped` reports how many ranked batches were dropped by the cap.
|
||||
let keepN = batches.length;
|
||||
const frac = Number(opts.topFraction);
|
||||
if (frac > 0 && frac < 1) keepN = Math.min(keepN, Math.max(1, Math.ceil(frac * batches.length)));
|
||||
const maxB = Number(opts.maxBatches);
|
||||
if (Number.isFinite(maxB) && maxB > 0) keepN = Math.min(keepN, maxB);
|
||||
const capped = batches.length - keepN;
|
||||
const kept = capped > 0 ? batches.slice(0, keepN) : batches;
|
||||
|
||||
return { batches: kept, unbatched, capped, total: (entries || []).length };
|
||||
}
|
||||
|
||||
function main() {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
if (args.help) {
|
||||
process.stdout.write("usage: adam-batch.mjs [--input <jsonl-path>] [--min-entries N] [--min-sessions N]\n");
|
||||
process.stdout.write("usage: adam-batch.mjs [--input <jsonl-path>] [--min-entries N] [--min-sessions N] [--max-batches N] [--top-fraction F]\n");
|
||||
process.exit(0);
|
||||
}
|
||||
try {
|
||||
@@ -170,7 +193,7 @@ function main() {
|
||||
process.stderr.write("adam-batch: no input (use --input or pipe)\n");
|
||||
process.exit(1);
|
||||
}
|
||||
const result = buildBatches(entries, { minEntries: args.minEntries, minSessions: args.minSessions });
|
||||
const result = buildBatches(entries, { minEntries: args.minEntries, minSessions: args.minSessions, maxBatches: args.maxBatches, topFraction: args.topFraction });
|
||||
process.stdout.write(JSON.stringify(result) + "\n");
|
||||
process.exit(0);
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user