@rubytech/create-maxy-code 0.1.144 → 0.1.146
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/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +154 -4
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/post-turn-graph-pass.sh +251 -0
- package/payload/platform/plugins/admin/skills/datetime/SKILL.md +63 -5
- package/payload/platform/plugins/docs/references/internals.md +16 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +10 -0
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +25 -3
- package/payload/platform/plugins/memory/mcp/dist/index.js +309 -11
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +33 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.js +30 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.js +51 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.js +68 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/timeline-extractor.test.js +41 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/timeline-extractor.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts +43 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js +33 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.d.ts +18 -5
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.js +64 -17
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts +44 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.js +14 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts +26 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js +219 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.js +39 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.js +42 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.d.ts +21 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.js +27 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.d.ts +18 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.js +60 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.d.ts +20 -3
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js +47 -12
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.d.ts +13 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.js +191 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.d.ts +7 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.js +37 -9
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js +81 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js +115 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js +50 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts +45 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js +170 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.d.ts +28 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.js +64 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.d.ts +24 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.js +49 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.d.ts +34 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.js +99 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.d.ts +29 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.js +66 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +122 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts +49 -13
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +184 -16
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +53 -10
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +6 -0
- package/payload/platform/plugins/memory/references/schema-base.md +4 -0
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +3 -4
- package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +13 -2
- package/payload/platform/scripts/seed-neo4j.sh +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +9 -1
- package/payload/platform/templates/specialists/agents/database-operator.md +30 -2
- package/payload/server/server.js +195 -91
- package/payload/platform/plugins/admin/hooks/signal-detector-stop.sh +0 -309
- package/payload/platform/templates/specialists/agents/signal-detector.md +0 -129
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-report-read-latest — fetch the most recent :Report(s) matching a
|
|
3
|
+
* keyword (Task 332). Resolves "what was last night's dream cycle" /
|
|
4
|
+
* "show me the latest briefing" routes by name; default `limit=1`.
|
|
5
|
+
*/
|
|
6
|
+
import { getSession } from "../lib/neo4j.js";
|
|
7
|
+
const DEFAULT_LIMIT = 1;
|
|
8
|
+
const MAX_LIMIT = 20;
|
|
9
|
+
export async function memoryReportReadLatest(params) {
|
|
10
|
+
const { accountId, keyword } = params;
|
|
11
|
+
const limit = Math.max(1, Math.min(params.limit ?? DEFAULT_LIMIT, MAX_LIMIT));
|
|
12
|
+
if (!accountId)
|
|
13
|
+
throw new Error("memory-report-read-latest: accountId is required");
|
|
14
|
+
if (!keyword || !keyword.trim()) {
|
|
15
|
+
throw new Error("memory-report-read-latest: keyword is required");
|
|
16
|
+
}
|
|
17
|
+
const session = getSession();
|
|
18
|
+
const t0 = Date.now();
|
|
19
|
+
try {
|
|
20
|
+
const res = await session.run(`MATCH (r:Report {accountId: $accountId})
|
|
21
|
+
WHERE $keyword IN r.keywords
|
|
22
|
+
RETURN elementId(r) AS nodeId,
|
|
23
|
+
r.reportId AS reportId,
|
|
24
|
+
r.title AS title,
|
|
25
|
+
r.body AS body,
|
|
26
|
+
r.keywords AS keywords,
|
|
27
|
+
r.sourceWorkflow AS sourceWorkflow,
|
|
28
|
+
toString(r.occurredAt) AS occurredAt
|
|
29
|
+
ORDER BY r.occurredAt DESC
|
|
30
|
+
LIMIT toInteger($limit)`, { accountId, keyword, limit });
|
|
31
|
+
const results = res.records.map((rec) => ({
|
|
32
|
+
nodeId: rec.get("nodeId"),
|
|
33
|
+
reportId: rec.get("reportId"),
|
|
34
|
+
title: rec.get("title"),
|
|
35
|
+
body: rec.get("body"),
|
|
36
|
+
keywords: rec.get("keywords"),
|
|
37
|
+
sourceWorkflow: rec.get("sourceWorkflow"),
|
|
38
|
+
occurredAt: rec.get("occurredAt"),
|
|
39
|
+
}));
|
|
40
|
+
const ms = Date.now() - t0;
|
|
41
|
+
const firstId = results[0]?.reportId.slice(0, 8) ?? "none";
|
|
42
|
+
process.stderr.write(`[reports] op=read-latest reportId=${firstId} keywords=${keyword} ms=${ms} hits=${results.length}\n`);
|
|
43
|
+
return { results };
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
await session.close();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=memory-report-read-latest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-report-read-latest.js","sourceRoot":"","sources":["../../src/tools/memory-report-read-latest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAsB7C,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;IAE9E,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACpF,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAC3B;;;;;;;;;;+BAUyB,EACzB,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAC9B,CAAC;QAEF,MAAM,OAAO,GAAgB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrD,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAW;YACnC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAW;YACvC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAW;YACjC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAW;YAC/B,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAa;YACzC,cAAc,EAAE,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAkB;YAC1D,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,CAAW;SAC5C,CAAC,CAAC,CAAC;QAEJ,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qCAAqC,OAAO,aAAa,OAAO,OAAO,EAAE,SAAS,OAAO,CAAC,MAAM,IAAI,CACrG,CAAC;QAEF,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-report-write — durable, keyword-routed report persistence (Task 332).
|
|
3
|
+
*
|
|
4
|
+
* Idempotent on (accountId, title, occurredAt-within-same-minute) to absorb
|
|
5
|
+
* accidental double-fires from a workflow dispatcher. Two distinct calls in
|
|
6
|
+
* the same minute with the same title return the existing :Report nodeId
|
|
7
|
+
* instead of creating a second row.
|
|
8
|
+
*
|
|
9
|
+
* Hierarchy: every :Report is parented to either the active
|
|
10
|
+
* :AdminConversation (when CONVERSATION_NODE_ID is set — the typical case
|
|
11
|
+
* for operator-initiated writes from chat) or to the account's :AdminUser
|
|
12
|
+
* as a fallback so the report still satisfies the graph-hierarchy doctrine
|
|
13
|
+
* when written from a non-conversation context (scheduled workflows etc.).
|
|
14
|
+
*/
|
|
15
|
+
export interface ReportWriteParams {
|
|
16
|
+
accountId: string;
|
|
17
|
+
title: string;
|
|
18
|
+
body: string;
|
|
19
|
+
keywords: string[];
|
|
20
|
+
sourceWorkflow?: string;
|
|
21
|
+
/** ISO timestamp. Defaults to now(). */
|
|
22
|
+
occurredAt?: string;
|
|
23
|
+
/** elementId of the active :AdminConversation when invoked in chat. */
|
|
24
|
+
conversationNodeId?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ReportWriteResult {
|
|
27
|
+
nodeId: string;
|
|
28
|
+
reportId: string;
|
|
29
|
+
created: boolean;
|
|
30
|
+
/** Reason the existing report was returned, when created=false. */
|
|
31
|
+
idempotencyReason?: "same-title-within-minute";
|
|
32
|
+
}
|
|
33
|
+
export declare function memoryReportWrite(params: ReportWriteParams): Promise<ReportWriteResult>;
|
|
34
|
+
//# sourceMappingURL=memory-report-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-report-write.d.ts","sourceRoot":"","sources":["../../src/tools/memory-report-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,0BAA0B,CAAC;CAChD;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CA2G5B"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-report-write — durable, keyword-routed report persistence (Task 332).
|
|
3
|
+
*
|
|
4
|
+
* Idempotent on (accountId, title, occurredAt-within-same-minute) to absorb
|
|
5
|
+
* accidental double-fires from a workflow dispatcher. Two distinct calls in
|
|
6
|
+
* the same minute with the same title return the existing :Report nodeId
|
|
7
|
+
* instead of creating a second row.
|
|
8
|
+
*
|
|
9
|
+
* Hierarchy: every :Report is parented to either the active
|
|
10
|
+
* :AdminConversation (when CONVERSATION_NODE_ID is set — the typical case
|
|
11
|
+
* for operator-initiated writes from chat) or to the account's :AdminUser
|
|
12
|
+
* as a fallback so the report still satisfies the graph-hierarchy doctrine
|
|
13
|
+
* when written from a non-conversation context (scheduled workflows etc.).
|
|
14
|
+
*/
|
|
15
|
+
import { randomUUID } from "node:crypto";
|
|
16
|
+
import { getSession } from "../lib/neo4j.js";
|
|
17
|
+
import { embed } from "../lib/embeddings.js";
|
|
18
|
+
const MAX_BODY_CHARS = 10_000;
|
|
19
|
+
export async function memoryReportWrite(params) {
|
|
20
|
+
const { accountId, title, body, keywords, sourceWorkflow, occurredAt, conversationNodeId, } = params;
|
|
21
|
+
if (!accountId)
|
|
22
|
+
throw new Error("memory-report-write: accountId is required");
|
|
23
|
+
if (!title || !title.trim())
|
|
24
|
+
throw new Error("memory-report-write: title is required");
|
|
25
|
+
if (body.length > MAX_BODY_CHARS) {
|
|
26
|
+
throw new Error(`memory-report-write: body exceeds ${MAX_BODY_CHARS} chars (got ${body.length})`);
|
|
27
|
+
}
|
|
28
|
+
const occurredAtIso = occurredAt ?? new Date().toISOString();
|
|
29
|
+
const session = getSession();
|
|
30
|
+
const t0 = Date.now();
|
|
31
|
+
try {
|
|
32
|
+
// Idempotency pre-check: same accountId + title + occurredAt within 1 min.
|
|
33
|
+
const existing = await session.run(`MATCH (r:Report {accountId: $accountId, title: $title})
|
|
34
|
+
WHERE r.occurredAt >= datetime($occurredAt) - duration('PT1M')
|
|
35
|
+
AND r.occurredAt <= datetime($occurredAt) + duration('PT1M')
|
|
36
|
+
RETURN elementId(r) AS nodeId, r.reportId AS reportId
|
|
37
|
+
ORDER BY r.occurredAt DESC
|
|
38
|
+
LIMIT 1`, { accountId, title, occurredAt: occurredAtIso });
|
|
39
|
+
if (existing.records.length > 0) {
|
|
40
|
+
const nodeId = existing.records[0].get("nodeId");
|
|
41
|
+
const reportId = existing.records[0].get("reportId");
|
|
42
|
+
const ms = Date.now() - t0;
|
|
43
|
+
const kwCsv = keywords.join(",");
|
|
44
|
+
process.stderr.write(`[reports] op=write reportId=${reportId.slice(0, 8)} keywords=${kwCsv} ms=${ms} idempotent=1\n`);
|
|
45
|
+
return {
|
|
46
|
+
nodeId,
|
|
47
|
+
reportId,
|
|
48
|
+
created: false,
|
|
49
|
+
idempotencyReason: "same-title-within-minute",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const embedding = await embed(`${title}\n\n${body}`);
|
|
53
|
+
const reportId = randomUUID();
|
|
54
|
+
// Parent edge: prefer active :AdminConversation, fall back to account's :AdminUser.
|
|
55
|
+
// The MATCH-OPTIONAL pattern picks whichever exists; we COALESCE to a single parent
|
|
56
|
+
// and assert it resolved before CREATEing the Report.
|
|
57
|
+
const writeRes = await session.run(`OPTIONAL MATCH (c:Conversation) WHERE elementId(c) = $conversationNodeId
|
|
58
|
+
OPTIONAL MATCH (au:AdminUser {accountId: $accountId})
|
|
59
|
+
WITH coalesce(c, au) AS parent
|
|
60
|
+
WHERE parent IS NOT NULL
|
|
61
|
+
CREATE (r:Report {
|
|
62
|
+
reportId: $reportId,
|
|
63
|
+
accountId: $accountId,
|
|
64
|
+
title: $title,
|
|
65
|
+
body: $body,
|
|
66
|
+
keywords: $keywords,
|
|
67
|
+
sourceWorkflow: $sourceWorkflow,
|
|
68
|
+
occurredAt: datetime($occurredAt),
|
|
69
|
+
createdAt: datetime(),
|
|
70
|
+
updatedAt: datetime(),
|
|
71
|
+
scope: 'admin',
|
|
72
|
+
embedding: $embedding
|
|
73
|
+
})
|
|
74
|
+
CREATE (parent)-[:PRODUCED]->(r)
|
|
75
|
+
RETURN elementId(r) AS nodeId`, {
|
|
76
|
+
reportId,
|
|
77
|
+
accountId,
|
|
78
|
+
title,
|
|
79
|
+
body,
|
|
80
|
+
keywords,
|
|
81
|
+
sourceWorkflow: sourceWorkflow ?? null,
|
|
82
|
+
occurredAt: occurredAtIso,
|
|
83
|
+
embedding,
|
|
84
|
+
conversationNodeId: conversationNodeId ?? null,
|
|
85
|
+
});
|
|
86
|
+
if (writeRes.records.length === 0) {
|
|
87
|
+
throw new Error(`memory-report-write: no parent resolved (conversationNodeId='${conversationNodeId ?? "<none>"}' and :AdminUser missing for account '${accountId}'). Report not written.`);
|
|
88
|
+
}
|
|
89
|
+
const nodeId = writeRes.records[0].get("nodeId");
|
|
90
|
+
const ms = Date.now() - t0;
|
|
91
|
+
const kwCsv = keywords.join(",");
|
|
92
|
+
process.stderr.write(`[reports] op=write reportId=${reportId.slice(0, 8)} keywords=${kwCsv} ms=${ms}\n`);
|
|
93
|
+
return { nodeId, reportId, created: true };
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await session.close();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=memory-report-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-report-write.js","sourceRoot":"","sources":["../../src/tools/memory-report-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-review-queue — Task 327.
|
|
3
|
+
*
|
|
4
|
+
* Read-only operator surface for the dream-cycle's review queues.
|
|
5
|
+
* Returns counts plus a small sample of `:OrphanCandidate` and
|
|
6
|
+
* `:CitationProposal` rows so the operator can decide whether to triage
|
|
7
|
+
* them. Without this, the dream-cycle's queue nodes are invisible — write-only
|
|
8
|
+
* shape.
|
|
9
|
+
*
|
|
10
|
+
* Phases 5 (backlinks) and 6 (tag consistency) are not in v1, so neither
|
|
11
|
+
* `:BackLinkGap` nor `:TagMergeProposal` appears here yet — when they
|
|
12
|
+
* land, this tool extends to surface them.
|
|
13
|
+
*/
|
|
14
|
+
export interface MemoryReviewQueueParams {
|
|
15
|
+
accountId: string;
|
|
16
|
+
/** Sample size per queue. Default 5, max 25. */
|
|
17
|
+
sampleSize?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface QueueSummary {
|
|
20
|
+
label: string;
|
|
21
|
+
count: number;
|
|
22
|
+
sample: Array<Record<string, string>>;
|
|
23
|
+
}
|
|
24
|
+
export interface MemoryReviewQueueResult {
|
|
25
|
+
queues: QueueSummary[];
|
|
26
|
+
totalPending: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function memoryReviewQueue(params: MemoryReviewQueueParams): Promise<MemoryReviewQueueResult>;
|
|
29
|
+
//# sourceMappingURL=memory-review-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-review-queue.d.ts","sourceRoot":"","sources":["../../src/tools/memory-review-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAyBD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAiClC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory-review-queue — Task 327.
|
|
3
|
+
*
|
|
4
|
+
* Read-only operator surface for the dream-cycle's review queues.
|
|
5
|
+
* Returns counts plus a small sample of `:OrphanCandidate` and
|
|
6
|
+
* `:CitationProposal` rows so the operator can decide whether to triage
|
|
7
|
+
* them. Without this, the dream-cycle's queue nodes are invisible — write-only
|
|
8
|
+
* shape.
|
|
9
|
+
*
|
|
10
|
+
* Phases 5 (backlinks) and 6 (tag consistency) are not in v1, so neither
|
|
11
|
+
* `:BackLinkGap` nor `:TagMergeProposal` appears here yet — when they
|
|
12
|
+
* land, this tool extends to surface them.
|
|
13
|
+
*/
|
|
14
|
+
import { getSession } from "../lib/neo4j.js";
|
|
15
|
+
const QUEUES = [
|
|
16
|
+
{
|
|
17
|
+
label: "OrphanCandidate",
|
|
18
|
+
sampleQuery: `MATCH (o:OrphanCandidate) WHERE o.accountId = $accountId
|
|
19
|
+
RETURN o.orphanCandidateId AS id,
|
|
20
|
+
o.targetLabel AS targetLabel,
|
|
21
|
+
o.targetName AS targetName,
|
|
22
|
+
toString(o.since) AS since
|
|
23
|
+
ORDER BY o.createdAt DESC LIMIT $limit`,
|
|
24
|
+
countQuery: `MATCH (o:OrphanCandidate) WHERE o.accountId = $accountId RETURN count(o) AS c`,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
label: "CitationProposal",
|
|
28
|
+
sampleQuery: `MATCH (p:CitationProposal) WHERE p.accountId = $accountId
|
|
29
|
+
RETURN p.citationProposalId AS id,
|
|
30
|
+
p.timelineEventId AS timelineEventId,
|
|
31
|
+
toString(coalesce(p.updatedAt, p.createdAt)) AS observedAt,
|
|
32
|
+
coalesce(p.reasoning, '') AS reasoning
|
|
33
|
+
ORDER BY coalesce(p.updatedAt, p.createdAt) DESC LIMIT $limit`,
|
|
34
|
+
countQuery: `MATCH (p:CitationProposal) WHERE p.accountId = $accountId RETURN count(p) AS c`,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
export async function memoryReviewQueue(params) {
|
|
38
|
+
const { accountId } = params;
|
|
39
|
+
const sampleSize = Math.min(Math.max(params.sampleSize ?? 5, 1), 25);
|
|
40
|
+
const session = getSession();
|
|
41
|
+
try {
|
|
42
|
+
const queues = [];
|
|
43
|
+
let totalPending = 0;
|
|
44
|
+
for (const q of QUEUES) {
|
|
45
|
+
const countRes = await session.run(q.countQuery, { accountId });
|
|
46
|
+
const count = Number(countRes.records[0]?.get("c") ?? 0);
|
|
47
|
+
totalPending += count;
|
|
48
|
+
const sampleRes = await session.run(q.sampleQuery, { accountId, limit: sampleSize });
|
|
49
|
+
const sample = sampleRes.records.map((rec) => {
|
|
50
|
+
const row = {};
|
|
51
|
+
for (const key of rec.keys) {
|
|
52
|
+
const value = rec.get(key);
|
|
53
|
+
row[String(key)] = value == null ? "" : String(value);
|
|
54
|
+
}
|
|
55
|
+
return row;
|
|
56
|
+
});
|
|
57
|
+
queues.push({ label: q.label, count, sample });
|
|
58
|
+
}
|
|
59
|
+
process.stderr.write(`[dream-cycle:review-queue] pending=${totalPending} queues=${queues.length}\n`);
|
|
60
|
+
return { queues, totalPending };
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await session.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=memory-review-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-review-queue.js","sourceRoot":"","sources":["../../src/tools/memory-review-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAmB7C,MAAM,MAAM,GAAG;IACb;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE;;;;;yDAKwC;QACrD,UAAU,EAAE,+EAA+E;KAC5F;IACD;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE;;;;;gFAK+D;QAC5E,UAAU,EAAE,gFAAgF;KAC7F;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAA+B;IAE/B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAErE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAmB,EAAE,CAAC;QAClC,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACzD,YAAY,IAAI,KAAK,CAAC;YAEtB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YACrF,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC3C,MAAM,GAAG,GAA2B,EAAE,CAAC;gBACvC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACxD,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,YAAY,WAAW,MAAM,CAAC,MAAM,IAAI,CAC/E,CAAC;QAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-search.d.ts","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-search.d.ts","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,+CAA+C,CAAC;AA8F7G,MAAM,MAAM,kBAAkB,GAC1B,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAC3B;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE1C,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CA2GzB"}
|
|
@@ -1,6 +1,91 @@
|
|
|
1
1
|
import { getSession } from "../lib/neo4j.js";
|
|
2
2
|
import { embed } from "../lib/embeddings.js";
|
|
3
3
|
import { hybrid } from "../../../../../lib/graph-search/dist/index.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Memory search — thin adapter over the shared `graph-search` lib.
|
|
6
|
+
// The hybrid pipeline, Lucene escape, BM25 normalisation, and graph expand
|
|
7
|
+
// all live in platform/lib/graph-search; this file threads the MCP tool
|
|
8
|
+
// parameters through and applies the trash-census observability log.
|
|
9
|
+
//
|
|
10
|
+
// Trash filter visibility: when the account holds `:Trashed` nodes we emit
|
|
11
|
+
// `[trash:read-filter-skipped]` so silent over-filtering stays observable.
|
|
12
|
+
// The census lives here (not in the shared lib) because it is MCP-tool-
|
|
13
|
+
// specific context the admin route doesn't share.
|
|
14
|
+
//
|
|
15
|
+
// Response-side `fields` projection (Task 138): narrows `properties` on each
|
|
16
|
+
// returned row to the caller-requested keys. Indexes and ranking are
|
|
17
|
+
// unaffected — hybrid() sees the full text either way. `related[*].properties`
|
|
18
|
+
// is intentionally NOT projected here.
|
|
19
|
+
//
|
|
20
|
+
// Public-scope compiled-truth projection (Task 392): when the caller's
|
|
21
|
+
// `allowedScopes` is exactly `['public']` (i.e. the public-agent spawn),
|
|
22
|
+
// rewrite the property bag on each result so the agent never sees the
|
|
23
|
+
// admin-side compiledTruth on a public-twin label, and never sees any
|
|
24
|
+
// compiledTruth on a :Person row. The Cypher `scope IN $allowedScopes`
|
|
25
|
+
// filter already drops nodes scoped admin/shared/user:X; this layer
|
|
26
|
+
// rewrites the *field shape* for the rows that survived that filter, so
|
|
27
|
+
// a :Organization with scope='public' surfaces compiledTruthPublic in
|
|
28
|
+
// the `compiledTruth` slot the agent already knows how to read.
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/** Labels whose admin-side compiledTruth gets swapped for compiledTruthPublic in public projection (Task 392). */
|
|
31
|
+
const PUBLIC_TWIN_LABELS = new Set([
|
|
32
|
+
"Organization",
|
|
33
|
+
"Concept",
|
|
34
|
+
"Project",
|
|
35
|
+
"LocalBusiness",
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Detect the public-agent read shape: scope filter is exactly `['public']`.
|
|
39
|
+
* Admin reads pass no scope filter or a broader allowedScopes list; either
|
|
40
|
+
* leaves the property bag untouched. Anything narrower than the exact
|
|
41
|
+
* `['public']` shape (e.g. `['public', 'shared']`) is treated as admin —
|
|
42
|
+
* we only project for the verified public-only entry point.
|
|
43
|
+
*/
|
|
44
|
+
function isPublicOnlyScope(allowedScopes) {
|
|
45
|
+
return Array.isArray(allowedScopes) && allowedScopes.length === 1 && allowedScopes[0] === "public";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Rewrite the property bag on a single result row to surface the public twin.
|
|
49
|
+
* - Public-twin labels: swap `compiledTruth` → `compiledTruthPublic` (drop the admin field).
|
|
50
|
+
* - :Person: strip `compiledTruth` entirely (no public twin exists by design).
|
|
51
|
+
* - Other labels: no-op.
|
|
52
|
+
* Always strips the public-twin housekeeping fields (`compiledTruthPublicUpdatedAt`,
|
|
53
|
+
* `compiledTruthPublicSource`) — they are operator-side metadata, never customer-facing.
|
|
54
|
+
*/
|
|
55
|
+
function projectPublicProperties(labels, properties) {
|
|
56
|
+
const isPublicTwin = labels.some((l) => PUBLIC_TWIN_LABELS.has(l));
|
|
57
|
+
const isPerson = labels.includes("Person");
|
|
58
|
+
const next = {};
|
|
59
|
+
let swapped = false;
|
|
60
|
+
let stripped = false;
|
|
61
|
+
for (const [k, v] of Object.entries(properties)) {
|
|
62
|
+
if (k === "compiledTruthPublicUpdatedAt" || k === "compiledTruthPublicSource") {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (k === "compiledTruthPublic") {
|
|
66
|
+
if (isPublicTwin) {
|
|
67
|
+
next.compiledTruth = v;
|
|
68
|
+
swapped = true;
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (k === "compiledTruth") {
|
|
73
|
+
if (isPublicTwin) {
|
|
74
|
+
// Drop — the public twin (if present in the bag) will land in
|
|
75
|
+
// `compiledTruth` instead. If the public twin is absent from the
|
|
76
|
+
// bag (caller did not request it), the row loses compiledTruth
|
|
77
|
+
// entirely, which is the correct safe default for public reads.
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (isPerson) {
|
|
81
|
+
stripped = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
next[k] = v;
|
|
86
|
+
}
|
|
87
|
+
return { properties: next, swapped, stripped };
|
|
88
|
+
}
|
|
4
89
|
export async function memorySearch(params) {
|
|
5
90
|
const session = getSession();
|
|
6
91
|
const limit = params.limit ?? 10;
|
|
@@ -37,12 +122,47 @@ export async function memorySearch(params) {
|
|
|
37
122
|
catch {
|
|
38
123
|
// observability-only; never break a search on census failure.
|
|
39
124
|
}
|
|
125
|
+
// Step 1: public-scope projection (Task 392). Runs before the `fields`
|
|
126
|
+
// narrowing so a caller that asks for `compiledTruth` on a public read
|
|
127
|
+
// gets the public twin in that slot — the narrowing then preserves the
|
|
128
|
+
// already-swapped key. Applied to both the top-level row and every
|
|
129
|
+
// `related[]` entry: graph-search's scope filter drops admin-scoped
|
|
130
|
+
// related nodes, but the property bag on the survivors still carries
|
|
131
|
+
// their compiledTruth, so without this pass a public-scope :Organization
|
|
132
|
+
// result could leak compiledTruth on a related :Person entry.
|
|
133
|
+
let workingResults = res.results;
|
|
134
|
+
const publicProjection = isPublicOnlyScope(params.allowedScopes);
|
|
135
|
+
if (publicProjection) {
|
|
136
|
+
let swappedRows = 0;
|
|
137
|
+
let strippedRows = 0;
|
|
138
|
+
let swappedRelated = 0;
|
|
139
|
+
let strippedRelated = 0;
|
|
140
|
+
workingResults = res.results.map((r) => {
|
|
141
|
+
const top = projectPublicProperties(r.labels, r.properties);
|
|
142
|
+
if (top.swapped)
|
|
143
|
+
swappedRows++;
|
|
144
|
+
if (top.stripped)
|
|
145
|
+
strippedRows++;
|
|
146
|
+
const related = r.related.map((rel) => {
|
|
147
|
+
const out = projectPublicProperties(rel.labels, rel.properties);
|
|
148
|
+
if (out.swapped)
|
|
149
|
+
swappedRelated++;
|
|
150
|
+
if (out.stripped)
|
|
151
|
+
strippedRelated++;
|
|
152
|
+
return { ...rel, properties: out.properties };
|
|
153
|
+
});
|
|
154
|
+
return { ...r, properties: top.properties, related };
|
|
155
|
+
});
|
|
156
|
+
process.stderr.write(`[memory-search:public-projection] accountId=${params.accountId} ` +
|
|
157
|
+
`rows=${workingResults.length} swapped=${swappedRows} stripped=${strippedRows} ` +
|
|
158
|
+
`relatedSwapped=${swappedRelated} relatedStripped=${strippedRelated}\n`);
|
|
159
|
+
}
|
|
40
160
|
if (fields === undefined)
|
|
41
|
-
return
|
|
161
|
+
return workingResults;
|
|
42
162
|
const allowed = new Set(fields);
|
|
43
163
|
let returnedProps = 0;
|
|
44
164
|
let droppedProps = 0;
|
|
45
|
-
const projected =
|
|
165
|
+
const projected = workingResults.map((r) => {
|
|
46
166
|
const next = {};
|
|
47
167
|
for (const [k, v] of Object.entries(r.properties)) {
|
|
48
168
|
if (allowed.has(k)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-search.js","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAwC,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-search.js","sourceRoot":"","sources":["../../src/tools/memory-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { COMPILED_TRUTH_MAX_CHARS } from "../lib/graph-write-gate.js";
|
|
2
2
|
import type { CreatedBy } from "../../../../../lib/graph-write/dist/index.js";
|
|
3
|
+
type RewriterOutcome = {
|
|
4
|
+
kind: "ok";
|
|
5
|
+
charsBefore: number;
|
|
6
|
+
charsAfter: number;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "refused";
|
|
9
|
+
reason: "no-events" | "operator-edit-cooldown";
|
|
10
|
+
daysRemaining?: number;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "too-long";
|
|
13
|
+
attemptedLen: number;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "llm-failure";
|
|
16
|
+
cause: string;
|
|
17
|
+
};
|
|
3
18
|
interface UpdateParams {
|
|
4
19
|
nodeId: string;
|
|
5
20
|
properties: Record<string, unknown>;
|
|
@@ -11,34 +26,55 @@ interface UpdateParams {
|
|
|
11
26
|
* recent :TimelineEvent rows to recompute `compiledTruth`. Direct writes
|
|
12
27
|
* to `compiledTruth` / `compiledTruthUpdatedAt` / `compiledTruthSource`
|
|
13
28
|
* are rejected loudly — this flag is the only path.
|
|
29
|
+
*
|
|
30
|
+
* Task 392: when the target label is in the public-twin set
|
|
31
|
+
* (:Organization | :Concept | :Project | :LocalBusiness) and the admin
|
|
32
|
+
* pass actually changes the truth (not a string-identical no-op), the
|
|
33
|
+
* public-twin rewriter pass auto-fires inline and updates
|
|
34
|
+
* `compiledTruthPublic`. The admin and public passes share the same
|
|
35
|
+
* timeline-event snapshot.
|
|
14
36
|
*/
|
|
15
37
|
rewriteCompiledTruth?: boolean;
|
|
16
38
|
/**
|
|
17
39
|
* Task 306: bypass the 7-day operator-edit cooldown. The cooldown exists
|
|
18
40
|
* so an automatic rewriter pass does not overwrite an operator-authored
|
|
19
41
|
* summary within a week of the edit. Only set this when the operator
|
|
20
|
-
* explicitly asks for a refresh.
|
|
42
|
+
* explicitly asks for a refresh. Applies to BOTH the admin and public
|
|
43
|
+
* cooldowns when set during a twin-pass.
|
|
21
44
|
*/
|
|
22
45
|
forceRewrite?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Task 392: operator override for the public-twin summary. Bypasses the
|
|
48
|
+
* rewriter, writes the supplied string to `compiledTruthPublic`, stamps
|
|
49
|
+
* `compiledTruthPublicSource = 'operator'`, and resets the public-cooldown
|
|
50
|
+
* timer. Length is enforced via graph-write-gate (≤ COMPILED_TRUTH_MAX_CHARS).
|
|
51
|
+
* Only valid when the target label is in the public-twin set.
|
|
52
|
+
*/
|
|
53
|
+
compiledTruthPublic?: string;
|
|
23
54
|
}
|
|
24
55
|
interface UpdateResult {
|
|
25
56
|
nodeId: string;
|
|
26
57
|
labels: string[];
|
|
27
58
|
updated: boolean;
|
|
28
|
-
rewriter?:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
59
|
+
rewriter?: RewriterOutcome;
|
|
60
|
+
/**
|
|
61
|
+
* Task 392: outcome of the public-twin rewriter pass when it was invoked.
|
|
62
|
+
* Absent when the target label is :Person, when `rewriteCompiledTruth`
|
|
63
|
+
* was false, when the admin pass was a no-op, or when the admin pass
|
|
64
|
+
* itself did not return `ok`.
|
|
65
|
+
*/
|
|
66
|
+
publicRewriter?: RewriterOutcome;
|
|
67
|
+
/**
|
|
68
|
+
* Task 392: outcome of the operator direct-write of `compiledTruthPublic`,
|
|
69
|
+
* when supplied. `applied` means the field was written; `refused` carries
|
|
70
|
+
* a reason matching the cooldown / label gates.
|
|
71
|
+
*/
|
|
72
|
+
publicOverride?: {
|
|
73
|
+
kind: "applied";
|
|
74
|
+
chars: number;
|
|
32
75
|
} | {
|
|
33
76
|
kind: "refused";
|
|
34
|
-
reason: "
|
|
35
|
-
daysRemaining?: number;
|
|
36
|
-
} | {
|
|
37
|
-
kind: "too-long";
|
|
38
|
-
attemptedLen: number;
|
|
39
|
-
} | {
|
|
40
|
-
kind: "llm-failure";
|
|
41
|
-
cause: string;
|
|
77
|
+
reason: "wrong-label" | "too-long";
|
|
42
78
|
};
|
|
43
79
|
}
|
|
44
80
|
export declare function memoryUpdate(params: UpdateParams): Promise<UpdateResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,wBAAwB,EACzB,MAAM,4BAA4B,CAAC;AAUpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAE9E,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,wBAAwB,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,SAAS,EAAE,SAAS,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC;;;;OAIG;IACH,cAAc,CAAC,EACX;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAClC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAA;KAAE,CAAC;CAC7D;AAmDD,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAO9E;AAoaD,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
|