agenr 1.9.1 → 1.9.3

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/CHANGELOG.md CHANGED
@@ -2,6 +2,40 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.9.3] - 2026-04-12
6
+
7
+ Supersession sweep-exhaustion and plugin-manifest alignment patch release.
8
+
9
+ ### Fixed
10
+
11
+ - **Supersession claim-key sweeps no longer strand the pass in a false remaining-work state.** Exhausted claim-key pages now record the actual unpaged remainder, which lets same-run subject review unblock correctly instead of tripping the autonomous semantic-stall guard.
12
+ - **OpenClaw plugin manifests stay version-aligned across release artifacts.** The shared adapter manifest now tracks the published package/plugin version again, avoiding package-metadata skew during validation and release packaging.
13
+
14
+ ### Validation
15
+
16
+ Changes since last push to `origin/master`:
17
+
18
+ - Fix supersession claim-key sweep exhaustion
19
+
20
+ ## [1.9.2] - 2026-04-12
21
+
22
+ Surgeon proposal-resolution hardening and claim-key progress-output patch release.
23
+
24
+ ### Changed
25
+
26
+ - **Claim-key preview progress output is less misleading.** Preview-only `claim_key_quality` lines no longer print applied or proposal counts before entry adjudication has actually started.
27
+
28
+ ### Fixed
29
+
30
+ - **Malformed eligible proposals no longer fail the whole autonomous run.** Proposal resolution now rejects invalid auto-apply candidates per proposal and continues through the rest of the backlog.
31
+ - **Ambiguous entity-family convergence proposals stay on the manual-review path.** Multi-target family-convergence proposals are no longer marked eligible for autonomous apply.
32
+
33
+ ### Validation
34
+
35
+ Changes since last push to `origin/master`:
36
+
37
+ - Fix surgeon proposal resolution and progress output
38
+
5
39
  ## [1.9.1] - 2026-04-12
6
40
 
7
41
  Supersession stall-recovery and review-order guard patch release.
