agenr 1.9.0 → 1.9.2
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 +38 -0
- package/dist/adapters/openclaw/index.js +1 -1
- package/dist/cli.js +77 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.9.2] - 2026-04-12
|
|
6
|
+
|
|
7
|
+
Surgeon proposal-resolution hardening and claim-key progress-output patch release.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **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.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **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.
|
|
16
|
+
- **Ambiguous entity-family convergence proposals stay on the manual-review path.** Multi-target family-convergence proposals are no longer marked eligible for autonomous apply.
|
|
17
|
+
|
|
18
|
+
### Validation
|
|
19
|
+
|
|
20
|
+
Changes since last push to `origin/master`:
|
|
21
|
+
|
|
22
|
+
- Fix surgeon proposal resolution and progress output
|
|
23
|
+
|
|
24
|
+
## [1.9.1] - 2026-04-12
|
|
25
|
+
|
|
26
|
+
Supersession stall-recovery and review-order guard patch release.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Supersession review order is now enforced at the tool boundary.** The supersession query tool now blocks widening into lower-confidence subject sweeps until the same run has actually exhausted claim-key work, keeping the pass aligned with its intended review order.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **Supersession passes no longer self-poison completion state by widening too early.** The surgeon now avoids the stuck `widenedBeforeClaimKeyExhausted` path that could leave a run unable to complete cleanly after later claim-key review caught up.
|
|
35
|
+
- **Supersession completion feedback is more actionable.** Rejected `complete_pass` calls now tell the model how to count reviewed-but-intentionally-unlinked clusters via `entries_skipped`, reducing repeated no-progress bounded slices.
|
|
36
|
+
|
|
37
|
+
### Validation
|
|
38
|
+
|
|
39
|
+
Changes since last push to `origin/master`:
|
|
40
|
+
|
|
41
|
+
- Fix surgeon supersession stall handling
|
|
42
|
+
|
|
5
43
|
## [1.9.0] - 2026-04-12
|
|
6
44
|
|
|
7
45
|
Surgeon autonomy, review-flow hardening, and CLI/runtime polish 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.
|
|
1058
|
+
version: "1.9.1",
|
|
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:
|
|
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:
|
|
8250
|
+
eligibleForApply: false,
|
|
8251
8251
|
createdAt: options.now().toISOString()
|
|
8252
8252
|
});
|
|
8253
8253
|
await persistProposal(proposal, {
|
|
@@ -10817,10 +10817,10 @@ function describeSupersessionRejection(progress, input) {
|
|
|
10817
10817
|
return "Completion rejected: the review widened beyond claim_key clusters before the claim_key sweep was exhausted.";
|
|
10818
10818
|
}
|
|
10819
10819
|
if (!progress.claimKeyScopeExhausted) {
|
|
10820
|
-
return input.budgetUsedPct === null ? `Completion rejected: ${progress.claimKeyClustersRemaining} claim_key clusters still remain in the current sweep.` : `Completion rejected: ${progress.claimKeyClustersRemaining} claim_key clusters still remain in the current sweep and only ${input.budgetUsedPct}% of the cost budget has been used.`;
|
|
10820
|
+
return input.budgetUsedPct === null ? `Completion rejected: ${progress.claimKeyClustersRemaining} claim_key clusters still remain in the current sweep. For reviewed-but-intentionally-unlinked clusters, include one paged entry_id per cluster in entries_skipped.` : `Completion rejected: ${progress.claimKeyClustersRemaining} claim_key clusters still remain in the current sweep and only ${input.budgetUsedPct}% of the cost budget has been used. For reviewed-but-intentionally-unlinked clusters, include one paged entry_id per cluster in entries_skipped.`;
|
|
10821
10821
|
}
|
|
10822
10822
|
if (input.subjectTotal > 0 && !progress.subjectScopeExhausted) {
|
|
10823
|
-
return input.budgetUsedPct === null ? `Completion rejected: the claim_key sweep is exhausted, but ${progress.subjectClustersRemaining} subject clusters still remain.` : `Completion rejected: the claim_key sweep is exhausted, but ${progress.subjectClustersRemaining} subject clusters still remain and only ${input.budgetUsedPct}% of the cost budget has been used.`;
|
|
10823
|
+
return input.budgetUsedPct === null ? `Completion rejected: the claim_key sweep is exhausted, but ${progress.subjectClustersRemaining} subject clusters still remain. For reviewed-but-intentionally-unlinked clusters, include one paged entry_id per cluster in entries_skipped.` : `Completion rejected: the claim_key sweep is exhausted, but ${progress.subjectClustersRemaining} subject clusters still remain and only ${input.budgetUsedPct}% of the cost budget has been used. For reviewed-but-intentionally-unlinked clusters, include one paged entry_id per cluster in entries_skipped.`;
|
|
10824
10824
|
}
|
|
10825
10825
|
if (!input.budgetForcedStop) {
|
|
10826
10826
|
return input.budgetUsedPct === null ? "Completion rejected: the supersession sweep still has unfinished work." : `Completion rejected: the supersession sweep still has unfinished work and only ${input.budgetUsedPct}% of the cost budget has been used.`;
|
|
@@ -11482,12 +11482,25 @@ function createQuerySupersessionCandidatesTool(deps) {
|
|
|
11482
11482
|
const limit = normalizeLimit4(params.limit);
|
|
11483
11483
|
const offset = normalizeOffset3(params.offset);
|
|
11484
11484
|
const type = normalizeOptionalString11(params.type);
|
|
11485
|
+
const progress = deps.completionGuards?.supersession.snapshot();
|
|
11486
|
+
if ((scope === "subject" || scope === "all") && shouldBlockLowerConfidenceScope(progress)) {
|
|
11487
|
+
return toolResult({
|
|
11488
|
+
clusters: [],
|
|
11489
|
+
count: 0,
|
|
11490
|
+
scope,
|
|
11491
|
+
limit,
|
|
11492
|
+
offset,
|
|
11493
|
+
claimKeyClusterCount: progress?.claimKeyClustersRemaining ?? 0,
|
|
11494
|
+
subjectClusterCount: progress?.subjectClustersRemaining ?? 0,
|
|
11495
|
+
blocked: true,
|
|
11496
|
+
message: buildClaimKeyFirstMessage(progress.claimKeyClustersRemaining)
|
|
11497
|
+
});
|
|
11498
|
+
}
|
|
11485
11499
|
const counts = await deps.port.countSupersessionCandidates({
|
|
11486
11500
|
type,
|
|
11487
11501
|
skipRecentlyEvaluatedDays: deps.skipRecentlyEvaluatedDays,
|
|
11488
11502
|
now: deps.now()
|
|
11489
11503
|
});
|
|
11490
|
-
const progress = deps.completionGuards?.supersession.snapshot();
|
|
11491
11504
|
const claimKeyClusters = scope === "subject" ? [] : await deps.port.listSupersessionCandidates({
|
|
11492
11505
|
scope: "claim_key",
|
|
11493
11506
|
type,
|
|
@@ -11546,6 +11559,15 @@ function buildEmptyResultMessage(scope) {
|
|
|
11546
11559
|
}
|
|
11547
11560
|
return "No more supersession clusters match the current filters. The review pool appears exhausted.";
|
|
11548
11561
|
}
|
|
11562
|
+
function shouldBlockLowerConfidenceScope(progress) {
|
|
11563
|
+
if (!progress) {
|
|
11564
|
+
return false;
|
|
11565
|
+
}
|
|
11566
|
+
return !progress.claimKeyScopeExhausted && progress.claimKeyClustersRemaining > 0;
|
|
11567
|
+
}
|
|
11568
|
+
function buildClaimKeyFirstMessage(remainingClaimKeyClusters) {
|
|
11569
|
+
return remainingClaimKeyClusters === 1 ? "The subject sweep is blocked until the claim_key sweep is exhausted. One claim_key cluster still remains - continue with scope = 'claim_key'." : `The subject sweep is blocked until the claim_key sweep is exhausted. ${remainingClaimKeyClusters} claim_key clusters still remain - continue with scope = 'claim_key'.`;
|
|
11570
|
+
}
|
|
11549
11571
|
function normalizeLimit4(value) {
|
|
11550
11572
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
11551
11573
|
return 20;
|
|
@@ -12724,6 +12746,7 @@ function buildContinuationPrompt(input) {
|
|
|
12724
12746
|
"Continue the supersession pass.",
|
|
12725
12747
|
progressReminder,
|
|
12726
12748
|
"Keep paginating claim_key clusters while any remain. Once the claim_key sweep returns no remaining clusters, query scope = 'subject' to confirm whether lower-confidence work remains.",
|
|
12749
|
+
"Viewed supersession clusters do not count as adjudicated unless you mutate them or include one paged entry_id from the cluster in entries_skipped during complete_pass.",
|
|
12727
12750
|
"If both claim_key and subject sweeps are exhausted, call complete_pass and include any reviewed but intentionally unlinked clusters in entries_skipped.",
|
|
12728
12751
|
"Avoid no-op metadata actions that do not change persisted state."
|
|
12729
12752
|
] : [
|
|
@@ -12744,6 +12767,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12744
12767
|
});
|
|
12745
12768
|
let appliedCount = 0;
|
|
12746
12769
|
let rejectedInactiveCount = 0;
|
|
12770
|
+
let rejectedInvalidCount = 0;
|
|
12747
12771
|
let noChangeCount = 0;
|
|
12748
12772
|
const updatedEntryIds = /* @__PURE__ */ new Set();
|
|
12749
12773
|
emitProposalResolutionProgress(input.reportProgress, {
|
|
@@ -12753,6 +12777,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12753
12777
|
processedProposals: 0,
|
|
12754
12778
|
appliedCount,
|
|
12755
12779
|
rejectedInactiveCount,
|
|
12780
|
+
rejectedInvalidCount,
|
|
12756
12781
|
noChangeCount,
|
|
12757
12782
|
targetedEntryCount: updatedEntryIds.size
|
|
12758
12783
|
});
|
|
@@ -12766,7 +12791,35 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12766
12791
|
}
|
|
12767
12792
|
for (const [index, item] of backlog.entries()) {
|
|
12768
12793
|
const proposal = item.proposal;
|
|
12769
|
-
|
|
12794
|
+
let targetClaimKey;
|
|
12795
|
+
try {
|
|
12796
|
+
targetClaimKey = resolveSurgeonProposalApplyTarget(proposal);
|
|
12797
|
+
} catch (error) {
|
|
12798
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12799
|
+
await deps.port.reviewProposal({
|
|
12800
|
+
proposalId: proposal.id,
|
|
12801
|
+
status: "rejected",
|
|
12802
|
+
reason: message,
|
|
12803
|
+
reviewedAt: input.now().toISOString(),
|
|
12804
|
+
appliedActionCount: 0
|
|
12805
|
+
});
|
|
12806
|
+
rejectedInvalidCount += 1;
|
|
12807
|
+
emitProposalResolutionProgress(input.reportProgress, {
|
|
12808
|
+
apply: input.apply,
|
|
12809
|
+
status: "proposal_processed",
|
|
12810
|
+
totalProposals: backlog.length,
|
|
12811
|
+
processedProposals: index + 1,
|
|
12812
|
+
appliedCount,
|
|
12813
|
+
rejectedInactiveCount,
|
|
12814
|
+
rejectedInvalidCount,
|
|
12815
|
+
noChangeCount,
|
|
12816
|
+
targetedEntryCount: updatedEntryIds.size,
|
|
12817
|
+
proposalId: proposal.id,
|
|
12818
|
+
issueKind: proposal.issueKind,
|
|
12819
|
+
outcome: "rejected_invalid"
|
|
12820
|
+
});
|
|
12821
|
+
continue;
|
|
12822
|
+
}
|
|
12770
12823
|
const reasoning = buildSurgeonProposalReviewReason(proposal, "Autonomous eligible proposal resolution.");
|
|
12771
12824
|
const proposalEntryIds = [];
|
|
12772
12825
|
if (input.apply) {
|
|
@@ -12807,6 +12860,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12807
12860
|
processedProposals: index + 1,
|
|
12808
12861
|
appliedCount,
|
|
12809
12862
|
rejectedInactiveCount,
|
|
12863
|
+
rejectedInvalidCount,
|
|
12810
12864
|
noChangeCount,
|
|
12811
12865
|
targetedEntryCount: updatedEntryIds.size,
|
|
12812
12866
|
proposalId: proposal.id,
|
|
@@ -12822,6 +12876,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12822
12876
|
processedProposals: index + 1,
|
|
12823
12877
|
appliedCount,
|
|
12824
12878
|
rejectedInactiveCount,
|
|
12879
|
+
rejectedInvalidCount,
|
|
12825
12880
|
noChangeCount,
|
|
12826
12881
|
targetedEntryCount: updatedEntryIds.size,
|
|
12827
12882
|
proposalId: proposal.id,
|
|
@@ -12870,6 +12925,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12870
12925
|
processedProposals: index + 1,
|
|
12871
12926
|
appliedCount,
|
|
12872
12927
|
rejectedInactiveCount,
|
|
12928
|
+
rejectedInvalidCount,
|
|
12873
12929
|
noChangeCount,
|
|
12874
12930
|
targetedEntryCount: updatedEntryIds.size,
|
|
12875
12931
|
proposalId: proposal.id,
|
|
@@ -12877,7 +12933,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12877
12933
|
outcome: input.apply ? "applied" : "dry_run"
|
|
12878
12934
|
});
|
|
12879
12935
|
}
|
|
12880
|
-
if (appliedCount === 0 && rejectedInactiveCount === 0) {
|
|
12936
|
+
if (appliedCount === 0 && rejectedInactiveCount === 0 && rejectedInvalidCount === 0) {
|
|
12881
12937
|
emitProposalResolutionProgress(input.reportProgress, {
|
|
12882
12938
|
apply: input.apply,
|
|
12883
12939
|
status: "stalled",
|
|
@@ -12885,6 +12941,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12885
12941
|
processedProposals: backlog.length,
|
|
12886
12942
|
appliedCount,
|
|
12887
12943
|
rejectedInactiveCount,
|
|
12944
|
+
rejectedInvalidCount,
|
|
12888
12945
|
noChangeCount,
|
|
12889
12946
|
targetedEntryCount: updatedEntryIds.size
|
|
12890
12947
|
});
|
|
@@ -12902,6 +12959,7 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12902
12959
|
processedProposals: backlog.length,
|
|
12903
12960
|
appliedCount,
|
|
12904
12961
|
rejectedInactiveCount,
|
|
12962
|
+
rejectedInvalidCount,
|
|
12905
12963
|
noChangeCount,
|
|
12906
12964
|
targetedEntryCount: updatedEntryIds.size
|
|
12907
12965
|
});
|
|
@@ -12913,7 +12971,10 @@ async function runProposalResolutionPass(input, deps) {
|
|
|
12913
12971
|
observations: [
|
|
12914
12972
|
`Processed ${appliedCount} eligible surgeon proposal${appliedCount === 1 ? "" : "s"}.`,
|
|
12915
12973
|
`${updatedEntryIds.size} entr${updatedEntryIds.size === 1 ? "y was" : "ies were"} targeted by proposal resolution.`,
|
|
12916
|
-
...rejectedInactiveCount > 0 ? [`Rejected ${rejectedInactiveCount} stale eligible proposal${rejectedInactiveCount === 1 ? "" : "s"} whose target entries were no longer active.`] : []
|
|
12974
|
+
...rejectedInactiveCount > 0 ? [`Rejected ${rejectedInactiveCount} stale eligible proposal${rejectedInactiveCount === 1 ? "" : "s"} whose target entries were no longer active.`] : [],
|
|
12975
|
+
...rejectedInvalidCount > 0 ? [
|
|
12976
|
+
`Rejected ${rejectedInvalidCount} malformed eligible proposal${rejectedInvalidCount === 1 ? "" : "s"} that did not resolve to exactly one safe claim-key target.`
|
|
12977
|
+
] : []
|
|
12917
12978
|
],
|
|
12918
12979
|
recommendations: ["Leave non-eligible surgeon proposals on the manual review path."]
|
|
12919
12980
|
},
|
|
@@ -12930,6 +12991,7 @@ function emitProposalResolutionProgress(reporter, input) {
|
|
|
12930
12991
|
processedProposals: input.processedProposals,
|
|
12931
12992
|
appliedCount: input.appliedCount,
|
|
12932
12993
|
rejectedInactiveCount: input.rejectedInactiveCount,
|
|
12994
|
+
rejectedInvalidCount: input.rejectedInvalidCount,
|
|
12933
12995
|
noChangeCount: input.noChangeCount,
|
|
12934
12996
|
targetedEntryCount: input.targetedEntryCount,
|
|
12935
12997
|
proposalId: input.proposalId,
|
|
@@ -16290,8 +16352,8 @@ function handleClaimKeyQualityEvent(event, verbose) {
|
|
|
16290
16352
|
const previewTotal = formatOptionalCount(event.previewTotal);
|
|
16291
16353
|
const previewCompleted = formatOptionalCount(event.previewCompleted);
|
|
16292
16354
|
const previewSuffix = previewTotal > 0 ? `, preview ${previewCompleted}/${previewTotal}` : "";
|
|
16293
|
-
const progressMsg = `${stageLabel}: ${event.completed}/${event.total} ${event.unitLabel}${previewSuffix}, ${appliedTotal} applied, ${event.counts.proposalsEmitted} proposals${skippedSummary}, ${formatElapsed(event.elapsedMs)}`;
|
|
16294
|
-
if (verbose) {
|
|
16355
|
+
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)}`;
|
|
16356
|
+
if (verbose && event.status !== "preview_progress") {
|
|
16295
16357
|
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})`;
|
|
16296
16358
|
writeStderr(` ${ui.dim(progressMsg + detail)}`);
|
|
16297
16359
|
} else {
|
|
@@ -16311,18 +16373,18 @@ function handleProposalResolutionEvent(event, verbose) {
|
|
|
16311
16373
|
const outcome = event.outcome ? `, ${formatProposalResolutionOutcome(event.outcome)}` : "";
|
|
16312
16374
|
const verboseSuffix = verbose && event.proposalId ? ` ${ui.dim(`(${event.proposalId}${event.issueKind ? `, ${event.issueKind}` : ""})`)}` : "";
|
|
16313
16375
|
writeStderr(
|
|
16314
|
-
` ${ui.dim(`proposal_resolution: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}${outcome}`)}${verboseSuffix}`
|
|
16376
|
+
` ${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}`
|
|
16315
16377
|
);
|
|
16316
16378
|
return;
|
|
16317
16379
|
}
|
|
16318
16380
|
case "completed":
|
|
16319
16381
|
writeStderr(
|
|
16320
|
-
` ${ui.success(`proposal_resolution complete: applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
|
|
16382
|
+
` ${ui.success(`proposal_resolution complete: applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, invalid ${event.rejectedInvalidCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
|
|
16321
16383
|
);
|
|
16322
16384
|
return;
|
|
16323
16385
|
case "stalled":
|
|
16324
16386
|
writeStderr(
|
|
16325
|
-
` ${ui.warn(`proposal_resolution stalled: ${event.processedProposals}/${event.totalProposals} proposals, applied ${event.appliedCount}, inactive ${event.rejectedInactiveCount}, no-op ${event.noChangeCount}, targeted ${event.targetedEntryCount}`)}`
|
|
16387
|
+
` ${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}`)}`
|
|
16326
16388
|
);
|
|
16327
16389
|
return;
|
|
16328
16390
|
default:
|
|
@@ -16464,6 +16526,8 @@ function formatProposalResolutionOutcome(outcome) {
|
|
|
16464
16526
|
return "previewed";
|
|
16465
16527
|
case "rejected_inactive":
|
|
16466
16528
|
return "rejected inactive";
|
|
16529
|
+
case "rejected_invalid":
|
|
16530
|
+
return "rejected invalid";
|
|
16467
16531
|
case "no_change":
|
|
16468
16532
|
return "no change";
|
|
16469
16533
|
default:
|