@rubytech/create-maxy-code 0.1.151 → 0.1.153
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/lib/graph-search/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-search/dist/index.js +10 -9
- package/payload/platform/lib/graph-search/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-search/src/index.ts +10 -9
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/pre-turn-graph-pass.test.sh +26 -129
- package/payload/platform/plugins/admin/hooks/pre-turn-graph-pass.sh +64 -131
- package/payload/platform/plugins/docs/PLUGIN.md +1 -1
- package/payload/platform/plugins/docs/references/admin-session.md +2 -2
- package/payload/platform/plugins/docs/references/internals.md +1 -64
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -2
- package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +25 -45
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +8 -16
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +14 -11
- package/payload/platform/plugins/memory/mcp/dist/index.js +13 -269
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts +1 -24
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js +8 -211
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/section-types.d.ts +99 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/section-types.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/section-types.js +56 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/section-types.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.d.ts +12 -32
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.js +19 -281
- package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-pass.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js +0 -3
- 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/conversation-archive-derive-insights.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +15 -14
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts +1 -76
- 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 +73 -329
- 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 +10 -12
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +4 -3
- package/payload/platform/plugins/memory/references/graph-primitives.md +2 -2
- package/payload/platform/plugins/memory/references/schema-base.md +2 -7
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +71 -46
- package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +2 -2
- package/payload/platform/scripts/seed-neo4j.sh +0 -49
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +3 -2
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
- package/payload/platform/templates/specialists/agents/citation-auditor.md +37 -0
- package/payload/platform/templates/specialists/agents/compiled-truth-rewriter.md +42 -0
- package/payload/platform/templates/specialists/agents/database-operator.md +2 -30
- package/payload/platform/templates/specialists/agents/research-assistant.md +2 -2
- package/payload/platform/templates/specialists/agents/typed-edge-classifier.md +37 -0
- package/payload/server/{adminuser-self-heal-YC47O34W.js → adminuser-self-heal-WSFCOEII.js} +1 -1
- package/payload/server/{chunk-T3DJD5QR.js → chunk-AXOL2PPG.js} +1 -1
- package/payload/server/{chunk-HYQNUVGO.js → chunk-PFF6I7KP.js} +1 -8
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/assets/{admin-CnLGltuE.js → admin-kh_oCHeS.js} +54 -54
- package/payload/server/public/assets/{data-MB2EWZUP.js → data-BHASh0_Y.js} +1 -1
- package/payload/server/public/assets/{graph-B2FnDRz-.js → graph-BhEI09tF.js} +1 -1
- package/payload/server/public/assets/graph-labels-DXlmm1og.js +1 -0
- package/payload/server/public/assets/{page-BJKRa6Db.js → page-CDWu1Aft.js} +3 -3
- package/payload/server/public/assets/{page-Bx2p3W1k.js → page-cyvshX4Z.js} +1 -1
- package/payload/server/public/data.html +3 -3
- package/payload/server/public/graph.html +3 -3
- package/payload/server/public/index.html +4 -4
- package/payload/server/server.js +319 -1286
- package/payload/platform/lib/graph-search/src/__tests__/query-expansion.test.ts +0 -96
- package/payload/platform/lib/graph-search/src/query-expansion.ts +0 -129
- package/payload/platform/lib/oauth-llm/src/index.ts +0 -583
- package/payload/platform/lib/oauth-llm/tsconfig.json +0 -8
- package/payload/platform/lib/screening-patterns/src/index.ts +0 -51
- package/payload/platform/lib/screening-patterns/tsconfig.json +0 -8
- package/payload/server/public/assets/graph-labels-DDYqDlu3.js +0 -1
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# UserPromptSubmit hook — pre-turn graph pass.
|
|
2
|
+
# UserPromptSubmit hook — pre-turn graph pass. Tasks 425, 430.
|
|
3
3
|
#
|
|
4
|
-
# Fires once per operator prompt submission.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
4
|
+
# Fires once per admin-agent operator prompt submission. Emits a
|
|
5
|
+
# directive into the admin agent's `additionalContext` that instructs
|
|
6
|
+
# **admin** to scan the just-submitted operator turn for new candidate
|
|
7
|
+
# graph rows (mentions, ideas, commitments, contacts, learnings — any
|
|
8
|
+
# label the schema admits), then dispatch one `database-operator` Task
|
|
9
|
+
# per candidate write. Admin is the session-walker; the specialist only
|
|
10
|
+
# sees a narrowly-scoped per-write brief, never the conversation.
|
|
11
|
+
#
|
|
12
|
+
# Task 430 corrects the Task 425 orchestration shape. The Task 425 hook
|
|
13
|
+
# packaged the full conversation blob into the specialist's prompt; that
|
|
14
|
+
# collapsed the data channel and the instruction channel into one
|
|
15
|
+
# context, so operator prose pattern-matching as a writer-binding
|
|
16
|
+
# instruction ("memory-update is denied this session") was treated as
|
|
17
|
+
# binding and the pass self-denied. Same failure class as the writer-POV
|
|
18
|
+
# schema doctrine read as binding the agent (Task 199 / 995). The
|
|
19
|
+
# session-end retrospective never had this defect because admin walked
|
|
20
|
+
# the transcript itself and dispatched per-item briefs to the
|
|
21
|
+
# specialist — Task 430 brings the per-turn pass to the same shape.
|
|
9
22
|
#
|
|
10
23
|
# Supersedes Task 412's Stop-hook registration. The Stop hook fired on
|
|
11
24
|
# every assistant `end_turn`, including the agent's own ack after the
|
|
@@ -16,19 +29,19 @@
|
|
|
16
29
|
# `session-end-retrospective.sh` Stop hook walks the full transcript at
|
|
17
30
|
# `/end` and picks up the final assistant reply.
|
|
18
31
|
#
|
|
19
|
-
# The
|
|
32
|
+
# The doctrinal early exits remain:
|
|
20
33
|
# - MAXY_SESSION_ROLE must equal "admin" → reason=role-not-admin
|
|
21
34
|
# - MAXY_SPECIALIST must be empty → reason=is-specialist
|
|
22
|
-
# `missing-transcript` is retained as a safety exit
|
|
23
|
-
#
|
|
35
|
+
# `missing-transcript` is retained as a safety exit (the prior-writes
|
|
36
|
+
# context fetch still needs a real session). `wrong-hook-event` rejects
|
|
37
|
+
# stale Stop-shaped fires.
|
|
24
38
|
#
|
|
25
39
|
# Input: Claude Code's UserPromptSubmit hook stdin shape
|
|
26
40
|
# { "session_id": "<intrinsic>", "transcript_path": "<jsonl path>",
|
|
27
41
|
# "cwd": "<…>", "hook_event_name": "UserPromptSubmit",
|
|
28
42
|
# "prompt": "<operator text>" }
|
|
29
|
-
# `prompt` is ignored — the
|
|
30
|
-
# already
|
|
31
|
-
# UserPromptSubmit fires after the prompt is written.
|
|
43
|
+
# `prompt` is ignored — the directive instructs admin to read the turn
|
|
44
|
+
# it already has in context.
|
|
32
45
|
#
|
|
33
46
|
# Output: stdout JSON of the documented UserPromptSubmit shape:
|
|
34
47
|
# { "hookSpecificOutput": { "hookEventName": "UserPromptSubmit",
|
|
@@ -36,8 +49,8 @@
|
|
|
36
49
|
# exit 0. The directive carries the literal token
|
|
37
50
|
# `[system: pre-turn-graph-pass-hook]` so the agent's IDENTITY.md
|
|
38
51
|
# UserPromptSubmit-directive section can distinguish it from operator
|
|
39
|
-
# text. The agent performs the
|
|
40
|
-
# and then continues with its normal response to the operator.
|
|
52
|
+
# text. The agent performs the per-write dispatches as a background
|
|
53
|
+
# pass and then continues with its normal response to the operator.
|
|
41
54
|
|
|
42
55
|
set -uo pipefail
|
|
43
56
|
|
|
@@ -103,96 +116,12 @@ fi
|
|
|
103
116
|
|
|
104
117
|
CONVERSATION_ID="${CONVERSATION_NODE_ID:-}"
|
|
105
118
|
|
|
106
|
-
# Walk the transcript and emit the conversation as `[role: text]` pairs,
|
|
107
|
-
# oldest first. User turns whose only content is `tool_result` blocks are
|
|
108
|
-
# skipped (they carry tool plumbing, not operator intent). Multi-block
|
|
109
|
-
# assistant turns concatenate their `text` blocks; `tool_use` blocks are
|
|
110
|
-
# dropped. The just-submitted operator prompt is already present in the
|
|
111
|
-
# JSONL by the time UserPromptSubmit fires.
|
|
112
|
-
CONVERSATION=$(TRANSCRIPT_PATH="$TRANSCRIPT_PATH" python3 - <<'PY'
|
|
113
|
-
import os, json, sys
|
|
114
|
-
|
|
115
|
-
def assistant_text(rec):
|
|
116
|
-
msg = rec.get("message", {}) or {}
|
|
117
|
-
if msg.get("role") != "assistant":
|
|
118
|
-
return ""
|
|
119
|
-
content = msg.get("content")
|
|
120
|
-
if isinstance(content, str):
|
|
121
|
-
return content
|
|
122
|
-
if isinstance(content, list):
|
|
123
|
-
parts = []
|
|
124
|
-
for b in content:
|
|
125
|
-
if isinstance(b, dict) and b.get("type") == "text":
|
|
126
|
-
t = b.get("text")
|
|
127
|
-
if isinstance(t, str):
|
|
128
|
-
parts.append(t)
|
|
129
|
-
return "".join(parts)
|
|
130
|
-
return ""
|
|
131
|
-
|
|
132
|
-
def user_text(rec):
|
|
133
|
-
msg = rec.get("message", {}) or {}
|
|
134
|
-
if msg.get("role") != "user":
|
|
135
|
-
return None
|
|
136
|
-
content = msg.get("content")
|
|
137
|
-
if isinstance(content, str):
|
|
138
|
-
return content
|
|
139
|
-
if isinstance(content, list):
|
|
140
|
-
parts = []
|
|
141
|
-
saw_non_tool_result = False
|
|
142
|
-
for b in content:
|
|
143
|
-
if not isinstance(b, dict):
|
|
144
|
-
continue
|
|
145
|
-
btype = b.get("type")
|
|
146
|
-
if btype == "tool_result":
|
|
147
|
-
continue
|
|
148
|
-
saw_non_tool_result = True
|
|
149
|
-
if btype == "text":
|
|
150
|
-
t = b.get("text")
|
|
151
|
-
if isinstance(t, str):
|
|
152
|
-
parts.append(t)
|
|
153
|
-
if not saw_non_tool_result:
|
|
154
|
-
return None
|
|
155
|
-
return "".join(parts)
|
|
156
|
-
return None
|
|
157
|
-
|
|
158
|
-
path = os.environ["TRANSCRIPT_PATH"]
|
|
159
|
-
out_lines = []
|
|
160
|
-
try:
|
|
161
|
-
with open(path, "r", encoding="utf-8") as f:
|
|
162
|
-
for raw in f:
|
|
163
|
-
raw = raw.strip()
|
|
164
|
-
if not raw:
|
|
165
|
-
continue
|
|
166
|
-
try:
|
|
167
|
-
rec = json.loads(raw)
|
|
168
|
-
except Exception:
|
|
169
|
-
continue
|
|
170
|
-
if not isinstance(rec, dict):
|
|
171
|
-
continue
|
|
172
|
-
rtype = rec.get("type")
|
|
173
|
-
if rtype == "user":
|
|
174
|
-
t = user_text(rec)
|
|
175
|
-
if t is None:
|
|
176
|
-
continue
|
|
177
|
-
out_lines.append(f"[user: {t.strip()}]")
|
|
178
|
-
elif rtype == "assistant":
|
|
179
|
-
t = assistant_text(rec)
|
|
180
|
-
if not t.strip():
|
|
181
|
-
continue
|
|
182
|
-
out_lines.append(f"[assistant: {t.strip()}]")
|
|
183
|
-
except Exception as e:
|
|
184
|
-
sys.stderr.write(f"transcript-walk-failed: {e}\n")
|
|
185
|
-
sys.exit(0)
|
|
186
|
-
|
|
187
|
-
print("\n\n".join(out_lines))
|
|
188
|
-
PY
|
|
189
|
-
)
|
|
190
|
-
CONVERSATION_TURNS=$(printf '%s\n' "$CONVERSATION" | grep -c '^\[' || true)
|
|
191
|
-
CONTEXT_BYTES=${#CONVERSATION}
|
|
192
|
-
|
|
193
119
|
# Fetch the actual content of every node already written under this
|
|
194
120
|
# conversation, account-scoped. The route runs loopback-only — the hook
|
|
195
121
|
# is in-process on the device, same trust boundary as `/log-ingest`.
|
|
122
|
+
# Admin reads this skip-list before deciding what new writes to
|
|
123
|
+
# dispatch; the specialist never sees it (per-write briefs name the
|
|
124
|
+
# elementId admin already resolved when attaching to an existing node).
|
|
196
125
|
PRIOR_WRITES="(none)"
|
|
197
126
|
PRIOR_WRITES_COUNT=0
|
|
198
127
|
if [ -n "$CONVERSATION_ID" ]; then
|
|
@@ -238,42 +167,46 @@ print(f"{len(writes)}\t" + "\n".join(lines))
|
|
|
238
167
|
fi
|
|
239
168
|
fi
|
|
240
169
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
CONVERSATION_ID_OUT="${CONVERSATION_ID:-<unset>}" \
|
|
250
|
-
CONVERSATION_OUT="${CONVERSATION}" \
|
|
251
|
-
PRIOR_WRITES_OUT="${PRIOR_WRITES}" \
|
|
252
|
-
python3 - <<'PY'
|
|
253
|
-
import os, json, sys
|
|
170
|
+
# Compose the directive body before logging so contextBytes reflects
|
|
171
|
+
# the actual payload size handed to admin (skip-list + directive prose).
|
|
172
|
+
DIRECTIVE_BODY=$(ACCOUNT_ID_OUT="${ACCOUNT_ID:-<unset>}" \
|
|
173
|
+
SESSION_ID_OUT="${SESSION_ID}" \
|
|
174
|
+
CONVERSATION_ID_OUT="${CONVERSATION_ID:-<unset>}" \
|
|
175
|
+
PRIOR_WRITES_OUT="${PRIOR_WRITES}" \
|
|
176
|
+
python3 - <<'PY'
|
|
177
|
+
import os
|
|
254
178
|
body = (
|
|
255
179
|
"[system: pre-turn-graph-pass-hook]\n"
|
|
256
|
-
"Before responding to the operator,
|
|
257
|
-
"
|
|
258
|
-
"
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
|
|
263
|
-
f"
|
|
264
|
-
f"
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
f"
|
|
268
|
-
"
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
180
|
+
"Before responding to the operator, run the pre-turn graph pass. "
|
|
181
|
+
"Scan the operator turn you just received for any new graph-worthy content not already covered by the prior-writes list below — "
|
|
182
|
+
"mentions of named entities, ideas or learnings the operator stated, contacts named for the first time, tasks the operator committed to, decisions, anything the schema admits. "
|
|
183
|
+
"For each candidate write, dispatch one Task to the `database-operator` specialist with a brief that names the label, the relevant properties, and (when attaching to an existing node) the elementId from the prior-writes list. "
|
|
184
|
+
"Skip writes the prior-writes list already covers — a `:MENTIONS` edge that is already there does not need re-emitting; an existing `:Person` is attached to by elementId, not re-created. "
|
|
185
|
+
"If the turn supports no new writes, dispatch nothing. "
|
|
186
|
+
"Do not surface these dispatches in your reply to the operator. After the dispatches return, continue with your normal response to the operator's prompt.\n\n"
|
|
187
|
+
f"accountId: {os.environ['ACCOUNT_ID_OUT']}\n"
|
|
188
|
+
f"sessionId: {os.environ['SESSION_ID_OUT']}\n"
|
|
189
|
+
f"conversationId: {os.environ['CONVERSATION_ID_OUT']}\n\n"
|
|
190
|
+
"<prior-writes>\n"
|
|
191
|
+
f"{os.environ['PRIOR_WRITES_OUT']}\n"
|
|
192
|
+
"</prior-writes>\n"
|
|
193
|
+
)
|
|
194
|
+
print(body, end="")
|
|
195
|
+
PY
|
|
272
196
|
)
|
|
197
|
+
CONTEXT_BYTES=${#DIRECTIVE_BODY}
|
|
198
|
+
|
|
199
|
+
emit_log "dispatch sessionId=${SESSION_ID} conversationId=${CONVERSATION_ID:-<unset>} directive-shape=admin-walks priorWritesCount=${PRIOR_WRITES_COUNT} contextBytes=${CONTEXT_BYTES} ms=0"
|
|
200
|
+
|
|
201
|
+
# Emit the documented UserPromptSubmit JSON envelope on stdout. Python
|
|
202
|
+
# handles JSON encoding so embedded newlines, quotes, and backslashes
|
|
203
|
+
# in the prior-writes block are escaped correctly.
|
|
204
|
+
DIRECTIVE_BODY_OUT="$DIRECTIVE_BODY" python3 - <<'PY'
|
|
205
|
+
import os, json, sys
|
|
273
206
|
sys.stdout.write(json.dumps({
|
|
274
207
|
"hookSpecificOutput": {
|
|
275
208
|
"hookEventName": "UserPromptSubmit",
|
|
276
|
-
"additionalContext":
|
|
209
|
+
"additionalContext": os.environ["DIRECTIVE_BODY_OUT"],
|
|
277
210
|
}
|
|
278
211
|
}))
|
|
279
212
|
PY
|
|
@@ -31,7 +31,7 @@ Load these when users ask about Maxy features or need guidance:
|
|
|
31
31
|
Load these when performing admin tasks or diagnosing platform behaviour:
|
|
32
32
|
|
|
33
33
|
- **Platform architecture** → `references/platform.md` — how the platform works, agent types, the plugin model
|
|
34
|
-
- **Platform internals** → `references/internals.md` — retrieval pipeline, embedding infrastructure, guard layers,
|
|
34
|
+
- **Platform internals** → `references/internals.md` — retrieval pipeline, embedding infrastructure, guard layers, graph expansion, keyword subscriptions, context assembly, tool call audit trail, programmatic spawn entry point and recorder auto-archive lifecycle. Load when answering architecture questions, assessing whether a capability exists, diagnosing retrieval behaviour, or reviewing security and privacy features.
|
|
35
35
|
- **Admin UI** → `references/admin-ui.md` — compact map of every `/api/admin/*` mount, every sidebar surface, the system-stats widget (CPU/RAM thresholds), the artefact pane, and the health-vs-version split. Load when diagnosing an admin route, explaining the CPU/RAM widget, or onboarding a new admin endpoint.
|
|
36
36
|
- **Admin session** → `references/admin-session.md` — signed sessionKey + PIN-rebind survival contract, SDK-resume across `systemctl restart`, and the single-entry `POST /api/admin/claude-sessions` wrapper that owns every programmatic admin spawn-with-initialMessage. Load when diagnosing admin session continuity, designing a programmatic admin spawn, or reviewing the turn-recorder lifecycle.
|
|
37
37
|
- **Cloudflare** → `references/cloudflare.md` — dashboard-first tunnel setup, the `cloudflared`-CLI-only tool surface, single-recovery-path (re-login) for every wrong-account failure.
|
|
@@ -129,7 +129,7 @@ The hook emits two summary lines per fire immediately before `spawn-request`:
|
|
|
129
129
|
- `--allowed-tools` is **not** pushed to argv. `--agent <name>` resolves the agent file's `tools:` frontmatter natively against Claude Code's plugin-tool registry; the argv push (Task 165) was empirically redundant and namespace-broke after Task 203's `mcp__plugin_…` rename (Task 207).
|
|
130
130
|
- The per-spawn `mcp.json` is **not** written and `--mcp-config` is **not** pushed. Plugin manifests register the MCPs at session start (Tasks 202+203). The per-account env that the JSON used to inject (`ACCOUNT_ID`, `USER_ID`, `NEO4J_URI`, `NEO4J_PASSWORD`, `PLATFORM_ROOT`, `CLAUDE_CONFIG_DIR`) now rides the PTY env block directly — see [`mcp-servers.md`](mcp-servers.md) §3 (Task 207).
|
|
131
131
|
- `--permission-mode bypassPermissions` is auto-pushed when the caller has not set `permissionMode`. Headless specialists have no operator to consent to write tools; default mode blocks them (Task 207).
|
|
132
|
-
- `--remote-control` is **not** attached and the URL-capture handler is not registered. Remote Control is channel-facing only; the recorder has no human in the loop, so no `claude.ai/code/session_<id>` URL is ever emitted and the per-byte URL regex consumes no PTY output. The spawn log line carries `remoteControl=false`. Channel-facing specialists (content-producer, librarian, personal-assistant, project-manager, research-assistant) keep `--remote-control`; only specialists named in `HEADLESS_ROLES` (`database-operator`, `
|
|
132
|
+
- `--remote-control` is **not** attached and the URL-capture handler is not registered. Remote Control is channel-facing only; the recorder has no human in the loop, so no `claude.ai/code/session_<id>` URL is ever emitted and the per-byte URL regex consumes no PTY output. The spawn log line carries `remoteControl=false`. Channel-facing specialists (content-producer, librarian, personal-assistant, project-manager, research-assistant) keep `--remote-control`; only specialists named in `HEADLESS_ROLES` (`database-operator`, `citation-auditor`, `typed-edge-classifier`, `compiled-truth-rewriter`) drop it.
|
|
133
133
|
|
|
134
134
|
**End-of-turn auto-archive.** When any session whose specialist is `database-operator` gains an assistant message with `stop_reason: "end_turn"` in its JSONL, the manager posts `/<sid>/stop` against itself, claude exits, the fs-watcher observes the PID-file removal and drops the row from the index. The auto-archive log line is `auto-archive sessionId=<sid> specialist=database-operator reason=end-turn …`. Every operator-request stop (auto-archive included) now ends in `master-fd=closed` because `stopSession()` calls `pty.destroy()` explicitly before `store.remove` (Task 170 — see `platform.md` "stopSession fd contract" for the failure mode this closes).
|
|
135
135
|
|
|
@@ -171,7 +171,7 @@ Line shapes:
|
|
|
171
171
|
|
|
172
172
|
Enumerated `reason` slugs (failure path): `invalid-input | schema-unknown-label | schema-property-naming | account-isolation | producedby-task-not-found | constraint-violation | conflicting-element-id | invalid-target-node-id | gate-blocked | neo4j-driver-error`. Free-form error text remains in the `detail` field. New slugs are added only by amending the helper's union type; nothing silently falls through to a generic `unknown`.
|
|
173
173
|
|
|
174
|
-
Wired tools: `memory-write`, `memory-update`, `memory-delete`, `memory-restore`, `memory-empty-trash`, `memory-archive-write`, `memory-ingest`, `memory-ingest-extract`, `memory-ingest-web`, `memory-
|
|
174
|
+
Wired tools: `memory-write`, `memory-update`, `memory-delete`, `memory-restore`, `memory-empty-trash`, `memory-archive-write`, `memory-ingest`, `memory-ingest-extract`, `memory-ingest-web`, `memory-reindex`, `memory-edit-attachment`, `memory-rename-attachment`, `profile-update`, `profile-delete`, `graph-prune-denylist-add`, `graph-prune-denylist-remove`, `conversation-archive-derive-insights`, `conversation-archive-enrich-rejection`, `conversation-memory-expunge`. Read-path tools (`memory-search`, etc.) are intentionally out of scope — reads do not change state and their failures already reach the caller. (Task 424 removed `memory-rank` and `memory-classify`.)
|
|
175
175
|
|
|
176
176
|
Diagnostic grep:
|
|
177
177
|
|
|
@@ -232,69 +232,6 @@ Admin: `[admin-query-classifier]` log line with `topicChange`, `topicChangeConfi
|
|
|
232
232
|
Public: `[public-query-classifier]` log line with `search`, `effectiveQuery`, `reason`, `latencyMs`. The intentional absence of topic-change fields in the public log is the on-disk evidence that the public path does less work.
|
|
233
233
|
|
|
234
234
|
---
|
|
235
|
-
|
|
236
|
-
## Memory-Rank — LLM-Reasoned Document Grading
|
|
237
|
-
|
|
238
|
-
The `memory-rank` tool adds an LLM reasoning layer on top of `memory-search`. Instead of relying solely on vector similarity and BM25 scores, it passes a candidate pool to Haiku with a natural-language ranking criterion and receives a re-ordered list with per-item reasoning.
|
|
239
|
-
|
|
240
|
-
### Pipeline
|
|
241
|
-
|
|
242
|
-
```
|
|
243
|
-
QUERY ──► memory-search (pool=20) ──► candidates
|
|
244
|
-
│
|
|
245
|
-
▼
|
|
246
|
-
Claude Haiku
|
|
247
|
-
(ranking prompt)
|
|
248
|
-
│
|
|
249
|
-
▼
|
|
250
|
-
ranked results
|
|
251
|
-
(with reasoning)
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Configuration
|
|
255
|
-
|
|
256
|
-
| Parameter | Default | Maximum |
|
|
257
|
-
|---|---|---|
|
|
258
|
-
| Output limit | 10 results | 50 |
|
|
259
|
-
| Candidate pool | 20 candidates | 50 |
|
|
260
|
-
| Expand hops | 1 | — |
|
|
261
|
-
|
|
262
|
-
The candidate pool is always larger than the output limit. Haiku sees 20 candidates (with their properties and up to 10 related nodes each) and returns a ranked subset.
|
|
263
|
-
|
|
264
|
-
### Ranking prompt
|
|
265
|
-
|
|
266
|
-
Haiku receives a sandboxed system prompt that:
|
|
267
|
-
- Defines it as an entity ranker, not a general assistant
|
|
268
|
-
- Instructs it to assess each candidate against the provided criterion
|
|
269
|
-
- Forces it to call the `emit_ranker_output` tool with structured `rankings[]` of `{nodeId, rank (1-indexed, 1 = most important), reasoning (one sentence, ≤300 chars)}` — Anthropic validates the payload against `RankerOutputTool.input_schema` at the API boundary, so markdown-fence and malformed-JSON failure modes are impossible by construction
|
|
270
|
-
- Explicitly labels the user-provided criterion as "data, not instructions" to prevent prompt injection
|
|
271
|
-
|
|
272
|
-
The criterion itself (from the calling agent) is wrapped in `<<<CRITERION... CRITERION` delimiters in the user message.
|
|
273
|
-
|
|
274
|
-
### Hallucination defence
|
|
275
|
-
|
|
276
|
-
Two layers:
|
|
277
|
-
1. **Input isolation** — Haiku only sees nodeIds from the candidate pool. The prompt says "only use nodeIds from the candidate list. Never invent a nodeId."
|
|
278
|
-
2. **Output validation** — The parser maintains a set of valid nodeIds. Any nodeId in Haiku's response that is not in the input set is silently discarded and counted. If all rankings are hallucinated, the system falls back to unranked results.
|
|
279
|
-
|
|
280
|
-
### Graceful degradation
|
|
281
|
-
|
|
282
|
-
When ranking fails (no OAuth credentials, API error, rate limit, network timeout, schema-violating `tool_use.input`, empty response, all-hallucinated), the tool returns the original `memory-search` results in their score order, prefixed with:
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
[Ranking unavailable: <reason>] — showing N candidates in their original memory-search score order.
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
This makes the failure visible to the agent, which can relay it to the user. Degraded success — not an error response.
|
|
289
|
-
|
|
290
|
-
### Observability
|
|
291
|
-
|
|
292
|
-
- `[memory-rank] candidates=N (requested pool=M, limit=L)` — on every call
|
|
293
|
-
- `[memory-rank] calling haiku (candidates=N)` — before API call
|
|
294
|
-
- `[memory-rank] [<accountId>] structured-output ok stop-reason=<r> output-tokens=<n>` — per-call surface naming the structured tool-use path. `stop_reason=tool_use` on the happy path; `max_tokens` indicates a structurally-truncated `tool_use.input` that the post-validator either drops or escalates.
|
|
295
|
-
- `[memory-rank] haiku ok (ranked=N, hallucinated=M)` — after successful ranking
|
|
296
|
-
- `[memory-rank] ERROR reason="..."` — when ranking fails (the classifier-error-rename fix — was `fallback reason="..."`). Schema-violating `tool_use.input` lands here as `tool_use input failed schema` instead of the pre-structured-output `malformed JSON` / `response-truncated` strings.
|
|
297
|
-
|
|
298
235
|
---
|
|
299
236
|
|
|
300
237
|
## Reports — durable workflow output (Task 332)
|
|
@@ -414,7 +351,7 @@ When both `KNOWLEDGE.md` and `KNOWLEDGE-SUMMARY.md` exist, the server compares m
|
|
|
414
351
|
|
|
415
352
|
### Admin agent path
|
|
416
353
|
|
|
417
|
-
The admin agent runs via Claude Code CLI, which manages its own system prompt assembly. Knowledge reaches the admin agent through MCP tools — `memory-search`
|
|
354
|
+
The admin agent runs via Claude Code CLI, which manages its own system prompt assembly. Knowledge reaches the admin agent through MCP tools — `memory-search` is the read-path entry point (server-side LLM ranking was removed by Task 424; the agent ranks in-turn against any criterion). The admin agent also receives session context via `loadSessionContext`, which injects:
|
|
418
355
|
|
|
419
356
|
- Recent review digest (last public chat or review digest `CreativeWork`)
|
|
420
357
|
- Open tasks (priority-ordered, capped)
|
|
@@ -54,7 +54,7 @@ Roles are installed during setup and listed when {{productName}} introduces itse
|
|
|
54
54
|
|
|
55
55
|
{{productName}} maintains a graph database (Neo4j) of everything you've told it. People, conversations, preferences, and context are stored as connected nodes. When you ask {{productName}} something, it searches this graph to retrieve relevant context before responding.
|
|
56
56
|
|
|
57
|
-
**The recording loop.** When you submit a prompt, a UserPromptSubmit hook (`pre-turn-graph-pass.sh`)
|
|
57
|
+
**The recording loop.** When you submit a prompt, a UserPromptSubmit hook (`pre-turn-graph-pass.sh`) injects a system directive into {{productName}}'s next turn, before it composes its reply. The directive instructs {{productName}} to scan your just-submitted turn for new graph-worthy content — mentions of named entities, ideas, learnings, contacts, tasks, anything the schema admits — and dispatch one `database-operator` Task per candidate write. The directive carries a skip-list of every node already written under this conversation (fetched via `GET /api/admin/post-turn-context`) so {{productName}} attaches to existing nodes by elementId instead of duplicating them. The per-write dispatches run as background work; you do not see them in the reply. {{productName}} can also dispatch `database-operator` inline at its own discretion when a write must complete before the assistant response ends. The final assistant reply of the session is not covered by the per-turn pass (no further operator prompt fires) and is picked up by the `session-end-retrospective.sh` Stop hook when you type `/end`. To disable the per-turn pass for an account, remove the `pre-turn-graph-pass.sh` UserPromptSubmit-hook entry from that account's `~/.<brand>/.claude/settings.json`; there is no toggle.
|
|
58
58
|
|
|
59
59
|
The memory graph is stored on your Pi. It never leaves your network.
|
|
60
60
|
|
|
@@ -41,8 +41,8 @@ These are enabled during onboarding and can be added or removed at any time. Som
|
|
|
41
41
|
| `notion-import` | Import a Notion workspace export (markdown + CSV) — pages, databases, hierarchy, attachments, schema-bounded relations, `@person` mentions account-filtered | Database operator |
|
|
42
42
|
| `obsidian-import` | Import an extracted Obsidian vault — pages map to `:KnowledgeDocument`, wikilinks resolve to intra-vault pages or existing entities, tags become `:DefinedTerm`, embedded images become `:DigitalDocument`. Two-phase tool (dry-run → operator disambiguation → commit). | Database operator |
|
|
43
43
|
| `x-import` | Import an X (Twitter) Basic Data Export — tweet stream renders as one chronological transcript and ingests as a single `:KnowledgeDocument` (`source='x'`); each DM `conversationId` ingests as one `:ConversationArchive` (`source='x-dm'`, keyed on `conversationIdentity`) via `conversation-archive-ingest.sh`. Mentions, replies, and quote-tweet authors resolve to `:Person` on lowercased `xHandle`; every handle and DM senderId confirms against existing nodes (no auto-create). Per-thread KD granularity and `:Post` / `:DirectMessage` labels are explicitly rejected. | Database operator |
|
|
44
|
-
| `memory/skills/conversation-archive` | Source-agnostic conversation transcript ingest. One skill for WhatsApp `_chat.txt`, Telegram, Signal, LinkedIn DMs, Zoom transcript, meeting minutes, iMessage, Slack, X DMs — `--source <enum>` selects the per-source normaliser. Single Bash entry — `bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source <enum> --owner-element-id <id> --participant-person-ids <csv> --scope <admin\|public>` — runs normalise → operator-confirms owner + every distinct sender → sessionize at gap-hours boundaries (default 12h) → classify each session
|
|
45
|
-
| `memory/skills/conversation-archive-enrich` | Phase 2 for any named `:ConversationArchive` — source-agnostic per-row insight derivation. Operator-triggered (never auto-fires on Phase 1 completion). Walks the parent's `:Section` chunks in pages via the read-only MCP tool `mcp__memory__conversation-archive-derive-insights`; surfaces high-confidence claims for per-row operator gate (`wire / skip / reject`) over four kinds — `mention`, `task`, `preference`, `observed-relationship`. Idempotent on `(elementId(chunk), kind, contentHash)` — re-runs collapse identical claims.
|
|
44
|
+
| `memory/skills/conversation-archive` | Source-agnostic conversation transcript ingest. One skill for WhatsApp `_chat.txt`, Telegram, Signal, LinkedIn DMs, Zoom transcript, meeting minutes, iMessage, Slack, X DMs — `--source <enum>` selects the per-source normaliser. Single Bash entry — `bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source <enum> --owner-element-id <id> --participant-person-ids <csv> --scope <admin\|public>` — runs normalise → operator-confirms owner + every distinct sender → sessionize at gap-hours boundaries (default 12h) → classify each session in-turn (the dispatched specialist produces topic-bounded chunk JSON from the parsed lines; the server-side `memory-classify` step was deleted in Task 424, and Task 435 finishes the driver-side cleanup) → memory-ingest with `conversationIdentity` set (writes `:ConversationArchive`), `source=<enum>`. Re-imports are delta-append. Auto-creating participants is forbidden — any sender outside the operator-confirmed closed set LOUD-FAILs with `parser-miss`. Distinct from the live `whatsapp` plugin (Baileys). | Database operator |
|
|
45
|
+
| `memory/skills/conversation-archive-enrich` | Phase 2 for any named `:ConversationArchive` — source-agnostic per-row insight derivation. Operator-triggered (never auto-fires on Phase 1 completion). Walks the parent's `:Section` chunks in pages via the read-only MCP tool `mcp__memory__conversation-archive-derive-insights`; surfaces high-confidence claims for per-row operator gate (`wire / skip / reject`) over four kinds — `mention`, `task`, `preference`, `observed-relationship`. Idempotent on `(elementId(chunk), kind, contentHash)` — re-runs collapse identical claims. Confidence floor is a hedging-avoidance instruction in the system prompt, not a numeric post-filter; per Task 424 the LLM step now runs in-turn from the dispatched specialist rather than as a separate server-side OAuth round-trip. | Database operator |
|
|
46
46
|
|
|
47
47
|
### Claude Official (marketplace)
|
|
48
48
|
|
|
@@ -13,7 +13,7 @@ export interface EmailData {
|
|
|
13
13
|
bodyPreview: string;
|
|
14
14
|
receivedAt: string;
|
|
15
15
|
accountId: string;
|
|
16
|
-
screening?: "clean" | "suspicious" | "discarded";
|
|
16
|
+
screening?: "clean" | "suspicious" | "discarded" | "unscreened";
|
|
17
17
|
screeningReason?: string;
|
|
18
18
|
promptInjectionFlag?: boolean;
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/lib/graph.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/lib/graph.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,CAAC;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOtE;AA2CD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAwCD,UAAU,WAAW;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAuK7E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,SAAS,EAAE,GACpB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBnF;AAOD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAO/B;AAOD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAoClC"}
|
|
@@ -33,7 +33,10 @@ import { loadCredentials, readPollState, updatePollState } from "../lib/credenti
|
|
|
33
33
|
import { fetchSinceUid } from "../lib/imap.js";
|
|
34
34
|
import { storeEmailMessages } from "../lib/graph.js";
|
|
35
35
|
import { closeDriver } from "../lib/neo4j.js";
|
|
36
|
-
|
|
36
|
+
// Task 424 — screening.ts deleted. Task 432 replaces this fetch script with an
|
|
37
|
+
// operator-initiated email-ingest flow; until then, every fetched email lands
|
|
38
|
+
// with screening='unscreened' so downstream consumers know classification was
|
|
39
|
+
// skipped.
|
|
37
40
|
// ---------------------------------------------------------------------------
|
|
38
41
|
// Brand-aware config directory — reads configDir from brand.json stamped at install time.
|
|
39
42
|
// No fallback: if brand.json is missing or incomplete, the platform wasn't properly installed.
|
|
@@ -165,50 +168,27 @@ async function main() {
|
|
|
165
168
|
await updatePollState(accountId, maxUid || sinceUid, uidValidity);
|
|
166
169
|
return;
|
|
167
170
|
}
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
else
|
|
190
|
-
countDiscard++;
|
|
191
|
-
emailData.push({
|
|
192
|
-
messageId: e.messageId,
|
|
193
|
-
inReplyTo: e.inReplyTo,
|
|
194
|
-
toAddresses: e.toAddresses,
|
|
195
|
-
ccAddresses: e.ccAddresses,
|
|
196
|
-
uid: e.uid,
|
|
197
|
-
uidValidity,
|
|
198
|
-
mailbox: "INBOX",
|
|
199
|
-
recipientAddress: config.agentAddress,
|
|
200
|
-
fromAddress: e.fromAddress,
|
|
201
|
-
fromName: e.fromName,
|
|
202
|
-
subject: e.subject,
|
|
203
|
-
bodyPreview: e.bodyPreview,
|
|
204
|
-
receivedAt: e.date,
|
|
205
|
-
accountId,
|
|
206
|
-
screening: storageVerdict,
|
|
207
|
-
screeningReason: screening.reason,
|
|
208
|
-
promptInjectionFlag: screening.promptInjectionRisk || undefined,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
log("INFO", `classification summary: ${countClean} clean, ${countSuspicious} suspicious, ${countDiscard} discarded`);
|
|
171
|
+
// Task 424 — per-email Haiku screening removed. Operator-initiated
|
|
172
|
+
// triage replaces it under Task 432.
|
|
173
|
+
const emailData = emails.map((e) => ({
|
|
174
|
+
messageId: e.messageId,
|
|
175
|
+
inReplyTo: e.inReplyTo,
|
|
176
|
+
toAddresses: e.toAddresses,
|
|
177
|
+
ccAddresses: e.ccAddresses,
|
|
178
|
+
uid: e.uid,
|
|
179
|
+
uidValidity,
|
|
180
|
+
mailbox: "INBOX",
|
|
181
|
+
recipientAddress: config.agentAddress,
|
|
182
|
+
fromAddress: e.fromAddress,
|
|
183
|
+
fromName: e.fromName,
|
|
184
|
+
subject: e.subject,
|
|
185
|
+
bodyPreview: e.bodyPreview,
|
|
186
|
+
receivedAt: e.date,
|
|
187
|
+
accountId,
|
|
188
|
+
screening: "unscreened",
|
|
189
|
+
screeningReason: "Task 424 — screener removed; awaiting Task 432 operator-initiated triage",
|
|
190
|
+
}));
|
|
191
|
+
log("INFO", `fetched ${emailData.length} email(s); per-email classification skipped (operator-initiated triage pending)`);
|
|
212
192
|
// Sort by receivedAt ascending so thread transcripts read chronologically
|
|
213
193
|
// (storeEmailMessage appends in input order).
|
|
214
194
|
emailData.sort((a, b) => a.receivedAt.localeCompare(b.receivedAt));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-fetch.js","sourceRoot":"","sources":["../../src/scripts/email-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzG,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAkB,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,
|
|
1
|
+
{"version":3,"file":"email-fetch.js","sourceRoot":"","sources":["../../src/scripts/email-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory",
|
|
3
|
-
"description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-
|
|
3
|
+
"description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 (`conversation-archive-derive-insights`) walks chunks of one named archive and emits per-row claim proposals for operator-gated wiring; `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships four skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks).",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Rubytech LLC"
|