@rubytech/create-sitedesk-code 0.1.524 → 0.1.525

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.
Files changed (117) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +26 -0
  3. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
  4. package/payload/platform/plugins/memory/PLUGIN.md +10 -0
  5. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +5 -1
  6. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -1
  7. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts +2 -0
  8. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts.map +1 -0
  9. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js +141 -0
  10. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js.map +1 -0
  11. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +1 -1
  12. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -1
  13. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +6 -0
  14. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
  15. package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts +45 -0
  16. package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts.map +1 -0
  17. package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js +122 -0
  18. package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js.map +1 -0
  19. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js +26 -0
  20. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js.map +1 -1
  21. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts +2 -0
  22. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js +201 -0
  24. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js.map +1 -0
  25. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
  26. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +89 -33
  27. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
  28. package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -0
  29. package/payload/platform/plugins/scheduling/PLUGIN.md +6 -0
  30. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts +2 -0
  31. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts.map +1 -0
  32. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js +148 -0
  33. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js.map +1 -0
  34. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +83 -6
  35. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  36. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +90 -5
  37. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  38. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +111 -2
  39. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
  40. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +38 -0
  41. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  42. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +116 -0
  43. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  44. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +13 -1
  45. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  46. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +81 -8
  47. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  48. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js +39 -0
  49. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js.map +1 -1
  50. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  51. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +9 -1
  52. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  53. package/payload/platform/scripts/__tests__/check-canonical-tool-names.test.sh +162 -0
  54. package/payload/platform/scripts/__tests__/check-no-task-id-leaks.test.sh +53 -0
  55. package/payload/platform/scripts/__tests__/task-id-citation.test.sh +72 -0
  56. package/payload/platform/scripts/check-canonical-tool-names.mjs +36 -4
  57. package/payload/platform/scripts/check-no-task-id-leaks.mjs +80 -62
  58. package/payload/platform/scripts/lib/canonical-tool-names.mjs +130 -26
  59. package/payload/platform/scripts/lib/task-id-citation.mjs +67 -0
  60. package/payload/platform/.docs/search-surface-contract.md +0 -58
  61. package/payload/platform/docs/superpowers/plans/2026-06-02-task-610-follower-202-retry.md +0 -372
  62. package/payload/platform/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +0 -230
  63. package/payload/platform/docs/superpowers/plans/2026-06-23-account-filesystem-schema.md +0 -544
  64. package/payload/platform/docs/superpowers/plans/2026-07-11-task-1557-operator-on-behalf-preference-attribution.md +0 -542
  65. package/payload/platform/docs/superpowers/plans/2026-07-13-account-schema-ontology-projection.md +0 -547
  66. package/payload/platform/docs/superpowers/plans/2026-07-14-graph-top-level-labels-ontology-single-source.md +0 -458
  67. package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +0 -397
  68. package/payload/platform/docs/superpowers/plans/2026-07-18-graph-native-ledger.md +0 -807
  69. package/payload/platform/docs/superpowers/plans/2026-07-18-ledger-write-path-fix.md +0 -109
  70. package/payload/platform/docs/superpowers/plans/2026-07-20-storage-pages-create.md +0 -82
  71. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1704-data-portal-standing-audit.md +0 -673
  72. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1789-reseat-channel-row-fork.md +0 -1244
  73. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1818-loop-gate-app-routes.md +0 -462
  74. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1819-top-level-label-allowlist.md +0 -321
  75. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1829-platform-ui-typecheck.md +0 -830
  76. package/payload/platform/docs/superpowers/plans/2026-07-20-task-1831-data-portal-class-derived-allowlist.md +0 -2177
  77. package/payload/platform/docs/superpowers/plans/2026-07-21-graph-caption-resolver.md +0 -124
  78. package/payload/platform/docs/superpowers/plans/2026-07-21-task-1877-bash-schema-enforcement.md +0 -107
  79. package/payload/platform/docs/superpowers/plans/2026-07-21-task-1887-reconcile-allowed-top-level.md +0 -205
  80. package/payload/platform/docs/superpowers/plans/2026-07-22-task-1899-reconcile-report-only.md +0 -748
  81. package/payload/platform/docs/superpowers/plans/2026-07-22-task-1910-two-way-portal-exchange.md +0 -1716
  82. package/payload/platform/docs/superpowers/plans/2026-07-23-task-1930-adherence-enforcement.md +0 -422
  83. package/payload/platform/docs/superpowers/plans/2026-07-24-task-1942-subaccount-switcher-brand-head.md +0 -327
  84. package/payload/platform/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +0 -235
  85. package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +0 -215
  86. package/payload/platform/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +0 -555
  87. package/payload/platform/docs/superpowers/plans/2026-07-26-task-1926-portal-push-concurrency-guard.md +0 -482
  88. package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +0 -394
  89. package/payload/platform/docs/superpowers/plans/2026-07-27-task-2016-disabled-agent-routing.md +0 -624
  90. package/payload/platform/docs/superpowers/plans/2026-07-27-task-2028-declared-file-write-deny.md +0 -303
  91. package/payload/platform/docs/superpowers/plans/2026-07-27-task-2052-account-machinery-write-fence.md +0 -250
  92. package/payload/platform/docs/superpowers/plans/2026-07-28-task-2097-email-signature-set.md +0 -65
  93. package/payload/platform/docs/superpowers/specs/2026-06-02-task-610-follower-202-retry-design.md +0 -116
  94. package/payload/platform/docs/superpowers/specs/2026-06-23-account-filesystem-schema-design.md +0 -170
  95. package/payload/platform/docs/superpowers/specs/2026-07-11-task-1557-operator-on-behalf-preference-attribution-design.md +0 -90
  96. package/payload/platform/docs/superpowers/specs/2026-07-13-account-schema-ontology-projection-design.md +0 -178
  97. package/payload/platform/docs/superpowers/specs/2026-07-14-graph-top-level-labels-ontology-single-source-design.md +0 -119
  98. package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +0 -128
  99. package/payload/platform/docs/superpowers/specs/2026-07-18-graph-native-ledger-design.md +0 -241
  100. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1704-data-portal-standing-audit-design.md +0 -177
  101. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1789-reseat-channel-row-fork-design.md +0 -201
  102. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1818-loop-gate-app-routes-design.md +0 -217
  103. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1819-top-level-label-allowlist-design.md +0 -80
  104. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1820-cpu-triage-admin-tools-design.md +0 -97
  105. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1829-platform-ui-typecheck-design.md +0 -163
  106. package/payload/platform/docs/superpowers/specs/2026-07-20-task-1831-data-portal-class-derived-allowlist-design.md +0 -163
  107. package/payload/platform/docs/superpowers/specs/2026-07-22-task-1899-reconcile-report-only-design.md +0 -121
  108. package/payload/platform/docs/superpowers/specs/2026-07-22-task-1910-two-way-portal-exchange-design.md +0 -103
  109. package/payload/platform/docs/superpowers/specs/2026-07-23-task-1930-adherence-enforcement-design.md +0 -81
  110. package/payload/platform/docs/superpowers/specs/2026-07-24-task-1942-subaccount-switcher-brand-head-design.md +0 -35
  111. package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +0 -232
  112. package/payload/platform/docs/superpowers/specs/2026-07-26-task-1926-portal-push-concurrency-guard-design.md +0 -200
  113. package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +0 -169
  114. package/payload/platform/docs/superpowers/specs/2026-07-27-task-2016-disabled-agent-routing-design.md +0 -139
  115. package/payload/platform/docs/superpowers/specs/2026-07-27-task-2028-declared-file-write-deny-design.md +0 -127
  116. package/payload/platform/docs/superpowers/specs/2026-07-27-task-2052-account-machinery-write-fence-design.md +0 -150
  117. package/payload/platform/docs/superpowers/specs/2026-07-28-task-2097-email-signature-set-design.md +0 -155
