@inerrata-corporation/errata 2.0.13-dev.2998 → 2.0.13-dev.3043
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/consolidate-worker.mjs +141 -1
- package/errata.mjs +992 -224
- package/package.json +1 -1
- package/pass-worker.mjs +180 -3
package/errata.mjs
CHANGED
|
@@ -15488,6 +15488,370 @@ var init_zod = __esm({
|
|
|
15488
15488
|
}
|
|
15489
15489
|
});
|
|
15490
15490
|
|
|
15491
|
+
// ../../packages/shared/src/history-text.ts
|
|
15492
|
+
function looksLikeSecretValue(raw2, quoted) {
|
|
15493
|
+
if (raw2.includes("${") || raw2.includes("{{") || raw2.includes("%(")) return false;
|
|
15494
|
+
if (raw2.startsWith("[redacted:")) return false;
|
|
15495
|
+
if (quoted) return raw2.length > 0;
|
|
15496
|
+
const lower = raw2.toLowerCase();
|
|
15497
|
+
if (ASSIGNMENT_STOPWORDS.has(lower)) return false;
|
|
15498
|
+
if (!/^[A-Za-z0-9+/=_-]{8,}$/.test(raw2)) return false;
|
|
15499
|
+
if (/\d/.test(raw2)) return true;
|
|
15500
|
+
if (raw2.length >= 12) return true;
|
|
15501
|
+
return /[a-z]/.test(raw2) && /[A-Z]/.test(raw2);
|
|
15502
|
+
}
|
|
15503
|
+
function applyRule(text, rule, removed) {
|
|
15504
|
+
let count = 0;
|
|
15505
|
+
const out2 = text.replace(rule.re, (...args2) => {
|
|
15506
|
+
const m = args2.slice(0, -2);
|
|
15507
|
+
const r = rule.replace(m);
|
|
15508
|
+
if (r === null) return m[0];
|
|
15509
|
+
const marker = r.indexOf(REDACTED_CREDENTIAL);
|
|
15510
|
+
if (removed && marker >= 0) {
|
|
15511
|
+
const prefix = r.slice(0, marker), suffix = r.slice(marker + REDACTED_CREDENTIAL.length);
|
|
15512
|
+
if (m[0].startsWith(prefix) && m[0].endsWith(suffix)) {
|
|
15513
|
+
const literal2 = m[0].slice(prefix.length, m[0].length - suffix.length);
|
|
15514
|
+
if (literal2 && !literal2.includes("[redacted:")) removed.add(literal2);
|
|
15515
|
+
}
|
|
15516
|
+
}
|
|
15517
|
+
count += 1;
|
|
15518
|
+
return r;
|
|
15519
|
+
});
|
|
15520
|
+
return { text: out2, count };
|
|
15521
|
+
}
|
|
15522
|
+
function scrubHistoryText(text) {
|
|
15523
|
+
return scrubText(text);
|
|
15524
|
+
}
|
|
15525
|
+
function scrubText(text, removed) {
|
|
15526
|
+
let out2 = text;
|
|
15527
|
+
let credentials = 0;
|
|
15528
|
+
for (const rule of CREDENTIAL_RULES) {
|
|
15529
|
+
const r = applyRule(out2, rule, removed);
|
|
15530
|
+
out2 = r.text;
|
|
15531
|
+
credentials += r.count;
|
|
15532
|
+
}
|
|
15533
|
+
let emails = 0;
|
|
15534
|
+
out2 = out2.replace(EMAIL_RE, () => {
|
|
15535
|
+
emails += 1;
|
|
15536
|
+
return REDACTED_EMAIL;
|
|
15537
|
+
});
|
|
15538
|
+
return { text: out2, credentials, emails };
|
|
15539
|
+
}
|
|
15540
|
+
function scrubHistoryValue(value) {
|
|
15541
|
+
const removed = /* @__PURE__ */ new Set();
|
|
15542
|
+
const visit = (input) => {
|
|
15543
|
+
if (typeof input === "string") return scrubText(input, removed).text;
|
|
15544
|
+
if (Array.isArray(input)) return input.map(visit);
|
|
15545
|
+
if (input && typeof input === "object") return Object.fromEntries(Object.entries(input).map(([key, item]) => {
|
|
15546
|
+
const field = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
15547
|
+
const credentialField = /^(?:token|credential|credentials|pwd|passwd|passphrase)$/.test(field) || /(?:password|secret|secretkey|apikey|accesskey|privatekey|authkey|accesstoken|refreshtoken)$/.test(field);
|
|
15548
|
+
if (typeof item === "string" && credentialField) {
|
|
15549
|
+
const assignment = `${key}: ${JSON.stringify(item)}`;
|
|
15550
|
+
if (scrubText(assignment, removed).credentials > 0) return [key, REDACTED_CREDENTIAL];
|
|
15551
|
+
}
|
|
15552
|
+
return [key, visit(item)];
|
|
15553
|
+
}));
|
|
15554
|
+
return input;
|
|
15555
|
+
};
|
|
15556
|
+
const safe = visit(value);
|
|
15557
|
+
if (!removed.size) return safe;
|
|
15558
|
+
const escaped = [...removed].sort((a, b) => b.length - a.length).map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
15559
|
+
const literals = new RegExp(`(?<![\\p{L}\\p{N}_])(?:${escaped.join("|")})(?![\\p{L}\\p{N}_])`, "gu");
|
|
15560
|
+
const clear = (input) => typeof input === "string" ? input.replace(literals, REDACTED_CREDENTIAL) : Array.isArray(input) ? input.map(clear) : input && typeof input === "object" ? Object.fromEntries(Object.entries(input).map(([k, v]) => [k, clear(v)])) : input;
|
|
15561
|
+
return clear(safe);
|
|
15562
|
+
}
|
|
15563
|
+
var HISTORY_SCRUBBER_VERSION, REDACTED_CREDENTIAL, REDACTED_EMAIL, cred, ASSIGNMENT_STOPWORDS, CREDENTIAL_RULES, EMAIL_RE;
|
|
15564
|
+
var init_history_text = __esm({
|
|
15565
|
+
"../../packages/shared/src/history-text.ts"() {
|
|
15566
|
+
"use strict";
|
|
15567
|
+
HISTORY_SCRUBBER_VERSION = "history-scrub-3";
|
|
15568
|
+
REDACTED_CREDENTIAL = "[redacted:credential]";
|
|
15569
|
+
REDACTED_EMAIL = "[redacted:email]";
|
|
15570
|
+
cred = () => REDACTED_CREDENTIAL;
|
|
15571
|
+
ASSIGNMENT_STOPWORDS = /* @__PURE__ */ new Set([
|
|
15572
|
+
"string",
|
|
15573
|
+
"boolean",
|
|
15574
|
+
"number",
|
|
15575
|
+
"required",
|
|
15576
|
+
"optional",
|
|
15577
|
+
"undefined",
|
|
15578
|
+
"unknown",
|
|
15579
|
+
"function",
|
|
15580
|
+
"process",
|
|
15581
|
+
"request",
|
|
15582
|
+
"response",
|
|
15583
|
+
"password",
|
|
15584
|
+
"secret",
|
|
15585
|
+
"token",
|
|
15586
|
+
"tokens",
|
|
15587
|
+
"credential",
|
|
15588
|
+
"credentials",
|
|
15589
|
+
"bearer",
|
|
15590
|
+
"basic",
|
|
15591
|
+
"example",
|
|
15592
|
+
"redacted",
|
|
15593
|
+
"nullable",
|
|
15594
|
+
"readonly",
|
|
15595
|
+
"override",
|
|
15596
|
+
"abstract",
|
|
15597
|
+
"interface",
|
|
15598
|
+
"constant",
|
|
15599
|
+
"variable",
|
|
15600
|
+
"property",
|
|
15601
|
+
"parameter",
|
|
15602
|
+
"argument",
|
|
15603
|
+
"callback",
|
|
15604
|
+
"promise",
|
|
15605
|
+
"settings",
|
|
15606
|
+
"options",
|
|
15607
|
+
"default",
|
|
15608
|
+
"disabled",
|
|
15609
|
+
"enabled",
|
|
15610
|
+
"internal",
|
|
15611
|
+
"external",
|
|
15612
|
+
"protected",
|
|
15613
|
+
"provided",
|
|
15614
|
+
"resolved",
|
|
15615
|
+
"rejected",
|
|
15616
|
+
"expected",
|
|
15617
|
+
"received",
|
|
15618
|
+
"salt",
|
|
15619
|
+
"hash",
|
|
15620
|
+
"hashed",
|
|
15621
|
+
"hashing",
|
|
15622
|
+
"authentication",
|
|
15623
|
+
"field",
|
|
15624
|
+
"format"
|
|
15625
|
+
]);
|
|
15626
|
+
CREDENTIAL_RULES = [
|
|
15627
|
+
// Human-written seed/reset notes omit assignment punctuation: password `…`
|
|
15628
|
+
// or password (…). Preserve names of fields and hash components.
|
|
15629
|
+
{
|
|
15630
|
+
re: /\b((?:password|passwd|passphrase|pwd)\s+)(["'`(])([^\s"'`,;)}\]]+)(["'`)])/gi,
|
|
15631
|
+
replace: (m) => !ASSIGNMENT_STOPWORDS.has((m[3] ?? "").toLowerCase()) && looksLikeSecretValue(m[3] ?? "", true) ? `${m[1]}${m[2]}${REDACTED_CREDENTIAL}${m[4]}` : null
|
|
15632
|
+
},
|
|
15633
|
+
// "with SeedValue42! credentials" and "with SeedValue42!/seeded account".
|
|
15634
|
+
// Require mixed-case letters plus a digit, or a password-like special char;
|
|
15635
|
+
// ordinary phrases such as "with test credentials" remain useful prose.
|
|
15636
|
+
{
|
|
15637
|
+
re: /\b(with\s+)(["'`]?)([A-Za-z0-9][A-Za-z0-9!@#$%^&*._+=?-]{7,})(["'`]?)(?=\s+credentials\b|\s*\/\s*seeded\b)/gi,
|
|
15638
|
+
replace: (m) => /[a-z]/.test(m[3]) && /[A-Z]/.test(m[3]) && /[0-9!@#$%^&*]/.test(m[3]) ? `${m[1]}${m[2]}${REDACTED_CREDENTIAL}${m[4]}` : null
|
|
15639
|
+
},
|
|
15640
|
+
// Userinfo in connection URLs must be removed before the email rule runs.
|
|
15641
|
+
{
|
|
15642
|
+
re: /\b([a-z][a-z0-9+.-]*:\/\/)([^\s/@:]+):([^\s/@]+)@/gi,
|
|
15643
|
+
replace: (m) => m[2] === "[redacted" && m[3] === "credential]" ? null : `${m[1]}${REDACTED_CREDENTIAL}@`
|
|
15644
|
+
},
|
|
15645
|
+
// Seeded login prose commonly writes email/password without an assignment.
|
|
15646
|
+
{
|
|
15647
|
+
re: /(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+|\[redacted:email\])(\s*\/\s*)(["'\x60]?)([^\s"'\x60,;)}\]]+)/gi,
|
|
15648
|
+
replace: (m) => m[4]?.startsWith("[redacted:") ? null : `${m[1]}${m[2]}${m[3]}${REDACTED_CREDENTIAL}`
|
|
15649
|
+
},
|
|
15650
|
+
// Explicit natural-language passwords, including weak seeded values.
|
|
15651
|
+
{
|
|
15652
|
+
re: /\b((?:password|passwd|passphrase|pwd)\s+(?:is|was|of)\s+)(["'\x60]?)([^\s"'\x60,;)}\]]+)/gi,
|
|
15653
|
+
replace: (m) => {
|
|
15654
|
+
const value = m[3] ?? "";
|
|
15655
|
+
if (ASSIGNMENT_STOPWORDS.has(value.toLowerCase()) || value.startsWith("[redacted:") || /\$\{|\{\{|process\./.test(value)) return null;
|
|
15656
|
+
return `${m[1]}${m[2]}${REDACTED_CREDENTIAL}`;
|
|
15657
|
+
}
|
|
15658
|
+
},
|
|
15659
|
+
// Private-key blocks, including ones a diff prefixes with `+`/`-` per line
|
|
15660
|
+
// and ones the diff context cut before the END line.
|
|
15661
|
+
{
|
|
15662
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY(?: BLOCK)?-----(?:[ \t]*\r?\n[+\- ]?[A-Za-z0-9+/=]{16,}[ \t]*)*(?:[ \t]*\r?\n[+\- ]?-----END [A-Z ]*PRIVATE KEY(?: BLOCK)?-----)?/g,
|
|
15663
|
+
replace: cred
|
|
15664
|
+
},
|
|
15665
|
+
{ re: /\b(?:AKIA|ASIA)[0-9A-Z]{16,}\b/g, replace: cred },
|
|
15666
|
+
// AWS access key id
|
|
15667
|
+
{ re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g, replace: cred },
|
|
15668
|
+
{ re: /\bgh[pousr]_[A-Za-z0-9]{30,}\b/g, replace: cred },
|
|
15669
|
+
{ re: /\bglpat-[A-Za-z0-9_-]{20,}\b/g, replace: cred },
|
|
15670
|
+
{ re: /\bxox[abeprs]-[A-Za-z0-9-]{10,}\b/g, replace: cred },
|
|
15671
|
+
// Slack
|
|
15672
|
+
{ re: /\bsk-(?:ant-)?[A-Za-z0-9_-]{20,}\b/g, replace: cred },
|
|
15673
|
+
// OpenAI / Anthropic
|
|
15674
|
+
{ re: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g, replace: cred },
|
|
15675
|
+
// Stripe
|
|
15676
|
+
{ re: /\brnd_[A-Za-z0-9]{20,}\b/g, replace: cred },
|
|
15677
|
+
// Render
|
|
15678
|
+
{ re: /\bnpm_[A-Za-z0-9]{36}\b/g, replace: cred },
|
|
15679
|
+
{ re: /\bAIza[0-9A-Za-z_-]{35}\b/g, replace: cred },
|
|
15680
|
+
// Google API key
|
|
15681
|
+
{ re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g, replace: cred },
|
|
15682
|
+
// JWT
|
|
15683
|
+
{ re: /(?<![A-Za-z0-9])[A-Za-z0-9]{84}(?![A-Za-z0-9])/g, replace: cred },
|
|
15684
|
+
// Azure-shaped
|
|
15685
|
+
{
|
|
15686
|
+
re: /\b(Bearer|Basic|Token)(\s+)([A-Za-z0-9._~+/=-]{16,})/g,
|
|
15687
|
+
replace: (m) => `${m[1]}${m[2]}${REDACTED_CREDENTIAL}`
|
|
15688
|
+
},
|
|
15689
|
+
// Assignments after key-ish names: `password=...`, `API_KEY: "..."`,
|
|
15690
|
+
// `"client_secret": "..."`, `AWS_SECRET_ACCESS_KEY=...`, 32+ hex/base64 after
|
|
15691
|
+
// any of them. The value heuristic keeps `token: string` and
|
|
15692
|
+
// `password = process.env.X` intact.
|
|
15693
|
+
{
|
|
15694
|
+
re: /((?:[A-Za-z0-9_.-]*?)(?:password|passwd|passphrase|pwd|secret|token|api[_-]?key|apikey|access[_-]?key|private[_-]?key|auth[_-]?key|credential)(?:[A-Za-z0-9_-]*))(["']?\s*(?:=>|=|:)\s*)(["'`]?)([^\s"'`,;)}\]]+)/gi,
|
|
15695
|
+
replace: (m) => {
|
|
15696
|
+
const value = m[4] ?? "";
|
|
15697
|
+
const quote = m[3] ?? "";
|
|
15698
|
+
if (m[1]?.toLowerCase() === "credentials" && /^(include|omit|same-origin)$/.test(value)) return null;
|
|
15699
|
+
if (!looksLikeSecretValue(value, quote.length > 0)) return null;
|
|
15700
|
+
return `${m[1]}${m[2]}${quote}${REDACTED_CREDENTIAL}`;
|
|
15701
|
+
}
|
|
15702
|
+
}
|
|
15703
|
+
];
|
|
15704
|
+
EMAIL_RE = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+\b/g;
|
|
15705
|
+
}
|
|
15706
|
+
});
|
|
15707
|
+
|
|
15708
|
+
// ../../packages/shared/src/history-evidence.ts
|
|
15709
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
15710
|
+
function historyTextDigest(text) {
|
|
15711
|
+
return createHash2("sha256").update(text).digest("hex");
|
|
15712
|
+
}
|
|
15713
|
+
function historySourceBlocks(input) {
|
|
15714
|
+
const blocks = [];
|
|
15715
|
+
const add = (kind, text, commitSha, pathToken) => {
|
|
15716
|
+
const safe = scrubHistoryText(text.replace(/\r\n?/g, "\n")).text.trim();
|
|
15717
|
+
if (safe && safe !== "[truncated]") blocks.push({ id: `b${blocks.length}`, kind, commitSha, pathToken, text: safe, digest: historyTextDigest(safe) });
|
|
15718
|
+
};
|
|
15719
|
+
const narrative2 = scrubHistoryText(input.narrative.replace(/\r\n?/g, "\n")).text;
|
|
15720
|
+
if (input.narrativeSources?.length) {
|
|
15721
|
+
for (const source of input.narrativeSources) {
|
|
15722
|
+
const safe = scrubHistoryText(source.text.replace(/\r\n?/g, "\n")).text.trim();
|
|
15723
|
+
if (safe && narrative2.includes(safe)) add("narrative", safe, source.commitSha, null);
|
|
15724
|
+
}
|
|
15725
|
+
} else {
|
|
15726
|
+
add("narrative", narrative2, input.isMerge ? null : input.commitSha, null);
|
|
15727
|
+
}
|
|
15728
|
+
let token = null;
|
|
15729
|
+
let hunk = [];
|
|
15730
|
+
const flush = () => {
|
|
15731
|
+
if (hunk.some((line) => /^[+-](?![+-]{2})/.test(line))) add("diff", hunk.join("\n"), input.commitSha, token);
|
|
15732
|
+
hunk = [];
|
|
15733
|
+
};
|
|
15734
|
+
for (const line of input.diff.replace(/\r\n?/g, "\n").split("\n")) {
|
|
15735
|
+
if (line.startsWith("diff --git ")) {
|
|
15736
|
+
flush();
|
|
15737
|
+
token = /^diff --git a\/(p\d+) b\/(p\d+)$/.exec(line)?.[2] ?? null;
|
|
15738
|
+
} else if (/^@@ /.test(line)) {
|
|
15739
|
+
flush();
|
|
15740
|
+
hunk.push(line);
|
|
15741
|
+
} else if (!/^(--- |\+\+\+ |index |new file |deleted file |similarity |rename |\[truncated\])/.test(line) && token && /^[ +\-\\]/.test(line)) {
|
|
15742
|
+
hunk.push(line);
|
|
15743
|
+
}
|
|
15744
|
+
}
|
|
15745
|
+
flush();
|
|
15746
|
+
return blocks;
|
|
15747
|
+
}
|
|
15748
|
+
function resolveHistoryEvidence(selection, blocks) {
|
|
15749
|
+
const block = blocks.find((b) => b.id === selection.blockId);
|
|
15750
|
+
if (!block) return null;
|
|
15751
|
+
const quote = selection.quote.replace(/\r\n?/g, "\n");
|
|
15752
|
+
if (scrubHistoryText(quote).text !== quote) return null;
|
|
15753
|
+
let start2 = block.text.indexOf(quote);
|
|
15754
|
+
if (selection.startByte !== void 0) {
|
|
15755
|
+
const prefix = Buffer.from(block.text, "utf8").subarray(0, selection.startByte).toString("utf8");
|
|
15756
|
+
if (Buffer.byteLength(prefix, "utf8") !== selection.startByte || !block.text.startsWith(prefix)) return null;
|
|
15757
|
+
start2 = prefix.length;
|
|
15758
|
+
if (!block.text.startsWith(quote, start2)) return null;
|
|
15759
|
+
} else if (start2 < 0 || block.text.indexOf(quote, start2 + 1) !== -1) return null;
|
|
15760
|
+
const firstLine = block.text.lastIndexOf("\n", start2 - 1) + 1;
|
|
15761
|
+
const selectedLines = block.text.slice(firstLine, start2 + quote.length).split("\n");
|
|
15762
|
+
if (block.kind === "diff" && selectedLines.every((l) => l.startsWith("@@"))) return null;
|
|
15763
|
+
const signs = new Set(selectedLines.filter((l) => !l.startsWith("@@")).map((l) => l[0]));
|
|
15764
|
+
const side = block.kind === "narrative" ? "narrative" : signs.has("+") && signs.has("-") ? "mixed" : signs.has("+") ? "after" : signs.has("-") ? "before" : "context";
|
|
15765
|
+
return {
|
|
15766
|
+
...selection,
|
|
15767
|
+
quote,
|
|
15768
|
+
blockDigest: block.digest,
|
|
15769
|
+
startByte: Buffer.byteLength(block.text.slice(0, start2), "utf8"),
|
|
15770
|
+
endByte: Buffer.byteLength(block.text.slice(0, start2 + quote.length), "utf8"),
|
|
15771
|
+
sourceKind: block.kind,
|
|
15772
|
+
commitSha: block.commitSha,
|
|
15773
|
+
pathToken: block.pathToken,
|
|
15774
|
+
scrubberVersion: HISTORY_SCRUBBER_VERSION,
|
|
15775
|
+
side
|
|
15776
|
+
};
|
|
15777
|
+
}
|
|
15778
|
+
function checkHistoryCandidate(atom, blocks) {
|
|
15779
|
+
const evidence = atom.evidence.map((e) => resolveHistoryEvidence(e, blocks));
|
|
15780
|
+
if (evidence.some((e) => e === null)) return { reason: "missing-evidence", evidence: [] };
|
|
15781
|
+
const refs = evidence;
|
|
15782
|
+
if (!refs.some((e) => e.supports === "statement") || atom.rationale !== null && !refs.some((e) => e.supports === "rationale") || atom.conditions.some((_, i2) => !refs.some((e) => e.supports === "condition" && e.conditionIndex === i2)) || refs.some((e) => e.supports === "relation" || (e.supports === "condition" ? e.conditionIndex === null || e.conditionIndex >= atom.conditions.length : e.conditionIndex !== null))) {
|
|
15783
|
+
return { reason: "missing-field-evidence", evidence: [] };
|
|
15784
|
+
}
|
|
15785
|
+
if (atom.label === "Claim" !== (atom.claimKind !== null)) return { reason: "invalid-kind", evidence: [] };
|
|
15786
|
+
if (atom.anchorTokens.some((token) => !blocks.some((b) => b.kind === "diff" && b.pathToken === token)) || atom.label !== "Claim" && atom.anchorTokens.length === 0) return { reason: "invalid-anchor", evidence: [] };
|
|
15787
|
+
return { reason: "accepted", evidence: refs };
|
|
15788
|
+
}
|
|
15789
|
+
var HISTORY_EVIDENCE_SCHEMA_VERSION, HistoryAnchorSourceSchema, HistorySymbolAnchorSchema, HistoryEvidenceSelectionSchema, HistoryCandidateSchema, HistoryRelationCandidateSchema, HistoryCandidateBatchSchema, HistoryEvidenceRefSchema;
|
|
15790
|
+
var init_history_evidence = __esm({
|
|
15791
|
+
"../../packages/shared/src/history-evidence.ts"() {
|
|
15792
|
+
"use strict";
|
|
15793
|
+
init_zod();
|
|
15794
|
+
init_history_text();
|
|
15795
|
+
HISTORY_EVIDENCE_SCHEMA_VERSION = "history-evidence-1";
|
|
15796
|
+
HistoryAnchorSourceSchema = external_exports.strictObject({
|
|
15797
|
+
sourceCommitSha: external_exports.string().regex(/^[a-f0-9]{40,64}$/),
|
|
15798
|
+
commitSha: external_exports.string().regex(/^[a-f0-9]{40,64}$/),
|
|
15799
|
+
side: external_exports.enum(["before", "after"]),
|
|
15800
|
+
blockDigest: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
15801
|
+
startByte: external_exports.number().int().nonnegative(),
|
|
15802
|
+
endByte: external_exports.number().int().positive(),
|
|
15803
|
+
bodyHash: external_exports.string().regex(/^[a-f0-9]{8,64}$/).optional()
|
|
15804
|
+
}).refine((v) => v.endByte > v.startByte);
|
|
15805
|
+
HistorySymbolAnchorSchema = external_exports.object({
|
|
15806
|
+
symbolId: external_exports.string().regex(/^sym_[a-f0-9]{8,64}$/),
|
|
15807
|
+
kind: external_exports.string().max(40),
|
|
15808
|
+
/** Legacy association, never a source-revision or live validation. */
|
|
15809
|
+
contentHash: external_exports.string().regex(/^[a-f0-9]{8,64}$/).optional(),
|
|
15810
|
+
historical: HistoryAnchorSourceSchema.optional()
|
|
15811
|
+
});
|
|
15812
|
+
HistoryEvidenceSelectionSchema = external_exports.strictObject({
|
|
15813
|
+
blockId: external_exports.string().min(1).max(80),
|
|
15814
|
+
quote: external_exports.string().min(3).max(1600),
|
|
15815
|
+
supports: external_exports.enum(["statement", "condition", "rationale", "relation"]),
|
|
15816
|
+
conditionIndex: external_exports.number().int().min(0).max(7).nullable(),
|
|
15817
|
+
/** Optional exact location disambiguates repeated source lines. */
|
|
15818
|
+
startByte: external_exports.number().int().nonnegative().optional()
|
|
15819
|
+
});
|
|
15820
|
+
HistoryCandidateSchema = external_exports.strictObject({
|
|
15821
|
+
tempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
|
|
15822
|
+
label: external_exports.enum(["Problem", "Solution", "RootCause", "Claim"]),
|
|
15823
|
+
statement: external_exports.string().min(10).max(2e3),
|
|
15824
|
+
claimKind: external_exports.enum(["snapshot", "decision", "constraint"]).nullable(),
|
|
15825
|
+
qualifier: external_exports.enum(["instance", "project"]),
|
|
15826
|
+
conditions: external_exports.array(external_exports.string().min(1).max(300)).max(8),
|
|
15827
|
+
rationale: external_exports.string().min(1).max(1e3).nullable(),
|
|
15828
|
+
evidence: external_exports.array(HistoryEvidenceSelectionSchema).min(1).max(12),
|
|
15829
|
+
anchorTokens: external_exports.array(external_exports.string().regex(/^p[0-9]+$/)).max(8)
|
|
15830
|
+
});
|
|
15831
|
+
HistoryRelationCandidateSchema = external_exports.strictObject({
|
|
15832
|
+
tempId: external_exports.string().regex(/^r[0-9]{1,3}$/),
|
|
15833
|
+
fromTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
|
|
15834
|
+
toTempId: external_exports.string().regex(/^a[0-9]{1,3}$/),
|
|
15835
|
+
meaning: external_exports.enum(["resolves", "mitigates", "caused-by"]),
|
|
15836
|
+
evidence: external_exports.array(HistoryEvidenceSelectionSchema).min(1).max(8)
|
|
15837
|
+
});
|
|
15838
|
+
HistoryCandidateBatchSchema = external_exports.strictObject({
|
|
15839
|
+
atoms: external_exports.array(HistoryCandidateSchema).max(32),
|
|
15840
|
+
relations: external_exports.array(HistoryRelationCandidateSchema).max(32)
|
|
15841
|
+
});
|
|
15842
|
+
HistoryEvidenceRefSchema = HistoryEvidenceSelectionSchema.extend({
|
|
15843
|
+
blockDigest: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
15844
|
+
startByte: external_exports.number().int().nonnegative(),
|
|
15845
|
+
endByte: external_exports.number().int().nonnegative(),
|
|
15846
|
+
sourceKind: external_exports.enum(["narrative", "diff"]),
|
|
15847
|
+
commitSha: external_exports.string().regex(/^[a-f0-9]{40,64}$/).nullable(),
|
|
15848
|
+
pathToken: external_exports.string().regex(/^p[0-9]+$/).nullable(),
|
|
15849
|
+
scrubberVersion: external_exports.string().max(80),
|
|
15850
|
+
side: external_exports.enum(["before", "after", "context", "mixed", "narrative"])
|
|
15851
|
+
});
|
|
15852
|
+
}
|
|
15853
|
+
});
|
|
15854
|
+
|
|
15491
15855
|
// ../../packages/shared/src/edge-rules.ts
|
|
15492
15856
|
function isValidEdge(from, type, to) {
|
|
15493
15857
|
const rule = EDGE_RULES[type];
|
|
@@ -15526,7 +15890,9 @@ var init_edge_rules = __esm({
|
|
|
15526
15890
|
// ── Security spine (v1 taxonomy.ts SECURITY_FORWARD_ONLY commentary) ──
|
|
15527
15891
|
TARGETS: { from: ["Exploit"], to: ["Vulnerability"] },
|
|
15528
15892
|
ENABLES: { from: ["AntiPattern"], to: ["Vulnerability"] },
|
|
15529
|
-
|
|
15893
|
+
// Partial remedies also apply to project Problems/RootCauses. Direction stays
|
|
15894
|
+
// remedy -> ailment; a mitigation must never claim complete SOLVED_BY status.
|
|
15895
|
+
MITIGATES: { from: ["Solution"], to: ["Vulnerability", "Problem", "RootCause"] },
|
|
15530
15896
|
PRESENTS: { from: ["Solution"], to: ["Problem", "Vulnerability"] },
|
|
15531
15897
|
// SOLVED_BY sources: Vulnerability (v1 comment) + Problem/RootCause
|
|
15532
15898
|
// (upstream design-problem.ts + triage.ts mint both).
|
|
@@ -15804,6 +16170,7 @@ var init_wire = __esm({
|
|
|
15804
16170
|
"../../packages/shared/src/wire.ts"() {
|
|
15805
16171
|
"use strict";
|
|
15806
16172
|
init_zod();
|
|
16173
|
+
init_history_evidence();
|
|
15807
16174
|
init_castalia();
|
|
15808
16175
|
init_edge_rules();
|
|
15809
16176
|
init_symbol_intent();
|
|
@@ -15930,6 +16297,12 @@ var init_wire = __esm({
|
|
|
15930
16297
|
attrs: external_exports.object({
|
|
15931
16298
|
confidence: external_exports.number().min(0).max(1).optional(),
|
|
15932
16299
|
extractedBy: external_exports.enum(INGEST_EXTRACTION_SOURCES).optional(),
|
|
16300
|
+
sourceSupport: external_exports.literal("supported").optional(),
|
|
16301
|
+
historicalAnchors: external_exports.array(HistoryAnchorSourceSchema).max(160).optional(),
|
|
16302
|
+
evidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
|
|
16303
|
+
verificationEvidence: external_exports.array(HistoryEvidenceRefSchema).max(12).optional(),
|
|
16304
|
+
verifierBuild: external_exports.string().max(80).optional(),
|
|
16305
|
+
unitDigest: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
15933
16306
|
/** Triage route per-context counts (T3 induction). Carried as structured data
|
|
15934
16307
|
* here; stored JSON-encoded on the Neo4j rel (`perContextJson`). */
|
|
15935
16308
|
perContext: external_exports.record(external_exports.string(), RouteContextCountWireSchema).optional(),
|
|
@@ -16740,6 +17113,178 @@ var init_manifests = __esm({
|
|
|
16740
17113
|
}
|
|
16741
17114
|
});
|
|
16742
17115
|
|
|
17116
|
+
// ../../packages/shared/src/history-quality.ts
|
|
17117
|
+
var init_history_quality = __esm({
|
|
17118
|
+
"../../packages/shared/src/history-quality.ts"() {
|
|
17119
|
+
"use strict";
|
|
17120
|
+
}
|
|
17121
|
+
});
|
|
17122
|
+
|
|
17123
|
+
// ../../packages/shared/src/history-read.ts
|
|
17124
|
+
function historyReadFields(source, attrsJson) {
|
|
17125
|
+
const attrs = unpackHistoryAttrs(typeof attrsJson === "string" ? { attrsJson } : {});
|
|
17126
|
+
const policy = historyReadPolicy({ extractionSource: source, attrs });
|
|
17127
|
+
if (!policy.history) return {};
|
|
17128
|
+
const quality = attrs["historyQuality"];
|
|
17129
|
+
return {
|
|
17130
|
+
historyNotice: policy.notice,
|
|
17131
|
+
...quality && typeof quality === "object" && !Array.isArray(quality) ? { historyQuality: quality } : {}
|
|
17132
|
+
};
|
|
17133
|
+
}
|
|
17134
|
+
function unpackHistoryAttrs(attrs = {}) {
|
|
17135
|
+
let nested = {};
|
|
17136
|
+
if (typeof attrs["attrsJson"] === "string") {
|
|
17137
|
+
try {
|
|
17138
|
+
const parsed = JSON.parse(attrs["attrsJson"]);
|
|
17139
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) nested = parsed;
|
|
17140
|
+
} catch {
|
|
17141
|
+
}
|
|
17142
|
+
}
|
|
17143
|
+
return { ...nested, ...attrs };
|
|
17144
|
+
}
|
|
17145
|
+
function historyReadPolicy(node2, options = {}) {
|
|
17146
|
+
const attrs = unpackHistoryAttrs(node2.attrs);
|
|
17147
|
+
if (attrs["source"] === "cloud" && typeof attrs["extractionSource"] !== "string" && attrs["historyQuality"] == null) {
|
|
17148
|
+
return { allow: options.mode !== "passive", history: false, notice: "Cloud provenance is missing; refresh this cached result before using it as a standing prior." };
|
|
17149
|
+
}
|
|
17150
|
+
const isHistory = node2.extractionSource === "history-mined" || attrs["extractionSource"] === "history-mined" || attrs["historyQuality"] != null;
|
|
17151
|
+
if (!isHistory) return { allow: true, history: false, notice: null };
|
|
17152
|
+
const raw2 = attrs["historyQuality"];
|
|
17153
|
+
const q = raw2 && typeof raw2 === "object" ? raw2 : {};
|
|
17154
|
+
const source = q["sourceSupport"] ?? "unreviewed";
|
|
17155
|
+
const applicability = q["applicability"] ?? "unknown";
|
|
17156
|
+
const current = options.atCommit !== void 0 && q["evaluatedAtCommit"] === options.atCommit;
|
|
17157
|
+
const invalid = source === "contradicted" || source === "quarantined";
|
|
17158
|
+
const passive = options.mode === "passive";
|
|
17159
|
+
const validation = node2.validationSource ?? attrs["validationSource"];
|
|
17160
|
+
const independentlyValidated = validation === "human-explicit" || validation === "human-implicit" || validation === "agent-observed";
|
|
17161
|
+
const allow = !invalid && (!passive || source === "supported" && current && applicability === "applicable" && independentlyValidated);
|
|
17162
|
+
const at = typeof attrs["commitSha"] === "string" ? ` at ${attrs["commitSha"].slice(0, 12)}` : "";
|
|
17163
|
+
return {
|
|
17164
|
+
allow,
|
|
17165
|
+
history: true,
|
|
17166
|
+
notice: `History-derived${at}; source ${String(source)}; applicability ${current ? String(applicability) : "unknown at this checkout"}; ${independentlyValidated ? "separate validation recorded" : "not independently validated"}.`
|
|
17167
|
+
};
|
|
17168
|
+
}
|
|
17169
|
+
var init_history_read = __esm({
|
|
17170
|
+
"../../packages/shared/src/history-read.ts"() {
|
|
17171
|
+
"use strict";
|
|
17172
|
+
}
|
|
17173
|
+
});
|
|
17174
|
+
|
|
17175
|
+
// ../../packages/shared/src/history-temporal.ts
|
|
17176
|
+
async function evaluateHistoryApplicability(intervals, atCommit, isAncestor) {
|
|
17177
|
+
let superseded = false;
|
|
17178
|
+
let historical = false;
|
|
17179
|
+
let uncertain = false;
|
|
17180
|
+
for (const interval of intervals) {
|
|
17181
|
+
const [begun, covered, coherent] = await Promise.all([
|
|
17182
|
+
isAncestor(interval.fromCommit, atCommit),
|
|
17183
|
+
isAncestor(atCommit, interval.throughCommit),
|
|
17184
|
+
isAncestor(interval.fromCommit, interval.throughCommit)
|
|
17185
|
+
]);
|
|
17186
|
+
if (begun === null || covered === null || coherent === null) {
|
|
17187
|
+
uncertain = true;
|
|
17188
|
+
continue;
|
|
17189
|
+
}
|
|
17190
|
+
if (!begun || !covered || !coherent) continue;
|
|
17191
|
+
if (interval.untilCommit) {
|
|
17192
|
+
const [ended, validEnd] = await Promise.all([isAncestor(interval.untilCommit, atCommit), isAncestor(interval.fromCommit, interval.untilCommit)]);
|
|
17193
|
+
if (ended === null || validEnd === null || !validEnd) {
|
|
17194
|
+
uncertain = true;
|
|
17195
|
+
continue;
|
|
17196
|
+
}
|
|
17197
|
+
if (ended) {
|
|
17198
|
+
if (interval.supersededByOccurrence) superseded = true;
|
|
17199
|
+
else historical = true;
|
|
17200
|
+
continue;
|
|
17201
|
+
}
|
|
17202
|
+
}
|
|
17203
|
+
return "applicable";
|
|
17204
|
+
}
|
|
17205
|
+
return uncertain ? "unknown" : superseded ? "superseded" : historical ? "historical" : "unknown";
|
|
17206
|
+
}
|
|
17207
|
+
var init_history_temporal = __esm({
|
|
17208
|
+
"../../packages/shared/src/history-temporal.ts"() {
|
|
17209
|
+
"use strict";
|
|
17210
|
+
}
|
|
17211
|
+
});
|
|
17212
|
+
|
|
17213
|
+
// ../../packages/shared/src/history-revision.ts
|
|
17214
|
+
function historyDag(records) {
|
|
17215
|
+
const graph = new Map(records.map((r) => [r.commit, r.parents]));
|
|
17216
|
+
if (graph.size !== records.length) throw new Error("duplicate Git commit in history proof");
|
|
17217
|
+
const incoming = new Map([...graph].map(([id, parents]) => [id, parents.filter((p) => graph.has(p)).length]));
|
|
17218
|
+
const children = /* @__PURE__ */ new Map();
|
|
17219
|
+
for (const [id, parents] of graph) for (const p of parents) if (graph.has(p)) children.set(p, [...children.get(p) ?? [], id]);
|
|
17220
|
+
const ready = [...incoming].filter(([, n]) => n === 0).map(([id]) => id);
|
|
17221
|
+
let visited = 0;
|
|
17222
|
+
while (ready.length) {
|
|
17223
|
+
const id = ready.pop();
|
|
17224
|
+
visited++;
|
|
17225
|
+
for (const child of children.get(id) ?? []) {
|
|
17226
|
+
const n = incoming.get(child) - 1;
|
|
17227
|
+
incoming.set(child, n);
|
|
17228
|
+
if (n === 0) ready.push(child);
|
|
17229
|
+
}
|
|
17230
|
+
}
|
|
17231
|
+
if (visited !== graph.size) throw new Error("cyclic history proof");
|
|
17232
|
+
return (a, b) => {
|
|
17233
|
+
if (!graph.has(a) || !graph.has(b)) return null;
|
|
17234
|
+
const pending = [b], seen = /* @__PURE__ */ new Set();
|
|
17235
|
+
let missing = false;
|
|
17236
|
+
while (pending.length) {
|
|
17237
|
+
const id = pending.pop();
|
|
17238
|
+
if (id === a) return true;
|
|
17239
|
+
if (seen.has(id)) continue;
|
|
17240
|
+
seen.add(id);
|
|
17241
|
+
const parents = graph.get(id);
|
|
17242
|
+
if (!parents) missing = true;
|
|
17243
|
+
else pending.push(...parents);
|
|
17244
|
+
}
|
|
17245
|
+
return missing ? null : false;
|
|
17246
|
+
};
|
|
17247
|
+
}
|
|
17248
|
+
function occurrenceSourceCommit(o) {
|
|
17249
|
+
const sha2 = o.quality["commitSha"];
|
|
17250
|
+
return typeof sha2 === "string" && Sha.safeParse(sha2).success ? sha2 : null;
|
|
17251
|
+
}
|
|
17252
|
+
function historySemanticKey(projectId, o) {
|
|
17253
|
+
const q = o.quality;
|
|
17254
|
+
const anchors = q["historicalAnchors"];
|
|
17255
|
+
if (q["sourceSupport"] !== "supported" || !anchors?.length || anchors.some((a) => !a.symbolId)) return null;
|
|
17256
|
+
return digest([projectId, o.label, o.statement, q["claimKind"] ?? null, q["qualifier"], q["conditions"], q["rationale"], [...new Set(anchors.map((a) => a.symbolId))].sort()]);
|
|
17257
|
+
}
|
|
17258
|
+
function preservedHistoryOccurrence(o, observed, atCommit, ancestor) {
|
|
17259
|
+
const q = o.quality, source = occurrenceSourceCommit(o);
|
|
17260
|
+
if (!source || ancestor(source, atCommit) !== true || q["sourceSupport"] !== "supported" || !observed) return false;
|
|
17261
|
+
const parsed = external_exports.array(HistoryEvidenceRefSchema).safeParse(q["evidence"]);
|
|
17262
|
+
if (!parsed.success || !parsed.data.length || parsed.data.some((e) => e.sourceKind !== "diff" || !["after", "context"].includes(e.side))) return false;
|
|
17263
|
+
const anchors = q["historicalAnchors"];
|
|
17264
|
+
if (!anchors?.length || anchors.some((a) => a.side !== "after" || !a.bodyHash || !observed.symbols.some((s) => s.symbolId === a.symbolId && s.bodyHash === a.bodyHash))) return false;
|
|
17265
|
+
return parsed.data.every((e) => anchors.some((a) => a.blockDigest === e.blockDigest && a.startByte <= e.startByte && a.endByte >= e.endByte));
|
|
17266
|
+
}
|
|
17267
|
+
var Sha, HistoryRevisionRequestSchema;
|
|
17268
|
+
var init_history_revision = __esm({
|
|
17269
|
+
"../../packages/shared/src/history-revision.ts"() {
|
|
17270
|
+
"use strict";
|
|
17271
|
+
init_zod();
|
|
17272
|
+
init_hash();
|
|
17273
|
+
init_history_evidence();
|
|
17274
|
+
Sha = external_exports.string().regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/);
|
|
17275
|
+
HistoryRevisionRequestSchema = external_exports.strictObject({
|
|
17276
|
+
atCommit: Sha,
|
|
17277
|
+
parents: external_exports.array(external_exports.strictObject({ commit: Sha, parents: external_exports.array(Sha).max(32) })).max(8192),
|
|
17278
|
+
observations: external_exports.array(external_exports.strictObject({
|
|
17279
|
+
occurrenceId: external_exports.string().min(1).max(100),
|
|
17280
|
+
symbols: external_exports.array(external_exports.strictObject({ symbolId: external_exports.string().regex(/^sym_[a-f0-9]{8,64}$/), bodyHash: external_exports.string().regex(/^[a-f0-9]{8,64}$/) })).max(32),
|
|
17281
|
+
/** Scrubbed, tokenized net change from this occurrence's source to atCommit. */
|
|
17282
|
+
diff: external_exports.string().max(16e3).optional()
|
|
17283
|
+
})).max(50)
|
|
17284
|
+
});
|
|
17285
|
+
}
|
|
17286
|
+
});
|
|
17287
|
+
|
|
16743
17288
|
// ../../packages/shared/src/nlp/canonicalize.ts
|
|
16744
17289
|
function canonicalize(value) {
|
|
16745
17290
|
return value.normalize("NFC").trim().toLowerCase().replace(/\s+/g, " ");
|
|
@@ -16809,6 +17354,16 @@ __export(src_exports, {
|
|
|
16809
17354
|
FILE_ANCHOR_QNAME: () => FILE_ANCHOR_QNAME,
|
|
16810
17355
|
GIT_EDGES: () => GIT_EDGES,
|
|
16811
17356
|
GRAPH_EVENT_VOCABULARIES: () => GRAPH_EVENT_VOCABULARIES,
|
|
17357
|
+
HISTORY_EVIDENCE_SCHEMA_VERSION: () => HISTORY_EVIDENCE_SCHEMA_VERSION,
|
|
17358
|
+
HISTORY_SCRUBBER_VERSION: () => HISTORY_SCRUBBER_VERSION,
|
|
17359
|
+
HistoryAnchorSourceSchema: () => HistoryAnchorSourceSchema,
|
|
17360
|
+
HistoryCandidateBatchSchema: () => HistoryCandidateBatchSchema,
|
|
17361
|
+
HistoryCandidateSchema: () => HistoryCandidateSchema,
|
|
17362
|
+
HistoryEvidenceRefSchema: () => HistoryEvidenceRefSchema,
|
|
17363
|
+
HistoryEvidenceSelectionSchema: () => HistoryEvidenceSelectionSchema,
|
|
17364
|
+
HistoryRelationCandidateSchema: () => HistoryRelationCandidateSchema,
|
|
17365
|
+
HistoryRevisionRequestSchema: () => HistoryRevisionRequestSchema,
|
|
17366
|
+
HistorySymbolAnchorSchema: () => HistorySymbolAnchorSchema,
|
|
16812
17367
|
IDENTITY_EDGES: () => IDENTITY_EDGES,
|
|
16813
17368
|
INGEST_EXTRACTION_SOURCES: () => INGEST_EXTRACTION_SOURCES,
|
|
16814
17369
|
INGEST_SOURCES: () => INGEST_SOURCES,
|
|
@@ -16824,6 +17379,8 @@ __export(src_exports, {
|
|
|
16824
17379
|
PROJECT_ONLY_EDGE_TYPES: () => PROJECT_ONLY_EDGE_TYPES,
|
|
16825
17380
|
PROJECT_ONLY_NODE_LABELS: () => PROJECT_ONLY_NODE_LABELS,
|
|
16826
17381
|
QUARANTINE_EXTRACTION_SOURCE_PREFIX: () => QUARANTINE_EXTRACTION_SOURCE_PREFIX,
|
|
17382
|
+
REDACTED_CREDENTIAL: () => REDACTED_CREDENTIAL,
|
|
17383
|
+
REDACTED_EMAIL: () => REDACTED_EMAIL,
|
|
16827
17384
|
RESOLUTION_EDGES: () => RESOLUTION_EDGES,
|
|
16828
17385
|
RE_LEADING_ARTICLE: () => RE_LEADING_ARTICLE,
|
|
16829
17386
|
ROUTING_REASONS: () => ROUTING_REASONS,
|
|
@@ -16854,6 +17411,7 @@ __export(src_exports, {
|
|
|
16854
17411
|
canonicalizeContext: () => canonicalizeContext,
|
|
16855
17412
|
canonicalizeError: () => canonicalizeError,
|
|
16856
17413
|
canonicalizeToken: () => canonicalizeToken,
|
|
17414
|
+
checkHistoryCandidate: () => checkHistoryCandidate,
|
|
16857
17415
|
claimStructure: () => claimStructure,
|
|
16858
17416
|
conceptBag: () => conceptBag,
|
|
16859
17417
|
conceptTokens: () => conceptTokens,
|
|
@@ -16863,8 +17421,15 @@ __export(src_exports, {
|
|
|
16863
17421
|
detectStance: () => detectStance,
|
|
16864
17422
|
digest: () => digest,
|
|
16865
17423
|
errorSignatureEqual: () => errorSignatureEqual,
|
|
17424
|
+
evaluateHistoryApplicability: () => evaluateHistoryApplicability,
|
|
16866
17425
|
extractIdentifierTokens: () => extractIdentifierTokens,
|
|
16867
17426
|
genericCanonicalId: () => genericCanonicalId,
|
|
17427
|
+
historyDag: () => historyDag,
|
|
17428
|
+
historyReadFields: () => historyReadFields,
|
|
17429
|
+
historyReadPolicy: () => historyReadPolicy,
|
|
17430
|
+
historySemanticKey: () => historySemanticKey,
|
|
17431
|
+
historySourceBlocks: () => historySourceBlocks,
|
|
17432
|
+
historyTextDigest: () => historyTextDigest,
|
|
16868
17433
|
identityId: () => identityId,
|
|
16869
17434
|
isAnchorLabelKind: () => isAnchorLabelKind,
|
|
16870
17435
|
isCausalProtected: () => isCausalProtected,
|
|
@@ -16891,6 +17456,7 @@ __export(src_exports, {
|
|
|
16891
17456
|
normalizeSymbolPath: () => normalizeSymbolPath,
|
|
16892
17457
|
normalizeToolName: () => normalizeToolName,
|
|
16893
17458
|
npmPurl: () => npmPurl,
|
|
17459
|
+
occurrenceSourceCommit: () => occurrenceSourceCommit,
|
|
16894
17460
|
operatingSystemCanonicalId: () => operatingSystemCanonicalId,
|
|
16895
17461
|
osNameForPlatform: () => osNameForPlatform,
|
|
16896
17462
|
packageCanonicalId: () => packageCanonicalId,
|
|
@@ -16902,14 +17468,18 @@ __export(src_exports, {
|
|
|
16902
17468
|
parsePackageRef: () => parsePackageRef,
|
|
16903
17469
|
parsePnpmLock: () => parsePnpmLock,
|
|
16904
17470
|
prefilterEntities: () => prefilterEntities,
|
|
17471
|
+
preservedHistoryOccurrence: () => preservedHistoryOccurrence,
|
|
16905
17472
|
problemIdFromError: () => problemIdFromError,
|
|
16906
17473
|
projectSaltedNodeId: () => projectSaltedNodeId,
|
|
16907
17474
|
projectSymbolId: () => projectSymbolId,
|
|
16908
17475
|
provenanceBand: () => provenanceBand,
|
|
16909
17476
|
resolveCanonical: () => resolveCanonical,
|
|
16910
17477
|
resolveCanonicalId: () => resolveCanonicalId,
|
|
17478
|
+
resolveHistoryEvidence: () => resolveHistoryEvidence,
|
|
16911
17479
|
resolveUnambiguousCanonicalId: () => resolveUnambiguousCanonicalId,
|
|
16912
17480
|
retrievalTokens: () => retrievalTokens,
|
|
17481
|
+
scrubHistoryText: () => scrubHistoryText,
|
|
17482
|
+
scrubHistoryValue: () => scrubHistoryValue,
|
|
16913
17483
|
sha256: () => sha256,
|
|
16914
17484
|
sha256Short: () => sha256Short,
|
|
16915
17485
|
sidecarDropBucket: () => sidecarDropBucket,
|
|
@@ -16922,6 +17492,7 @@ __export(src_exports, {
|
|
|
16922
17492
|
toCloudAttrs: () => toCloudAttrs,
|
|
16923
17493
|
toolCanonicalId: () => toolCanonicalId,
|
|
16924
17494
|
triageDiscriminatorAttrs: () => triageDiscriminatorAttrs,
|
|
17495
|
+
unpackHistoryAttrs: () => unpackHistoryAttrs,
|
|
16925
17496
|
unregisteredGraphEventKeys: () => unregisteredGraphEventKeys,
|
|
16926
17497
|
validateCastaliaPayload: () => validateCastaliaPayload,
|
|
16927
17498
|
versionlessPurl: () => versionlessPurl,
|
|
@@ -16940,6 +17511,11 @@ var init_src = __esm({
|
|
|
16940
17511
|
init_project_symbol();
|
|
16941
17512
|
init_lockfile();
|
|
16942
17513
|
init_manifests();
|
|
17514
|
+
init_history_quality();
|
|
17515
|
+
init_history_read();
|
|
17516
|
+
init_history_temporal();
|
|
17517
|
+
init_history_revision();
|
|
17518
|
+
init_history_evidence();
|
|
16943
17519
|
init_hash();
|
|
16944
17520
|
init_error_signature();
|
|
16945
17521
|
init_canonicalize();
|
|
@@ -16949,6 +17525,7 @@ var init_src = __esm({
|
|
|
16949
17525
|
init_predicate();
|
|
16950
17526
|
init_taxonomy();
|
|
16951
17527
|
init_triage_canon();
|
|
17528
|
+
init_history_text();
|
|
16952
17529
|
}
|
|
16953
17530
|
});
|
|
16954
17531
|
|
|
@@ -21307,6 +21884,15 @@ function percolate(l1, l2, opts) {
|
|
|
21307
21884
|
for (const label of PERCOLATING_LABELS) {
|
|
21308
21885
|
for (const n of l1.findNodesByLabel(label)) {
|
|
21309
21886
|
if (n.label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
21887
|
+
if (n.attrs["source"] === "cloud") {
|
|
21888
|
+
const raw2 = l2.getMeta?.(`history-correction:${String(n.attrs["cloudNodeId"] ?? n.id)}`);
|
|
21889
|
+
const correction = raw2 ? JSON.parse(raw2) : null;
|
|
21890
|
+
const support2 = n.attrs["historyQuality"]?.["sourceSupport"];
|
|
21891
|
+
if (correction?.action === "quarantine" || correction?.sourceSupport === "contradicted" || support2 === "quarantined" || support2 === "contradicted") {
|
|
21892
|
+
result.nodesSkipped++;
|
|
21893
|
+
continue;
|
|
21894
|
+
}
|
|
21895
|
+
}
|
|
21310
21896
|
present.add(n.id);
|
|
21311
21897
|
const existing = l2.getNode(n.id);
|
|
21312
21898
|
if (!existing) {
|
|
@@ -24222,6 +24808,7 @@ var init_src5 = __esm({
|
|
|
24222
24808
|
|
|
24223
24809
|
// ../../packages/context-writer/src/render.ts
|
|
24224
24810
|
function isPassiveInjectable(node2) {
|
|
24811
|
+
if (!historyReadPolicy(node2, { mode: "passive" }).allow) return false;
|
|
24225
24812
|
if (node2.label === "Pattern" || node2.label === "Technique" || node2.label === "AntiPattern") {
|
|
24226
24813
|
return true;
|
|
24227
24814
|
}
|
|
@@ -24231,7 +24818,7 @@ function isPassiveInjectable(node2) {
|
|
|
24231
24818
|
return false;
|
|
24232
24819
|
}
|
|
24233
24820
|
function buildSnapshot(opts) {
|
|
24234
|
-
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0);
|
|
24821
|
+
const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive" }).allow);
|
|
24235
24822
|
const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
|
|
24236
24823
|
const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
|
|
24237
24824
|
allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
|
|
@@ -24261,10 +24848,11 @@ function buildSnapshot(opts) {
|
|
|
24261
24848
|
...opts.store.findNodesByLabel("Pattern"),
|
|
24262
24849
|
...opts.store.findNodesByLabel("Technique"),
|
|
24263
24850
|
...opts.store.findNodesByLabel("AntiPattern")
|
|
24264
|
-
].sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
|
|
24851
|
+
].filter((n) => historyReadPolicy(n, { mode: "passive" }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
|
|
24265
24852
|
const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile) : void 0;
|
|
24266
24853
|
const byEpisode = /* @__PURE__ */ new Map();
|
|
24267
24854
|
for (const sol of opts.store.findNodesByLabel("Solution")) {
|
|
24855
|
+
if (!historyReadPolicy(sol, { mode: "passive" }).allow) continue;
|
|
24268
24856
|
if (sol.attrs["enrichmentPending"] !== true) continue;
|
|
24269
24857
|
const ep = sol.attrs["episodeId"] ?? sol.id;
|
|
24270
24858
|
const list = byEpisode.get(ep) ?? [];
|
|
@@ -24374,6 +24962,14 @@ function sliceForFile(store, relPath) {
|
|
|
24374
24962
|
if (externalRefs.length >= 20) break;
|
|
24375
24963
|
}
|
|
24376
24964
|
const fp = priorsForFile(store, relPath);
|
|
24965
|
+
if (fp) {
|
|
24966
|
+
const allowed = (n) => historyReadPolicy(n, { mode: "passive" }).allow;
|
|
24967
|
+
fp.openProblems = fp.openProblems.filter(allowed);
|
|
24968
|
+
fp.constraints = fp.constraints.filter(allowed);
|
|
24969
|
+
fp.resolvedProblems = fp.resolvedProblems.filter(allowed);
|
|
24970
|
+
fp.related = fp.related.filter(allowed);
|
|
24971
|
+
for (const [id, solutions] of fp.solutionsByProblem) fp.solutionsByProblem.set(id, solutions.filter(allowed));
|
|
24972
|
+
}
|
|
24377
24973
|
const priors = fp ? {
|
|
24378
24974
|
openProblems: fp.openProblems.slice(0, 3).map((p) => ({
|
|
24379
24975
|
id: p.id,
|
|
@@ -24846,6 +25442,7 @@ var init_render = __esm({
|
|
|
24846
25442
|
"use strict";
|
|
24847
25443
|
init_src5();
|
|
24848
25444
|
init_src2();
|
|
25445
|
+
init_src();
|
|
24849
25446
|
RECALL_FIRST_HEADER = "## errata \u2014 recall before you work";
|
|
24850
25447
|
RECALL_FIRST_BODY = "Before investigating any bug or error, your FIRST tool call must be `mcp__errata__errata_search` with a few words describing the problem. This machine's knowledge graph records previously solved problems \u2014 the answer may already be recorded. Read what it returns before touching any files.";
|
|
24851
25448
|
RECALL_FIRST_BLOCK = `${RECALL_FIRST_HEADER}
|
|
@@ -24993,7 +25590,7 @@ function selectDurableMemory(store, profile, opts = {}) {
|
|
|
24993
25590
|
const minContributors = opts.minContributors ?? 1;
|
|
24994
25591
|
const wsLangs = new Set(profile.languages.map((l) => l.toLowerCase()));
|
|
24995
25592
|
return store.findNodesByLabel("Claim").filter(
|
|
24996
|
-
(n) => Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) === ABSTRACTION_LEVEL.PRINCIPLE && n.attrs["provisional"] === false && contributorsOf(n) >= minContributors && // Lang-relevance: universal principles (no scope.lang) bleed everywhere; a
|
|
25593
|
+
(n) => historyReadPolicy(n, { mode: "passive" }).allow && Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) === ABSTRACTION_LEVEL.PRINCIPLE && n.attrs["provisional"] === false && contributorsOf(n) >= minContributors && // Lang-relevance: universal principles (no scope.lang) bleed everywhere; a
|
|
24997
25594
|
// language-scoped principle only bleeds into repos that USE that language —
|
|
24998
25595
|
// so a Python principle never lands a dead `**/*.py` rule in a TS repo.
|
|
24999
25596
|
(scopeLangOf(n) == null || wsLangs.has(scopeLangOf(n)))
|
|
@@ -25017,6 +25614,7 @@ var init_select_durable_memory = __esm({
|
|
|
25017
25614
|
"../../packages/context-writer/src/select-durable-memory.ts"() {
|
|
25018
25615
|
"use strict";
|
|
25019
25616
|
init_src2();
|
|
25617
|
+
init_src();
|
|
25020
25618
|
num2 = (v, d = 0) => typeof v === "number" && Number.isFinite(v) ? v : d;
|
|
25021
25619
|
LANG_GLOBS = {
|
|
25022
25620
|
typescript: ["**/*.ts", "**/*.tsx"],
|
|
@@ -25854,7 +26452,7 @@ var init_client = __esm({
|
|
|
25854
26452
|
label: n.label,
|
|
25855
26453
|
description: n.description,
|
|
25856
26454
|
extractionConfidence: typeof n.attrs["score"] === "number" ? clamp012(n.attrs["score"]) : 0.5,
|
|
25857
|
-
extractionSource: "
|
|
26455
|
+
extractionSource: INGEST_EXTRACTION_SOURCES.includes(n.attrs["extractionSource"]) ? n.attrs["extractionSource"] : "cold-start-seed",
|
|
25858
26456
|
embedding: [],
|
|
25859
26457
|
cumulativeSurprise: 0,
|
|
25860
26458
|
peakSurprise: 0,
|
|
@@ -25866,7 +26464,7 @@ var init_client = __esm({
|
|
|
25866
26464
|
isLandmark: false,
|
|
25867
26465
|
community: null,
|
|
25868
26466
|
stability: "stable",
|
|
25869
|
-
attrs: { ...n.attrs, source: "cloud", cloudNodeId: n.nodeId }
|
|
26467
|
+
attrs: { ...unpackHistoryAttrs(n.attrs), source: "cloud", cloudNodeId: n.nodeId }
|
|
25870
26468
|
}));
|
|
25871
26469
|
const edges = res.edges.map((e) => ({
|
|
25872
26470
|
id: digest({ from: e.fromCanonicalId, type: e.type, to: e.toCanonicalId }),
|
|
@@ -25915,6 +26513,17 @@ var init_client = __esm({
|
|
|
25915
26513
|
* daemon filters the page against its own checkout, and nothing about which
|
|
25916
26514
|
* symbols it holds is sent. Same membership gate as priors.
|
|
25917
26515
|
*/
|
|
26516
|
+
/** Content-free invalidations, independent of code-symbol/anchor availability. */
|
|
26517
|
+
async getProjectHistoryCorrections(projectId, since, limit = 200) {
|
|
26518
|
+
return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/anchors?correctionsOnly=1&correctionSince=${String(since)}&limit=${String(limit)}`);
|
|
26519
|
+
}
|
|
26520
|
+
async getHistoryOccurrences(projectId, atCommit, after) {
|
|
26521
|
+
const query = new URLSearchParams({ atCommit, limit: "50", ...after ? { after } : {} });
|
|
26522
|
+
return this.json("GET", `/v2/projects/${encodeURIComponent(projectId)}/history/occurrences?${query}`);
|
|
26523
|
+
}
|
|
26524
|
+
async reconcileHistory(projectId, proof) {
|
|
26525
|
+
return this.json("POST", `/v2/projects/${encodeURIComponent(projectId)}/history/reconcile`, proof);
|
|
26526
|
+
}
|
|
25918
26527
|
async getProjectAnchors(projectId, since, limit = 200) {
|
|
25919
26528
|
const res = await this.json(
|
|
25920
26529
|
"GET",
|
|
@@ -26066,13 +26675,13 @@ var init_client = __esm({
|
|
|
26066
26675
|
});
|
|
26067
26676
|
|
|
26068
26677
|
// ../../packages/cloud-client/src/pkce.ts
|
|
26069
|
-
import { createHash as
|
|
26678
|
+
import { createHash as createHash3, randomBytes } from "node:crypto";
|
|
26070
26679
|
function base64url3(buf) {
|
|
26071
26680
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
26072
26681
|
}
|
|
26073
26682
|
function generatePkce() {
|
|
26074
26683
|
const verifier = base64url3(randomBytes(32));
|
|
26075
|
-
const challenge = base64url3(
|
|
26684
|
+
const challenge = base64url3(createHash3("sha256").update(verifier).digest());
|
|
26076
26685
|
return { verifier, challenge, method: "S256" };
|
|
26077
26686
|
}
|
|
26078
26687
|
function randomState() {
|
|
@@ -29368,14 +29977,14 @@ var init_git_remote = __esm({
|
|
|
29368
29977
|
|
|
29369
29978
|
// src/profile.ts
|
|
29370
29979
|
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
29371
|
-
import { createHash as
|
|
29980
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
29372
29981
|
import { join as join7 } from "node:path";
|
|
29373
29982
|
function workspaceId(root) {
|
|
29374
|
-
return "wp_" +
|
|
29983
|
+
return "wp_" + createHash4("sha256").update(root).digest("hex").slice(0, 12);
|
|
29375
29984
|
}
|
|
29376
29985
|
function sessionOriginKey(sessionId) {
|
|
29377
29986
|
if (!sessionId) return void 0;
|
|
29378
|
-
return "ws_" +
|
|
29987
|
+
return "ws_" + createHash4("sha256").update(sessionId).digest("hex").slice(0, 12);
|
|
29379
29988
|
}
|
|
29380
29989
|
function refreshRepoLocator(root, profile) {
|
|
29381
29990
|
const detected = detectRepoLocator(root, profile.repoRemote);
|
|
@@ -29813,7 +30422,7 @@ function scrub(input) {
|
|
|
29813
30422
|
return `<api-key:${id}>`;
|
|
29814
30423
|
});
|
|
29815
30424
|
}
|
|
29816
|
-
text = text.replace(
|
|
30425
|
+
text = text.replace(EMAIL_RE2, (m) => {
|
|
29817
30426
|
const id = sha256Short(m, 6);
|
|
29818
30427
|
bump("email", `<email:${id}>`);
|
|
29819
30428
|
return `<email:${id}>`;
|
|
@@ -29864,8 +30473,8 @@ function detectViolations(input) {
|
|
|
29864
30473
|
if (p.re.test(input)) violations.add("api-key");
|
|
29865
30474
|
p.re.lastIndex = 0;
|
|
29866
30475
|
}
|
|
29867
|
-
if (
|
|
29868
|
-
|
|
30476
|
+
if (EMAIL_RE2.test(input)) violations.add("email");
|
|
30477
|
+
EMAIL_RE2.lastIndex = 0;
|
|
29869
30478
|
if (WIN_PATH_RE.test(input)) violations.add("windows-path");
|
|
29870
30479
|
WIN_PATH_RE.lastIndex = 0;
|
|
29871
30480
|
if (WIN_UNC_RE.test(input)) violations.add("windows-path");
|
|
@@ -29876,7 +30485,7 @@ function detectViolations(input) {
|
|
|
29876
30485
|
IPV4_RE.lastIndex = 0;
|
|
29877
30486
|
return [...violations];
|
|
29878
30487
|
}
|
|
29879
|
-
var API_KEY_PATTERNS,
|
|
30488
|
+
var API_KEY_PATTERNS, EMAIL_RE2, IPV4_RE, IPV6_RE, WIN_PATH_RE, WIN_UNC_RE, POSIX_USER_PATH_RE, LONG_HASH_RE, UUID_RE;
|
|
29880
30489
|
var init_scrub = __esm({
|
|
29881
30490
|
"../../packages/canonical/src/scrub.ts"() {
|
|
29882
30491
|
"use strict";
|
|
@@ -29890,7 +30499,7 @@ var init_scrub = __esm({
|
|
|
29890
30499
|
{ name: "stripe-key", re: /\b(sk|pk)_(test|live)_[0-9a-zA-Z]{24,}\b/g },
|
|
29891
30500
|
{ name: "bearer", re: /\bBearer\s+[A-Za-z0-9_\-\.]{16,}\b/gi }
|
|
29892
30501
|
];
|
|
29893
|
-
|
|
30502
|
+
EMAIL_RE2 = /\b[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}\b/g;
|
|
29894
30503
|
IPV4_RE = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
29895
30504
|
IPV6_RE = /\b(?:[A-Fa-f0-9]{1,4}:){2,7}[A-Fa-f0-9:]{1,4}\b/g;
|
|
29896
30505
|
WIN_PATH_RE = /\b[A-Za-z]:[\\/](?![\\/])(?:[^\\/\s"']+[\\/])*[^\\/\s"']*/g;
|
|
@@ -32901,7 +33510,7 @@ var init_src10 = __esm({
|
|
|
32901
33510
|
});
|
|
32902
33511
|
|
|
32903
33512
|
// ../../packages/indexer/src/parse-cache.ts
|
|
32904
|
-
import { createHash as
|
|
33513
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
32905
33514
|
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
32906
33515
|
import { homedir as homedir3 } from "node:os";
|
|
32907
33516
|
import { join as join11 } from "node:path";
|
|
@@ -32909,7 +33518,7 @@ function parseCacheDir() {
|
|
|
32909
33518
|
return process.env["ERRATA_PARSE_CACHE"] ?? join11(homedir3(), ".errata", "parse-cache");
|
|
32910
33519
|
}
|
|
32911
33520
|
function parseCacheKey(source, providerId) {
|
|
32912
|
-
return
|
|
33521
|
+
return createHash5("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
|
|
32913
33522
|
}
|
|
32914
33523
|
function entryPath(dir, key) {
|
|
32915
33524
|
return join11(dir, key.slice(0, 2), `${key.slice(2)}.json`);
|
|
@@ -33207,7 +33816,7 @@ var init_identity3 = __esm({
|
|
|
33207
33816
|
import { appendFileSync, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
|
|
33208
33817
|
import { readdir } from "node:fs/promises";
|
|
33209
33818
|
import { extname, join as join12, relative as relative2, sep } from "node:path";
|
|
33210
|
-
import { createHash as
|
|
33819
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
33211
33820
|
import { execFileSync } from "node:child_process";
|
|
33212
33821
|
function nowTs() {
|
|
33213
33822
|
return indexNow ?? Date.now();
|
|
@@ -33216,7 +33825,7 @@ function fingerprintOf(signature, bodyHash) {
|
|
|
33216
33825
|
return `${signature ?? ""}|${bodyHash ?? ""}`;
|
|
33217
33826
|
}
|
|
33218
33827
|
function sha(s) {
|
|
33219
|
-
return
|
|
33828
|
+
return createHash6("sha256").update(s).digest("hex").slice(0, 16);
|
|
33220
33829
|
}
|
|
33221
33830
|
function fileNodeId(workspaceId2, relPath) {
|
|
33222
33831
|
return `file_${sha(workspaceId2 + ":" + relPath.replace(/\\/g, "/"))}`;
|
|
@@ -33344,7 +33953,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
33344
33953
|
for (const rel of [...changedRelPaths]) {
|
|
33345
33954
|
let h;
|
|
33346
33955
|
try {
|
|
33347
|
-
h =
|
|
33956
|
+
h = createHash6("sha256").update(readFileSync11(join12(rootPath, rel))).digest("hex");
|
|
33348
33957
|
} catch {
|
|
33349
33958
|
continue;
|
|
33350
33959
|
}
|
|
@@ -34267,7 +34876,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
|
|
|
34267
34876
|
if (existing && fileUnchanged(existing.attrs, f, skip)) return;
|
|
34268
34877
|
let contentHash;
|
|
34269
34878
|
try {
|
|
34270
|
-
contentHash =
|
|
34879
|
+
contentHash = createHash6("sha256").update(readFileSync11(f.absPath)).digest("hex");
|
|
34271
34880
|
} catch {
|
|
34272
34881
|
}
|
|
34273
34882
|
const carried = { ...existing?.attrs ?? {} };
|
|
@@ -38796,7 +39405,7 @@ var init_tree_sitter_loader = __esm({
|
|
|
38796
39405
|
});
|
|
38797
39406
|
|
|
38798
39407
|
// ../../packages/indexer/src/languages/typescript-treesitter.ts
|
|
38799
|
-
import { createHash as
|
|
39408
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
38800
39409
|
function extractNode(node2, source, containerQname, containerKind) {
|
|
38801
39410
|
switch (node2.type) {
|
|
38802
39411
|
case "function_declaration":
|
|
@@ -39009,7 +39618,7 @@ function scopeRecord(kind, name2, qname, node2, body2, source) {
|
|
|
39009
39618
|
const sig = header.replace(/\s+/g, " ").trim();
|
|
39010
39619
|
if (sig) rec.signature = sig;
|
|
39011
39620
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
39012
|
-
rec.bodyHash =
|
|
39621
|
+
rec.bodyHash = createHash7("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
39013
39622
|
rec.bodySimhash = toHex(simhash(bodyText));
|
|
39014
39623
|
}
|
|
39015
39624
|
}
|
|
@@ -39451,14 +40060,14 @@ var init_typescript_treesitter = __esm({
|
|
|
39451
40060
|
});
|
|
39452
40061
|
|
|
39453
40062
|
// ../../packages/indexer/src/languages/python-treesitter.ts
|
|
39454
|
-
import { createHash as
|
|
40063
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
39455
40064
|
function sigAndHash(node2, body2, source) {
|
|
39456
40065
|
if (!body2) return {};
|
|
39457
40066
|
const out2 = {};
|
|
39458
40067
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
39459
40068
|
if (sig) out2.signature = sig;
|
|
39460
40069
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
39461
|
-
out2.bodyHash =
|
|
40070
|
+
out2.bodyHash = createHash8("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
39462
40071
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
39463
40072
|
return out2;
|
|
39464
40073
|
}
|
|
@@ -39871,7 +40480,7 @@ var init_python_treesitter = __esm({
|
|
|
39871
40480
|
});
|
|
39872
40481
|
|
|
39873
40482
|
// ../../packages/indexer/src/languages/cpp-treesitter.ts
|
|
39874
|
-
import { createHash as
|
|
40483
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
39875
40484
|
function extractNode3(node2, containerQname, containerIsClass, source) {
|
|
39876
40485
|
switch (node2.type) {
|
|
39877
40486
|
case "function_definition":
|
|
@@ -40055,7 +40664,7 @@ function sigAndHash2(node2, body2, source) {
|
|
|
40055
40664
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
40056
40665
|
if (sig) out2.signature = sig;
|
|
40057
40666
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
40058
|
-
out2.bodyHash =
|
|
40667
|
+
out2.bodyHash = createHash9("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
40059
40668
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
40060
40669
|
return out2;
|
|
40061
40670
|
}
|
|
@@ -40216,7 +40825,7 @@ var init_cpp_treesitter = __esm({
|
|
|
40216
40825
|
});
|
|
40217
40826
|
|
|
40218
40827
|
// ../../packages/indexer/src/languages/go-treesitter.ts
|
|
40219
|
-
import { createHash as
|
|
40828
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
40220
40829
|
function extractNode4(node2, containerQname, source) {
|
|
40221
40830
|
switch (node2.type) {
|
|
40222
40831
|
case "function_declaration": {
|
|
@@ -40378,7 +40987,7 @@ function sigAndHash3(node2, body2, source) {
|
|
|
40378
40987
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
40379
40988
|
if (sig) out2.signature = sig;
|
|
40380
40989
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
40381
|
-
out2.bodyHash =
|
|
40990
|
+
out2.bodyHash = createHash10("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
40382
40991
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
40383
40992
|
return out2;
|
|
40384
40993
|
}
|
|
@@ -40522,7 +41131,7 @@ var init_go_treesitter = __esm({
|
|
|
40522
41131
|
});
|
|
40523
41132
|
|
|
40524
41133
|
// ../../packages/indexer/src/languages/rust-treesitter.ts
|
|
40525
|
-
import { createHash as
|
|
41134
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
40526
41135
|
function extractNode5(node2, containerQname, containerIsClass, source) {
|
|
40527
41136
|
switch (node2.type) {
|
|
40528
41137
|
case "function_item":
|
|
@@ -40737,7 +41346,7 @@ function sigAndHash4(node2, body2, source) {
|
|
|
40737
41346
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
40738
41347
|
if (sig) out2.signature = sig;
|
|
40739
41348
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
40740
|
-
out2.bodyHash =
|
|
41349
|
+
out2.bodyHash = createHash11("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
40741
41350
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
40742
41351
|
return out2;
|
|
40743
41352
|
}
|
|
@@ -40888,7 +41497,7 @@ var init_rust_treesitter = __esm({
|
|
|
40888
41497
|
});
|
|
40889
41498
|
|
|
40890
41499
|
// ../../packages/indexer/src/languages/ruby-treesitter.ts
|
|
40891
|
-
import { createHash as
|
|
41500
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
40892
41501
|
function sigAndHash5(node2, body2, source) {
|
|
40893
41502
|
if (!body2) {
|
|
40894
41503
|
const sig2 = source.slice(node2.startIndex, node2.endIndex).replace(/\s+/g, " ").trim();
|
|
@@ -40898,7 +41507,7 @@ function sigAndHash5(node2, body2, source) {
|
|
|
40898
41507
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
40899
41508
|
if (sig) out2.signature = sig;
|
|
40900
41509
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
40901
|
-
out2.bodyHash =
|
|
41510
|
+
out2.bodyHash = createHash12("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
40902
41511
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
40903
41512
|
return out2;
|
|
40904
41513
|
}
|
|
@@ -41244,7 +41853,7 @@ var init_ruby_treesitter = __esm({
|
|
|
41244
41853
|
});
|
|
41245
41854
|
|
|
41246
41855
|
// ../../packages/indexer/src/languages/csharp-treesitter.ts
|
|
41247
|
-
import { createHash as
|
|
41856
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
41248
41857
|
function extractNode7(node2, containerQname, containerIsType, source, eof) {
|
|
41249
41858
|
switch (node2.type) {
|
|
41250
41859
|
case "method_declaration":
|
|
@@ -41446,7 +42055,7 @@ function sigAndHash6(node2, body2, source) {
|
|
|
41446
42055
|
const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
|
|
41447
42056
|
if (sig) out2.signature = sig;
|
|
41448
42057
|
const bodyText = source.slice(body2.startIndex, body2.endIndex);
|
|
41449
|
-
out2.bodyHash =
|
|
42058
|
+
out2.bodyHash = createHash13("sha256").update(bodyText).digest("hex").slice(0, 16);
|
|
41450
42059
|
out2.bodySimhash = toHex(simhash(bodyText));
|
|
41451
42060
|
return out2;
|
|
41452
42061
|
}
|
|
@@ -51362,10 +51971,10 @@ import {
|
|
|
51362
51971
|
writeFileSync as writeFileSync11
|
|
51363
51972
|
} from "node:fs";
|
|
51364
51973
|
import { join as join16 } from "node:path";
|
|
51365
|
-
import { createHash as
|
|
51974
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
51366
51975
|
function enqueueOutbox(paths, payload) {
|
|
51367
51976
|
ensureDir(paths.outbox);
|
|
51368
|
-
const id =
|
|
51977
|
+
const id = createHash14("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
51369
51978
|
const file2 = join16(paths.outbox, `${Date.now()}-${id}.json`);
|
|
51370
51979
|
writeFileSync11(file2, JSON.stringify(payload, null, 2), "utf8");
|
|
51371
51980
|
return file2;
|
|
@@ -63247,7 +63856,7 @@ var require_mock_interceptor = __commonJS({
|
|
|
63247
63856
|
var require_mock_client = __commonJS({
|
|
63248
63857
|
"../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-client.js"(exports, module2) {
|
|
63249
63858
|
"use strict";
|
|
63250
|
-
var { promisify:
|
|
63859
|
+
var { promisify: promisify4 } = __require("node:util");
|
|
63251
63860
|
var Client = require_client();
|
|
63252
63861
|
var { buildMockDispatch } = require_mock_utils();
|
|
63253
63862
|
var {
|
|
@@ -63287,7 +63896,7 @@ var require_mock_client = __commonJS({
|
|
|
63287
63896
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
63288
63897
|
}
|
|
63289
63898
|
async [kClose]() {
|
|
63290
|
-
await
|
|
63899
|
+
await promisify4(this[kOriginalClose])();
|
|
63291
63900
|
this[kConnected] = 0;
|
|
63292
63901
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
63293
63902
|
}
|
|
@@ -63300,7 +63909,7 @@ var require_mock_client = __commonJS({
|
|
|
63300
63909
|
var require_mock_pool = __commonJS({
|
|
63301
63910
|
"../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-pool.js"(exports, module2) {
|
|
63302
63911
|
"use strict";
|
|
63303
|
-
var { promisify:
|
|
63912
|
+
var { promisify: promisify4 } = __require("node:util");
|
|
63304
63913
|
var Pool = require_pool();
|
|
63305
63914
|
var { buildMockDispatch } = require_mock_utils();
|
|
63306
63915
|
var {
|
|
@@ -63340,7 +63949,7 @@ var require_mock_pool = __commonJS({
|
|
|
63340
63949
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
63341
63950
|
}
|
|
63342
63951
|
async [kClose]() {
|
|
63343
|
-
await
|
|
63952
|
+
await promisify4(this[kOriginalClose])();
|
|
63344
63953
|
this[kConnected] = 0;
|
|
63345
63954
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
63346
63955
|
}
|
|
@@ -74104,7 +74713,7 @@ init_checkout_root();
|
|
|
74104
74713
|
import { closeSync, existsSync as existsSync16, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync6 } from "node:fs";
|
|
74105
74714
|
import { basename as basename5, delimiter, dirname as dirname10, join as join20, normalize as normalize3 } from "node:path";
|
|
74106
74715
|
import { homedir as homedir4 } from "node:os";
|
|
74107
|
-
import { createHash as
|
|
74716
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
74108
74717
|
function readFrom(path2, fromByte, maxBytes) {
|
|
74109
74718
|
let fd;
|
|
74110
74719
|
try {
|
|
@@ -74413,7 +75022,7 @@ function parseCodexAssistantTurns(raw2, skipFirstLineParseFailure = false, start
|
|
|
74413
75022
|
turns.push({
|
|
74414
75023
|
// Slice-local line numbers repeat on every Stop. Position distinguishes
|
|
74415
75024
|
// identical messages; the digest distinguishes a replaced row at that position.
|
|
74416
|
-
uuid: typeof payload["id"] === "string" && payload["id"].length > 0 ? payload["id"] : `codex-${lineByte}-${
|
|
75025
|
+
uuid: typeof payload["id"] === "string" && payload["id"].length > 0 ? payload["id"] : `codex-${lineByte}-${createHash15("sha256").update(line.trimEnd()).digest("hex")}`,
|
|
74417
75026
|
text: parts2.join("\n\n"),
|
|
74418
75027
|
hostHarness: "codex"
|
|
74419
75028
|
});
|
|
@@ -74662,7 +75271,7 @@ function geminiSessionRoots(env2 = process.env, home = homedir4()) {
|
|
|
74662
75271
|
return [...roots];
|
|
74663
75272
|
}
|
|
74664
75273
|
function geminiProjectHash(cwd) {
|
|
74665
|
-
return
|
|
75274
|
+
return createHash15("sha256").update(cwd).digest("hex");
|
|
74666
75275
|
}
|
|
74667
75276
|
function geminiHashesFor(cwd) {
|
|
74668
75277
|
const variants = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
|
|
@@ -77983,7 +78592,7 @@ var TelemetryRecorder = class {
|
|
|
77983
78592
|
// src/file-activity.ts
|
|
77984
78593
|
import { readFileSync as readFileSync22 } from "node:fs";
|
|
77985
78594
|
import { join as join28 } from "node:path";
|
|
77986
|
-
import { createHash as
|
|
78595
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
77987
78596
|
|
|
77988
78597
|
// ../../packages/privacy/src/patterns/credentials.ts
|
|
77989
78598
|
var CREDENTIAL_PATTERNS = [
|
|
@@ -78732,6 +79341,7 @@ var openaiAgent = new import_undici.Agent({
|
|
|
78732
79341
|
init_git_remote();
|
|
78733
79342
|
|
|
78734
79343
|
// src/history-bundle.ts
|
|
79344
|
+
init_src();
|
|
78735
79345
|
import { execFile as execFile2 } from "node:child_process";
|
|
78736
79346
|
import { readFileSync as readFileSync21 } from "node:fs";
|
|
78737
79347
|
import { join as join27 } from "node:path";
|
|
@@ -78740,8 +79350,6 @@ var FILE_LIST_CAP = 60;
|
|
|
78740
79350
|
var DIFF_FILE_CAP = 40;
|
|
78741
79351
|
var GENERATED_JSON_MAX_CHURN = 800;
|
|
78742
79352
|
var TRUNCATION_MARKER = "\n[truncated]";
|
|
78743
|
-
var REDACTED_CREDENTIAL = "[redacted:credential]";
|
|
78744
|
-
var REDACTED_EMAIL = "[redacted:email]";
|
|
78745
79353
|
var CHARS_PER_TOKEN = 3.5;
|
|
78746
79354
|
function estimateTokens(text) {
|
|
78747
79355
|
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
@@ -78882,138 +79490,6 @@ function isSourceFile(f) {
|
|
|
78882
79490
|
if (ext === "json" && f.adds + f.dels > GENERATED_JSON_MAX_CHURN) return false;
|
|
78883
79491
|
return true;
|
|
78884
79492
|
}
|
|
78885
|
-
var cred = () => REDACTED_CREDENTIAL;
|
|
78886
|
-
var ASSIGNMENT_STOPWORDS = /* @__PURE__ */ new Set([
|
|
78887
|
-
"string",
|
|
78888
|
-
"boolean",
|
|
78889
|
-
"number",
|
|
78890
|
-
"required",
|
|
78891
|
-
"optional",
|
|
78892
|
-
"undefined",
|
|
78893
|
-
"unknown",
|
|
78894
|
-
"function",
|
|
78895
|
-
"process",
|
|
78896
|
-
"request",
|
|
78897
|
-
"response",
|
|
78898
|
-
"password",
|
|
78899
|
-
"secret",
|
|
78900
|
-
"token",
|
|
78901
|
-
"tokens",
|
|
78902
|
-
"credential",
|
|
78903
|
-
"credentials",
|
|
78904
|
-
"bearer",
|
|
78905
|
-
"basic",
|
|
78906
|
-
"example",
|
|
78907
|
-
"redacted",
|
|
78908
|
-
"nullable",
|
|
78909
|
-
"readonly",
|
|
78910
|
-
"override",
|
|
78911
|
-
"abstract",
|
|
78912
|
-
"interface",
|
|
78913
|
-
"constant",
|
|
78914
|
-
"variable",
|
|
78915
|
-
"property",
|
|
78916
|
-
"parameter",
|
|
78917
|
-
"argument",
|
|
78918
|
-
"callback",
|
|
78919
|
-
"promise",
|
|
78920
|
-
"settings",
|
|
78921
|
-
"options",
|
|
78922
|
-
"default",
|
|
78923
|
-
"disabled",
|
|
78924
|
-
"enabled",
|
|
78925
|
-
"internal",
|
|
78926
|
-
"external",
|
|
78927
|
-
"protected",
|
|
78928
|
-
"provided",
|
|
78929
|
-
"resolved",
|
|
78930
|
-
"rejected",
|
|
78931
|
-
"expected",
|
|
78932
|
-
"received"
|
|
78933
|
-
]);
|
|
78934
|
-
function looksLikeSecretValue(raw2, quoted) {
|
|
78935
|
-
if (raw2.includes("${") || raw2.includes("{{") || raw2.includes("%(")) return false;
|
|
78936
|
-
if (raw2.startsWith(REDACTED_CREDENTIAL) || raw2.startsWith(REDACTED_EMAIL)) return false;
|
|
78937
|
-
const lower = raw2.toLowerCase();
|
|
78938
|
-
if (ASSIGNMENT_STOPWORDS.has(lower)) return false;
|
|
78939
|
-
if (quoted) return raw2.length >= 6;
|
|
78940
|
-
if (!/^[A-Za-z0-9+/=_-]{8,}$/.test(raw2)) return false;
|
|
78941
|
-
if (/\d/.test(raw2)) return true;
|
|
78942
|
-
if (raw2.length >= 12) return true;
|
|
78943
|
-
return /[a-z]/.test(raw2) && /[A-Z]/.test(raw2);
|
|
78944
|
-
}
|
|
78945
|
-
var CREDENTIAL_RULES = [
|
|
78946
|
-
// Private-key blocks, including ones a diff prefixes with `+`/`-` per line
|
|
78947
|
-
// and ones the diff context cut before the END line.
|
|
78948
|
-
{
|
|
78949
|
-
re: /-----BEGIN [A-Z ]*PRIVATE KEY(?: BLOCK)?-----(?:[ \t]*\r?\n[+\- ]?[A-Za-z0-9+/=]{16,}[ \t]*)*(?:[ \t]*\r?\n[+\- ]?-----END [A-Z ]*PRIVATE KEY(?: BLOCK)?-----)?/g,
|
|
78950
|
-
replace: cred
|
|
78951
|
-
},
|
|
78952
|
-
{ re: /\b(?:AKIA|ASIA)[0-9A-Z]{16,}\b/g, replace: cred },
|
|
78953
|
-
// AWS access key id
|
|
78954
|
-
{ re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g, replace: cred },
|
|
78955
|
-
{ re: /\bgh[pousr]_[A-Za-z0-9]{30,}\b/g, replace: cred },
|
|
78956
|
-
{ re: /\bglpat-[A-Za-z0-9_-]{20,}\b/g, replace: cred },
|
|
78957
|
-
{ re: /\bxox[abeprs]-[A-Za-z0-9-]{10,}\b/g, replace: cred },
|
|
78958
|
-
// Slack
|
|
78959
|
-
{ re: /\bsk-(?:ant-)?[A-Za-z0-9_-]{20,}\b/g, replace: cred },
|
|
78960
|
-
// OpenAI / Anthropic
|
|
78961
|
-
{ re: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g, replace: cred },
|
|
78962
|
-
// Stripe
|
|
78963
|
-
{ re: /\brnd_[A-Za-z0-9]{20,}\b/g, replace: cred },
|
|
78964
|
-
// Render
|
|
78965
|
-
{ re: /\bnpm_[A-Za-z0-9]{36}\b/g, replace: cred },
|
|
78966
|
-
{ re: /\bAIza[0-9A-Za-z_-]{35}\b/g, replace: cred },
|
|
78967
|
-
// Google API key
|
|
78968
|
-
{ re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g, replace: cred },
|
|
78969
|
-
// JWT
|
|
78970
|
-
{ re: /(?<![A-Za-z0-9])[A-Za-z0-9]{84}(?![A-Za-z0-9])/g, replace: cred },
|
|
78971
|
-
// Azure-shaped
|
|
78972
|
-
{
|
|
78973
|
-
re: /\b(Bearer|Basic|Token)(\s+)([A-Za-z0-9._~+/=-]{16,})/g,
|
|
78974
|
-
replace: (m) => `${m[1]}${m[2]}${REDACTED_CREDENTIAL}`
|
|
78975
|
-
},
|
|
78976
|
-
// Assignments after key-ish names: `password=...`, `API_KEY: "..."`,
|
|
78977
|
-
// `"client_secret": "..."`, `AWS_SECRET_ACCESS_KEY=...`, 32+ hex/base64 after
|
|
78978
|
-
// any of them. The value heuristic keeps `token: string` and
|
|
78979
|
-
// `password = process.env.X` intact.
|
|
78980
|
-
{
|
|
78981
|
-
re: /((?:[A-Za-z0-9_.-]*?)(?:password|passwd|passphrase|pwd|secret|token|api[_-]?key|apikey|access[_-]?key|private[_-]?key|auth[_-]?key|credential)(?:[A-Za-z0-9_-]*))(["']?\s*(?:=>|=|:)\s*)(["'`]?)([^\s"'`,;)}\]]+)/gi,
|
|
78982
|
-
replace: (m) => {
|
|
78983
|
-
const value = m[4] ?? "";
|
|
78984
|
-
const quote = m[3] ?? "";
|
|
78985
|
-
if (!looksLikeSecretValue(value, quote.length > 0)) return null;
|
|
78986
|
-
return `${m[1]}${m[2]}${quote}${REDACTED_CREDENTIAL}`;
|
|
78987
|
-
}
|
|
78988
|
-
}
|
|
78989
|
-
];
|
|
78990
|
-
var EMAIL_RE2 = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+\b/g;
|
|
78991
|
-
function applyRule(text, rule) {
|
|
78992
|
-
let count = 0;
|
|
78993
|
-
const out2 = text.replace(rule.re, (...args2) => {
|
|
78994
|
-
const m = args2.slice(0, -2);
|
|
78995
|
-
const r = rule.replace(m);
|
|
78996
|
-
if (r === null) return m[0];
|
|
78997
|
-
count += 1;
|
|
78998
|
-
return r;
|
|
78999
|
-
});
|
|
79000
|
-
return { text: out2, count };
|
|
79001
|
-
}
|
|
79002
|
-
function scrubText(text) {
|
|
79003
|
-
let out2 = text;
|
|
79004
|
-
let credentials = 0;
|
|
79005
|
-
for (const rule of CREDENTIAL_RULES) {
|
|
79006
|
-
const r = applyRule(out2, rule);
|
|
79007
|
-
out2 = r.text;
|
|
79008
|
-
credentials += r.count;
|
|
79009
|
-
}
|
|
79010
|
-
let emails = 0;
|
|
79011
|
-
out2 = out2.replace(EMAIL_RE2, () => {
|
|
79012
|
-
emails += 1;
|
|
79013
|
-
return REDACTED_EMAIL;
|
|
79014
|
-
});
|
|
79015
|
-
return { text: out2, credentials, emails };
|
|
79016
|
-
}
|
|
79017
79493
|
var TRAILER_KEYS = [
|
|
79018
79494
|
"signed-off-by",
|
|
79019
79495
|
"co-authored-by",
|
|
@@ -79135,12 +79611,18 @@ async function buildUnitBundle(root, unit, opts = {}) {
|
|
|
79135
79611
|
const rawDiff = await unitDiff(root, unit, diffPaths);
|
|
79136
79612
|
for (const p of headerPaths(rawDiff)) tokens.token(p);
|
|
79137
79613
|
const narrativeRaw = opts.narrative ?? [unit.subject.trim(), stripTrailers(unit.body)].filter((s) => s.length > 0).join("\n\n");
|
|
79138
|
-
const n =
|
|
79139
|
-
const fl =
|
|
79140
|
-
const d =
|
|
79141
|
-
|
|
79142
|
-
|
|
79143
|
-
|
|
79614
|
+
const n = scrubHistoryText(tokens.apply(stripTrailers(narrativeRaw)));
|
|
79615
|
+
const fl = scrubHistoryText(tokens.apply(fileListRaw));
|
|
79616
|
+
const d = scrubHistoryText(tokens.apply(rawDiff));
|
|
79617
|
+
const safe = scrubHistoryValue({
|
|
79618
|
+
narrative: tokens.apply(stripTrailers(narrativeRaw)),
|
|
79619
|
+
fileList: tokens.apply(fileListRaw),
|
|
79620
|
+
diff: tokens.apply(rawDiff),
|
|
79621
|
+
narrativeSources: opts.narrativeSources?.map((source) => ({ commitSha: source.commitSha, text: tokens.apply(stripTrailers(source.text)).trim() }))
|
|
79622
|
+
});
|
|
79623
|
+
let narrative2 = safe.narrative;
|
|
79624
|
+
let fileList = safe.fileList;
|
|
79625
|
+
let diff = safe.diff;
|
|
79144
79626
|
const separators = 2;
|
|
79145
79627
|
let prose = estimateTokens(narrative2) + estimateTokens(fileList) + separators;
|
|
79146
79628
|
if (prose > maxTokens) {
|
|
@@ -79159,6 +79641,7 @@ async function buildUnitBundle(root, unit, opts = {}) {
|
|
|
79159
79641
|
return {
|
|
79160
79642
|
sha: unit.sha,
|
|
79161
79643
|
narrative: narrative2,
|
|
79644
|
+
...safe.narrativeSources ? { narrativeSources: safe.narrativeSources.filter((source) => source.text.length > 0 && narrative2.includes(source.text)).slice(0, 64) } : {},
|
|
79162
79645
|
fileList,
|
|
79163
79646
|
diff,
|
|
79164
79647
|
tokenEstimate: estimateTokens(narrative2) + estimateTokens(fileList) + estimateTokens(diff) + separators,
|
|
@@ -79281,7 +79764,7 @@ var FileActivityReporter = class {
|
|
|
79281
79764
|
const current = this.options.binding();
|
|
79282
79765
|
if (!identity || this.stopped || !current.enabled || current.projectId !== binding.projectId)
|
|
79283
79766
|
return false;
|
|
79284
|
-
const hash2 =
|
|
79767
|
+
const hash2 = createHash16("sha256").update(JSON.stringify([identity, source, at, clean, operation, branch, previousBranch])).digest("hex");
|
|
79285
79768
|
const id = `${hash2.slice(0, 8)}-${hash2.slice(8, 12)}-5${hash2.slice(13, 16)}-8${hash2.slice(17, 20)}-${hash2.slice(20, 32)}`;
|
|
79286
79769
|
if (!this.pending.some((item) => item.event.id === id))
|
|
79287
79770
|
this.pending.push({
|
|
@@ -80338,7 +80821,7 @@ function createWatchBreaker(deps) {
|
|
|
80338
80821
|
}
|
|
80339
80822
|
|
|
80340
80823
|
// src/engine.ts
|
|
80341
|
-
var DAEMON_VERSION = true ? "2.0.13-dev.
|
|
80824
|
+
var DAEMON_VERSION = true ? "2.0.13-dev.3043" : "2.0.0-alpha.0";
|
|
80342
80825
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
80343
80826
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
80344
80827
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -82797,10 +83280,10 @@ init_registry();
|
|
|
82797
83280
|
init_identity2();
|
|
82798
83281
|
|
|
82799
83282
|
// src/instance-receipts.ts
|
|
82800
|
-
import { createHash as
|
|
83283
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
82801
83284
|
var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
|
|
82802
83285
|
function instanceDestinationKey(input) {
|
|
82803
|
-
return
|
|
83286
|
+
return createHash17("sha256").update(JSON.stringify([
|
|
82804
83287
|
input.workspace,
|
|
82805
83288
|
input.cloudUrl.replace(/\/+$/, ""),
|
|
82806
83289
|
input.installationId ?? input.profileName ?? "default",
|
|
@@ -84282,6 +84765,69 @@ init_profile2();
|
|
|
84282
84765
|
init_src();
|
|
84283
84766
|
init_src11();
|
|
84284
84767
|
init_profile2();
|
|
84768
|
+
|
|
84769
|
+
// src/history-corrections.ts
|
|
84770
|
+
init_profile2();
|
|
84771
|
+
function applyHistoryCorrections(store, page) {
|
|
84772
|
+
let changed = 0;
|
|
84773
|
+
for (const correction of page.changes) {
|
|
84774
|
+
const key = `history-correction:${correction.nodeId}`;
|
|
84775
|
+
const previous = store.getMeta?.(key);
|
|
84776
|
+
if (!previous || Number(JSON.parse(previous).seq) < correction.seq) store.setMeta?.(key, JSON.stringify(correction));
|
|
84777
|
+
const current = store.getNode(correction.canonicalId) ?? store.getNode(correction.nodeId);
|
|
84778
|
+
if (!current) continue;
|
|
84779
|
+
const privacy = correction.action === "quarantine";
|
|
84780
|
+
const copies = privacy ? store.nodeHistory(current.logicalId ?? current.id) : [current];
|
|
84781
|
+
for (const node2 of copies) {
|
|
84782
|
+
if (node2.attrs["source"] !== "cloud" || node2.attrs["cloudNodeId"] && node2.attrs["cloudNodeId"] !== correction.nodeId || Number(node2.attrs["historyCorrectionSeq"] ?? 0) >= correction.seq) continue;
|
|
84783
|
+
const quality = { sourceSupport: correction.sourceSupport ?? (privacy ? "quarantined" : "unreviewed"), applicability: "unknown" };
|
|
84784
|
+
store.mergeNode({
|
|
84785
|
+
...node2,
|
|
84786
|
+
lastUpdatedAt: Date.now(),
|
|
84787
|
+
...privacy ? { description: "History source withdrawn.", embedding: [], isLandmark: false } : {},
|
|
84788
|
+
attrs: {
|
|
84789
|
+
...privacy ? {} : node2.attrs,
|
|
84790
|
+
source: "cloud",
|
|
84791
|
+
cloudNodeId: correction.nodeId,
|
|
84792
|
+
extractionSource: "history-mined",
|
|
84793
|
+
historyQuality: quality,
|
|
84794
|
+
historyCorrectionSeq: correction.seq
|
|
84795
|
+
}
|
|
84796
|
+
});
|
|
84797
|
+
if (privacy) for (const edge2 of [...store.inEdges(node2.id), ...store.outEdges(node2.id)]) {
|
|
84798
|
+
if (edge2.attrs["source"] === "cloud") store.mergeEdge({ ...edge2, attrs: { source: "cloud", historySourceWithdrawn: true } });
|
|
84799
|
+
}
|
|
84800
|
+
changed++;
|
|
84801
|
+
}
|
|
84802
|
+
}
|
|
84803
|
+
return changed;
|
|
84804
|
+
}
|
|
84805
|
+
async function syncHistoryCorrections(opts) {
|
|
84806
|
+
const { root, profile, store, cloud } = opts;
|
|
84807
|
+
if (!profile.projectId || !cloud.getProjectHistoryCorrections) return;
|
|
84808
|
+
let cursor = profile.projectHistoryCorrectionCursor ?? 0;
|
|
84809
|
+
for (let i2 = 0; i2 < 25; i2++) {
|
|
84810
|
+
const page = await cloud.getProjectHistoryCorrections(profile.projectId, cursor, 200);
|
|
84811
|
+
if (!Number.isSafeInteger(page.cursor) || page.cursor < cursor || !Array.isArray(page.changes) || page.changes.length > 200 || page.changes.some((c, j) => !Number.isSafeInteger(c.seq) || c.seq <= (page.changes[j - 1]?.seq ?? cursor) || c.seq > page.cursor || !["quarantine", "unreviewed"].includes(c.action) || c.sourceSupport !== void 0 && !["supported", "contradicted", "unreviewed", "quarantined"].includes(c.sourceSupport) || typeof c.nodeId !== "string" || typeof c.canonicalId !== "string")) {
|
|
84812
|
+
throw new Error("Invalid history correction page");
|
|
84813
|
+
}
|
|
84814
|
+
if (page.cursor !== (page.changes.at(-1)?.seq ?? cursor)) throw new Error("History correction cursor skipped a page");
|
|
84815
|
+
applyHistoryCorrections(store, page);
|
|
84816
|
+
for (const mirror of opts.mirrors ?? []) applyHistoryCorrections(mirror, page);
|
|
84817
|
+
if (page.changes.some((c) => c.sourceSupport === "supported")) {
|
|
84818
|
+
profile.projectAnchorCursor = 0;
|
|
84819
|
+
delete profile.historyRevisionCursor;
|
|
84820
|
+
}
|
|
84821
|
+
if (page.cursor > cursor) {
|
|
84822
|
+
cursor = page.cursor;
|
|
84823
|
+
profile.projectHistoryCorrectionCursor = cursor;
|
|
84824
|
+
saveProfile(root, profile);
|
|
84825
|
+
}
|
|
84826
|
+
if (page.changes.length < 200) break;
|
|
84827
|
+
}
|
|
84828
|
+
}
|
|
84829
|
+
|
|
84830
|
+
// src/project-reanchor.ts
|
|
84285
84831
|
var DEFAULT_LIMIT = 50;
|
|
84286
84832
|
var ANCHOR_SYMBOL_KINDS2 = [
|
|
84287
84833
|
"Function",
|
|
@@ -84497,6 +85043,7 @@ async function syncProjectAnchors(opts) {
|
|
|
84497
85043
|
let landed = 0;
|
|
84498
85044
|
let cursor = profile.projectAnchorCursor ?? 0;
|
|
84499
85045
|
try {
|
|
85046
|
+
await syncHistoryCorrections({ root, profile, store, cloud, ...opts.correctionMirrors ? { mirrors: opts.correctionMirrors } : {} });
|
|
84500
85047
|
for (let page = 0; page < maxPages; page++) {
|
|
84501
85048
|
const res = await cloud.getProjectAnchors(projectId, cursor, limit);
|
|
84502
85049
|
if (res.anchors.length === 0) break;
|
|
@@ -84611,13 +85158,109 @@ async function hydrateProject(opts) {
|
|
|
84611
85158
|
}
|
|
84612
85159
|
}
|
|
84613
85160
|
|
|
85161
|
+
// src/history-reconcile.ts
|
|
85162
|
+
init_src11();
|
|
85163
|
+
init_src();
|
|
85164
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
85165
|
+
import { promisify as promisify2 } from "node:util";
|
|
85166
|
+
import { extname as extname3 } from "node:path";
|
|
85167
|
+
init_profile2();
|
|
85168
|
+
var exec = promisify2(execFile4);
|
|
85169
|
+
var KINDS = { function: "Function", class: "Class", method: "Method", interface: "Interface", const: "Const", enum: "Enum", typealias: "TypeAlias", namespace: "Namespace", property: "Property" };
|
|
85170
|
+
async function syncHistoryRevision(opts) {
|
|
85171
|
+
const { root, profile, store, cloud, salt } = opts;
|
|
85172
|
+
if (!profile.projectId) return { changed: 0, remaining: false };
|
|
85173
|
+
const projectId = profile.projectId;
|
|
85174
|
+
const git3 = opts.git ?? (async (args2) => (await exec("git", ["-C", root, ...args2], { windowsHide: true, maxBuffer: 8 * 1024 * 1024 })).stdout);
|
|
85175
|
+
const atCommit = (await git3(["rev-parse", "--verify", "HEAD"])).trim();
|
|
85176
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(atCommit)) throw new Error("history revision is not a full Git object id");
|
|
85177
|
+
const oldCursor = profile.historyRevisionCursor;
|
|
85178
|
+
const same = oldCursor?.atCommit === atCommit;
|
|
85179
|
+
if (same && oldCursor.complete && Date.now() - oldCursor.updatedAt < 60 * 6e4) return { changed: 0, remaining: false };
|
|
85180
|
+
const after = same && !oldCursor.complete ? oldCursor.after : void 0;
|
|
85181
|
+
const page = await cloud.getHistoryOccurrences(projectId, atCommit, after);
|
|
85182
|
+
if (!Array.isArray(page.occurrences) || page.occurrences.length > 50 || page.occurrences.some((o, i2) => o.occurrenceId <= (page.occurrences[i2 - 1]?.occurrenceId ?? after ?? "")) || page.cursor !== null && page.cursor !== page.occurrences.at(-1)?.occurrenceId) throw new Error("invalid history occurrence page");
|
|
85183
|
+
const parents = (await git3(["rev-list", "--parents", "--max-count=8192", atCommit])).trim().split("\n").filter(Boolean).map((row) => {
|
|
85184
|
+
const [commit, ...parents2] = row.trim().split(/\s+/);
|
|
85185
|
+
return { commit, parents: parents2 };
|
|
85186
|
+
});
|
|
85187
|
+
const reverse = buildReverseSymbolMap({ store, projectId, salt });
|
|
85188
|
+
const ignore2 = loadRepoIgnore(root, profile.ignoreExtra ?? []);
|
|
85189
|
+
const providers = defaultProviders();
|
|
85190
|
+
const parsedFiles = /* @__PURE__ */ new Map();
|
|
85191
|
+
const observations = [];
|
|
85192
|
+
for (const occurrence of page.occurrences) {
|
|
85193
|
+
const anchors = occurrence.quality["historicalAnchors"];
|
|
85194
|
+
const paths = /* @__PURE__ */ new Set(), symbols = [];
|
|
85195
|
+
for (const anchor of anchors ?? []) {
|
|
85196
|
+
const localId = reverse.get(anchor.symbolId), local = localId ? store.getNode(localId) : null;
|
|
85197
|
+
const path2 = local?.attrs["relPath"];
|
|
85198
|
+
if (typeof path2 !== "string" || !pathAllowedByFloor(path2) || isPathBlocked(ignore2, path2) || /[\r\n]/.test(path2)) continue;
|
|
85199
|
+
paths.add(path2);
|
|
85200
|
+
if (!parsedFiles.has(path2)) {
|
|
85201
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
85202
|
+
parsedFiles.set(path2, hashes);
|
|
85203
|
+
const provider = providers.find((p) => p.fileExtensions.includes(extname3(path2).toLowerCase()));
|
|
85204
|
+
if (!provider) continue;
|
|
85205
|
+
const source2 = await git3(["show", `${atCommit}:${path2}`]).catch(() => null);
|
|
85206
|
+
if (source2 === null || Buffer.byteLength(source2) > 1e6 || source2.includes("\0")) continue;
|
|
85207
|
+
await provider.preload?.();
|
|
85208
|
+
for (const symbol2 of provider.extractSymbols(source2, path2)) {
|
|
85209
|
+
const kind = KINDS[symbol2.kind];
|
|
85210
|
+
if (kind && symbol2.bodyHash) hashes.set(projectSymbolId(salt, projectId, path2, symbol2.qname ?? symbol2.name, kind), symbol2.bodyHash);
|
|
85211
|
+
}
|
|
85212
|
+
}
|
|
85213
|
+
const bodyHash = parsedFiles.get(path2).get(anchor.symbolId);
|
|
85214
|
+
if (bodyHash) symbols.push({ symbolId: anchor.symbolId, bodyHash });
|
|
85215
|
+
}
|
|
85216
|
+
const source = occurrenceSourceCommit(occurrence);
|
|
85217
|
+
let diff;
|
|
85218
|
+
if (source && source !== atCommit && paths.size) {
|
|
85219
|
+
const bundle = await buildUnitBundle(root, {
|
|
85220
|
+
sha: atCommit,
|
|
85221
|
+
parents: [source],
|
|
85222
|
+
isMerge: true,
|
|
85223
|
+
index: 0,
|
|
85224
|
+
subIndex: 0,
|
|
85225
|
+
subject: "",
|
|
85226
|
+
body: "",
|
|
85227
|
+
authorDate: "",
|
|
85228
|
+
files: [...paths].map((path2) => ({ path: path2, adds: 1, dels: 1, binary: false }))
|
|
85229
|
+
}, { maxTokens: 4e3, ignorePatterns: profile.ignoreExtra ?? [] }).catch(() => null);
|
|
85230
|
+
if (bundle && !bundle.truncated) diff = bundle.diff;
|
|
85231
|
+
}
|
|
85232
|
+
observations.push({ occurrenceId: occurrence.occurrenceId, symbols, ...diff ? { diff } : {} });
|
|
85233
|
+
}
|
|
85234
|
+
const response = page.occurrences.length ? await cloud.reconcileHistory(projectId, { atCommit, parents, observations }) : { atCommit, receipts: [] };
|
|
85235
|
+
if (response.atCommit !== atCommit || response.receipts.length !== page.occurrences.length || new Set(response.receipts.map((r) => r.occurrenceId)).size !== response.receipts.length || response.receipts.some((r) => r.atCommit !== atCommit || !observations.some((o) => o.occurrenceId === r.occurrenceId))) throw new Error("incomplete history reconciliation response");
|
|
85236
|
+
if ((await git3(["rev-parse", "--verify", "HEAD"])).trim() !== atCommit) return { changed: 0, remaining: true };
|
|
85237
|
+
let changed = 0;
|
|
85238
|
+
for (const occurrence of page.occurrences) {
|
|
85239
|
+
const node2 = store.getNode(occurrence.canonicalId) ?? (occurrence.nodeId ? store.getNode(occurrence.nodeId) : null);
|
|
85240
|
+
if (!node2 || node2.attrs["source"] !== "cloud" || node2.attrs["historyQuality"]?.["sourceSupport"] === "quarantined") continue;
|
|
85241
|
+
const receipt = response.receipts.find((r) => r.occurrenceId === occurrence.occurrenceId);
|
|
85242
|
+
const previous = node2.attrs["historyQuality"];
|
|
85243
|
+
if (previous?.["evaluatedAtCommit"] === atCommit && previous["applicability"] === "applicable" && receipt.verdict !== "applicable") continue;
|
|
85244
|
+
store.mergeNode({ ...node2, attrs: { ...node2.attrs, historyQuality: {
|
|
85245
|
+
...occurrence.quality,
|
|
85246
|
+
evaluatedAtCommit: atCommit,
|
|
85247
|
+
applicability: receipt.verdict,
|
|
85248
|
+
reconciliationEvidence: receipt.evidence
|
|
85249
|
+
} } });
|
|
85250
|
+
changed++;
|
|
85251
|
+
}
|
|
85252
|
+
profile.historyRevisionCursor = { atCommit, ...page.cursor ? { after: page.cursor } : {}, complete: page.cursor === null, updatedAt: Date.now() };
|
|
85253
|
+
(opts.save ?? ((p) => saveProfile(root, p)))(profile);
|
|
85254
|
+
return { changed, remaining: page.cursor !== null };
|
|
85255
|
+
}
|
|
85256
|
+
|
|
84614
85257
|
// src/project-history.ts
|
|
84615
85258
|
init_src7();
|
|
84616
85259
|
init_src();
|
|
84617
|
-
import { execFile as
|
|
85260
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
84618
85261
|
import { readFileSync as readFileSync32 } from "node:fs";
|
|
84619
85262
|
import { join as join37 } from "node:path";
|
|
84620
|
-
import { promisify as
|
|
85263
|
+
import { promisify as promisify3 } from "node:util";
|
|
84621
85264
|
|
|
84622
85265
|
// src/history-walk.ts
|
|
84623
85266
|
var LOCKFILE_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -84935,10 +85578,13 @@ function message(u) {
|
|
|
84935
85578
|
${u.body}` : u.subject;
|
|
84936
85579
|
}
|
|
84937
85580
|
function narrative(unit, group) {
|
|
84938
|
-
|
|
85581
|
+
return narrativeSources(unit, group).map((source) => source.text).join("\n\n");
|
|
85582
|
+
}
|
|
85583
|
+
function narrativeSources(unit, group) {
|
|
85584
|
+
if (!group || group.length === 0) return [{ commitSha: unit.sha, text: message(unit).trim() }].filter((s) => s.text.length > 0);
|
|
84939
85585
|
const members = group.filter((g) => g.groupSha === (unit.groupSha ?? unit.sha)).sort((a, b) => a.subIndex - b.subIndex);
|
|
84940
85586
|
const source = members.length > 0 ? members : [...group].sort((a, b) => a.subIndex - b.subIndex);
|
|
84941
|
-
return source.map(
|
|
85587
|
+
return source.map((member) => ({ commitSha: member.sha, text: message(member).trim() })).filter((s) => s.text.length > 0);
|
|
84942
85588
|
}
|
|
84943
85589
|
|
|
84944
85590
|
// src/git-batch.ts
|
|
@@ -85042,13 +85688,116 @@ var GitBlobReader = class {
|
|
|
85042
85688
|
}
|
|
85043
85689
|
};
|
|
85044
85690
|
|
|
85691
|
+
// src/history-anchors.ts
|
|
85692
|
+
init_src11();
|
|
85693
|
+
init_src();
|
|
85694
|
+
import { extname as extname4 } from "node:path";
|
|
85695
|
+
var LABELS = {
|
|
85696
|
+
function: "Function",
|
|
85697
|
+
class: "Class",
|
|
85698
|
+
method: "Method",
|
|
85699
|
+
interface: "Interface",
|
|
85700
|
+
const: "Const",
|
|
85701
|
+
enum: "Enum",
|
|
85702
|
+
typealias: "TypeAlias",
|
|
85703
|
+
namespace: "Namespace",
|
|
85704
|
+
property: "Property"
|
|
85705
|
+
};
|
|
85706
|
+
var MAX_SOURCE_BYTES = 1e6;
|
|
85707
|
+
var MAX_ANCHORS = 20;
|
|
85708
|
+
async function historicalAnchors(input) {
|
|
85709
|
+
if (!/^[a-f0-9]{40,64}$/.test(input.unit.sha)) return void 0;
|
|
85710
|
+
const ignore2 = loadRepoIgnore(input.root, input.ignorePatterns);
|
|
85711
|
+
const providers = input.providers ?? defaultProviders();
|
|
85712
|
+
const beforeTokens = /* @__PURE__ */ new Map();
|
|
85713
|
+
for (const line of input.bundle.diff.split("\n")) {
|
|
85714
|
+
const m = /^diff --git a\/(p\d+) b\/(p\d+)$/.exec(line);
|
|
85715
|
+
if (m) beforeTokens.set(m[2], m[1]);
|
|
85716
|
+
}
|
|
85717
|
+
const parsed = /* @__PURE__ */ new Map();
|
|
85718
|
+
const parse4 = (commit, token) => {
|
|
85719
|
+
const path2 = input.bundle.pathTokens[token];
|
|
85720
|
+
if (!path2 || /[\r\n]/.test(path2) || !pathAllowedByFloor(path2) || isPathBlocked(ignore2, path2)) return Promise.resolve(null);
|
|
85721
|
+
const provider = providers.find((p) => p.fileExtensions.includes(extname4(path2).toLowerCase()));
|
|
85722
|
+
if (!provider) return Promise.resolve(null);
|
|
85723
|
+
const spec = `${commit}:${path2}`;
|
|
85724
|
+
if (!parsed.has(spec)) parsed.set(spec, (async () => {
|
|
85725
|
+
try {
|
|
85726
|
+
const source = await input.readBlob(spec);
|
|
85727
|
+
if (source === null || source.includes("\0") || Buffer.byteLength(source) > MAX_SOURCE_BYTES) return null;
|
|
85728
|
+
await provider.preload?.();
|
|
85729
|
+
const symbols = provider.extractSymbols(source, path2).filter((s) => LABELS[s.kind] && s.startByte >= 0 && s.endByte > s.startByte);
|
|
85730
|
+
const offsets = [0];
|
|
85731
|
+
for (let i2 = 0; i2 < source.length; i2++) if (source[i2] === "\n") offsets.push(i2 + 1);
|
|
85732
|
+
offsets.push(source.length + 1);
|
|
85733
|
+
return { symbols, offsets };
|
|
85734
|
+
} catch {
|
|
85735
|
+
return null;
|
|
85736
|
+
}
|
|
85737
|
+
})());
|
|
85738
|
+
return parsed.get(spec);
|
|
85739
|
+
};
|
|
85740
|
+
const out2 = {};
|
|
85741
|
+
const blocks = historySourceBlocks({ narrative: "", diff: input.bundle.diff, commitSha: input.unit.sha });
|
|
85742
|
+
for (const block of blocks) {
|
|
85743
|
+
if (block.kind !== "diff" || !block.pathToken) continue;
|
|
85744
|
+
const lines = block.text.split("\n");
|
|
85745
|
+
const header = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(lines[0]);
|
|
85746
|
+
if (!header) continue;
|
|
85747
|
+
let before = Number(header[1]), after = Number(header[2]);
|
|
85748
|
+
let offset = Buffer.byteLength(lines[0]) + 1;
|
|
85749
|
+
const list = out2[block.pathToken] ?? [];
|
|
85750
|
+
for (const line of lines.slice(1)) {
|
|
85751
|
+
const end = offset + Buffer.byteLength(line);
|
|
85752
|
+
const side = line[0] === "+" ? "after" : line[0] === "-" ? "before" : null;
|
|
85753
|
+
if (side) {
|
|
85754
|
+
const commit = side === "after" ? input.unit.sha : input.unit.parents[0];
|
|
85755
|
+
const token = side === "after" ? block.pathToken : beforeTokens.get(block.pathToken);
|
|
85756
|
+
if (commit && /^[a-f0-9]{40,64}$/.test(commit) && token) {
|
|
85757
|
+
const file2 = await parse4(commit, token);
|
|
85758
|
+
const row = (side === "after" ? after : before) - 1;
|
|
85759
|
+
const start2 = file2?.offsets[row], stop2 = file2?.offsets[row + 1];
|
|
85760
|
+
if (file2 && start2 !== void 0 && stop2 !== void 0) {
|
|
85761
|
+
const symbols = file2.symbols.filter((s) => s.startByte < stop2 && s.endByte > start2).sort((a, b) => a.endByte - a.startByte - (b.endByte - b.startByte));
|
|
85762
|
+
const symbol2 = symbols[0];
|
|
85763
|
+
if (symbol2) {
|
|
85764
|
+
const kind = LABELS[symbol2.kind];
|
|
85765
|
+
const symbolId = projectSymbolId(input.salt, input.projectId, input.bundle.pathTokens[token], symbol2.qname ?? symbol2.name, kind);
|
|
85766
|
+
const prev = list.at(-1);
|
|
85767
|
+
if (prev?.symbolId === symbolId && prev.historical?.side === side && prev.historical.blockDigest === block.digest && prev.historical.endByte + 1 === offset) {
|
|
85768
|
+
prev.historical.endByte = end;
|
|
85769
|
+
} else if (list.length < MAX_ANCHORS) list.push({
|
|
85770
|
+
symbolId,
|
|
85771
|
+
kind,
|
|
85772
|
+
historical: {
|
|
85773
|
+
sourceCommitSha: input.unit.sha,
|
|
85774
|
+
commitSha: commit,
|
|
85775
|
+
side,
|
|
85776
|
+
blockDigest: block.digest,
|
|
85777
|
+
startByte: offset,
|
|
85778
|
+
endByte: end,
|
|
85779
|
+
...symbol2.bodyHash ? { bodyHash: symbol2.bodyHash } : {}
|
|
85780
|
+
}
|
|
85781
|
+
});
|
|
85782
|
+
}
|
|
85783
|
+
}
|
|
85784
|
+
}
|
|
85785
|
+
}
|
|
85786
|
+
if (line[0] === " " || line[0] === "-") before++;
|
|
85787
|
+
if (line[0] === " " || line[0] === "+") after++;
|
|
85788
|
+
offset = end + 1;
|
|
85789
|
+
}
|
|
85790
|
+
if (list.length) out2[block.pathToken] = list;
|
|
85791
|
+
}
|
|
85792
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
85793
|
+
}
|
|
85794
|
+
|
|
85045
85795
|
// src/project-history.ts
|
|
85046
85796
|
init_profile2();
|
|
85047
|
-
var execFileAsync2 =
|
|
85797
|
+
var execFileAsync2 = promisify3(execFile5);
|
|
85048
85798
|
var HISTORY_EXTRACTOR_VERSION = "history-2";
|
|
85049
85799
|
var LEASE_POLL_MS = 2e4;
|
|
85050
85800
|
var RECOVERY_DEADLINE_MS = 15 * 6e4;
|
|
85051
|
-
var MAX_ANCHORS_PER_TOKEN = 20;
|
|
85052
85801
|
var DEFAULT_LOOKAHEAD = 2;
|
|
85053
85802
|
async function defaultGit(root, args2) {
|
|
85054
85803
|
const { stdout } = await execFileAsync2("git", ["-C", root, ...args2], { maxBuffer: 64 * 1024 * 1024, windowsHide: true });
|
|
@@ -85099,27 +85848,6 @@ async function spineForUnit(git3, root, unit, readBlob) {
|
|
|
85099
85848
|
const wire = (d) => ({ ecosystem: d.ecosystem, name: d.name, version: d.version, kind: d.kind, manifest: d.manifest });
|
|
85100
85849
|
return { declared: rings.declared.map(wire), context: rings.context.map(wire) };
|
|
85101
85850
|
}
|
|
85102
|
-
function anchorsFor(pathTokens, ignoreLines, projectId, anchors) {
|
|
85103
|
-
if (!anchors) return void 0;
|
|
85104
|
-
const out2 = {};
|
|
85105
|
-
const ignored = (p) => ignoreLines.some((rule) => p === rule || p.startsWith(rule.replace(/\/+$/, "") + "/"));
|
|
85106
|
-
for (const [token, relPath] of Object.entries(pathTokens)) {
|
|
85107
|
-
if (ignored(relPath)) continue;
|
|
85108
|
-
const nodes = anchors.index.nodesByRelPath([relPath]);
|
|
85109
|
-
const list = [];
|
|
85110
|
-
for (const n of nodes) {
|
|
85111
|
-
const qname = n.attrs["qname"];
|
|
85112
|
-
if (typeof qname !== "string") continue;
|
|
85113
|
-
list.push({
|
|
85114
|
-
symbolId: projectSymbolId(anchors.salt, projectId, relPath, qname, n.label),
|
|
85115
|
-
kind: n.label
|
|
85116
|
-
});
|
|
85117
|
-
if (list.length >= MAX_ANCHORS_PER_TOKEN) break;
|
|
85118
|
-
}
|
|
85119
|
-
if (list.length > 0) out2[token] = list;
|
|
85120
|
-
}
|
|
85121
|
-
return Object.keys(out2).length > 0 ? out2 : void 0;
|
|
85122
|
-
}
|
|
85123
85851
|
function stage(profile, patch, now) {
|
|
85124
85852
|
const at = now().toISOString();
|
|
85125
85853
|
const prev = profile.historyStage;
|
|
@@ -85137,6 +85865,7 @@ function stage(profile, patch, now) {
|
|
|
85137
85865
|
// keep showing the error it recovered from); an absent key keeps it.
|
|
85138
85866
|
..."lastError" in patch ? patch.lastError ? { lastError: patch.lastError } : {} : prev?.lastError ? { lastError: prev.lastError } : {},
|
|
85139
85867
|
...patch.counts ? { counts: patch.counts } : prev?.counts ? { counts: prev.counts } : {},
|
|
85868
|
+
...patch.coverageGaps ? { coverageGaps: patch.coverageGaps } : prev?.coverageGaps ? { coverageGaps: prev.coverageGaps } : {},
|
|
85140
85869
|
...patch.backfillAnchor ? { backfillAnchor: patch.backfillAnchor } : prev?.backfillAnchor ? { backfillAnchor: prev.backfillAnchor } : {}
|
|
85141
85870
|
}
|
|
85142
85871
|
};
|
|
@@ -85156,7 +85885,7 @@ function unitTiming(postStarted, prepMs, receipt) {
|
|
|
85156
85885
|
}
|
|
85157
85886
|
function addCounts(a, b) {
|
|
85158
85887
|
const sum = (k) => (a[k] ?? 0) + (b[k] ?? 0);
|
|
85159
|
-
return { commitsWalked: sum("commitsWalked"), changesExtracted: sum("changesExtracted"), pairs: sum("pairs"), claims: sum("claims"), anchors: sum("anchors"), packages: sum("packages") };
|
|
85888
|
+
return { commitsWalked: sum("commitsWalked"), changesExtracted: sum("changesExtracted"), pairs: sum("pairs"), claims: sum("claims"), anchors: sum("anchors"), packages: sum("packages"), deferredUnits: sum("deferredUnits") };
|
|
85160
85889
|
}
|
|
85161
85890
|
async function runHistoryWalk(root, input, client, opts = {}) {
|
|
85162
85891
|
const reader = opts.git ? null : new GitBlobReader(root);
|
|
@@ -85198,7 +85927,12 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85198
85927
|
return { profile, processed: 0, state: "refused" };
|
|
85199
85928
|
}
|
|
85200
85929
|
if (units.length === 0) {
|
|
85201
|
-
|
|
85930
|
+
const deferred = profile.historyStage?.counts?.deferredUnits ?? 0;
|
|
85931
|
+
profile = stage(profile, {
|
|
85932
|
+
state: "done",
|
|
85933
|
+
watermarkSha: headSha,
|
|
85934
|
+
...deferred > 0 ? { lastError: `${deferred} history units deferred; coverage gaps require source review and re-extraction.` } : {}
|
|
85935
|
+
}, now);
|
|
85202
85936
|
persist(profile);
|
|
85203
85937
|
await reportHistoryStage(client, profile, log);
|
|
85204
85938
|
return { profile, processed: 0, state: "done" };
|
|
@@ -85227,7 +85961,8 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85227
85961
|
const group = byIndex.get(u.index) ?? [u];
|
|
85228
85962
|
const bundle = await buildUnitBundle(root, u, {
|
|
85229
85963
|
ignorePatterns: ignoreLines,
|
|
85230
|
-
narrative: narrative(u, u.isMerge ? group : void 0)
|
|
85964
|
+
narrative: narrative(u, u.isMerge ? group : void 0),
|
|
85965
|
+
narrativeSources: narrativeSources(u, u.isMerge ? group : void 0)
|
|
85231
85966
|
});
|
|
85232
85967
|
const prev = dryRun ? void 0 : predecessor(k);
|
|
85233
85968
|
const body2 = {
|
|
@@ -85240,6 +85975,7 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85240
85975
|
...u.authorDate ? { authorDate: u.authorDate } : {}
|
|
85241
85976
|
},
|
|
85242
85977
|
narrative: bundle.narrative,
|
|
85978
|
+
...bundle.narrativeSources?.length ? { narrativeSources: bundle.narrativeSources } : {},
|
|
85243
85979
|
fileList: bundle.fileList,
|
|
85244
85980
|
diff: bundle.diff,
|
|
85245
85981
|
pathTokens: Object.keys(bundle.pathTokens),
|
|
@@ -85251,7 +85987,15 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85251
85987
|
};
|
|
85252
85988
|
const spine = await spineForUnit(git3, root, u, readBlob);
|
|
85253
85989
|
if (spine) body2.spine = spine;
|
|
85254
|
-
const anchors =
|
|
85990
|
+
const anchors = opts.anchors ? await historicalAnchors({
|
|
85991
|
+
root,
|
|
85992
|
+
projectId,
|
|
85993
|
+
salt: opts.anchors.salt,
|
|
85994
|
+
unit: u,
|
|
85995
|
+
bundle,
|
|
85996
|
+
ignorePatterns: ignoreLines,
|
|
85997
|
+
readBlob
|
|
85998
|
+
}) : void 0;
|
|
85255
85999
|
if (anchors) body2.anchors = anchors;
|
|
85256
86000
|
return { body: body2, prepMs: Date.now() - prepStarted };
|
|
85257
86001
|
})();
|
|
@@ -85384,6 +86128,15 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85384
86128
|
return { profile, processed, state: "refused" };
|
|
85385
86129
|
case "rejected":
|
|
85386
86130
|
case "error":
|
|
86131
|
+
if (outcome.status === "error" && outcome.parked && outcome.runId && ["deferred-context", "deferred-budget"].includes(outcome.errorCode ?? "")) {
|
|
86132
|
+
const gaps = [...profile.historyStage?.coverageGaps ?? []];
|
|
86133
|
+
const known = gaps.some((g) => g.runId === outcome.runId);
|
|
86134
|
+
counts = addCounts(counts, { commitsWalked: 1, deferredUnits: known ? 0 : 1 });
|
|
86135
|
+
if (!known) gaps.push({ sha: u.sha, subIndex: u.subIndex, runId: outcome.runId, reason: outcome.errorCode });
|
|
86136
|
+
profile = stage(profile, { coverageGaps: gaps.slice(-1e3) }, now);
|
|
86137
|
+
log(`[errata] history ${label}: deferred (${outcome.errorCode}); coverage gap retained as ${outcome.runId}`);
|
|
86138
|
+
break;
|
|
86139
|
+
}
|
|
85387
86140
|
profile = stage(profile, { state: "paused", lastError: `unit ${label} ${outcome.status}: ${outcome.error.slice(0, 200)}` }, now);
|
|
85388
86141
|
persist(profile);
|
|
85389
86142
|
await reportHistoryStage(client, profile, log);
|
|
@@ -85394,7 +86147,11 @@ async function walk10(root, input, client, opts, readBlob) {
|
|
|
85394
86147
|
processed += 1;
|
|
85395
86148
|
}
|
|
85396
86149
|
const reachedHead = (profile.historyStage?.unitsDone ?? 0) >= total;
|
|
85397
|
-
profile = stage(profile, reachedHead ? {
|
|
86150
|
+
profile = stage(profile, reachedHead ? {
|
|
86151
|
+
state: "done",
|
|
86152
|
+
watermarkSha: headSha,
|
|
86153
|
+
...(counts.deferredUnits ?? 0) > 0 ? { lastError: `${counts.deferredUnits} history units deferred; coverage gaps require source review and re-extraction.` } : {}
|
|
86154
|
+
} : { state: dryRun ? "extracting" : "contributing" }, now);
|
|
85398
86155
|
persist(profile);
|
|
85399
86156
|
await reportHistoryStage(client, profile, log);
|
|
85400
86157
|
return { profile, processed, state: profile.historyStage?.state ?? "done" };
|
|
@@ -85477,7 +86234,7 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
|
|
|
85477
86234
|
|
|
85478
86235
|
// src/link-flow.ts
|
|
85479
86236
|
init_cloud_auth();
|
|
85480
|
-
import { createHash as
|
|
86237
|
+
import { createHash as createHash18 } from "node:crypto";
|
|
85481
86238
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
85482
86239
|
import { existsSync as existsSync30, writeFileSync as writeFileSync23 } from "node:fs";
|
|
85483
86240
|
import { join as join38 } from "node:path";
|
|
@@ -85771,7 +86528,7 @@ async function loginOAuthLoopback(opts) {
|
|
|
85771
86528
|
|
|
85772
86529
|
// src/link-flow.ts
|
|
85773
86530
|
function remoteFingerprint(locator) {
|
|
85774
|
-
return
|
|
86531
|
+
return createHash18("sha256").update(locator).digest("hex");
|
|
85775
86532
|
}
|
|
85776
86533
|
function isDecision(value) {
|
|
85777
86534
|
if (!value || typeof value !== "object") return false;
|
|
@@ -87057,13 +87814,24 @@ async function startMultiDaemon(opts = {}) {
|
|
|
87057
87814
|
});
|
|
87058
87815
|
const pullProjectAnchors = async (r, client, salt) => {
|
|
87059
87816
|
const donePass = markPass(`anchor-pull:${r.engine.profile.name}`);
|
|
87817
|
+
const beforeCorrections = r.engine.profile.projectHistoryCorrectionCursor ?? 0;
|
|
87060
87818
|
const sync = await syncProjectAnchors({
|
|
87061
87819
|
root: r.root,
|
|
87062
87820
|
profile: r.engine.profile,
|
|
87063
87821
|
store: r.engine.store,
|
|
87822
|
+
correctionMirrors: [sharedStore],
|
|
87064
87823
|
cloud: client,
|
|
87065
87824
|
salt
|
|
87066
87825
|
}).finally(donePass);
|
|
87826
|
+
if ((r.engine.profile.projectHistoryCorrectionCursor ?? 0) > beforeCorrections) {
|
|
87827
|
+
for (const record2 of records) record2.engine.markContextDirty();
|
|
87828
|
+
}
|
|
87829
|
+
try {
|
|
87830
|
+
const revision = await syncHistoryRevision({ root: r.root, profile: r.engine.profile, store: r.engine.store, cloud: client, salt });
|
|
87831
|
+
if (revision.changed) r.engine.markContextDirty();
|
|
87832
|
+
} catch (err2) {
|
|
87833
|
+
console.warn(`[errata] history revision reconciliation failed for ${r.engine.profile.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
87834
|
+
}
|
|
87067
87835
|
if (sync.synced) {
|
|
87068
87836
|
if (sync.anchors + sync.updated > 0) {
|
|
87069
87837
|
r.engine.markContextDirty();
|