@nathapp/nax 0.65.0 → 0.65.1
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/dist/nax.js +238 -32
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -40710,6 +40710,9 @@ var init_checks_cli = __esm(() => {
|
|
|
40710
40710
|
|
|
40711
40711
|
// src/precheck/checks-system.ts
|
|
40712
40712
|
import { existsSync as existsSync12, statSync as statSync4 } from "fs";
|
|
40713
|
+
function discoverCanonicalRuleRoots(workdir) {
|
|
40714
|
+
return [workdir];
|
|
40715
|
+
}
|
|
40713
40716
|
async function checkDependenciesInstalled(workdir) {
|
|
40714
40717
|
const depPaths = [
|
|
40715
40718
|
{ path: "node_modules" },
|
|
@@ -40787,7 +40790,47 @@ async function checkTypecheckCommand(config2) {
|
|
|
40787
40790
|
message: `Typecheck command configured: ${typecheckCommand}`
|
|
40788
40791
|
};
|
|
40789
40792
|
}
|
|
40790
|
-
|
|
40793
|
+
async function checkCanonicalRulesLint(workdir) {
|
|
40794
|
+
const roots = _checkCanonicalRulesDeps.discoverRoots(workdir);
|
|
40795
|
+
let ruleCount = 0;
|
|
40796
|
+
try {
|
|
40797
|
+
for (const root of roots) {
|
|
40798
|
+
const rules = await _checkCanonicalRulesDeps.loadCanonicalRules(root);
|
|
40799
|
+
ruleCount += rules.length;
|
|
40800
|
+
}
|
|
40801
|
+
} catch (err) {
|
|
40802
|
+
if (err instanceof NeutralityLintError) {
|
|
40803
|
+
const first = err.violations[0];
|
|
40804
|
+
const detail = first ? `${first.file}:${first.lineNumber} (${first.ruleId})` : "unknown location";
|
|
40805
|
+
return {
|
|
40806
|
+
name: "canonical-rules-lint",
|
|
40807
|
+
tier: "blocker",
|
|
40808
|
+
passed: false,
|
|
40809
|
+
message: `Canonical rules lint failed (${err.violations.length} violation(s)): ${detail}`
|
|
40810
|
+
};
|
|
40811
|
+
}
|
|
40812
|
+
return {
|
|
40813
|
+
name: "canonical-rules-lint",
|
|
40814
|
+
tier: "blocker",
|
|
40815
|
+
passed: false,
|
|
40816
|
+
message: `Canonical rules lint failed: ${errorMessage(err)}`
|
|
40817
|
+
};
|
|
40818
|
+
}
|
|
40819
|
+
return {
|
|
40820
|
+
name: "canonical-rules-lint",
|
|
40821
|
+
tier: "blocker",
|
|
40822
|
+
passed: true,
|
|
40823
|
+
message: `Canonical rules lint passed (${ruleCount} file(s) across ${roots.length} root(s))`
|
|
40824
|
+
};
|
|
40825
|
+
}
|
|
40826
|
+
var _checkCanonicalRulesDeps;
|
|
40827
|
+
var init_checks_system = __esm(() => {
|
|
40828
|
+
init_canonical_loader();
|
|
40829
|
+
_checkCanonicalRulesDeps = {
|
|
40830
|
+
discoverRoots: discoverCanonicalRuleRoots,
|
|
40831
|
+
loadCanonicalRules
|
|
40832
|
+
};
|
|
40833
|
+
});
|
|
40791
40834
|
|
|
40792
40835
|
// src/precheck/checks-blockers.ts
|
|
40793
40836
|
var init_checks_blockers = __esm(() => {
|
|
@@ -41255,6 +41298,7 @@ function getLateEnvironmentBlockers(config2, workdir) {
|
|
|
41255
41298
|
() => checkTestCommand(config2),
|
|
41256
41299
|
() => checkLintCommand(config2),
|
|
41257
41300
|
() => checkTypecheckCommand(config2),
|
|
41301
|
+
() => checkCanonicalRulesLint(workdir),
|
|
41258
41302
|
() => checkGitUserConfigured(workdir)
|
|
41259
41303
|
];
|
|
41260
41304
|
}
|
|
@@ -44712,6 +44756,109 @@ var init_diff_utils = __esm(() => {
|
|
|
44712
44756
|
DEFAULT_SUFFIX_STRIPPERS = [/\.(test|spec)\.(ts|js|tsx|jsx)$/, /_test\.go$/];
|
|
44713
44757
|
});
|
|
44714
44758
|
|
|
44759
|
+
// src/review/finding-projection.ts
|
|
44760
|
+
function narrowSeverity(raw) {
|
|
44761
|
+
return SEVERITY_MAP[raw] ?? "info";
|
|
44762
|
+
}
|
|
44763
|
+
function slugLeadingTokens(text, tokenCount = RULE_ID_SLUG_TOKENS) {
|
|
44764
|
+
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter(Boolean).slice(0, tokenCount).join("-");
|
|
44765
|
+
}
|
|
44766
|
+
function deriveRuleId(category, issue2) {
|
|
44767
|
+
const prefix = category?.trim() ? category.trim() : "review";
|
|
44768
|
+
const slug = slugLeadingTokens(issue2) || "unspecified";
|
|
44769
|
+
return `${prefix}:${slug}`;
|
|
44770
|
+
}
|
|
44771
|
+
function joinMessage(issue2, suggestion) {
|
|
44772
|
+
const trimmedIssue = issue2.trim();
|
|
44773
|
+
const trimmedSuggestion = (suggestion ?? "").trim();
|
|
44774
|
+
if (trimmedIssue && trimmedSuggestion) {
|
|
44775
|
+
return `${trimmedIssue}
|
|
44776
|
+
\u2192 ${trimmedSuggestion}`;
|
|
44777
|
+
}
|
|
44778
|
+
return trimmedIssue;
|
|
44779
|
+
}
|
|
44780
|
+
function buildMeta(f, originalSeverity) {
|
|
44781
|
+
const meta3 = {};
|
|
44782
|
+
if (f.issue)
|
|
44783
|
+
meta3.issue = f.issue;
|
|
44784
|
+
if (f.suggestion)
|
|
44785
|
+
meta3.suggestion = f.suggestion;
|
|
44786
|
+
if (f.acQuote)
|
|
44787
|
+
meta3.acQuote = f.acQuote;
|
|
44788
|
+
if (typeof f.acIndex === "number" && f.acIndex >= 1)
|
|
44789
|
+
meta3.acIndex = f.acIndex;
|
|
44790
|
+
if ("acId" in f && f.acId)
|
|
44791
|
+
meta3.acId = f.acId;
|
|
44792
|
+
if ("verifiedBy" in f && f.verifiedBy)
|
|
44793
|
+
meta3.verifiedBy = f.verifiedBy;
|
|
44794
|
+
if (originalSeverity !== undefined)
|
|
44795
|
+
meta3.originalSeverity = originalSeverity;
|
|
44796
|
+
return Object.keys(meta3).length > 0 ? meta3 : undefined;
|
|
44797
|
+
}
|
|
44798
|
+
function findingCategory(f) {
|
|
44799
|
+
return "category" in f && f.category ? f.category : undefined;
|
|
44800
|
+
}
|
|
44801
|
+
function llmFindingToReviewFinding(f, opts = {}) {
|
|
44802
|
+
const category = findingCategory(f);
|
|
44803
|
+
const narrowed = narrowSeverity(f.severity);
|
|
44804
|
+
const result = {
|
|
44805
|
+
ruleId: deriveRuleId(category, f.issue),
|
|
44806
|
+
severity: narrowed,
|
|
44807
|
+
file: f.file,
|
|
44808
|
+
line: f.line,
|
|
44809
|
+
message: joinMessage(f.issue, f.suggestion)
|
|
44810
|
+
};
|
|
44811
|
+
if (category)
|
|
44812
|
+
result.category = category;
|
|
44813
|
+
if (opts.source)
|
|
44814
|
+
result.source = opts.source;
|
|
44815
|
+
const meta3 = buildMeta(f, f.severity !== narrowed ? f.severity : undefined);
|
|
44816
|
+
if (meta3)
|
|
44817
|
+
result.meta = meta3;
|
|
44818
|
+
return result;
|
|
44819
|
+
}
|
|
44820
|
+
function llmFindingsToReviewFindings(findings, opts = {}) {
|
|
44821
|
+
return findings.map((f) => llmFindingToReviewFinding(f, opts));
|
|
44822
|
+
}
|
|
44823
|
+
function findingToReviewFinding(f, opts = {}) {
|
|
44824
|
+
const narrowed = narrowSeverity(f.severity);
|
|
44825
|
+
const ruleId = f.rule?.trim() ? f.rule.trim() : deriveRuleId(f.category, f.message);
|
|
44826
|
+
const result = {
|
|
44827
|
+
ruleId,
|
|
44828
|
+
severity: narrowed,
|
|
44829
|
+
file: f.file ?? "",
|
|
44830
|
+
line: f.line ?? 0,
|
|
44831
|
+
message: f.message
|
|
44832
|
+
};
|
|
44833
|
+
if (f.category)
|
|
44834
|
+
result.category = f.category;
|
|
44835
|
+
const effectiveSource = opts.source ?? f.source;
|
|
44836
|
+
if (effectiveSource)
|
|
44837
|
+
result.source = effectiveSource;
|
|
44838
|
+
const meta3 = { ...f.meta ?? {} };
|
|
44839
|
+
if (f.suggestion)
|
|
44840
|
+
meta3.suggestion = f.suggestion;
|
|
44841
|
+
if (f.severity !== narrowed)
|
|
44842
|
+
meta3.originalSeverity = f.severity;
|
|
44843
|
+
if (Object.keys(meta3).length > 0)
|
|
44844
|
+
result.meta = meta3;
|
|
44845
|
+
return result;
|
|
44846
|
+
}
|
|
44847
|
+
function findingsToReviewFindings(findings, opts = {}) {
|
|
44848
|
+
return findings.map((f) => findingToReviewFinding(f, opts));
|
|
44849
|
+
}
|
|
44850
|
+
var SEVERITY_MAP, RULE_ID_SLUG_TOKENS = 6;
|
|
44851
|
+
var init_finding_projection = __esm(() => {
|
|
44852
|
+
SEVERITY_MAP = {
|
|
44853
|
+
critical: "critical",
|
|
44854
|
+
error: "error",
|
|
44855
|
+
warning: "warning",
|
|
44856
|
+
warn: "warning",
|
|
44857
|
+
info: "info",
|
|
44858
|
+
low: "low"
|
|
44859
|
+
};
|
|
44860
|
+
});
|
|
44861
|
+
|
|
44715
44862
|
// src/review/adversarial.ts
|
|
44716
44863
|
import { relative as relative11, sep as sep3 } from "path";
|
|
44717
44864
|
function recordAdversarialAudit(opts) {
|
|
@@ -45002,8 +45149,11 @@ async function runAdversarialReview(opts) {
|
|
|
45002
45149
|
failOpen: false,
|
|
45003
45150
|
passed: false,
|
|
45004
45151
|
blockingThreshold: threshold,
|
|
45005
|
-
result: {
|
|
45006
|
-
|
|
45152
|
+
result: {
|
|
45153
|
+
passed: false,
|
|
45154
|
+
findings: llmFindingsToReviewFindings(parsed.findings, { source: "adversarial-review" })
|
|
45155
|
+
},
|
|
45156
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "adversarial-review" }) : undefined
|
|
45007
45157
|
});
|
|
45008
45158
|
return {
|
|
45009
45159
|
check: "adversarial",
|
|
@@ -45035,8 +45185,11 @@ ${formatFindings2(blockingFindings)}`,
|
|
|
45035
45185
|
failOpen: false,
|
|
45036
45186
|
passed: true,
|
|
45037
45187
|
blockingThreshold: threshold,
|
|
45038
|
-
result: {
|
|
45039
|
-
|
|
45188
|
+
result: {
|
|
45189
|
+
passed: true,
|
|
45190
|
+
findings: llmFindingsToReviewFindings(parsed.findings, { source: "adversarial-review" })
|
|
45191
|
+
},
|
|
45192
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "adversarial-review" }) : undefined
|
|
45040
45193
|
});
|
|
45041
45194
|
return {
|
|
45042
45195
|
check: "adversarial",
|
|
@@ -45063,8 +45216,11 @@ ${formatFindings2(blockingFindings)}`,
|
|
|
45063
45216
|
failOpen: false,
|
|
45064
45217
|
passed: parsed.passed,
|
|
45065
45218
|
blockingThreshold: threshold,
|
|
45066
|
-
result: {
|
|
45067
|
-
|
|
45219
|
+
result: {
|
|
45220
|
+
passed: parsed.passed,
|
|
45221
|
+
findings: llmFindingsToReviewFindings(parsed.findings, { source: "adversarial-review" })
|
|
45222
|
+
},
|
|
45223
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "adversarial-review" }) : undefined
|
|
45068
45224
|
});
|
|
45069
45225
|
return {
|
|
45070
45226
|
check: "adversarial",
|
|
@@ -45089,6 +45245,7 @@ var init_adversarial = __esm(() => {
|
|
|
45089
45245
|
init_ac_quote_validator();
|
|
45090
45246
|
init_adversarial_helpers();
|
|
45091
45247
|
init_diff_utils();
|
|
45248
|
+
init_finding_projection();
|
|
45092
45249
|
init_review_audit();
|
|
45093
45250
|
_adversarialDeps = {
|
|
45094
45251
|
writeReviewAudit,
|
|
@@ -45481,7 +45638,10 @@ async function runSemanticDebate(opts) {
|
|
|
45481
45638
|
parsed: true,
|
|
45482
45639
|
passed: false,
|
|
45483
45640
|
blockingThreshold,
|
|
45484
|
-
result: {
|
|
45641
|
+
result: {
|
|
45642
|
+
passed: false,
|
|
45643
|
+
findings: findingsToReviewFindings(findings, { source: "semantic-debate-review" })
|
|
45644
|
+
}
|
|
45485
45645
|
});
|
|
45486
45646
|
return {
|
|
45487
45647
|
check: "semantic",
|
|
@@ -45507,7 +45667,10 @@ ${findings.map((f) => `${f.rule ?? "semantic"}: ${f.message}`).join(`
|
|
|
45507
45667
|
parsed: true,
|
|
45508
45668
|
passed: true,
|
|
45509
45669
|
blockingThreshold,
|
|
45510
|
-
result: {
|
|
45670
|
+
result: {
|
|
45671
|
+
passed: true,
|
|
45672
|
+
findings: findingsToReviewFindings(findings, { source: "semantic-debate-review" })
|
|
45673
|
+
}
|
|
45511
45674
|
});
|
|
45512
45675
|
return {
|
|
45513
45676
|
check: "semantic",
|
|
@@ -45567,8 +45730,11 @@ ${findings.map((f) => `${f.rule ?? "semantic"}: ${f.message}`).join(`
|
|
|
45567
45730
|
parsed: true,
|
|
45568
45731
|
passed: false,
|
|
45569
45732
|
blockingThreshold: debateThreshold,
|
|
45570
|
-
result: {
|
|
45571
|
-
|
|
45733
|
+
result: {
|
|
45734
|
+
passed: false,
|
|
45735
|
+
findings: llmFindingsToReviewFindings(debateFindings, { source: "semantic-debate-review" })
|
|
45736
|
+
},
|
|
45737
|
+
advisoryFindings: debateAdvisory.length > 0 ? llmFindingsToReviewFindings(debateAdvisory, { source: "semantic-debate-review" }) : undefined
|
|
45572
45738
|
});
|
|
45573
45739
|
return {
|
|
45574
45740
|
check: "semantic",
|
|
@@ -45596,8 +45762,11 @@ ${formatFindings(debateBlocking)}`,
|
|
|
45596
45762
|
parsed: true,
|
|
45597
45763
|
passed: true,
|
|
45598
45764
|
blockingThreshold: debateThreshold,
|
|
45599
|
-
result: {
|
|
45600
|
-
|
|
45765
|
+
result: {
|
|
45766
|
+
passed: true,
|
|
45767
|
+
findings: llmFindingsToReviewFindings(debateFindings, { source: "semantic-debate-review" })
|
|
45768
|
+
},
|
|
45769
|
+
advisoryFindings: debateAdvisory.length > 0 ? llmFindingsToReviewFindings(debateAdvisory, { source: "semantic-debate-review" }) : undefined
|
|
45601
45770
|
});
|
|
45602
45771
|
return {
|
|
45603
45772
|
check: "semantic",
|
|
@@ -45619,8 +45788,11 @@ ${formatFindings(debateBlocking)}`,
|
|
|
45619
45788
|
parsed: true,
|
|
45620
45789
|
passed: true,
|
|
45621
45790
|
blockingThreshold: debateThreshold,
|
|
45622
|
-
result: {
|
|
45623
|
-
|
|
45791
|
+
result: {
|
|
45792
|
+
passed: true,
|
|
45793
|
+
findings: llmFindingsToReviewFindings(debateFindings, { source: "semantic-debate-review" })
|
|
45794
|
+
},
|
|
45795
|
+
advisoryFindings: debateAdvisory.length > 0 ? llmFindingsToReviewFindings(debateAdvisory, { source: "semantic-debate-review" }) : undefined
|
|
45624
45796
|
});
|
|
45625
45797
|
return {
|
|
45626
45798
|
check: "semantic",
|
|
@@ -45636,6 +45808,7 @@ ${formatFindings(debateBlocking)}`,
|
|
|
45636
45808
|
var init_semantic_debate = __esm(() => {
|
|
45637
45809
|
init_logger2();
|
|
45638
45810
|
init_ac_quote_validator();
|
|
45811
|
+
init_finding_projection();
|
|
45639
45812
|
init_semantic_helpers();
|
|
45640
45813
|
});
|
|
45641
45814
|
|
|
@@ -46036,8 +46209,11 @@ ${formatFindings(blockingFindings)}`;
|
|
|
46036
46209
|
failOpen: false,
|
|
46037
46210
|
passed: false,
|
|
46038
46211
|
blockingThreshold: threshold,
|
|
46039
|
-
result: {
|
|
46040
|
-
|
|
46212
|
+
result: {
|
|
46213
|
+
passed: false,
|
|
46214
|
+
findings: llmFindingsToReviewFindings(sanitizedParsed.findings, { source: "semantic-review" })
|
|
46215
|
+
},
|
|
46216
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "semantic-review" }) : undefined
|
|
46041
46217
|
});
|
|
46042
46218
|
return {
|
|
46043
46219
|
check: "semantic",
|
|
@@ -46067,8 +46243,11 @@ ${formatFindings(blockingFindings)}`;
|
|
|
46067
46243
|
failOpen: false,
|
|
46068
46244
|
passed: true,
|
|
46069
46245
|
blockingThreshold: threshold,
|
|
46070
|
-
result: {
|
|
46071
|
-
|
|
46246
|
+
result: {
|
|
46247
|
+
passed: true,
|
|
46248
|
+
findings: llmFindingsToReviewFindings(sanitizedParsed.findings, { source: "semantic-review" })
|
|
46249
|
+
},
|
|
46250
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "semantic-review" }) : undefined
|
|
46072
46251
|
});
|
|
46073
46252
|
return {
|
|
46074
46253
|
check: "semantic",
|
|
@@ -46095,8 +46274,11 @@ ${formatFindings(blockingFindings)}`;
|
|
|
46095
46274
|
failOpen: false,
|
|
46096
46275
|
passed: sanitizedParsed.passed,
|
|
46097
46276
|
blockingThreshold: threshold,
|
|
46098
|
-
result: {
|
|
46099
|
-
|
|
46277
|
+
result: {
|
|
46278
|
+
passed: sanitizedParsed.passed,
|
|
46279
|
+
findings: llmFindingsToReviewFindings(sanitizedParsed.findings, { source: "semantic-review" })
|
|
46280
|
+
},
|
|
46281
|
+
advisoryFindings: advisoryFindings.length > 0 ? llmFindingsToReviewFindings(advisoryFindings, { source: "semantic-review" }) : undefined
|
|
46100
46282
|
});
|
|
46101
46283
|
return {
|
|
46102
46284
|
check: "semantic",
|
|
@@ -46122,6 +46304,7 @@ var init_semantic = __esm(() => {
|
|
|
46122
46304
|
init_test_runners();
|
|
46123
46305
|
init_ac_quote_validator();
|
|
46124
46306
|
init_diff_utils();
|
|
46307
|
+
init_finding_projection();
|
|
46125
46308
|
init_review_audit();
|
|
46126
46309
|
init_semantic_debate();
|
|
46127
46310
|
init_semantic_evidence();
|
|
@@ -52583,7 +52766,18 @@ async function collectFromMetrics(context) {
|
|
|
52583
52766
|
return observations;
|
|
52584
52767
|
}
|
|
52585
52768
|
function findingRuleId(finding) {
|
|
52586
|
-
return stringValue(finding.
|
|
52769
|
+
return stringValue(finding.ruleId ?? finding.rule ?? finding.checkId ?? finding.category, "unknown");
|
|
52770
|
+
}
|
|
52771
|
+
function findingMessage(finding) {
|
|
52772
|
+
const message = stringValue(finding.message);
|
|
52773
|
+
if (message)
|
|
52774
|
+
return message;
|
|
52775
|
+
const issue2 = stringValue(finding.issue);
|
|
52776
|
+
const suggestion = stringValue(finding.suggestion);
|
|
52777
|
+
if (issue2 && suggestion)
|
|
52778
|
+
return `${issue2}
|
|
52779
|
+
\u2192 ${suggestion}`;
|
|
52780
|
+
return issue2;
|
|
52587
52781
|
}
|
|
52588
52782
|
async function collectFromReviewAudit(context) {
|
|
52589
52783
|
const observations = [];
|
|
@@ -52619,7 +52813,7 @@ async function collectFromReviewAudit(context) {
|
|
|
52619
52813
|
severity: stringValue(finding.severity, "info"),
|
|
52620
52814
|
file: stringValue(finding.file),
|
|
52621
52815
|
line: numberValue(finding.line, 0),
|
|
52622
|
-
message:
|
|
52816
|
+
message: findingMessage(finding)
|
|
52623
52817
|
}
|
|
52624
52818
|
};
|
|
52625
52819
|
observations.push(obs);
|
|
@@ -52893,31 +53087,43 @@ function mergeThresholds(thresholds) {
|
|
|
52893
53087
|
function uniqueStoryIds(storyIds) {
|
|
52894
53088
|
return [...new Set(storyIds)];
|
|
52895
53089
|
}
|
|
53090
|
+
function firstLine2(message) {
|
|
53091
|
+
return message.split(`
|
|
53092
|
+
`)[0] ?? message;
|
|
53093
|
+
}
|
|
52896
53094
|
function h1RepeatedReviewFinding(observations, threshold) {
|
|
52897
53095
|
const findings = observations.filter((o) => o.kind === "review-finding");
|
|
52898
|
-
const
|
|
53096
|
+
const groups = new Map;
|
|
52899
53097
|
for (const obs of findings) {
|
|
52900
53098
|
const ruleId = obs.payload.ruleId;
|
|
52901
|
-
const
|
|
53099
|
+
const message = obs.payload.message;
|
|
53100
|
+
const existing = groups.get(ruleId);
|
|
52902
53101
|
if (existing) {
|
|
52903
|
-
existing.push(obs.storyId);
|
|
53102
|
+
existing.storyIds.push(obs.storyId);
|
|
53103
|
+
const sampleKey = firstLine2(message);
|
|
53104
|
+
if (existing.samples.length < 2 && sampleKey && !existing.samples.includes(sampleKey)) {
|
|
53105
|
+
existing.samples.push(sampleKey);
|
|
53106
|
+
}
|
|
52904
53107
|
} else {
|
|
52905
|
-
|
|
53108
|
+
const sampleKey = firstLine2(message);
|
|
53109
|
+
groups.set(ruleId, { storyIds: [obs.storyId], samples: sampleKey ? [sampleKey] : [] });
|
|
52906
53110
|
}
|
|
52907
53111
|
}
|
|
52908
53112
|
const proposals = [];
|
|
52909
|
-
for (const [ruleId, storyIds] of
|
|
53113
|
+
for (const [ruleId, { storyIds, samples }] of groups.entries()) {
|
|
52910
53114
|
if (storyIds.length < threshold)
|
|
52911
53115
|
continue;
|
|
52912
53116
|
const count = storyIds.length;
|
|
52913
53117
|
const severity = count >= 4 ? "HIGH" : "MED";
|
|
52914
53118
|
const unique = uniqueStoryIds(storyIds);
|
|
53119
|
+
const sampleSection = samples.length > 0 ? `
|
|
53120
|
+
Examples: ${samples.join(" | ")}` : "";
|
|
52915
53121
|
proposals.push({
|
|
52916
53122
|
id: "H1",
|
|
52917
53123
|
severity,
|
|
52918
53124
|
target: { canonicalFile: ".nax/rules/curator-suggestions.md", action: "add" },
|
|
52919
53125
|
description: `Repeated review finding: ${ruleId} appeared ${count}x across stories`,
|
|
52920
|
-
evidence: `Rule ${ruleId} fired ${count}\xD7 in stories: ${unique.join(", ")}`,
|
|
53126
|
+
evidence: `Rule ${ruleId} fired ${count}\xD7 in stories: ${unique.join(", ")}${sampleSection}`,
|
|
52921
53127
|
sourceKinds: ["review-finding"],
|
|
52922
53128
|
storyIds: unique
|
|
52923
53129
|
});
|
|
@@ -54080,7 +54286,7 @@ var package_default;
|
|
|
54080
54286
|
var init_package = __esm(() => {
|
|
54081
54287
|
package_default = {
|
|
54082
54288
|
name: "@nathapp/nax",
|
|
54083
|
-
version: "0.65.
|
|
54289
|
+
version: "0.65.1",
|
|
54084
54290
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
54085
54291
|
type: "module",
|
|
54086
54292
|
bin: {
|
|
@@ -54166,8 +54372,8 @@ var init_version = __esm(() => {
|
|
|
54166
54372
|
NAX_VERSION = package_default.version;
|
|
54167
54373
|
NAX_COMMIT = (() => {
|
|
54168
54374
|
try {
|
|
54169
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
54170
|
-
return "
|
|
54375
|
+
if (/^[0-9a-f]{6,10}$/.test("3aa1ff6b"))
|
|
54376
|
+
return "3aa1ff6b";
|
|
54171
54377
|
} catch {}
|
|
54172
54378
|
try {
|
|
54173
54379
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|