@@ -1 +1 @@
1
- {"version":3,"file":"memory-update-by-name.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-by-name.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-update-by-name.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-by-name.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=memory-update-type-preserve.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-update-type-preserve.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-type-preserve.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,201 @@
1
+ // Task 2148 — memory-update must not be able to change a property's Neo4j
2
+ // type. Before this, `SET n += $props` wrote an ISO string straight over a
3
+ // :Meeting's ZONED DATETIME `startsAt`, and every `m.startsAt < datetime(...)`
4
+ // comparison against the result was NULL rather than false — the booking page
5
+ // offered a busy afternoon as open time for two days with no error logged.
6
+ //
7
+ // The suite asserts the Cypher the tool builds, which is the surface the fix
8
+ // lives on: neither plugin has a live-Neo4j harness, so a `valueType()` read is
9
+ // not available to a unit test. Every temporal value is vetted by Neo4j's own
10
+ // parser through a probe query BEFORE the update runs, so a rejection can never
11
+ // leave a partially-applied node.
12
+ import { describe, it, expect, beforeEach, vi } from "vitest";
13
+ const mockSession = {
14
+ run: vi.fn(),
15
+ close: vi.fn().mockResolvedValue(undefined),
16
+ };
17
+ vi.mock("../../lib/neo4j.js", () => ({
18
+ getSession: () => mockSession,
19
+ }));
20
+ vi.mock("../../lib/embeddings.js", () => ({
21
+ embed: vi.fn().mockResolvedValue([0.1, 0.2]),
22
+ }));
23
+ vi.mock("../memory-write.js", () => ({
24
+ buildTextRepresentation: () => "text",
25
+ }));
26
+ vi.mock("../../lib/graph-write-gate.js", () => ({
27
+ checkGraphWriteGate: vi.fn().mockResolvedValue({ ok: true }),
28
+ checkLabelWriteGate: vi.fn().mockReturnValue({ ok: true }),
29
+ checkPropertyWriteGate: vi.fn().mockReturnValue({ ok: true }),
30
+ }));
31
+ import { memoryUpdate } from "../memory-update.js";
32
+ const ACCOUNT_ID = "dddb9148-7ba4-4de7-a0da-6eadc5743eda";
33
+ const NODE_ID = "4:meeting:17";
34
+ const CREATED_BY = { agent: undefined, session: undefined, tool: "memory-update" };
35
+ /** The pre-read row: labels, name, sliceToken, and the `valueType()` of each
36
+ * incoming key the node already holds. */
37
+ function preRead(labels, propTypes) {
38
+ return {
39
+ records: [
40
+ {
41
+ get: (k) => k === "nodeLabels" ? labels : k === "propTypes" ? propTypes : null,
42
+ },
43
+ ],
44
+ };
45
+ }
46
+ function updateRow() {
47
+ return {
48
+ records: [
49
+ {
50
+ get: (k) => k === "nodeId" ? NODE_ID : k === "nodeLabels" ? ["Meeting"] : {},
51
+ },
52
+ ],
53
+ };
54
+ }
55
+ /** Every `session.run` call's Cypher, in order. */
56
+ function cyphers() {
57
+ return mockSession.run.mock.calls.map((c) => c[0]);
58
+ }
59
+ beforeEach(() => {
60
+ mockSession.run.mockReset();
61
+ mockSession.close.mockClear();
62
+ });
63
+ describe("memory-update — reads the existing property types", () => {
64
+ it("asks Neo4j for valueType() of every incoming key plus updatedAt", async () => {
65
+ mockSession.run
66
+ .mockResolvedValueOnce(preRead(["Meeting"], []))
67
+ .mockResolvedValueOnce(updateRow())
68
+ .mockResolvedValueOnce({ records: [] });
69
+ await memoryUpdate({
70
+ nodeId: NODE_ID,
71
+ properties: { title: "Golf" },
72
+ accountId: ACCOUNT_ID,
73
+ createdBy: CREATED_BY,
74
+ });
75
+ const [cypher, params] = mockSession.run.mock.calls[0];
76
+ expect(cypher).toContain("valueType(n[k])");
77
+ expect(params.propKeys).toEqual(["title", "updatedAt"]);
78
+ });
79
+ });
80
+ describe("memory-update — a temporal property keeps its type", () => {
81
+ it("rebuilds a ZONED DATETIME key with datetime() instead of the props bag", async () => {
82
+ mockSession.run
83
+ .mockResolvedValueOnce(preRead(["Meeting"], [
84
+ ["startsAt", "ZONED DATETIME NOT NULL"],
85
+ ["title", "STRING NOT NULL"],
86
+ ["updatedAt", "ZONED DATETIME NOT NULL"],
87
+ ]))
88
+ // the probe
89
+ .mockResolvedValueOnce({ records: [{ get: () => null }] })
90
+ .mockResolvedValueOnce(updateRow())
91
+ .mockResolvedValueOnce({ records: [] });
92
+ await memoryUpdate({
93
+ nodeId: NODE_ID,
94
+ properties: { startsAt: "2026-07-29T13:30:00Z", title: "Golf" },
95
+ accountId: ACCOUNT_ID,
96
+ createdBy: CREATED_BY,
97
+ });
98
+ // The probe runs before the write, so a bad value can never half-apply.
99
+ expect(cyphers()[1]).toBe("RETURN datetime($tp0) AS probe");
100
+ const [updateCypher, updateParams] = mockSession.run.mock.calls[2];
101
+ expect(updateCypher).toContain("SET n += $props, n.`startsAt` = datetime($tp0), n.`updatedAt` = datetime()");
102
+ expect(updateCypher).not.toContain("n.updatedAt = $updatedAt");
103
+ expect(updateParams.props).toEqual({ title: "Golf" });
104
+ expect(updateParams.tp0).toBe("2026-07-29T13:30:00Z");
105
+ });
106
+ it("leaves a node with no temporal keys on the plain props bag and an ISO stamp", async () => {
107
+ mockSession.run
108
+ .mockResolvedValueOnce(preRead(["Organization"], [["name", "STRING NOT NULL"], ["updatedAt", "STRING NOT NULL"]]))
109
+ .mockResolvedValueOnce(updateRow())
110
+ .mockResolvedValueOnce({ records: [] });
111
+ await memoryUpdate({
112
+ nodeId: NODE_ID,
113
+ properties: { name: "Acme" },
114
+ accountId: ACCOUNT_ID,
115
+ createdBy: CREATED_BY,
116
+ });
117
+ // No probe: the second call is the update itself.
118
+ expect(cyphers()).toHaveLength(3);
119
+ const [updateCypher, updateParams] = mockSession.run.mock.calls[1];
120
+ expect(updateCypher).toContain("SET n += $props, n.`updatedAt` = $tp0");
121
+ expect(typeof updateParams.tp0).toBe("string");
122
+ expect(Number.isNaN(Date.parse(updateParams.tp0))).toBe(false);
123
+ });
124
+ });
125
+ describe("memory-update — the updatedAt stamp keeps the node's own type", () => {
126
+ it("writes a string stamp on a node whose updatedAt is a string", async () => {
127
+ mockSession.run
128
+ .mockResolvedValueOnce(preRead(["Organization"], [["updatedAt", "STRING NOT NULL"]]))
129
+ .mockResolvedValueOnce(updateRow())
130
+ .mockResolvedValueOnce({ records: [] });
131
+ await memoryUpdate({
132
+ nodeId: NODE_ID,
133
+ properties: { name: "Acme" },
134
+ accountId: ACCOUNT_ID,
135
+ createdBy: CREATED_BY,
136
+ });
137
+ expect(mockSession.run.mock.calls[1][0]).toContain("n.`updatedAt` = $tp0");
138
+ });
139
+ it("writes datetime() on a node whose updatedAt is a ZONED DATETIME", async () => {
140
+ mockSession.run
141
+ .mockResolvedValueOnce(preRead(["Meeting"], [["updatedAt", "ZONED DATETIME NOT NULL"]]))
142
+ .mockResolvedValueOnce(updateRow())
143
+ .mockResolvedValueOnce({ records: [] });
144
+ await memoryUpdate({
145
+ nodeId: NODE_ID,
146
+ properties: { title: "Golf" },
147
+ accountId: ACCOUNT_ID,
148
+ createdBy: CREATED_BY,
149
+ });
150
+ expect(mockSession.run.mock.calls[1][0]).toContain("n.`updatedAt` = datetime()");
151
+ });
152
+ });
153
+ describe("memory-update — rejection is whole-update", () => {
154
+ it("refuses a non-string value for a temporal key without running any write", async () => {
155
+ mockSession.run.mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]));
156
+ await expect(memoryUpdate({
157
+ nodeId: NODE_ID,
158
+ properties: { startsAt: 1754000000000, title: "Golf" },
159
+ accountId: ACCOUNT_ID,
160
+ createdBy: CREATED_BY,
161
+ })).rejects.toThrow(/Update blocked \(type-preserving\): startsAt holds ZONED DATETIME/);
162
+ // Only the pre-read ran — `title` would have succeeded and did not.
163
+ expect(mockSession.run).toHaveBeenCalledTimes(1);
164
+ });
165
+ it("lets a transient driver failure through instead of blaming the value", async () => {
166
+ // A disconnect is not a verdict on the timestamp. Reporting it as
167
+ // "not a valid ZONED DATETIME" would send the agent to reword a value that
168
+ // was correct, and no rewording could ever succeed.
169
+ const transient = Object.assign(new Error("Connection was closed by server"), {
170
+ code: "Neo.TransientError.General.DatabaseUnavailable",
171
+ });
172
+ mockSession.run
173
+ .mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]))
174
+ .mockRejectedValueOnce(transient);
175
+ await expect(memoryUpdate({
176
+ nodeId: NODE_ID,
177
+ properties: { startsAt: "2026-07-29T13:30:00Z" },
178
+ accountId: ACCOUNT_ID,
179
+ createdBy: CREATED_BY,
180
+ })).rejects.toThrow(/Connection was closed by server/);
181
+ expect(mockSession.run).toHaveBeenCalledTimes(2);
182
+ });
183
+ it("turns a Neo4j parser refusal into the type-preserving message, before any write", async () => {
184
+ const clientError = Object.assign(new Error("Text cannot be parsed to a DateTime"), {
185
+ code: "Neo.ClientError.Statement.ArgumentError",
186
+ });
187
+ mockSession.run
188
+ .mockResolvedValueOnce(preRead(["Meeting"], [["startsAt", "ZONED DATETIME NOT NULL"]]))
189
+ .mockRejectedValueOnce(clientError);
190
+ await expect(memoryUpdate({
191
+ nodeId: NODE_ID,
192
+ properties: { startsAt: "next tuesday", title: "Golf" },
193
+ accountId: ACCOUNT_ID,
194
+ createdBy: CREATED_BY,
195
+ })).rejects.toThrow(/Update blocked \(type-preserving\): startsAt holds ZONED DATETIME and "next tuesday" is not a valid ZONED DATETIME/);
196
+ // Pre-read + probe only. The update never ran.
197
+ expect(mockSession.run).toHaveBeenCalledTimes(2);
198
+ expect(cyphers()[1]).toBe("RETURN datetime($tp0) AS probe");
199
+ });
200
+ });
201
+ //# sourceMappingURL=memory-update-type-preserve.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-update-type-preserve.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/memory-update-type-preserve.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAE9E,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;CACtB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAyBD,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAO9E"}
1
+ {"version":3,"file":"memory-update.d.ts","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAE9E,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;CACtB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AA0DD,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAO9E"}
@@ -3,6 +3,7 @@ import { embed } from "../lib/embeddings.js";
3
3
  import { buildTextRepresentation } from "./memory-write.js";
