@inerrata-corporation/errata 2.0.0-dev.77 → 2.0.0-dev.79
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/errata.mjs +85 -3
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -15290,7 +15290,14 @@ var init_edge_rules = __esm({
|
|
|
15290
15290
|
// SOLVED_BY sources: Vulnerability (v1 comment) + Problem/RootCause
|
|
15291
15291
|
// (upstream design-problem.ts + triage.ts mint both).
|
|
15292
15292
|
SOLVED_BY: { from: ["Vulnerability", "Problem", "RootCause"], to: ["Solution"] },
|
|
15293
|
-
FIXED_BY
|
|
15293
|
+
// FIXED_BY sources mirror SOLVED_BY's (same ailment→fix semantics; live-graph
|
|
15294
|
+
// census 2026-07-14: 512 Problem + 13 RootCause sources, zero others besides
|
|
15295
|
+
// 3 REVERSED Solution→Problem edges the missing `from` let through — the
|
|
15296
|
+
// "Problem solved by Problem" splash bug. A reversed resolution edge is NOT
|
|
15297
|
+
// mechanically flippable (half the sample were PoC-not-fix claims), so the
|
|
15298
|
+
// door rejects rather than repairs; a correct re-emission lands via
|
|
15299
|
+
// recognition-at-the-door.
|
|
15300
|
+
FIXED_BY: { from: ["Vulnerability", "Problem", "RootCause"], to: ["Solution"] },
|
|
15294
15301
|
// ── Triage family (upstream castalia.ts: Problem —TRIAGED_BY→ Triage —{INDICATES|CONFIRMS}→ cause) ──
|
|
15295
15302
|
// Two-edge differential model (T3-rename): INDICATES = provisional candidate,
|
|
15296
15303
|
// CONFIRMS = promoted router (a discriminator exists). Same endpoint matrix.
|
|
@@ -21353,6 +21360,16 @@ var init_client = __esm({
|
|
|
21353
21360
|
if (q.seed?.length) qs.set("seed", q.seed.join(","));
|
|
21354
21361
|
if (q.q) qs.set("q", q.q);
|
|
21355
21362
|
const res = await this.json("GET", `/v2/search?${qs.toString()}`);
|
|
21363
|
+
const { nodes, edges } = this.toCastalia(res);
|
|
21364
|
+
return { nodes, edges, generatedAt: res.generatedAt };
|
|
21365
|
+
}
|
|
21366
|
+
/**
|
|
21367
|
+
* The castalia wire shape → local-mergeable graph. Extracted so the priming fetch
|
|
21368
|
+
* (`getProjectPriors`) lands nodes through the EXACT same mapper as `search`: a
|
|
21369
|
+
* second mapper would be a second convergence-key convention to keep in sync, and
|
|
21370
|
+
* an id-keying drift between the two is a silent no-op, not a crash.
|
|
21371
|
+
*/
|
|
21372
|
+
toCastalia(res) {
|
|
21356
21373
|
const now = Date.now();
|
|
21357
21374
|
const nodes = res.nodes.map((n) => ({
|
|
21358
21375
|
id: n.canonicalId,
|
|
@@ -21386,7 +21403,25 @@ var init_client = __esm({
|
|
|
21386
21403
|
navFailures: 0,
|
|
21387
21404
|
attrs: { ...e.attrs, source: "cloud" }
|
|
21388
21405
|
}));
|
|
21389
|
-
return { nodes, edges
|
|
21406
|
+
return { nodes, edges };
|
|
21407
|
+
}
|
|
21408
|
+
/**
|
|
21409
|
+
* PJ-hydrate: the one-time seeded prime a fresh clone pulls at attach.
|
|
21410
|
+
*
|
|
21411
|
+
* A clone can already READ its project stratum (query-time federation, PJ-read) —
|
|
21412
|
+
* what it can't do is PRIME, because the passive block builds from the local store
|
|
21413
|
+
* and the remote blend is seeded from local problems a new checkout doesn't have.
|
|
21414
|
+
* This lands the top of the stratum locally so both have something to stand on.
|
|
21415
|
+
*
|
|
21416
|
+
* Membership-gated server-side by the same fail-closed check as ingest: a caller
|
|
21417
|
+
* who couldn't write this project's stratum can't prime from it.
|
|
21418
|
+
*/
|
|
21419
|
+
async getProjectPriors(projectId, limit = 50) {
|
|
21420
|
+
const res = await this.json(
|
|
21421
|
+
"GET",
|
|
21422
|
+
`/v2/projects/${encodeURIComponent(projectId)}/priors?limit=${String(limit)}`
|
|
21423
|
+
);
|
|
21424
|
+
return this.toCastalia(res);
|
|
21390
21425
|
}
|
|
21391
21426
|
/** Pull cloud-induced skills + the session-bootstrap prime payload. `seed` is the
|
|
21392
21427
|
* canonical ids of the agent's recent problems — the cloud ranks the skills whose
|
|
@@ -43293,7 +43328,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
43293
43328
|
}
|
|
43294
43329
|
|
|
43295
43330
|
// src/engine.ts
|
|
43296
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
43331
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.79" : "2.0.0-alpha.0";
|
|
43297
43332
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
43298
43333
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
43299
43334
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -45463,6 +45498,39 @@ async function ensureProjectLink(root, profile, client) {
|
|
|
45463
45498
|
}
|
|
45464
45499
|
}
|
|
45465
45500
|
|
|
45501
|
+
// src/project-hydrate.ts
|
|
45502
|
+
var DEFAULT_LIMIT = 50;
|
|
45503
|
+
async function hydrateProject(opts) {
|
|
45504
|
+
const { root, profile, store, cloud } = opts;
|
|
45505
|
+
if (!profile.projectId) return { hydrated: false, reason: "no-project" };
|
|
45506
|
+
if (profile.projectHydratedAt) return { hydrated: false, reason: "already-hydrated" };
|
|
45507
|
+
try {
|
|
45508
|
+
const res = await cloud.getProjectPriors(profile.projectId, opts.limit ?? DEFAULT_LIMIT);
|
|
45509
|
+
let landedNodes = 0;
|
|
45510
|
+
for (const n of res.nodes) {
|
|
45511
|
+
if (store.getNode(n.id)) continue;
|
|
45512
|
+
store.mergeNode(n);
|
|
45513
|
+
landedNodes++;
|
|
45514
|
+
}
|
|
45515
|
+
let landedEdges = 0;
|
|
45516
|
+
for (const e of res.edges) {
|
|
45517
|
+
if (!store.getNode(e.from) || !store.getNode(e.to)) continue;
|
|
45518
|
+
if (store.getEdge(e.id)) continue;
|
|
45519
|
+
store.mergeEdge(e);
|
|
45520
|
+
landedEdges++;
|
|
45521
|
+
}
|
|
45522
|
+
profile.projectHydratedAt = Date.now();
|
|
45523
|
+
saveProfile(root, profile);
|
|
45524
|
+
return { hydrated: true, nodes: landedNodes, edges: landedEdges };
|
|
45525
|
+
} catch (err2) {
|
|
45526
|
+
return {
|
|
45527
|
+
hydrated: false,
|
|
45528
|
+
reason: "error",
|
|
45529
|
+
detail: err2 instanceof Error ? err2.message : String(err2)
|
|
45530
|
+
};
|
|
45531
|
+
}
|
|
45532
|
+
}
|
|
45533
|
+
|
|
45466
45534
|
// src/adopt.ts
|
|
45467
45535
|
import { existsSync as existsSync22 } from "node:fs";
|
|
45468
45536
|
import { dirname as dirname8, join as join25 } from "node:path";
|
|
@@ -45904,6 +45972,20 @@ async function startMultiDaemon(opts = {}) {
|
|
|
45904
45972
|
} else if (out2.reason === "error") {
|
|
45905
45973
|
console.warn(`[errata] project link failed for ${r.engine.profile.name}: ${out2.detail}`);
|
|
45906
45974
|
}
|
|
45975
|
+
const hyd = await hydrateProject({
|
|
45976
|
+
root: r.root,
|
|
45977
|
+
profile: r.engine.profile,
|
|
45978
|
+
store: r.engine.store,
|
|
45979
|
+
cloud: client
|
|
45980
|
+
});
|
|
45981
|
+
if (hyd.hydrated) {
|
|
45982
|
+
r.engine.markContextDirty();
|
|
45983
|
+
console.log(
|
|
45984
|
+
`[errata] primed ${r.engine.profile.name} from project \u2014 ${hyd.nodes} priors, ${hyd.edges} links`
|
|
45985
|
+
);
|
|
45986
|
+
} else if (hyd.reason === "error") {
|
|
45987
|
+
console.warn(`[errata] project prime failed for ${r.engine.profile.name}: ${hyd.detail}`);
|
|
45988
|
+
}
|
|
45907
45989
|
}
|
|
45908
45990
|
};
|
|
45909
45991
|
void ambientLinkAll();
|