@inerrata-corporation/errata 2.0.1-dev.99 → 2.0.2-dev.1020
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 +670 -288
- package/errata.mjs +8867 -2233
- package/package.json +1 -1
- package/pass-worker.mjs +1370 -326
package/consolidate-worker.mjs
CHANGED
|
@@ -133,7 +133,14 @@ var init_castalia = __esm({
|
|
|
133
133
|
"SOLVED_BY",
|
|
134
134
|
"MITIGATES",
|
|
135
135
|
"REPORTED_FAILURE",
|
|
136
|
-
"CONTRADICTS"
|
|
136
|
+
"CONTRADICTS",
|
|
137
|
+
// Motif twin-faces (KN-twin-faces): failure-face motif → remedy-face motif
|
|
138
|
+
// across layers (AntiPattern/Weakness ↔ Technique/Pattern). Same
|
|
139
|
+
// problem→fix direction as FIXED_BY/SOLVED_BY. Minted by the nightly LLM
|
|
140
|
+
// twin-face pass — these are the near-identical cross-layer pairs the
|
|
141
|
+
// polarity gate (finding 5) correctly refuses to FUSE; the link carries
|
|
142
|
+
// what fusion can't.
|
|
143
|
+
"REMEDIED_BY"
|
|
137
144
|
];
|
|
138
145
|
CONCEPTUAL_EDGES = [
|
|
139
146
|
"INSTANCE_OF",
|
|
@@ -223,6 +230,10 @@ var init_castalia = __esm({
|
|
|
223
230
|
CAUSED_BY: 3,
|
|
224
231
|
FIXED_BY: 3,
|
|
225
232
|
SOLVED_BY: 3,
|
|
233
|
+
// Twin-face link (failure motif → remedy motif, KN-twin-faces) — causal-grade
|
|
234
|
+
// but a notch below witnessed FIXED_BY/SOLVED_BY: the pairing is an LLM
|
|
235
|
+
// judgment over descriptions, not an agent-witnessed resolution.
|
|
236
|
+
REMEDIED_BY: 2.5,
|
|
226
237
|
MANIFESTS_AS: 2,
|
|
227
238
|
ESCALATES_TO: 1.5,
|
|
228
239
|
AFFECTS: 1.2,
|
|
@@ -354,6 +365,13 @@ var init_castalia = __esm({
|
|
|
354
365
|
}
|
|
355
366
|
});
|
|
356
367
|
|
|
368
|
+
// ../../packages/shared/src/graph-events.ts
|
|
369
|
+
var init_graph_events = __esm({
|
|
370
|
+
"../../packages/shared/src/graph-events.ts"() {
|
|
371
|
+
"use strict";
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
357
375
|
// ../../packages/shared/src/canonical/hash.ts
|
|
358
376
|
import { createHash } from "node:crypto";
|
|
359
377
|
function sha256(input) {
|
|
@@ -662,7 +680,7 @@ function lemma(token) {
|
|
|
662
680
|
}
|
|
663
681
|
return token;
|
|
664
682
|
}
|
|
665
|
-
function
|
|
683
|
+
function tokenize(text, resolve) {
|
|
666
684
|
const matches = text.normalize("NFC").toLowerCase().match(TOKEN_RE) ?? [];
|
|
667
685
|
const out = /* @__PURE__ */ new Set();
|
|
668
686
|
for (const raw of matches) {
|
|
@@ -672,11 +690,14 @@ function conceptTokens(text) {
|
|
|
672
690
|
out.add(token);
|
|
673
691
|
continue;
|
|
674
692
|
}
|
|
675
|
-
const canonical =
|
|
693
|
+
const canonical = resolve(token);
|
|
676
694
|
out.add(canonical ?? lemma(token));
|
|
677
695
|
}
|
|
678
696
|
return [...out].sort();
|
|
679
697
|
}
|
|
698
|
+
function conceptTokens(text) {
|
|
699
|
+
return tokenize(text, resolveCanonicalId);
|
|
700
|
+
}
|
|
680
701
|
function conceptBag(text) {
|
|
681
702
|
return conceptTokens(text).join(" ");
|
|
682
703
|
}
|
|
@@ -15194,13 +15215,21 @@ var init_edge_rules = __esm({
|
|
|
15194
15215
|
// NOT ruled here — the type pre-exists with broader extractor senses, and a
|
|
15195
15216
|
// new rule on an old type would reject legitimate live flows (reject-never-flip
|
|
15196
15217
|
// cuts both ways: only rule types you introduce or senses that are documented).
|
|
15197
|
-
|
|
15218
|
+
// `Component` joined the target set with OM-agent-anchors: an agent-named
|
|
15219
|
+
// component ("React Router") is the same knowledge→named-unit anchor shape as
|
|
15220
|
+
// a Tool — the knowledge is ABOUT it, not dependent on it.
|
|
15221
|
+
CONCERNS: { from: ["Problem", "Solution", "RootCause", "Claim", "Pattern"], to: ["Tool", "Component"] },
|
|
15198
15222
|
OPERATES_ON: { from: ["Algorithm"], to: ["DataStructure"] },
|
|
15199
15223
|
INVOLVES: { from: ["Problem", "Solution"], to: ["DataStructure"] },
|
|
15200
15224
|
// ── Taxonomy (Track 4 Stream C: MITRE CWE `ChildOf` → `Weakness —IS_A→ Weakness`) ──
|
|
15201
15225
|
IS_A: { from: ["Weakness"], to: ["Weakness"] },
|
|
15202
15226
|
// ── Conceptual (v1 taxonomy.ts: instance → motif/pattern reference) ──
|
|
15203
|
-
|
|
15227
|
+
// `AntiPattern` joined the target set 2026-08-02: it is one of the three motif
|
|
15228
|
+
// kinds (generalizer motifs.ts `layerOf`: pattern | technique | antipattern) and
|
|
15229
|
+
// the SUPPRESSED-close path mints `Problem ─INSTANCE_OF→ AntiPattern` as the
|
|
15230
|
+
// negative-knowledge binding ("silenced, not solved") — the original three-label
|
|
15231
|
+
// rule predates AntiPattern joining the motif layer and silently ate that edge.
|
|
15232
|
+
INSTANCE_OF: { to: ["Pattern", "AntiPattern", "Weakness", "Technique"] },
|
|
15204
15233
|
IMPLEMENTS: { from: ["Solution", "Language", "Component"], to: ["Pattern", "Technique"] },
|
|
15205
15234
|
MATCHES: { to: ["Pattern"] },
|
|
15206
15235
|
// ── Artifact evidence (v1 taxonomy.ts artifact rows) ──
|
|
@@ -15301,13 +15330,35 @@ var init_wire = __esm({
|
|
|
15301
15330
|
/** Canonical human-readable description (no raw paths — daemon scrubs; server rechecks). */
|
|
15302
15331
|
description: external_exports.string().min(1).max(4e3),
|
|
15303
15332
|
attrs: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
|
|
15333
|
+
/** One-way origin key of the SESSION that minted this node (`ws_…`, a
|
|
15334
|
+
* truncated digest — never the raw session id). Stamped onto the created
|
|
15335
|
+
* node as `authoringSession`, which is the independence unit for the
|
|
15336
|
+
* evidence channels: the session that authored a claim may not corroborate
|
|
15337
|
+
* or refute it, while a DIFFERENT session on the same checkout may (alyssa,
|
|
15338
|
+
* 2026-07-31 — the workspace key made every witness on a single-checkout
|
|
15339
|
+
* deployment a self-corroboration). Optional + additive: absent leaves the
|
|
15340
|
+
* gate fail-open for that node, exactly today's behaviour. */
|
|
15341
|
+
originSession: external_exports.string().min(3).max(64).optional(),
|
|
15342
|
+
/** Epoch ms of the ORIGINATING local node's creation — when the knowledge was
|
|
15343
|
+
* actually captured, as opposed to when its public twin reached the cloud.
|
|
15344
|
+
* Stored as `observedAt`; the network board's chronological view orders on
|
|
15345
|
+
* it. Without this the wire carried NO timestamp at all, so a node captured
|
|
15346
|
+
* days ago surfaced as "new" the moment it was generalized and published —
|
|
15347
|
+
* the board showed ingest order wearing a chronology's clothes. Optional +
|
|
15348
|
+
* additive: absent keeps ingest-time ordering for that node. */
|
|
15349
|
+
originCreatedAtMs: external_exports.number().int().positive().optional(),
|
|
15304
15350
|
extractionSource: external_exports.enum(INGEST_EXTRACTION_SOURCES),
|
|
15305
15351
|
validationSource: external_exports.enum(VALIDATION_SOURCES).optional(),
|
|
15306
15352
|
/** Org-membrane (M2): the daemon's anchor tag — it owns the lockfile, so it
|
|
15307
15353
|
* knows which packages are private. The door does NOT trust a `public` claim
|
|
15308
15354
|
* blindly (it re-confirms on the spine); absent ⇒ unknown ⇒ fail-closed to
|
|
15309
15355
|
* org-private. Accepted-but-ignored until ORG_MEMBRANE_ENABLED flips. */
|
|
15310
|
-
anchorVisibility: external_exports.enum(["public", "private"]).optional()
|
|
15356
|
+
anchorVisibility: external_exports.enum(["public", "private"]).optional(),
|
|
15357
|
+
/** The spine-resolvable anchor id backing a `public` tag (OM-anchor-tag): a
|
|
15358
|
+
* Package purl or `languageCanonicalId`. The door validates THIS on the
|
|
15359
|
+
* public spine (falling back to `canonicalId` when absent — context stubs
|
|
15360
|
+
* are self-anchored). Never trusted without spine confirmation. */
|
|
15361
|
+
anchor: external_exports.string().min(1).max(300).optional()
|
|
15311
15362
|
});
|
|
15312
15363
|
RouteContextCountWireSchema = external_exports.object({
|
|
15313
15364
|
confirmed: external_exports.number().int().min(0),
|
|
@@ -15396,7 +15447,7 @@ var init_canonicalize = __esm({
|
|
|
15396
15447
|
|
|
15397
15448
|
// ../../packages/shared/src/nlp/triage-canon.ts
|
|
15398
15449
|
function canonicalizeToken(t) {
|
|
15399
|
-
const base = t.trim().toLowerCase().replace(/
|
|
15450
|
+
const base = t.trim().toLowerCase().replace(/(?!^)@.*$|\s.*$/, "");
|
|
15400
15451
|
if (!base) return "";
|
|
15401
15452
|
return resolveCanonicalId(base) ?? base;
|
|
15402
15453
|
}
|
|
@@ -15417,6 +15468,7 @@ var init_src = __esm({
|
|
|
15417
15468
|
"../../packages/shared/src/index.ts"() {
|
|
15418
15469
|
"use strict";
|
|
15419
15470
|
init_castalia();
|
|
15471
|
+
init_graph_events();
|
|
15420
15472
|
init_identity();
|
|
15421
15473
|
init_wire();
|
|
15422
15474
|
init_edge_rules();
|
|
@@ -15478,6 +15530,51 @@ var init_review = __esm({
|
|
|
15478
15530
|
}
|
|
15479
15531
|
});
|
|
15480
15532
|
|
|
15533
|
+
// ../../packages/local-shared/src/anchorable.ts
|
|
15534
|
+
function anchorableExtensionAlternation() {
|
|
15535
|
+
return BY_LENGTH.map((e) => e.slice(1).replace(/[+.]/g, (c) => `\\${c}`)).join("|");
|
|
15536
|
+
}
|
|
15537
|
+
var ANCHORABLE_EXTENSIONS, BY_LENGTH;
|
|
15538
|
+
var init_anchorable = __esm({
|
|
15539
|
+
"../../packages/local-shared/src/anchorable.ts"() {
|
|
15540
|
+
"use strict";
|
|
15541
|
+
ANCHORABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
15542
|
+
// typescript provider
|
|
15543
|
+
".ts",
|
|
15544
|
+
".tsx",
|
|
15545
|
+
".js",
|
|
15546
|
+
".jsx",
|
|
15547
|
+
".mjs",
|
|
15548
|
+
".cjs",
|
|
15549
|
+
// python / go / rust / ruby / csharp providers
|
|
15550
|
+
".py",
|
|
15551
|
+
".go",
|
|
15552
|
+
".rs",
|
|
15553
|
+
".rb",
|
|
15554
|
+
".cs",
|
|
15555
|
+
// cpp provider — every variant it parses, not just the three that were listed
|
|
15556
|
+
".c",
|
|
15557
|
+
".h",
|
|
15558
|
+
".cpp",
|
|
15559
|
+
".cc",
|
|
15560
|
+
".cxx",
|
|
15561
|
+
".c++",
|
|
15562
|
+
".hpp",
|
|
15563
|
+
".hh",
|
|
15564
|
+
".hxx",
|
|
15565
|
+
".h++",
|
|
15566
|
+
// CUDA — the cpp provider parses these too. Missed when this list was first
|
|
15567
|
+
// transcribed by hand; the parity test caught them on its very first run,
|
|
15568
|
+
// which is the argument for the test existing.
|
|
15569
|
+
".cu",
|
|
15570
|
+
".cuh",
|
|
15571
|
+
// no provider yet; the grammar ships. Inert, not wrong — see above.
|
|
15572
|
+
".java"
|
|
15573
|
+
]);
|
|
15574
|
+
BY_LENGTH = [...ANCHORABLE_EXTENSIONS].sort((a, b) => b.length - a.length);
|
|
15575
|
+
}
|
|
15576
|
+
});
|
|
15577
|
+
|
|
15481
15578
|
// ../../packages/local-shared/src/sqlite-adapter.ts
|
|
15482
15579
|
function openDatabase(path) {
|
|
15483
15580
|
const db = new DatabaseSync(path);
|
|
@@ -15490,6 +15587,7 @@ function openDatabase(path) {
|
|
|
15490
15587
|
db.exec("PRAGMA journal_mode = WAL");
|
|
15491
15588
|
db.exec("PRAGMA synchronous = NORMAL");
|
|
15492
15589
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
15590
|
+
db.exec("PRAGMA journal_size_limit = 67108864");
|
|
15493
15591
|
} catch {
|
|
15494
15592
|
}
|
|
15495
15593
|
}
|
|
@@ -15525,7 +15623,7 @@ function openDatabase(path) {
|
|
|
15525
15623
|
return db.prepare(`PRAGMA ${key}`).get();
|
|
15526
15624
|
},
|
|
15527
15625
|
transaction(fn) {
|
|
15528
|
-
db.exec("BEGIN");
|
|
15626
|
+
db.exec("BEGIN IMMEDIATE");
|
|
15529
15627
|
try {
|
|
15530
15628
|
const r = fn();
|
|
15531
15629
|
db.exec("COMMIT");
|
|
@@ -15579,10 +15677,21 @@ var init_src2 = __esm({
|
|
|
15579
15677
|
init_profile();
|
|
15580
15678
|
init_daemon_wire();
|
|
15581
15679
|
init_review();
|
|
15680
|
+
init_anchorable();
|
|
15582
15681
|
init_sqlite_adapter();
|
|
15583
15682
|
}
|
|
15584
15683
|
});
|
|
15585
15684
|
|
|
15685
|
+
// ../../packages/indexer/src/parse-cache.ts
|
|
15686
|
+
var ENTRY_TTL_MS, MAX_ENTRY_BYTES;
|
|
15687
|
+
var init_parse_cache = __esm({
|
|
15688
|
+
"../../packages/indexer/src/parse-cache.ts"() {
|
|
15689
|
+
"use strict";
|
|
15690
|
+
ENTRY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
15691
|
+
MAX_ENTRY_BYTES = 2 * 1024 * 1024;
|
|
15692
|
+
}
|
|
15693
|
+
});
|
|
15694
|
+
|
|
15586
15695
|
// ../../packages/indexer/src/simhash.ts
|
|
15587
15696
|
var MASK64;
|
|
15588
15697
|
var init_simhash = __esm({
|
|
@@ -15605,6 +15714,7 @@ var init_pipeline = __esm({
|
|
|
15605
15714
|
"../../packages/indexer/src/pipeline.ts"() {
|
|
15606
15715
|
"use strict";
|
|
15607
15716
|
init_src2();
|
|
15717
|
+
init_parse_cache();
|
|
15608
15718
|
init_identity2();
|
|
15609
15719
|
}
|
|
15610
15720
|
});
|
|
@@ -15744,9 +15854,32 @@ var LOCAL_RULE_OVERRIDES = {
|
|
|
15744
15854
|
to: [...CODE_NODE_LABELS, "Symbol"]
|
|
15745
15855
|
},
|
|
15746
15856
|
REVEALED_BY: null,
|
|
15747
|
-
PRODUCED: null
|
|
15857
|
+
PRODUCED: null,
|
|
15858
|
+
// FIXED_BY locally ALSO carries the fix-provenance sense: `resolveProblem`
|
|
15859
|
+
// attributes a closed Problem to the fixing `Episode` (PLAN_PLASTICITY §2.1)
|
|
15860
|
+
// alongside the cloud's Problem→Solution knowledge claim. Same shape as
|
|
15861
|
+
// PRODUCED/REVEALED_BY above — an Episode is code-layer and never drains, so
|
|
15862
|
+
// the cloud door's `to: [Solution]` rule is untouched. The `from` constraint
|
|
15863
|
+
// stays: the reversed (Solution)-FIXED_BY->(...) splash bug is the reason
|
|
15864
|
+
// this rule exists at all.
|
|
15865
|
+
FIXED_BY: { from: EDGE_RULES["FIXED_BY"]?.from, to: ["Solution", "Episode"] }
|
|
15748
15866
|
};
|
|
15749
|
-
|
|
15867
|
+
function localEdgeViolation(fromLabel, type, toLabel) {
|
|
15868
|
+
if (type in LOCAL_RULE_OVERRIDES) {
|
|
15869
|
+
const rule = LOCAL_RULE_OVERRIDES[type];
|
|
15870
|
+
if (!rule) return null;
|
|
15871
|
+
if (fromLabel && rule.from && !rule.from.includes(fromLabel)) {
|
|
15872
|
+
return `${type} cannot originate from ${fromLabel} locally (allowed: ${rule.from.join(", ")})`;
|
|
15873
|
+
}
|
|
15874
|
+
if (toLabel && rule.to && !rule.to.includes(toLabel)) {
|
|
15875
|
+
return `${type} cannot target ${toLabel} locally (allowed: ${rule.to.join(", ")})`;
|
|
15876
|
+
}
|
|
15877
|
+
return null;
|
|
15878
|
+
}
|
|
15879
|
+
const verdict = isValidEdge(fromLabel, type, toLabel);
|
|
15880
|
+
return verdict.ok ? null : verdict.reason ?? "edge rule violation";
|
|
15881
|
+
}
|
|
15882
|
+
var SCHEMA_VERSION = 6;
|
|
15750
15883
|
var SCHEMA_SQL = `
|
|
15751
15884
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
15752
15885
|
version INTEGER PRIMARY KEY
|
|
@@ -15761,6 +15894,21 @@ CREATE TABLE IF NOT EXISTS store_meta (
|
|
|
15761
15894
|
value TEXT NOT NULL
|
|
15762
15895
|
);
|
|
15763
15896
|
|
|
15897
|
+
-- Durable ledger of edges the ontology gate REFUSED, keyed by edge type.
|
|
15898
|
+
-- Durable rather than in-memory for one specific reason: the status command runs
|
|
15899
|
+
-- in a SEPARATE process and opens its own store handle, so a counter living on
|
|
15900
|
+
-- the instance reads 0 there forever. That is exactly how a producer rejecting
|
|
15901
|
+
-- 100% of its output stayed invisible for 17 days. Persisting it also survives
|
|
15902
|
+
-- the daemon restart that would otherwise erase the evidence.
|
|
15903
|
+
-- Keyed by type because a systematic producer bug shows up as ONE type
|
|
15904
|
+
-- dominating; sample keeps the latest reason so the count is actionable.
|
|
15905
|
+
CREATE TABLE IF NOT EXISTS edge_rejections (
|
|
15906
|
+
type TEXT PRIMARY KEY,
|
|
15907
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
15908
|
+
last_at INTEGER NOT NULL,
|
|
15909
|
+
sample TEXT
|
|
15910
|
+
);
|
|
15911
|
+
|
|
15764
15912
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
15765
15913
|
id TEXT PRIMARY KEY,
|
|
15766
15914
|
label TEXT NOT NULL,
|
|
@@ -16023,6 +16171,13 @@ var SqliteGraphStore = class {
|
|
|
16023
16171
|
findByLabel: this.db.prepare(
|
|
16024
16172
|
"SELECT * FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16025
16173
|
),
|
|
16174
|
+
// Scalar count twin of findByLabel — same live-row semantics, no row
|
|
16175
|
+
// hydration. Exists because status surfaces (daemon `/` + `/health`) used
|
|
16176
|
+
// findNodesByLabel(...).length, materializing every row's attrs JSON and
|
|
16177
|
+
// embedding blob per request — seconds of synchronous loop-hold per poll.
|
|
16178
|
+
countByLabel: this.db.prepare(
|
|
16179
|
+
"SELECT COUNT(*) AS n FROM nodes WHERE label = ? AND valid_to IS NULL"
|
|
16180
|
+
),
|
|
16026
16181
|
// ALL versions of a label — incl frozen/closed (valid_to set). Used by the
|
|
16027
16182
|
// clean-reindex purge so a true wipe removes history too, not just live rows.
|
|
16028
16183
|
findByLabelAll: this.db.prepare("SELECT * FROM nodes WHERE label = ?"),
|
|
@@ -16130,6 +16285,16 @@ var SqliteGraphStore = class {
|
|
|
16130
16285
|
if (!cols.has(name)) this.db.exec(ddl);
|
|
16131
16286
|
}
|
|
16132
16287
|
}
|
|
16288
|
+
if (from < 6) {
|
|
16289
|
+
this.db.exec(`
|
|
16290
|
+
CREATE TABLE IF NOT EXISTS edge_rejections (
|
|
16291
|
+
type TEXT PRIMARY KEY,
|
|
16292
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
16293
|
+
last_at INTEGER NOT NULL,
|
|
16294
|
+
sample TEXT
|
|
16295
|
+
)
|
|
16296
|
+
`);
|
|
16297
|
+
}
|
|
16133
16298
|
this.db.prepare("UPDATE schema_version SET version = ?").run(SCHEMA_VERSION);
|
|
16134
16299
|
});
|
|
16135
16300
|
}
|
|
@@ -16211,6 +16376,7 @@ var SqliteGraphStore = class {
|
|
|
16211
16376
|
const violation = this.edgeRuleViolation(edge);
|
|
16212
16377
|
if (violation) {
|
|
16213
16378
|
this.rejectedEdgeCount++;
|
|
16379
|
+
this.recordEdgeRejection(edge.type, violation, edge.lastSeenAt || edge.createdAt || 0);
|
|
16214
16380
|
console.warn(`[local-graph] rejected edge ${edge.from}-[:${edge.type}]->${edge.to}: ${violation}`);
|
|
16215
16381
|
return;
|
|
16216
16382
|
}
|
|
@@ -16235,22 +16401,51 @@ var SqliteGraphStore = class {
|
|
|
16235
16401
|
* overlay consulted first. Returns the reason string on a documented-
|
|
16236
16402
|
* forbidden combination, else null. Point lookups on the id PK — negligible
|
|
16237
16403
|
* next to the insert itself. */
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
|
|
16404
|
+
/** Upsert one refusal into the durable ledger. Best-effort: a bookkeeping
|
|
16405
|
+
* failure must never turn a refused edge into a thrown write. */
|
|
16406
|
+
recordEdgeRejection(type, reason, at) {
|
|
16407
|
+
try {
|
|
16408
|
+
this.db.prepare(
|
|
16409
|
+
`INSERT INTO edge_rejections (type, count, last_at, sample) VALUES (?, 1, ?, ?)
|
|
16410
|
+
ON CONFLICT(type) DO UPDATE SET
|
|
16411
|
+
count = count + 1, last_at = excluded.last_at, sample = excluded.sample`
|
|
16412
|
+
).run(type, at, reason.slice(0, 200));
|
|
16413
|
+
} catch {
|
|
16414
|
+
}
|
|
16415
|
+
}
|
|
16416
|
+
/** Refusals recorded by the ontology gate, per edge type, newest activity first.
|
|
16417
|
+
* Durable across restarts and readable from any process (see the table note). */
|
|
16418
|
+
edgeRejections() {
|
|
16419
|
+
try {
|
|
16420
|
+
return this.db.prepare(
|
|
16421
|
+
"SELECT type, count, last_at AS lastAt, sample FROM edge_rejections ORDER BY count DESC, last_at DESC"
|
|
16422
|
+
).all();
|
|
16423
|
+
} catch {
|
|
16424
|
+
return [];
|
|
16425
|
+
}
|
|
16426
|
+
}
|
|
16427
|
+
/** Drop ledger entries whose last refusal predates `cutoff`. A still-misbehaving
|
|
16428
|
+
* producer keeps refreshing `last_at` and survives; a fixed one fades out. */
|
|
16429
|
+
pruneEdgeRejections(cutoff) {
|
|
16430
|
+
try {
|
|
16431
|
+
this.db.prepare("DELETE FROM edge_rejections WHERE last_at < ?").run(cutoff);
|
|
16432
|
+
} catch {
|
|
16433
|
+
}
|
|
16434
|
+
}
|
|
16435
|
+
/** Clear the ledger outright, whole or per type — operator escape hatch. */
|
|
16436
|
+
clearEdgeRejections(type) {
|
|
16437
|
+
try {
|
|
16438
|
+
if (type) this.db.prepare("DELETE FROM edge_rejections WHERE type = ?").run(type);
|
|
16439
|
+
else this.db.exec("DELETE FROM edge_rejections");
|
|
16440
|
+
} catch {
|
|
16251
16441
|
}
|
|
16252
|
-
|
|
16253
|
-
|
|
16442
|
+
}
|
|
16443
|
+
edgeRuleViolation(edge) {
|
|
16444
|
+
return localEdgeViolation(
|
|
16445
|
+
this.getNode(edge.from)?.label,
|
|
16446
|
+
edge.type,
|
|
16447
|
+
this.getNode(edge.to)?.label
|
|
16448
|
+
);
|
|
16254
16449
|
}
|
|
16255
16450
|
updateEdge(id, patch) {
|
|
16256
16451
|
this.stmts.updateEdge.run({
|
|
@@ -16276,6 +16471,13 @@ var SqliteGraphStore = class {
|
|
|
16276
16471
|
const rows = this.stmts.findByLabel.all(label);
|
|
16277
16472
|
return rows.map(rowToNode);
|
|
16278
16473
|
}
|
|
16474
|
+
/** Live-row count for a label — `findNodesByLabel(label).length` without the
|
|
16475
|
+
* per-row hydration (attrs JSON + embedding blob). Status surfaces poll this
|
|
16476
|
+
* per project per request; the materializing form held the daemon's event
|
|
16477
|
+
* loop for seconds at scale. */
|
|
16478
|
+
countNodesByLabel(label) {
|
|
16479
|
+
return Number(this.stmts.countByLabel.get(label).n);
|
|
16480
|
+
}
|
|
16279
16481
|
findAllVersionsByLabel(label) {
|
|
16280
16482
|
const rows = this.stmts.findByLabelAll.all(label);
|
|
16281
16483
|
return rows.map(rowToNode);
|
|
@@ -16380,6 +16582,163 @@ var SqliteGraphStore = class {
|
|
|
16380
16582
|
const rows = this.db.prepare("SELECT from_id, to_id, type FROM edges WHERE valid_to IS NULL").all();
|
|
16381
16583
|
return rows.map((r) => ({ from: r.from_id, to: r.to_id, type: r.type }));
|
|
16382
16584
|
}
|
|
16585
|
+
getMeta(key) {
|
|
16586
|
+
const r = this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(key);
|
|
16587
|
+
return r?.value ?? null;
|
|
16588
|
+
}
|
|
16589
|
+
setMeta(key, value) {
|
|
16590
|
+
this.db.prepare(
|
|
16591
|
+
"INSERT INTO store_meta (key, value) VALUES (:key, :value) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
16592
|
+
).run({ key, value });
|
|
16593
|
+
}
|
|
16594
|
+
dirtyNodeIdsSince(ts) {
|
|
16595
|
+
const rows = this.db.prepare("SELECT id FROM nodes WHERE valid_to IS NULL AND last_updated_at > ?").all(ts);
|
|
16596
|
+
return rows.map((r) => r.id);
|
|
16597
|
+
}
|
|
16598
|
+
/** Endpoints of edges TOUCHED since `ts` — created, re-seen, or CLOSED.
|
|
16599
|
+
* Closures matter as much as additions: a node that lost inflow is rank-dirty
|
|
16600
|
+
* while its own row never updated, so removal endpoints must seed the
|
|
16601
|
+
* incremental region or the stale inflow persists until the full backstop. */
|
|
16602
|
+
edgeEndpointsTouchedSince(ts) {
|
|
16603
|
+
const rows = this.db.prepare(
|
|
16604
|
+
`SELECT from_id, to_id FROM edges
|
|
16605
|
+
WHERE (valid_to IS NULL AND (created_at > :ts OR last_seen_at > :ts))
|
|
16606
|
+
OR (valid_to IS NOT NULL AND valid_to > :ts)`
|
|
16607
|
+
).all({ ts });
|
|
16608
|
+
return rows.map((r) => ({ from: r.from_id, to: r.to_id }));
|
|
16609
|
+
}
|
|
16610
|
+
/** Lightweight out-edges for a SET of sources, chunked IN-lists — the region
|
|
16611
|
+
* assembly path for incremental PageRank (per-node outEdges() at region
|
|
16612
|
+
* scale re-creates the 106k-prepared-calls problem the batch scan solved). */
|
|
16613
|
+
outEdgesForMany(ids) {
|
|
16614
|
+
return this.edgesForMany(ids, "from_id");
|
|
16615
|
+
}
|
|
16616
|
+
inEdgesForMany(ids) {
|
|
16617
|
+
return this.edgesForMany(ids, "to_id");
|
|
16618
|
+
}
|
|
16619
|
+
/** Stored pageRank for a SET of ids (live rows only — a closed id is simply
|
|
16620
|
+
* absent, which is how incremental region assembly drops dead endpoints). */
|
|
16621
|
+
ranksForMany(ids) {
|
|
16622
|
+
const out = /* @__PURE__ */ new Map();
|
|
16623
|
+
const CHUNK = 400;
|
|
16624
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
16625
|
+
const chunk = ids.slice(i, i + CHUNK);
|
|
16626
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
16627
|
+
const rows = this.db.prepare(
|
|
16628
|
+
`SELECT id, page_rank FROM nodes WHERE id IN (${placeholders}) AND valid_to IS NULL`
|
|
16629
|
+
).all(...chunk);
|
|
16630
|
+
for (const r of rows) out.set(r.id, r.page_rank);
|
|
16631
|
+
}
|
|
16632
|
+
return out;
|
|
16633
|
+
}
|
|
16634
|
+
/** The minimal row set the landmark sweep needs — landmark CANDIDATES
|
|
16635
|
+
* (Pattern/RootCause), everything currently flagged, and every
|
|
16636
|
+
* persistent-tier node (force-landmarks). A few thousand rows, so the
|
|
16637
|
+
* incremental path can refresh the GLOBAL landmark set without the 179k-row
|
|
16638
|
+
* scanLiveNodes materialization. */
|
|
16639
|
+
landmarkSweepRows() {
|
|
16640
|
+
const rows = this.db.prepare(
|
|
16641
|
+
`SELECT id, label, page_rank, is_landmark, memory_tier, extraction_source FROM nodes
|
|
16642
|
+
WHERE valid_to IS NULL
|
|
16643
|
+
AND (memory_tier = 'persistent' OR is_landmark = 1 OR label IN ('Pattern', 'RootCause'))`
|
|
16644
|
+
).all();
|
|
16645
|
+
return rows.map((r) => ({
|
|
16646
|
+
id: r.id,
|
|
16647
|
+
label: r.label,
|
|
16648
|
+
pageRank: r.page_rank,
|
|
16649
|
+
isLandmark: r.is_landmark === 1,
|
|
16650
|
+
memoryTier: r.memory_tier,
|
|
16651
|
+
extractionSource: r.extraction_source
|
|
16652
|
+
}));
|
|
16653
|
+
}
|
|
16654
|
+
edgesForMany(ids, col) {
|
|
16655
|
+
const out = [];
|
|
16656
|
+
const CHUNK = 400;
|
|
16657
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
16658
|
+
const chunk = ids.slice(i, i + CHUNK);
|
|
16659
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
16660
|
+
const rows = this.db.prepare(
|
|
16661
|
+
`SELECT from_id, to_id, type FROM edges WHERE ${col} IN (${placeholders}) AND valid_to IS NULL`
|
|
16662
|
+
).all(...chunk);
|
|
16663
|
+
for (const r of rows) out.push({ from: r.from_id, to: r.to_id, type: r.type });
|
|
16664
|
+
}
|
|
16665
|
+
return out;
|
|
16666
|
+
}
|
|
16667
|
+
checkpointWal() {
|
|
16668
|
+
try {
|
|
16669
|
+
const r = this.db.prepare("PRAGMA wal_checkpoint(TRUNCATE)").get();
|
|
16670
|
+
return r ?? null;
|
|
16671
|
+
} catch {
|
|
16672
|
+
return null;
|
|
16673
|
+
}
|
|
16674
|
+
}
|
|
16675
|
+
reviveReobserved(relPaths, workspaceId, since) {
|
|
16676
|
+
let revived = 0;
|
|
16677
|
+
const CHUNK = 400;
|
|
16678
|
+
for (let i = 0; i < relPaths.length; i += CHUNK) {
|
|
16679
|
+
const slice = relPaths.slice(i, i + CHUNK);
|
|
16680
|
+
if (slice.length === 0) continue;
|
|
16681
|
+
const r = this.db.prepare(
|
|
16682
|
+
`UPDATE nodes SET valid_to = NULL
|
|
16683
|
+
WHERE valid_to IS NOT NULL
|
|
16684
|
+
AND last_updated_at >= ?
|
|
16685
|
+
AND json_extract(attrs_json, '$.workspaceId') = ?
|
|
16686
|
+
AND json_extract(attrs_json, '$.relPath') IN (${slice.map(() => "?").join(",")})`
|
|
16687
|
+
).run(since, workspaceId, ...slice);
|
|
16688
|
+
revived += Number(r.changes);
|
|
16689
|
+
}
|
|
16690
|
+
if (revived > 0) this.mutations++;
|
|
16691
|
+
return revived;
|
|
16692
|
+
}
|
|
16693
|
+
recentEdgeAttrCoverage(marker, attr, limit) {
|
|
16694
|
+
const r = this.db.prepare(
|
|
16695
|
+
`SELECT COUNT(*) AS total,
|
|
16696
|
+
COALESCE(SUM(CASE WHEN json_extract(attrs_json, '$.' || ?) = 1 THEN 1 ELSE 0 END), 0) AS count
|
|
16697
|
+
FROM (SELECT attrs_json FROM edges
|
|
16698
|
+
WHERE valid_to IS NULL AND attrs_json LIKE ?
|
|
16699
|
+
ORDER BY created_at DESC LIMIT ?)`
|
|
16700
|
+
).get(attr, `%${marker}%`, limit);
|
|
16701
|
+
return { count: Number(r.count), total: Number(r.total) };
|
|
16702
|
+
}
|
|
16703
|
+
liveNodeIds(ids) {
|
|
16704
|
+
const live = /* @__PURE__ */ new Set();
|
|
16705
|
+
const CHUNK = 900;
|
|
16706
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
16707
|
+
const slice = ids.slice(i, i + CHUNK);
|
|
16708
|
+
if (slice.length === 0) continue;
|
|
16709
|
+
const rows = this.db.prepare(
|
|
16710
|
+
`SELECT id FROM nodes WHERE valid_to IS NULL AND id IN (${slice.map(() => "?").join(",")})`
|
|
16711
|
+
).all(...slice);
|
|
16712
|
+
for (const r of rows) live.add(r.id);
|
|
16713
|
+
}
|
|
16714
|
+
return live;
|
|
16715
|
+
}
|
|
16716
|
+
/**
|
|
16717
|
+
* Live edges WITH their endpoint labels and ids, resolved in ONE join.
|
|
16718
|
+
*
|
|
16719
|
+
* The ontology sweep needs (id, type, fromLabel, toLabel) for every live edge.
|
|
16720
|
+
* Doing that as `scanLiveEdges()` + two `getNode()` calls is 2N node reads —
|
|
16721
|
+
* 550,000 on this store — and each one deserializes the node's embedding blob.
|
|
16722
|
+
* Measured: the sweep did not finish in 10 minutes. As a single join it is one
|
|
16723
|
+
* query over an index-covered scan. Labels only; nothing here touches embeddings.
|
|
16724
|
+
*/
|
|
16725
|
+
scanLiveEdgeRows() {
|
|
16726
|
+
const rows = this.db.prepare(
|
|
16727
|
+
`SELECT e.id, e.from_id, e.to_id, e.type, a.label AS from_label, b.label AS to_label
|
|
16728
|
+
FROM edges e
|
|
16729
|
+
LEFT JOIN nodes a ON a.id = e.from_id AND a.valid_to IS NULL
|
|
16730
|
+
LEFT JOIN nodes b ON b.id = e.to_id AND b.valid_to IS NULL
|
|
16731
|
+
WHERE e.valid_to IS NULL`
|
|
16732
|
+
).all();
|
|
16733
|
+
return rows.map((r) => ({
|
|
16734
|
+
id: r.id,
|
|
16735
|
+
from: r.from_id,
|
|
16736
|
+
to: r.to_id,
|
|
16737
|
+
type: r.type,
|
|
16738
|
+
fromLabel: r.from_label ?? void 0,
|
|
16739
|
+
toLabel: r.to_label ?? void 0
|
|
16740
|
+
}));
|
|
16741
|
+
}
|
|
16383
16742
|
/** Live nodes whose attrs.relPath is one of `relPaths`. Uses the nodes_relpath
|
|
16384
16743
|
* expression index so the incremental reindex fetches only the changed files'
|
|
16385
16744
|
* symbols instead of scanning every versioned node. */
|
|
@@ -16400,6 +16759,10 @@ var SqliteGraphStore = class {
|
|
|
16400
16759
|
if (!live) return null;
|
|
16401
16760
|
const version2 = live.version ?? 1;
|
|
16402
16761
|
const frozenId = `${liveId}@v${version2}`;
|
|
16762
|
+
if (this.getNode(frozenId)) {
|
|
16763
|
+
this.stmts.advanceLive.run({ live_id: liveId, t });
|
|
16764
|
+
return frozenId;
|
|
16765
|
+
}
|
|
16403
16766
|
this.stmts.freezeCopy.run({ frozen_id: frozenId, live_id: liveId, t });
|
|
16404
16767
|
this.mergeEdge({
|
|
16405
16768
|
id: `edge_superseded_${frozenId}`,
|
|
@@ -16458,6 +16821,7 @@ var CAUSAL_FAMILY = [
|
|
|
16458
16821
|
|
|
16459
16822
|
// ../../packages/local-graph/src/justification.ts
|
|
16460
16823
|
init_src();
|
|
16824
|
+
init_src2();
|
|
16461
16825
|
|
|
16462
16826
|
// ../../packages/local-graph/src/credit.ts
|
|
16463
16827
|
init_src2();
|
|
@@ -16474,11 +16838,28 @@ init_src();
|
|
|
16474
16838
|
// ../../packages/local-graph/src/design-problem.ts
|
|
16475
16839
|
init_src();
|
|
16476
16840
|
init_src();
|
|
16477
|
-
init_src2();
|
|
16478
16841
|
|
|
16479
16842
|
// ../../packages/local-graph/src/problem-package-link.ts
|
|
16480
16843
|
init_src();
|
|
16481
16844
|
|
|
16845
|
+
// ../../packages/local-graph/src/design-problem.ts
|
|
16846
|
+
init_src2();
|
|
16847
|
+
|
|
16848
|
+
// ../../packages/local-graph/src/problem-dedup.ts
|
|
16849
|
+
init_src();
|
|
16850
|
+
init_src();
|
|
16851
|
+
|
|
16852
|
+
// ../../packages/local-graph/src/intent.ts
|
|
16853
|
+
init_src();
|
|
16854
|
+
|
|
16855
|
+
// ../../packages/local-graph/src/anchor-backfill.ts
|
|
16856
|
+
init_src();
|
|
16857
|
+
init_src2();
|
|
16858
|
+
var STATEMENT_PATH_RE = new RegExp(
|
|
16859
|
+
String.raw`(?:[\w.+-]+\/)+[\w.+-]+\.(?:${anchorableExtensionAlternation()})`,
|
|
16860
|
+
"g"
|
|
16861
|
+
);
|
|
16862
|
+
|
|
16482
16863
|
// ../../packages/local-graph/src/percolate.ts
|
|
16483
16864
|
init_src2();
|
|
16484
16865
|
var PERCOLATING_LABELS = ["Claim", "Problem", "Solution"];
|
|
@@ -16749,30 +17130,19 @@ function detectCommunitiesLeiden(input, opts = {}) {
|
|
|
16749
17130
|
return normalize(assignment);
|
|
16750
17131
|
}
|
|
16751
17132
|
|
|
16752
|
-
// ../../packages/local-graph/src/
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
16756
|
-
|
|
16757
|
-
|
|
16758
|
-
|
|
16759
|
-
const s = l2.getNode(id)?.attrs["scope"] ?? {};
|
|
16760
|
-
if (typeof s[field] === "string") vals.add(s[field]);
|
|
16761
|
-
}
|
|
16762
|
-
return vals.size === 1 ? [...vals][0] : void 0;
|
|
16763
|
-
};
|
|
16764
|
-
const lang = shared("lang");
|
|
16765
|
-
const versionRange = shared("versionRange");
|
|
16766
|
-
return { ...lang ? { lang } : {}, ...versionRange ? { versionRange } : {} };
|
|
16767
|
-
}
|
|
16768
|
-
function buildCandidate(id, ts, members, contexts, originMachine, scope) {
|
|
17133
|
+
// ../../packages/local-graph/src/triage.ts
|
|
17134
|
+
init_src();
|
|
17135
|
+
init_src();
|
|
17136
|
+
init_src();
|
|
17137
|
+
init_src2();
|
|
17138
|
+
function semNode(store, id, label, description, ts, attrs) {
|
|
17139
|
+
const seq = SEMANTIC_NODE_LABELS.includes(label) ? store.nextIngestSeq() : void 0;
|
|
16769
17140
|
return {
|
|
16770
17141
|
id,
|
|
16771
|
-
label
|
|
16772
|
-
description
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
extractionSource: "agent-observed",
|
|
17142
|
+
label,
|
|
17143
|
+
description,
|
|
17144
|
+
extractionConfidence: 0.5,
|
|
17145
|
+
extractionSource: "daemon-extracted",
|
|
16776
17146
|
embedding: [],
|
|
16777
17147
|
cumulativeSurprise: 0,
|
|
16778
17148
|
peakSurprise: 0,
|
|
@@ -16784,250 +17154,56 @@ function buildCandidate(id, ts, members, contexts, originMachine, scope) {
|
|
|
16784
17154
|
isLandmark: false,
|
|
16785
17155
|
community: null,
|
|
16786
17156
|
stability: "unstable",
|
|
16787
|
-
|
|
16788
|
-
|
|
16789
|
-
kind: "abstraction-candidate",
|
|
16790
|
-
provisional: true,
|
|
16791
|
-
pendingDistillation: true,
|
|
16792
|
-
// membership is the unit of truth — the harness validates its fence against
|
|
16793
|
-
// this set (P3 / C3) and may only phrase, never alter, it.
|
|
16794
|
-
members,
|
|
16795
|
-
memberContexts: contexts,
|
|
16796
|
-
distinctContexts: contexts.length,
|
|
16797
|
-
// standard Claim envelope so it crystallizes/syncs unchanged once distilled
|
|
16798
|
-
truthKind: "contextual",
|
|
16799
|
-
// Derived from members (P1): a single-language cluster becomes a lang-scoped
|
|
16800
|
-
// principle; a cross-language one stays universal (`{}`).
|
|
16801
|
-
scope,
|
|
16802
|
-
groundedSupport: 0,
|
|
16803
|
-
sources: [],
|
|
16804
|
-
crystallized: "hypothesis",
|
|
16805
|
-
confidence: 0.4,
|
|
16806
|
-
...originMachine ? { originMachine } : {}
|
|
16807
|
-
}
|
|
17157
|
+
...seq !== void 0 ? { createdAtSeq: seq, lastReinforcedAtSeq: seq } : {},
|
|
17158
|
+
attrs
|
|
16808
17159
|
};
|
|
16809
17160
|
}
|
|
16810
|
-
function
|
|
16811
|
-
|
|
16812
|
-
id
|
|
16813
|
-
from
|
|
16814
|
-
to
|
|
16815
|
-
type
|
|
16816
|
-
confidence: 0.
|
|
16817
|
-
extractionSource: "
|
|
17161
|
+
function semEdge(id, from, to, type, ts, attrs) {
|
|
17162
|
+
return {
|
|
17163
|
+
id,
|
|
17164
|
+
from,
|
|
17165
|
+
to,
|
|
17166
|
+
type,
|
|
17167
|
+
confidence: 0.5,
|
|
17168
|
+
extractionSource: "daemon-extracted",
|
|
16818
17169
|
createdAt: ts,
|
|
16819
17170
|
lastSeenAt: ts,
|
|
16820
17171
|
navSuccesses: 0,
|
|
16821
17172
|
navFailures: 0,
|
|
16822
|
-
attrs
|
|
16823
|
-
});
|
|
16824
|
-
}
|
|
16825
|
-
function induceAbstractions(l2, opts) {
|
|
16826
|
-
const K = opts.minClusterSize ?? DEFAULT_MIN_CLUSTER_SIZE;
|
|
16827
|
-
const minCtx = opts.minDistinctContexts ?? DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
16828
|
-
const report = {
|
|
16829
|
-
communities: 0,
|
|
16830
|
-
candidatesMinted: 0,
|
|
16831
|
-
candidatesExisting: 0,
|
|
16832
|
-
skippedSmall: 0,
|
|
16833
|
-
skippedSingleContext: 0,
|
|
16834
|
-
generalizesEdges: 0
|
|
17173
|
+
attrs
|
|
16835
17174
|
};
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
|
|
16839
|
-
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
17175
|
+
}
|
|
17176
|
+
var routeEdgeId = (triageId, causeId) => `edge_rt_${triageId}_${causeId}`;
|
|
17177
|
+
var ROUTE_EDGE_TYPES = ["CONFIRMS", "INDICATES", "ROUTES_TO"];
|
|
17178
|
+
var routeTypeFor = (provisional) => provisional ? "INDICATES" : "CONFIRMS";
|
|
17179
|
+
var isRouterRoute = (e) => e.type === "CONFIRMS" || e.type === "ROUTES_TO" && e.attrs["provisional"] === false;
|
|
17180
|
+
function recordTriageObservation(l2, obs, ts) {
|
|
17181
|
+
const statement = obs.presentingStatement.trim();
|
|
17182
|
+
const presentingId = obs.presentingId?.trim() || identityId({ kind: "DesignProblem", statement });
|
|
17183
|
+
const triageId = identityId({ kind: "Triage", statement });
|
|
17184
|
+
const routeId = routeEdgeId(triageId, obs.causeId);
|
|
17185
|
+
const buckets = [...triageContextBuckets(canonicalizeContext(obs.context)), TRIAGE_GLOBAL_BUCKET];
|
|
17186
|
+
l2.transaction(() => {
|
|
17187
|
+
if (!l2.getNode(presentingId)) {
|
|
17188
|
+
l2.mergeNode(semNode(l2, presentingId, "Problem", statement, ts, { scope: {} }));
|
|
16844
17189
|
}
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
}
|
|
16863
|
-
}
|
|
16864
|
-
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
16865
|
-
report.communities = comm.count;
|
|
16866
|
-
const members = /* @__PURE__ */ new Map();
|
|
16867
|
-
for (const [id, c] of comm.community) {
|
|
16868
|
-
const l = members.get(c) ?? [];
|
|
16869
|
-
l.push(id);
|
|
16870
|
-
members.set(c, l);
|
|
16871
|
-
}
|
|
16872
|
-
l2.transaction(() => {
|
|
16873
|
-
for (const mem of members.values()) {
|
|
16874
|
-
if (opts.touched && !mem.some((id) => opts.touched.has(id))) continue;
|
|
16875
|
-
if (mem.length < K) {
|
|
16876
|
-
report.skippedSmall++;
|
|
16877
|
-
continue;
|
|
16878
|
-
}
|
|
16879
|
-
if (mem.some((id) => l2.inEdges(id, ["GENERALIZES"]).length > 0)) {
|
|
16880
|
-
report.candidatesExisting++;
|
|
16881
|
-
continue;
|
|
16882
|
-
}
|
|
16883
|
-
const contexts = /* @__PURE__ */ new Set();
|
|
16884
|
-
for (const id of mem) {
|
|
16885
|
-
const n = l2.getNode(id);
|
|
16886
|
-
const obs = n?.attrs["observedInProjects"];
|
|
16887
|
-
if (Array.isArray(obs)) {
|
|
16888
|
-
for (const ws of obs) contexts.add(opts.contextOf(ws) ?? `project:${ws}`);
|
|
16889
|
-
}
|
|
16890
|
-
}
|
|
16891
|
-
if (contexts.size < minCtx) {
|
|
16892
|
-
report.skippedSingleContext++;
|
|
16893
|
-
continue;
|
|
16894
|
-
}
|
|
16895
|
-
const sorted = [...mem].sort();
|
|
16896
|
-
const principleId = `princ_${digest({ members: sorted })}`.slice(0, 56);
|
|
16897
|
-
l2.mergeNode(
|
|
16898
|
-
buildCandidate(principleId, opts.ts, sorted, [...contexts].sort(), opts.originMachine, sharedScope(l2, sorted))
|
|
16899
|
-
);
|
|
16900
|
-
for (const id of sorted) {
|
|
16901
|
-
mergeGeneralizes(l2, principleId, id, opts.ts);
|
|
16902
|
-
report.generalizesEdges++;
|
|
16903
|
-
}
|
|
16904
|
-
report.candidatesMinted++;
|
|
16905
|
-
}
|
|
16906
|
-
});
|
|
16907
|
-
return report;
|
|
16908
|
-
}
|
|
16909
|
-
function revisitContradictedPrinciples(l2, ts) {
|
|
16910
|
-
const report = { flagged: 0 };
|
|
16911
|
-
l2.transaction(() => {
|
|
16912
|
-
for (const n of l2.findNodesByLabel("Claim")) {
|
|
16913
|
-
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
16914
|
-
if (n.attrs["revisit"] === true) continue;
|
|
16915
|
-
const members = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
16916
|
-
const memberSet = new Set(members);
|
|
16917
|
-
let reason = "";
|
|
16918
|
-
for (const id of members) {
|
|
16919
|
-
const m = l2.getNode(id);
|
|
16920
|
-
if (!m) {
|
|
16921
|
-
reason = `member ${id} was removed`;
|
|
16922
|
-
break;
|
|
16923
|
-
}
|
|
16924
|
-
if (m.attrs["revisit"] === true) {
|
|
16925
|
-
reason = `member "${m.description}" needs revisit`;
|
|
16926
|
-
break;
|
|
16927
|
-
}
|
|
16928
|
-
const contradictors = [
|
|
16929
|
-
...l2.outEdges(id, ["CONTRADICTS"]).map((e) => e.to),
|
|
16930
|
-
...l2.inEdges(id, ["CONTRADICTS"]).map((e) => e.from)
|
|
16931
|
-
];
|
|
16932
|
-
if (contradictors.some((other) => !memberSet.has(other))) {
|
|
16933
|
-
reason = `member "${m.description}" is now contradicted by external evidence`;
|
|
16934
|
-
break;
|
|
16935
|
-
}
|
|
16936
|
-
}
|
|
16937
|
-
if (!reason) continue;
|
|
16938
|
-
l2.updateNode(n.id, {
|
|
16939
|
-
attrs: {
|
|
16940
|
-
...n.attrs,
|
|
16941
|
-
revisit: true,
|
|
16942
|
-
revisitReason: reason,
|
|
16943
|
-
revisitSinceTs: ts,
|
|
16944
|
-
provisional: true,
|
|
16945
|
-
// re-queue for re-distillation (P3 re-name)
|
|
16946
|
-
pendingDistillation: true
|
|
16947
|
-
},
|
|
16948
|
-
lastUpdatedAt: ts
|
|
16949
|
-
});
|
|
16950
|
-
report.flagged++;
|
|
16951
|
-
}
|
|
16952
|
-
});
|
|
16953
|
-
return report;
|
|
16954
|
-
}
|
|
16955
|
-
|
|
16956
|
-
// ../../packages/local-graph/src/community.ts
|
|
16957
|
-
init_src2();
|
|
16958
|
-
|
|
16959
|
-
// ../../packages/local-graph/src/triage.ts
|
|
16960
|
-
init_src();
|
|
16961
|
-
init_src();
|
|
16962
|
-
init_src();
|
|
16963
|
-
init_src2();
|
|
16964
|
-
function semNode(id, label, description, ts, attrs) {
|
|
16965
|
-
return {
|
|
16966
|
-
id,
|
|
16967
|
-
label,
|
|
16968
|
-
description,
|
|
16969
|
-
extractionConfidence: 0.5,
|
|
16970
|
-
extractionSource: "daemon-extracted",
|
|
16971
|
-
embedding: [],
|
|
16972
|
-
cumulativeSurprise: 0,
|
|
16973
|
-
peakSurprise: 0,
|
|
16974
|
-
cumulativeHits: 1,
|
|
16975
|
-
lastUpdatedAt: ts,
|
|
16976
|
-
createdAt: ts,
|
|
16977
|
-
memoryTier: "short-term",
|
|
16978
|
-
pageRank: 0,
|
|
16979
|
-
isLandmark: false,
|
|
16980
|
-
community: null,
|
|
16981
|
-
stability: "unstable",
|
|
16982
|
-
attrs
|
|
16983
|
-
};
|
|
16984
|
-
}
|
|
16985
|
-
function semEdge(id, from, to, type, ts, attrs) {
|
|
16986
|
-
return {
|
|
16987
|
-
id,
|
|
16988
|
-
from,
|
|
16989
|
-
to,
|
|
16990
|
-
type,
|
|
16991
|
-
confidence: 0.5,
|
|
16992
|
-
extractionSource: "daemon-extracted",
|
|
16993
|
-
createdAt: ts,
|
|
16994
|
-
lastSeenAt: ts,
|
|
16995
|
-
navSuccesses: 0,
|
|
16996
|
-
navFailures: 0,
|
|
16997
|
-
attrs
|
|
16998
|
-
};
|
|
16999
|
-
}
|
|
17000
|
-
var routeEdgeId = (triageId, causeId) => `edge_rt_${triageId}_${causeId}`;
|
|
17001
|
-
var ROUTE_EDGE_TYPES = ["CONFIRMS", "INDICATES", "ROUTES_TO"];
|
|
17002
|
-
var routeTypeFor = (provisional) => provisional ? "INDICATES" : "CONFIRMS";
|
|
17003
|
-
var isRouterRoute = (e) => e.type === "CONFIRMS" || e.type === "ROUTES_TO" && e.attrs["provisional"] === false;
|
|
17004
|
-
function recordTriageObservation(l2, obs, ts) {
|
|
17005
|
-
const statement = obs.presentingStatement.trim();
|
|
17006
|
-
const presentingId = obs.presentingId?.trim() || identityId({ kind: "DesignProblem", statement });
|
|
17007
|
-
const triageId = identityId({ kind: "Triage", statement });
|
|
17008
|
-
const routeId = routeEdgeId(triageId, obs.causeId);
|
|
17009
|
-
const buckets = [...triageContextBuckets(canonicalizeContext(obs.context)), TRIAGE_GLOBAL_BUCKET];
|
|
17010
|
-
l2.transaction(() => {
|
|
17011
|
-
if (!l2.getNode(presentingId)) {
|
|
17012
|
-
l2.mergeNode(semNode(presentingId, "Problem", statement, ts, { scope: {} }));
|
|
17013
|
-
}
|
|
17014
|
-
const tri = l2.getNode(triageId);
|
|
17015
|
-
const seen = {
|
|
17016
|
-
...tri?.attrs["perContextSeen"] ?? {}
|
|
17017
|
-
};
|
|
17018
|
-
for (const b of buckets) seen[b] = (seen[b] ?? 0) + 1;
|
|
17019
|
-
if (tri) {
|
|
17020
|
-
l2.updateNode(triageId, {
|
|
17021
|
-
attrs: { ...tri.attrs, statement, perContextSeen: seen },
|
|
17022
|
-
lastUpdatedAt: ts
|
|
17023
|
-
});
|
|
17024
|
-
} else {
|
|
17025
|
-
l2.mergeNode(
|
|
17026
|
-
semNode(triageId, "Triage", `differential for: ${statement}`, ts, {
|
|
17027
|
-
statement,
|
|
17028
|
-
perContextSeen: seen
|
|
17029
|
-
})
|
|
17030
|
-
);
|
|
17190
|
+
const tri = l2.getNode(triageId);
|
|
17191
|
+
const seen = {
|
|
17192
|
+
...tri?.attrs["perContextSeen"] ?? {}
|
|
17193
|
+
};
|
|
17194
|
+
for (const b of buckets) seen[b] = (seen[b] ?? 0) + 1;
|
|
17195
|
+
if (tri) {
|
|
17196
|
+
l2.updateNode(triageId, {
|
|
17197
|
+
attrs: { ...tri.attrs, statement, perContextSeen: seen },
|
|
17198
|
+
lastUpdatedAt: ts
|
|
17199
|
+
});
|
|
17200
|
+
} else {
|
|
17201
|
+
l2.mergeNode(
|
|
17202
|
+
semNode(l2, triageId, "Triage", `differential for: ${statement}`, ts, {
|
|
17203
|
+
statement,
|
|
17204
|
+
perContextSeen: seen
|
|
17205
|
+
})
|
|
17206
|
+
);
|
|
17031
17207
|
}
|
|
17032
17208
|
const tbId = `edge_tb_${presentingId}_${triageId}`;
|
|
17033
17209
|
if (!l2.getEdge(tbId)) {
|
|
@@ -17035,7 +17211,7 @@ function recordTriageObservation(l2, obs, ts) {
|
|
|
17035
17211
|
}
|
|
17036
17212
|
if (!l2.getNode(obs.causeId)) {
|
|
17037
17213
|
l2.mergeNode(
|
|
17038
|
-
semNode(obs.causeId, obs.causeLabel ?? "RootCause", obs.causeDescription ?? "(cause)", ts, {
|
|
17214
|
+
semNode(l2, obs.causeId, obs.causeLabel ?? "RootCause", obs.causeDescription ?? "(cause)", ts, {
|
|
17039
17215
|
scope: {}
|
|
17040
17216
|
})
|
|
17041
17217
|
);
|
|
@@ -17208,9 +17384,212 @@ function revisitStaleRoutes(l2, ts, opts = {}) {
|
|
|
17208
17384
|
}
|
|
17209
17385
|
var DRIFT_VALUES = new Set(Object.values(DRIFT_KIND));
|
|
17210
17386
|
|
|
17211
|
-
// ../../packages/local-graph/src/
|
|
17212
|
-
|
|
17213
|
-
|
|
17387
|
+
// ../../packages/local-graph/src/abstraction.ts
|
|
17388
|
+
var DEFAULT_MIN_CLUSTER_SIZE = 3;
|
|
17389
|
+
var DEFAULT_MIN_DISTINCT_CONTEXTS = 2;
|
|
17390
|
+
function sharedScope(l2, memberIds) {
|
|
17391
|
+
const shared = (field) => {
|
|
17392
|
+
const vals = /* @__PURE__ */ new Set();
|
|
17393
|
+
for (const id of memberIds) {
|
|
17394
|
+
const s = l2.getNode(id)?.attrs["scope"] ?? {};
|
|
17395
|
+
if (typeof s[field] === "string") vals.add(s[field]);
|
|
17396
|
+
}
|
|
17397
|
+
return vals.size === 1 ? [...vals][0] : void 0;
|
|
17398
|
+
};
|
|
17399
|
+
const lang = shared("lang");
|
|
17400
|
+
const versionRange = shared("versionRange");
|
|
17401
|
+
return { ...lang ? { lang } : {}, ...versionRange ? { versionRange } : {} };
|
|
17402
|
+
}
|
|
17403
|
+
function buildCandidate(id, ts, members, contexts, originMachine, scope) {
|
|
17404
|
+
return {
|
|
17405
|
+
id,
|
|
17406
|
+
label: "Claim",
|
|
17407
|
+
description: "",
|
|
17408
|
+
// empty — the harness distills the prose in P3
|
|
17409
|
+
extractionConfidence: 0.4,
|
|
17410
|
+
extractionSource: "agent-observed",
|
|
17411
|
+
embedding: [],
|
|
17412
|
+
cumulativeSurprise: 0,
|
|
17413
|
+
peakSurprise: 0,
|
|
17414
|
+
cumulativeHits: 1,
|
|
17415
|
+
lastUpdatedAt: ts,
|
|
17416
|
+
createdAt: ts,
|
|
17417
|
+
memoryTier: "short-term",
|
|
17418
|
+
pageRank: 0,
|
|
17419
|
+
isLandmark: false,
|
|
17420
|
+
community: null,
|
|
17421
|
+
stability: "unstable",
|
|
17422
|
+
attrs: {
|
|
17423
|
+
abstractionLevel: ABSTRACTION_LEVEL.PRINCIPLE,
|
|
17424
|
+
kind: "abstraction-candidate",
|
|
17425
|
+
provisional: true,
|
|
17426
|
+
pendingDistillation: true,
|
|
17427
|
+
// membership is the unit of truth — the harness validates its fence against
|
|
17428
|
+
// this set (P3 / C3) and may only phrase, never alter, it.
|
|
17429
|
+
members,
|
|
17430
|
+
memberContexts: contexts,
|
|
17431
|
+
distinctContexts: contexts.length,
|
|
17432
|
+
// standard Claim envelope so it crystallizes/syncs unchanged once distilled
|
|
17433
|
+
truthKind: "contextual",
|
|
17434
|
+
// Derived from members (P1): a single-language cluster becomes a lang-scoped
|
|
17435
|
+
// principle; a cross-language one stays universal (`{}`).
|
|
17436
|
+
scope,
|
|
17437
|
+
groundedSupport: 0,
|
|
17438
|
+
sources: [],
|
|
17439
|
+
crystallized: "hypothesis",
|
|
17440
|
+
confidence: 0.4,
|
|
17441
|
+
...originMachine ? { originMachine } : {}
|
|
17442
|
+
}
|
|
17443
|
+
};
|
|
17444
|
+
}
|
|
17445
|
+
function mergeGeneralizes(store, principleId, memberId, ts) {
|
|
17446
|
+
store.mergeEdge({
|
|
17447
|
+
id: `edge_${digest({ from: principleId, type: "GENERALIZES", to: memberId })}`.slice(0, 24),
|
|
17448
|
+
from: principleId,
|
|
17449
|
+
to: memberId,
|
|
17450
|
+
type: "GENERALIZES",
|
|
17451
|
+
confidence: 0.4,
|
|
17452
|
+
extractionSource: "agent-observed",
|
|
17453
|
+
createdAt: ts,
|
|
17454
|
+
lastSeenAt: ts,
|
|
17455
|
+
navSuccesses: 0,
|
|
17456
|
+
navFailures: 0,
|
|
17457
|
+
attrs: { provisional: true }
|
|
17458
|
+
});
|
|
17459
|
+
}
|
|
17460
|
+
function induceAbstractions(l2, opts) {
|
|
17461
|
+
const K = opts.minClusterSize ?? DEFAULT_MIN_CLUSTER_SIZE;
|
|
17462
|
+
const minCtx = opts.minDistinctContexts ?? DEFAULT_MIN_DISTINCT_CONTEXTS;
|
|
17463
|
+
const report = {
|
|
17464
|
+
communities: 0,
|
|
17465
|
+
candidatesMinted: 0,
|
|
17466
|
+
candidatesExisting: 0,
|
|
17467
|
+
skippedSmall: 0,
|
|
17468
|
+
skippedSingleContext: 0,
|
|
17469
|
+
generalizesEdges: 0
|
|
17470
|
+
};
|
|
17471
|
+
const ids = /* @__PURE__ */ new Set();
|
|
17472
|
+
for (const label of PERCOLATING_LABELS) {
|
|
17473
|
+
for (const n of l2.findNodesByLabel(label)) {
|
|
17474
|
+
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) >= ABSTRACTION_LEVEL.PRINCIPLE) {
|
|
17475
|
+
continue;
|
|
17476
|
+
}
|
|
17477
|
+
if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
|
|
17478
|
+
ids.add(n.id);
|
|
17479
|
+
}
|
|
17480
|
+
}
|
|
17481
|
+
if (ids.size === 0) return report;
|
|
17482
|
+
const adj = /* @__PURE__ */ new Map();
|
|
17483
|
+
const protect = [];
|
|
17484
|
+
const add = (a, b, w) => {
|
|
17485
|
+
const l = adj.get(a) ?? [];
|
|
17486
|
+
l.push({ to: b, weight: w });
|
|
17487
|
+
adj.set(a, l);
|
|
17488
|
+
};
|
|
17489
|
+
for (const id of ids) {
|
|
17490
|
+
for (const e of l2.outEdges(id, [...PERCOLATING_EDGES])) {
|
|
17491
|
+
if (!ids.has(e.to)) continue;
|
|
17492
|
+
const conf = e.confidence > 0 ? e.confidence : 0.5;
|
|
17493
|
+
const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
|
|
17494
|
+
add(id, e.to, w);
|
|
17495
|
+
add(e.to, id, w);
|
|
17496
|
+
if (isCausalProtected(e.type)) protect.push([id, e.to]);
|
|
17497
|
+
}
|
|
17498
|
+
}
|
|
17499
|
+
const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
|
|
17500
|
+
report.communities = comm.count;
|
|
17501
|
+
const members = /* @__PURE__ */ new Map();
|
|
17502
|
+
for (const [id, c] of comm.community) {
|
|
17503
|
+
const l = members.get(c) ?? [];
|
|
17504
|
+
l.push(id);
|
|
17505
|
+
members.set(c, l);
|
|
17506
|
+
}
|
|
17507
|
+
l2.transaction(() => {
|
|
17508
|
+
for (const mem of members.values()) {
|
|
17509
|
+
if (opts.touched && !mem.some((id) => opts.touched.has(id))) continue;
|
|
17510
|
+
if (mem.length < K) {
|
|
17511
|
+
report.skippedSmall++;
|
|
17512
|
+
continue;
|
|
17513
|
+
}
|
|
17514
|
+
if (mem.some((id) => l2.inEdges(id, ["GENERALIZES"]).length > 0)) {
|
|
17515
|
+
report.candidatesExisting++;
|
|
17516
|
+
continue;
|
|
17517
|
+
}
|
|
17518
|
+
const contexts = /* @__PURE__ */ new Set();
|
|
17519
|
+
for (const id of mem) {
|
|
17520
|
+
const n = l2.getNode(id);
|
|
17521
|
+
const obs = n?.attrs["observedInProjects"];
|
|
17522
|
+
if (Array.isArray(obs)) {
|
|
17523
|
+
for (const ws of obs) contexts.add(opts.contextOf(ws) ?? `project:${ws}`);
|
|
17524
|
+
}
|
|
17525
|
+
}
|
|
17526
|
+
if (contexts.size < minCtx) {
|
|
17527
|
+
report.skippedSingleContext++;
|
|
17528
|
+
continue;
|
|
17529
|
+
}
|
|
17530
|
+
const sorted = [...mem].sort();
|
|
17531
|
+
const principleId = `princ_${digest({ members: sorted })}`.slice(0, 56);
|
|
17532
|
+
l2.mergeNode(
|
|
17533
|
+
buildCandidate(principleId, opts.ts, sorted, [...contexts].sort(), opts.originMachine, sharedScope(l2, sorted))
|
|
17534
|
+
);
|
|
17535
|
+
for (const id of sorted) {
|
|
17536
|
+
mergeGeneralizes(l2, principleId, id, opts.ts);
|
|
17537
|
+
report.generalizesEdges++;
|
|
17538
|
+
}
|
|
17539
|
+
report.candidatesMinted++;
|
|
17540
|
+
}
|
|
17541
|
+
});
|
|
17542
|
+
return report;
|
|
17543
|
+
}
|
|
17544
|
+
function revisitContradictedPrinciples(l2, ts) {
|
|
17545
|
+
const report = { flagged: 0 };
|
|
17546
|
+
l2.transaction(() => {
|
|
17547
|
+
for (const n of l2.findNodesByLabel("Claim")) {
|
|
17548
|
+
if (Number(n.attrs["abstractionLevel"] ?? ABSTRACTION_LEVEL.CONCRETE) < ABSTRACTION_LEVEL.PRINCIPLE) continue;
|
|
17549
|
+
if (n.attrs["revisit"] === true) continue;
|
|
17550
|
+
const members = Array.isArray(n.attrs["members"]) ? n.attrs["members"] : [];
|
|
17551
|
+
const memberSet = new Set(members);
|
|
17552
|
+
let reason = "";
|
|
17553
|
+
for (const id of members) {
|
|
17554
|
+
const m = l2.getNode(id);
|
|
17555
|
+
if (!m) {
|
|
17556
|
+
reason = `member ${id} was removed`;
|
|
17557
|
+
break;
|
|
17558
|
+
}
|
|
17559
|
+
if (m.attrs["revisit"] === true) {
|
|
17560
|
+
reason = `member "${m.description}" needs revisit`;
|
|
17561
|
+
break;
|
|
17562
|
+
}
|
|
17563
|
+
const contradictors = [
|
|
17564
|
+
...l2.outEdges(id, ["CONTRADICTS"]).map((e) => e.to),
|
|
17565
|
+
...l2.inEdges(id, ["CONTRADICTS"]).map((e) => e.from)
|
|
17566
|
+
];
|
|
17567
|
+
if (contradictors.some((other) => !memberSet.has(other))) {
|
|
17568
|
+
reason = `member "${m.description}" is now contradicted by external evidence`;
|
|
17569
|
+
break;
|
|
17570
|
+
}
|
|
17571
|
+
}
|
|
17572
|
+
if (!reason) continue;
|
|
17573
|
+
l2.updateNode(n.id, {
|
|
17574
|
+
attrs: {
|
|
17575
|
+
...n.attrs,
|
|
17576
|
+
revisit: true,
|
|
17577
|
+
revisitReason: reason,
|
|
17578
|
+
revisitSinceTs: ts,
|
|
17579
|
+
provisional: true,
|
|
17580
|
+
// re-queue for re-distillation (P3 re-name)
|
|
17581
|
+
pendingDistillation: true
|
|
17582
|
+
},
|
|
17583
|
+
lastUpdatedAt: ts
|
|
17584
|
+
});
|
|
17585
|
+
report.flagged++;
|
|
17586
|
+
}
|
|
17587
|
+
});
|
|
17588
|
+
return report;
|
|
17589
|
+
}
|
|
17590
|
+
|
|
17591
|
+
// ../../packages/local-graph/src/community.ts
|
|
17592
|
+
init_src2();
|
|
17214
17593
|
|
|
17215
17594
|
// ../../packages/local-graph/src/tools.ts
|
|
17216
17595
|
init_src();
|
|
@@ -17218,6 +17597,9 @@ init_src();
|
|
|
17218
17597
|
// ../../packages/local-graph/src/principle-sync.ts
|
|
17219
17598
|
init_src2();
|
|
17220
17599
|
|
|
17600
|
+
// ../../packages/local-graph/src/mechanism-liveness.ts
|
|
17601
|
+
var STALL_MIN_SPAN_MS = 60 * 60 * 1e3;
|
|
17602
|
+
|
|
17221
17603
|
// src/reconcile.ts
|
|
17222
17604
|
init_src3();
|
|
17223
17605
|
function isLive(n) {
|