4
4
  import { checkGraphWriteGate, checkLabelWriteGate, checkPropertyWriteGate, } from "../lib/graph-write-gate.js";
5
5
  import { withWriteEvent, pickName } from "../lib/log-ingest.js";
6
+ import { compileTypePreservingSet, typePreserveRejection, } from "../lib/temporal-type-preserve.js";
6
7
  import { REVISION_CYPHER_FRAGMENT_UNWIND, } from "../lib/compiled-truth-revision.js";
7
8
  /** Stripped silently — operator can't update these via the agent. */
8
9
  const RESTRICTED_KEYS = new Set(["embedding", "accountId", "createdAt", "createdOn"]);
@@ -24,6 +25,35 @@ const SYSTEM_MANAGED_KEYS = new Set([
24
25
  function isCompiledTruthRewriter() {
25
26
  return process.env.MAXY_SPECIALIST === "compiled-truth-rewriter";
26
27
  }
28
+ /** The write-time stamp. It is type-preserved like any other property: nodes
29
+ * written by `memory-write` hold it as an ISO string, :Meeting nodes hold it as
30
+ * a ZONED DATETIME, and this tool must not convert either into the other. */
31
+ const UPDATED_AT_KEY = "updatedAt";
32
+ /**
33
+ * Vet each temporal value with Neo4j's own constructor before the update runs.
34
+ * A probe is a read — nothing is written — so a refusal here leaves every
35
+ * property, including the ones that would have succeeded, untouched.
36
+ */
37
+ async function probeTemporalValues(session, probes) {
38
+ for (const probe of probes) {
39
+ try {
40
+ await session.run(`RETURN ${probe.constructorName}($${probe.paramName}) AS probe`, {
41
+ [probe.paramName]: probe.value,
42
+ });
43
+ }
44
+ catch (err) {
45
+ // Only a client error is a verdict on the value. A disconnect, an auth
46
+ // failure or a timeout says nothing about it, and reporting one as
47
+ // "not a valid ZONED DATETIME" would send the agent to reword a
48
+ // timestamp that was correct all along. Those propagate unchanged.
49
+ const code = err?.code;
50
+ if (typeof code === "string" && code.startsWith("Neo.ClientError.")) {
51
+ throw typePreserveRejection(probe.key, probe.existingType, probe.value);
52
+ }
53
+ throw err;
54
+ }
55
+ }
56
+ }
27
57
  export async function memoryUpdate(params) {
28
58
  const nameHint = pickName(params.properties);
29
59
  return withWriteEvent({ tool: "memory-update", accountId: params.accountId, name: nameHint }, () => memoryUpdateImpl(params), (r) => ({ elementId: r.nodeId, labels: r.labels, name: nameHint }));
@@ -60,15 +90,57 @@ async function memoryUpdateImpl(params) {
60
90
  if (Object.keys(safeProps).length === 0) {
61
91
  throw new Error("All provided properties are restricted and cannot be updated.");
62
92
  }
93
+ // When the compiled-truth-rewriter specialist writes a compiledTruth /
94
+ // compiledTruthPublic field, stamp the matching *UpdatedAt + *Source values
95
+ // automatically so the audit trail stays consistent — the specialist
96
+ // shouldn't have to remember the housekeeping fields.
97
+ //
98
+ // Task 2148 — built before the session opens, because the pre-read has to ask
99
+ // for the existing type of every key that will actually be written, and the
100
+ // rewriter's housekeeping keys are part of that set.
101
+ const stamped = { ...safeProps };
102
+ const revisionRows = [];
103
+ if (rewriterCaller) {
104
+ const now = new Date().toISOString();
105
+ if ("compiledTruth" in stamped) {
106
+ stamped.compiledTruthUpdatedAt = now;
107
+ if (!("compiledTruthSource" in stamped))
108
+ stamped.compiledTruthSource = "rewriter";
109
+ revisionRows.push({
110
+ truth: String(stamped.compiledTruth ?? ""),
111
+ twin: "compiledTruth",
112
+ source: stamped.compiledTruthSource === "operator" ? "operator" : "rewriter",
113
+ });
114
+ }
115
+ if ("compiledTruthPublic" in stamped) {
116
+ stamped.compiledTruthPublicUpdatedAt = now;
117
+ if (!("compiledTruthPublicSource" in stamped))
118
+ stamped.compiledTruthPublicSource = "rewriter";
119
+ revisionRows.push({
120
+ truth: String(stamped.compiledTruthPublic ?? ""),
121
+ twin: "compiledTruthPublic",
122
+ source: stamped.compiledTruthPublicSource === "operator" ? "operator" : "rewriter",
123
+ });
124
+ }
125
+ }
126
+ const propKeys = [...Object.keys(stamped), UPDATED_AT_KEY];
63
127
  const session = getSession();
64
128
  try {
129
+ // Task 2148 — `propTypes` is the node's own `valueType()` per incoming key.
130
+ // Without it the SET below has no way to tell a ZONED DATETIME `startsAt`
131
+ // from a STRING `title`, and `n += $props` retypes the former to the latter.
65
132
  const labelResult = await session.run(`MATCH (n) WHERE elementId(n) = $nodeId AND n.accountId = $accountId
66
- RETURN labels(n) AS nodeLabels, n.name AS name, n.sliceToken AS sliceToken`, { nodeId, accountId });
133
+ RETURN labels(n) AS nodeLabels, n.name AS name, n.sliceToken AS sliceToken,
134
+ [k IN $propKeys WHERE n[k] IS NOT NULL | [k, valueType(n[k])]] AS propTypes`, { nodeId, accountId, propKeys });
67
135
  if (labelResult.records.length === 0) {
68
136
  throw new Error(`Node not found or not owned by this account (ID: ${nodeId}).`);
69
137
  }
70
138
  const targetLabels = labelResult.records[0].get("nodeLabels");
71
139
  const targetSliceToken = labelResult.records[0].get("sliceToken");
140
+ const existingTypes = {};
141
+ for (const pair of (labelResult.records[0].get("propTypes") ?? [])) {
142
+ existingTypes[pair[0]] = pair[1];
143
+ }
72
144
  // Task 485 — when the caller runs under a reviewer dispatch, refuse any
73
145
  // update whose target sliceToken does not match the env var. The check
74
146
  // is loud (throws) and logs every refusal — every occurrence is a
@@ -106,35 +178,6 @@ async function memoryUpdateImpl(params) {
106
178
  if (!gate.ok) {
107
179
  throw new Error(`Update blocked (${gate.reason}): ${gate.message}`);
108
180
  }
109
- // When the compiled-truth-rewriter specialist writes a compiledTruth /
110
- // compiledTruthPublic field, stamp the matching *UpdatedAt + *Source values
111
- // automatically so the audit trail stays consistent — the specialist
112
- // shouldn't have to remember the housekeeping fields.
113
- const stamped = { ...safeProps };
114
- const revisionRows = [];
115
- if (rewriterCaller) {
116
- const now = new Date().toISOString();
117
- if ("compiledTruth" in stamped) {
118
- stamped.compiledTruthUpdatedAt = now;
119
- if (!("compiledTruthSource" in stamped))
120
- stamped.compiledTruthSource = "rewriter";
121
- revisionRows.push({
122
- truth: String(stamped.compiledTruth ?? ""),
123
- twin: "compiledTruth",
124
- source: stamped.compiledTruthSource === "operator" ? "operator" : "rewriter",
125
- });
126
- }
127
- if ("compiledTruthPublic" in stamped) {
128
- stamped.compiledTruthPublicUpdatedAt = now;
129
- if (!("compiledTruthPublicSource" in stamped))
130
- stamped.compiledTruthPublicSource = "rewriter";
131
- revisionRows.push({
132
- truth: String(stamped.compiledTruthPublic ?? ""),
133
- twin: "compiledTruthPublic",
134
- source: stamped.compiledTruthPublicSource === "operator" ? "operator" : "rewriter",
135
- });
136
- }
137
- }
138
181
  // Task 436: when the rewriter writes a twin, the `:CompiledTruthRevision`
139
182
  // CREATE rides in the same `session.run` as the live SET so revision
140
183
  // history can never desync from the live property. UNWIND-on-empty is a
@@ -147,19 +190,32 @@ async function memoryUpdateImpl(params) {
147
190
  WITH DISTINCT n
148
191
  `
149
192
  : "";
193
+ // Task 2148 — the SET clause is compiled against the node's own property
194
+ // types, so a temporal property is rebuilt with its constructor rather than
195
+ // overwritten verbatim by `n += $props`.
196
+ const compiled = compileTypePreservingSet({
197
+ alias: "n",
198
+ existingTypes,
199
+ props: stamped,
200
+ now: { key: UPDATED_AT_KEY, isoValue: new Date().toISOString() },
201
+ });
202
+ // Every temporal value is vetted by Neo4j's own parser first. Validating
203
+ // here rather than reimplementing Neo4j's temporal grammar in JS keeps this
204
+ // from being stricter than the database and rejecting values it accepts,
205
+ // and running it before the SET is what makes a refusal all-or-nothing.
206
+ await probeTemporalValues(session, compiled.probes);
150
207
  const updateQuery = `
151
208
  MATCH (n)
152
209
  WHERE elementId(n) = $nodeId AND n.accountId = $accountId
153
- SET n += $props, n.updatedAt = $updatedAt
210
+ SET ${compiled.setClause}
154
211
  ${revisionClause}
155
212
  RETURN elementId(n) AS nodeId, labels(n) AS nodeLabels, properties(n) AS allProps
156
213
  `;
157
214
  const result = await session.run(updateQuery, {
158
215
  nodeId,
159
216
  accountId,
160
- updatedAt: new Date().toISOString(),
161
- props: stamped,
162
217
  revisions: revisionRows,
218
+ ...compiled.params,
163
219
  });
164
220
  if (result.records.length === 0) {
165
221
  throw new Error(`Node not found or not owned by this account (ID: ${nodeId}).`);
@@ -1 +1 @@
1
- {"version":3,"file":"memory-update.js","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-update.js","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,8 @@ export default defineConfig({
49
49
  "src/lib/__tests__/compiled-truth-revision.test.ts",
50
50
  // Vertical relationship-pattern projector + warn-only edge check.
51
51
  "src/lib/__tests__/relationship-patterns.test.ts",
52
+ // Task 2148 — type-preserving SET compiler for memory-update.
53
+ "src/lib/__tests__/temporal-type-preserve.test.ts",
52
54
  // Task 1944 — scheduled dream-cycle sweep throttle policy (vitest).
53
55
  "src/scripts/__tests__/**/*.test.ts",
54
56
  ],
@@ -276,6 +276,12 @@ Env: `PLATFORM_ROOT`, `NEO4J_URI` (and `NEO4J_PASSWORD` or `config/.neo4j-passwo
276
276
 
277
277
  Observability: one `[calendar-booking]` line per step keyed by `bookingId` (`reconcile-claim`, `meeting-write`, `notify`, `booked`), and one `[calendar-reconcile] account=… eligibleExamined=… pendingUnreconciled=… pendingOldestAgeMin=… orphanMeetings=…` audit line per account per run. `eligibleExamined` separates "nothing to do" from "verified clean". A `pendingUnreconciled` that persists across runs means those rows are failing to become meetings rather than merely lagging — the `attempt=` count on the claim and failure lines says how many times each has been tried. `orphanMeetings` means a booking meeting has no backing eligible D1 row. `pendingOldestAgeMin` ages that backlog: a count cannot separate a short lag from a nine-hour one. The companion `[calendar-reconcile] op=liveness lastRunAgeMin=… lastAuditAgeMin=… lastSkipReason=… stale=<bool>` line is emitted every ten minutes by the platform/ui server rather than by this script, because the failure it detects is this script not reporting at all. `op=liveness-write-failed` is the one case where that record could not be written; it carries the error body and never stops the run, because a run that worked must not be reported as failed for losing its own bookkeeping.
278
278
 
279
+ Two further lines print per account on every tick whether or not anything is wrong. `[calendar-availability] op=meeting-retype account=… scanned=… repaired=… unparseable=… failed=…` is the timestamp type census: it matches `:Meeting` rows whose `startsAt` or `endsAt` is stored as a `STRING` and rebuilds each with `datetime()`. It answers "is anything in this calendar stored with the wrong type right now?" without reproducing the failure and without waiting for a customer to hit a bad slot. A repaired row stops matching, so a steady install reads `scanned=0 repaired=0` and this stays a standing repair rather than a migration to remove. A non-zero `repaired` on a steady install means something is still writing strings and names the account. The two failure counts are deliberately separate: `unparseable` is a value Neo4j's own parser rejects and needs a human, while `failed` is the write not landing (a timeout, a disconnect) and retries on the next tick. Neo4j's error code decides which, so a transient fault is never reported as a corrupt value. No JS pre-check stands in for that parser — `Date.parse` rejects the zone-id form `2026-07-29T13:30:00[Europe/London]` that `datetime()` accepts, and would report a repairable row as needing a human.
280
+
281
+ `[calendar-availability] op=cal-drift account=… outcome=… published=… busyMeetings=… busyConnector=… busyUnusable=… conflicts=…` re-reads what was published and reconciles it against both labels the public free/busy page subtracts, `:Meeting` and `:ConnectorBusy`. It read `:ConnectorBusy` alone before this, so any meeting conflict was outside what it could measure, and it reported `outcome=verified conflicts=0` throughout an incident where five meetings were invisible. The census is split into named counts because one total cannot distinguish "3 connector intervals, no meetings" from "3 meetings, no connector" — the exact ambiguity that made `busy=3 conflicts=0` read as healthy. A meeting with no `endsAt` (nullable by schema) is given `start + durationMins`, the same substitution the free/busy route makes, rather than dropped; `busyUnusable` counts the rows that had no resolvable bound even so, because an interval excluded without a count is the silent drop this whole signal exists to remove. Read together the two lines discriminate three states: a conflict with `repaired=0` is a slot-math or publish fault, a conflict alongside `repaired>0` is corruption caught mid-repair, and `conflicts=0` with `busyMeetings>0` is evidence the meeting path was checked at all.
282
+
283
+ The **audit** widened; what the **blocking** step acts on did not. `planBlockWrites` still reads `:ConnectorBusy` alone, because its empty-set rule is a liveness test for the connector sync: a set padded with meetings would report a deauthorised connector as healthy on any account that has ever taken a booking, and every held `kind='block'` row would be deleted, putting genuinely busy times back on sale.
284
+
279
285
  ## Ingesting calendar archives (.ics → graph)
280
286
 
281
287
  `schedule-archive-ics` is the bulk-ingest path: it reads an `.ics` export from any calendar app (Google, Apple, Outlook, Fastmail, etc.) and writes one `:Meeting` per VEVENT into the graph, with attendees resolved to `:Person` by lowercased email. Distinct from `schedule-import-ics`, which only parses + returns events for the operator to recreate via `schedule-event` one at a time.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=meeting-retype.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-retype.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/meeting-retype.test.ts"],"names":[],"mappings":""}