@@ -1055,7 +1055,7 @@ function registerAgenrOpenClawTools(api, servicesPromise, logger) {
1055
1055
  var openclaw_plugin_default = {
1056
1056
  id: "agenr",
1057
1057
  name: "agenr",
1058
- version: "1.9.0",
1058
+ version: "1.9.3",
1059
1059
  description: "agenr memory plugin for OpenClaw",
1060
1060
  kind: "memory",
1061
1061
  contracts: {
package/dist/cli.js CHANGED
@@ -8204,7 +8204,7 @@ async function runClaimKeyQualityPass(options, deps) {
8204
8204
  rationale: buildSurgeonProposalLifecycleRationale(buildEntityFamilyConvergenceRationale(candidate), proposalLifecycle),
8205
8205
  confidence: candidate.confidence,
8206
8206
  source: canonicalEntityPrefix ? "entity_family_canonical_candidate" : "entity_family_ambiguous",
8207
- eligibleForApply: canonicalEntityPrefix !== null,
8207
+ eligibleForApply: proposedClaimKeys.length === 1,
8208
8208
  createdAt: options.now().toISOString()
8209
8209
  });
8210
8210
  await persistProposal(proposal, {
@@ -8247,7 +8247,7 @@ async function runClaimKeyQualityPass(options, deps) {
8247
8247
  ),
8248
8248
  confidence: candidate.confidence,
8249
8249
  source: "entity_family_collision",
8250
- eligibleForApply: true,
8250
+ eligibleForApply: false,
8251
8251
  createdAt: options.now().toISOString()
8252
8252
  });
8253
8253
  await persistProposal(proposal, {
@@ -9689,9 +9689,9 @@ function createSupersessionReviewTracker(input) {
9689
9689
  progress = createEmptySupersessionProgress(input);
9690
9690
  entryToClusterKeys = /* @__PURE__ */ new Map();
9691
9691
  },
9692
- recordPage({ scope, claimKeyTotal, subjectTotal, clusters }) {
9693
- const normalizedClaimKeyRemaining = normalizeCount(claimKeyTotal);
9694
- const normalizedSubjectRemaining = normalizeCount(subjectTotal);
9692
+ recordPage({ scope, claimKeyRemaining, subjectRemaining, clusters }) {
9693
+ const normalizedClaimKeyRemaining = normalizeCount(claimKeyRemaining);
9694
+ const normalizedSubjectRemaining = normalizeCount(subjectRemaining);
9695
9695
  const nextClaimKeyViewed = new Set(progress.claimKeyViewedKeys);
9696
9696
  const nextSubjectViewed = new Set(progress.subjectViewedKeys);
9697
9697
  const nextEntryMap = cloneEntryClusterMap(entryToClusterKeys);
@@ -11519,10 +11519,13 @@ function createQuerySupersessionCandidatesTool(deps) {
11519
11519
  const subjectClusterCount = scope === "claim_key" ? progress?.subjectClustersRemaining ?? counts.subjectCount : pendingSubjectClusters.length;
11520
11520
  const allClusters = scope === "claim_key" ? pendingClaimKeyClusters : scope === "subject" ? pendingSubjectClusters : [...pendingClaimKeyClusters, ...pendingSubjectClusters];
11521
11521
  const clusters = allClusters.slice(offset, offset + limit);
11522
+ const remainingClusters = allClusters.slice(Math.min(allClusters.length, offset + clusters.length));
11523
+ const claimKeyRemaining = scope === "subject" ? claimKeyClusterCount : countClustersByGrouping(remainingClusters, "claim_key");
11524
+ const subjectRemaining = scope === "claim_key" ? subjectClusterCount : countClustersByGrouping(remainingClusters, "subject");
11522
11525
  deps.completionGuards?.supersession.recordPage({
11523
11526
  scope,
11524
- claimKeyTotal: claimKeyClusterCount,
11525
- subjectTotal: subjectClusterCount,
11527
+ claimKeyRemaining,
11528
+ subjectRemaining,
11526
11529
  clusters
11527
11530
  });
11528
11531
  if (clusters.length === 0) {
@@ -11590,6 +11593,15 @@ function normalizeOptionalString11(value) {
11590
11593
  const normalized = value?.trim();
11591
11594
  return normalized ? normalized : void 0;
11592
11595
  }
11596
+ function countClustersByGrouping(clusters, groupedBy) {
11597
+ let count = 0;
11598
+ for (const cluster of clusters) {
11599
+ if (cluster.groupedBy === groupedBy) {
11600
+ count += 1;
11601
+ }
11602
+ }
11603
+ return count;
11604
+ }
11593
11605
 
11594
11606
  // src/app/surgeon/tools/supersession-validity.ts
11595
11607
  import { randomUUID as randomUUID7 } from "crypto";
@@ -12767,6 +12779,7 @@ async function runProposalResolutionPass(input, deps) {
12767
12779
  });
12768
12780
  let appliedCount = 0;
12769
12781
  let rejectedInactiveCount = 0;
12782
+ let rejectedInvalidCount = 0;
12770
12783
  let noChangeCount = 0;
12771
12784
  const updatedEntryIds = /* @__PURE__ */ new Set();
12772
12785
  emitProposalResolutionProgress(input.reportProgress, {
@@ -12776,6 +12789,7 @@ async function runProposalResolutionPass(input, deps) {
12776
12789
  processedProposals: 0,
12777
12790
  appliedCount,
12778
12791
  rejectedInactiveCount,
12792
+ rejectedInvalidCount,
12779
12793
  noChangeCount,
12780
12794
  targetedEntryCount: updatedEntryIds.size
12781
12795
  });
@@ -12789,7 +12803,35 @@ async function runProposalResolutionPass(input, deps) {
12789
12803
  }
12790
12804
  for (const [index, item] of backlog.entries()) {
12791
12805
  const proposal = item.proposal;
12792
- const targetClaimKey = resolveSurgeonProposalApplyTarget(proposal);
12806
+ let targetClaimKey;
12807
+ try {
12808
+ targetClaimKey = resolveSurgeonProposalApplyTarget(proposal);
12809
+ } catch (error) {
12810
+ const message = error instanceof Error ? error.message : String(error);
12811
+ await deps.port.reviewProposal({
12812
+ proposalId: proposal.id,
12813
+ status: "rejected",
12814
+ reason: message,
12815
+ reviewedAt: input.now().toISOString(),
12816
+ appliedActionCount: 0
12817
+ });
12818
+ rejectedInvalidCount += 1;
12819
+ emitProposalResolutionProgress(input.reportProgress, {
12820
+ apply: input.apply,
12821
+ status: "proposal_processed",
12822
+ totalProposals: backlog.length,
12823
+ processedProposals: index + 1,
12824
+ appliedCount,
12825
+ rejectedInactiveCount,
12826
+ rejectedInvalidCount,
12827
+ noChangeCount,
12828
+ targetedEntryCount: updatedEntryIds.size,
12829
+ proposalId: proposal.id,
12830
+ issueKind: proposal.issueKind,
12831
+ outcome: "rejected_invalid"
12832
+ });
12833
+ continue;
12834
+ }
12793
12835
  const reasoning = buildSurgeonProposalReviewReason(proposal, "Autonomous eligible proposal resolution.");
12794
12836
  const proposalEntryIds = [];
12795
12837
  if (input.apply) {
@@ -12830,6 +12872,7 @@ async function runProposalResolutionPass(input, deps) {
12830
12872
  processedProposals: index + 1,
12831
12873
  appliedCount,
12832
12874
  rejectedInactiveCount,
12875
+ rejectedInvalidCount,
12833
12876
  noChangeCount,
12834
12877
  targetedEntryCount: updatedEntryIds.size,
12835
12878
  proposalId: proposal.id,
@@ -12845,6 +12888,7 @@ async function runProposalResolutionPass(input, deps) {
12845
12888
  processedProposals: index + 1,
12846
12889
  appliedCount,
12847
12890
  rejectedInactiveCount,
12891
+ rejectedInvalidCount,
12848
12892
  noChangeCount,
12849
12893
  targetedEntryCount: updatedEntryIds.size,
12850
12894
  proposalId: proposal.id,
@@ -12893,6 +12937,7 @@ async function runProposalResolutionPass(input, deps) {
12893
12937
  processedProposals: index + 1,
12894
12938
  appliedCount,
12895
12939
  rejectedInactiveCount,
12940
+ rejectedInvalidCount,
12896
12941
  noChangeCount,
12897
12942
  targetedEntryCount: updatedEntryIds.size,
12898
12943
  proposalId: proposal.id,
@@ -12900,7 +12945,7 @@ async function runProposalResolutionPass(input, deps) {
12900
12945
  outcome: input.apply ? "applied" : "dry_run"
12901
12946
  });
12902
12947
  }
12903
- if (appliedCount === 0 && rejectedInactiveCount === 0) {
12948
+ if (appliedCount === 0 && rejectedInactiveCount === 0 && rejectedInvalidCount === 0) {
12904
12949
  emitProposalResolutionProgress(input.reportProgress, {
12905
12950
  apply: input.apply,
12906
12951
  status: "stalled",
@@ -12908,6 +12953,7 @@ async function runProposalResolutionPass(input, deps) {
12908
12953
  processedProposals: backlog.length,
12909
12954
  appliedCount,
12910
12955
  rejectedInactiveCount,
12956
+ rejectedInvalidCount,
12911
12957
  noChangeCount,
12912
12958
  targetedEntryCount: updatedEntryIds.size
12913
12959
  });
@@ -12925,6 +12971,7 @@ async function runProposalResolutionPass(input, deps) {
12925
12971
  processedProposals: backlog.length,
12926
12972
  appliedCount,
12927
12973
  rejectedInactiveCount,
12974
+ rejectedInvalidCount,
12928
12975
  noChangeCount,
12929
12976
  targetedEntryCount: updatedEntryIds.size
12930
12977
  });
@@ -12936,7 +12983,10 @@ async function runProposalResolutionPass(input, deps) {
12936
12983
  observations: [
12937
12984
  `Processed ${appliedCount} eligible surgeon proposal${appliedCount === 1 ? "" : "s"}.`,
12938
12985
  `${updatedEntryIds.size} entr${updatedEntryIds.size === 1 ? "y was" : "ies were"} targeted by proposal resolution.`,
12939
- ...rejectedInactiveCount > 0 ? [`Rejected ${rejectedInactiveCount} stale eligible proposal${rejectedInactiveCount === 1 ? "" : "s"} whose target entries were no longer active.`] : []
12986
+ ...rejectedInactiveCount > 0 ? [`Rejected ${rejectedInactiveCount} stale eligible proposal${rejectedInactiveCount === 1 ? "" : "s"} whose target entries were no longer active.`] : [],
12987
+ ...rejectedInvalidCount > 0 ? [
12988
+ `Rejected ${rejectedInvalidCount} malformed eligible proposal${rejectedInvalidCount === 1 ? "" : "s"} that did not resolve to exactly one safe claim-key target.`
12989
+ ] : []
12940
12990
  ],
12941
12991
  recommendations: ["Leave non-eligible surgeon proposals on the manual review path."]
12942
12992
  },
@@ -12953,6 +13003,7 @@ function emitProposalResolutionProgress(reporter, input) {
12953
13003
  processedProposals: input.processedProposals,
12954
13004
  appliedCount: input.appliedCount,
12955
13005
  rejectedInactiveCount: input.rejectedInactiveCount,
13006
+ rejectedInvalidCount: input.rejectedInvalidCount,
12956
13007
  noChangeCount: input.noChangeCount,
12957
13008
  targetedEntryCount: input.targetedEntryCount,
12958
13009
  proposalId: input.proposalId,
@@ -16313,8 +16364,8 @@ function handleClaimKeyQualityEvent(event, verbose) {
16313
16364
  const previewTotal = formatOptionalCount(event.previewTotal);
16314
16365
  const previewCompleted = formatOptionalCount(event.previewCompleted);
16315
16366
  const previewSuffix = previewTotal > 0 ? `, preview ${previewCompleted}/${previewTotal}` : "";
16316
- const progressMsg = `${stageLabel}: ${event.completed}/${event.total} ${event.unitLabel}${previewSuffix}, ${appliedTotal} applied, ${event.counts.proposalsEmitted} proposals${skippedSummary}, ${formatElapsed(event.elapsedMs)}`;
16317
- if (verbose) {
16367
+ const progressMsg = event.status === "preview_progress" ? `${stageLabel}: ${event.completed}/${event.total} ${event.unitLabel}${previewSuffix}${skippedSummary}, ${formatElapsed(event.elapsedMs)}` : `${stageLabel}: ${event.completed}/${event.total} ${event.unitLabel}${previewSuffix}, ${appliedTotal} applied, ${event.counts.proposalsEmitted} proposals${skippedSummary}, ${formatElapsed(event.elapsedMs)}`;
16368
+ if (verbose && event.status !== "preview_progress") {
16318
16369
  const detail = ` (normalize ${event.counts.appliedNormalizations}/${event.counts.identifiedNormalizations}, backfill ${event.counts.appliedBackfills}/${event.counts.identifiedBackfills}, metadata ${event.counts.appliedMetadataRewrites}/${event.counts.identifiedMetadataRewrites}, family ${event.counts.appliedEntityFamilyConvergences}/${event.counts.identifiedEntityFamilyConvergences})`;
16319
16370
  writeStderr(` ${ui.dim(progressMsg + detail)}`);
16320
16371
  } else {
@@ -16334,18 +16385,18 @@ function handleProposalResolutionEvent(event, verbose) {
16334
16385
  const outcome = event.outcome ? `, ${formatProposalResolutionOutcome(event.outcome)}` : "";
16335
16386
  const verboseSuffix = verbose && event.proposalId ? ` ${ui.dim(`(${event.proposalId}${event.issueKind ? `, ${event.issueKind}` : ""})`)}` : "";
16336
16387
  writeStderr(
16337
- ` ${ui.dim(`proposal_resolution: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}${outcome}`)}${verboseSuffix}`
16388
+ ` ${ui.dim(`proposal_resolution: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, invalid ${event.rejectedInvalidCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}${outcome}`)}${verboseSuffix}`
16338
16389
  );
16339
16390
  return;
16340
16391
  }
16341
16392
  case "completed":
16342
16393
  writeStderr(
16343
- ` ${ui.success(`proposal_resolution complete: applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
16394
+ ` ${ui.success(`proposal_resolution complete: applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, invalid ${event.rejectedInvalidCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
16344
16395
  );
16345
16396
  return;
16346
16397
  case "stalled":
16347
16398
  writeStderr(
16348
- ` ${ui.warn(`proposal_resolution stalled: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
16399
+ ` ${ui.warn(`proposal_resolution stalled: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, invalid ${event.rejectedInvalidCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
16349
16400
  );
16350
16401
  return;
16351
16402
  default:
@@ -16487,6 +16538,8 @@ function formatProposalResolutionOutcome(outcome) {
16487
16538
  return "previewed";
16488
16539
  case "rejected_inactive":
16489
16540
  return "rejected inactive";
16541
+ case "rejected_invalid":
16542
+ return "rejected invalid";
16490
16543
  case "no_change":
16491
16544
  return "no change";
16492
16545
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenr",
3
- "version": "1.9.1",
3
+ "version": "1.9.3",
4
4
  "description": "Agent memory - local-first knowledge infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "bin": {