@aitne/daemon 0.1.9 → 0.1.10

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 (65) hide show
  1. package/dist/api/env-writer.d.ts +1 -0
  2. package/dist/api/env-writer.js +9 -2
  3. package/dist/api/routes/agent-schedule.js +5 -1
  4. package/dist/api/routes/apple-calendar.js +4 -1
  5. package/dist/api/routes/calendar.js +12 -2
  6. package/dist/api/routes/context/path-resolve.js +6 -1
  7. package/dist/api/routes/context/permissions.js +9 -0
  8. package/dist/api/routes/dashboard/config.js +10 -0
  9. package/dist/api/routes/dashboard/oauth-google.js +5 -3
  10. package/dist/api/routes/feedback.d.ts +3 -0
  11. package/dist/api/routes/feedback.js +349 -0
  12. package/dist/api/routes/git.js +10 -3
  13. package/dist/api/routes/github.js +5 -1
  14. package/dist/api/routes/mcp.js +65 -13
  15. package/dist/api/server.js +3 -0
  16. package/dist/bootstrap/event-pipeline.js +1 -1
  17. package/dist/config.js +6 -0
  18. package/dist/core/backends/gemini-cli-core.js +13 -0
  19. package/dist/core/backends/plan-presets.js +8 -3
  20. package/dist/core/context-builder.js +149 -3
  21. package/dist/core/context-paths.d.ts +10 -0
  22. package/dist/core/context-paths.js +16 -0
  23. package/dist/core/daemon-api-cli.js +1 -1
  24. package/dist/core/dispatcher-message-handler.js +7 -0
  25. package/dist/core/dispatcher-scheduled-tasks.d.ts +41 -0
  26. package/dist/core/dispatcher-scheduled-tasks.js +267 -2
  27. package/dist/core/dispatcher.js +13 -1
  28. package/dist/core/feedback/consolidation-prep.d.ts +94 -0
  29. package/dist/core/feedback/consolidation-prep.js +242 -0
  30. package/dist/core/feedback/eviction-scorer.d.ts +81 -0
  31. package/dist/core/feedback/eviction-scorer.js +132 -0
  32. package/dist/core/feedback/lesson-format.d.ts +79 -0
  33. package/dist/core/feedback/lesson-format.js +194 -0
  34. package/dist/core/feedback/lesson-injection.d.ts +98 -0
  35. package/dist/core/feedback/lesson-injection.js +159 -0
  36. package/dist/core/feedback/lesson-merge.d.ts +51 -0
  37. package/dist/core/feedback/lesson-merge.js +88 -0
  38. package/dist/core/feedback/lesson-store-overview.d.ts +42 -0
  39. package/dist/core/feedback/lesson-store-overview.js +38 -0
  40. package/dist/core/feedback/promotion-gate.d.ts +69 -0
  41. package/dist/core/feedback/promotion-gate.js +117 -0
  42. package/dist/core/feedback/regeneralization-prep.d.ts +87 -0
  43. package/dist/core/feedback/regeneralization-prep.js +139 -0
  44. package/dist/core/feedback/scope-parser.d.ts +86 -0
  45. package/dist/core/feedback/scope-parser.js +141 -0
  46. package/dist/core/injection-policy.d.ts +82 -0
  47. package/dist/core/injection-policy.js +58 -0
  48. package/dist/core/signal-detector.d.ts +39 -1
  49. package/dist/core/signal-detector.js +277 -24
  50. package/dist/core/today-direct-writer.d.ts +59 -13
  51. package/dist/core/today-direct-writer.js +90 -13
  52. package/dist/core/wiki/wiki-fts.js +13 -6
  53. package/dist/db/feedback-signals-store.d.ts +77 -0
  54. package/dist/db/feedback-signals-store.js +144 -0
  55. package/dist/db/migrations.js +50 -0
  56. package/dist/db/schema.js +43 -6
  57. package/dist/safety/always-disallowed.d.ts +1 -1
  58. package/dist/safety/always-disallowed.js +39 -0
  59. package/dist/safety/risk-classifier.js +22 -7
  60. package/dist/services/browser-history/automation/egress-denylist.js +18 -2
  61. package/dist/services/browser-history/lifecycle/platform.js +44 -2
  62. package/dist/services/mcp/probe.js +30 -8
  63. package/dist/settings/runtime-settings.d.ts +8 -2
  64. package/dist/settings/runtime-settings.js +12 -0
  65. package/package.json +2 -2
@@ -186,6 +186,22 @@ export const ALWAYS_DISALLOWED_TOOLS = [
186
186
  "Read(~/.personal-agent/backups/**)",
187
187
  "Read(~/.personal-agent/whatsapp/auth/**)",
188
188
  "Read(~/.personal-agent/secrets/**)",
189
+ // ── Backend CLI credential files ──
190
+ // The agent's own Claude / Codex / Gemini OAuth tokens. The daemon
191
+ // reads these itself (claude-credentials-store.ts, codex-core.ts:377,
192
+ // gemini-cli-core.ts:488) to drive auth-health recovery, but the agent
193
+ // must never reach around to lift the long-lived refresh token for its
194
+ // own — or a sibling — backend and exfiltrate it through the sanctioned
195
+ // curl-to-localhost write path. On macOS the Claude token lives in the
196
+ // Keychain (covered by `~/Library/Keychains/**` above); these are the
197
+ // Linux/Windows plaintext fallback (Claude) and the all-platform
198
+ // plaintext stores (Codex `auth.json`, Gemini OAuth json).
199
+ "Read(~/.claude/.credentials.json)",
200
+ "Read(~/.claude.json)",
201
+ "Read(~/.codex/auth.json)",
202
+ "Read(~/.gemini/gemini-credentials.json)",
203
+ "Read(~/.gemini/oauth_creds.json)",
204
+ "Read(~/.config/anthropic/**)",
189
205
  // ── Secret-file writes ──
190
206
  // Kept symmetrical to the read list — an agent that can WRITE .env or
191
207
  // ~/.ssh/authorized_keys can leak via its own exfil channel even without
@@ -208,6 +224,15 @@ export const ALWAYS_DISALLOWED_TOOLS = [
208
224
  "Write(~/.personal-agent/backups/**)", "Edit(~/.personal-agent/backups/**)",
209
225
  "Write(~/.personal-agent/whatsapp/auth/**)", "Edit(~/.personal-agent/whatsapp/auth/**)",
210
226
  "Write(~/.personal-agent/secrets/**)", "Edit(~/.personal-agent/secrets/**)",
227
+ // Backend CLI credential files (symmetric twins of the read block above —
228
+ // an agent that can overwrite a token store can plant/replace credentials,
229
+ // which is strictly worse than reading them).
230
+ "Write(~/.claude/.credentials.json)", "Edit(~/.claude/.credentials.json)",
231
+ "Write(~/.claude.json)", "Edit(~/.claude.json)",
232
+ "Write(~/.codex/auth.json)", "Edit(~/.codex/auth.json)",
233
+ "Write(~/.gemini/gemini-credentials.json)", "Edit(~/.gemini/gemini-credentials.json)",
234
+ "Write(~/.gemini/oauth_creds.json)", "Edit(~/.gemini/oauth_creds.json)",
235
+ "Write(~/.config/anthropic/**)", "Edit(~/.config/anthropic/**)",
211
236
  // ── Browser-history profile directories (BROWSER_HISTORY_INTEGRATION_PLAN §11.4) ──
212
237
  // The browser-history integration's threat model assumes the agent
213
238
  // never reads raw browser profile files directly — all access goes
@@ -646,6 +671,13 @@ export function looksLikeBashSecretRead(cmd) {
646
671
  "/.personal-agent/backups/",
647
672
  "/.personal-agent/whatsapp/auth/",
648
673
  "/.personal-agent/secrets/",
674
+ // Backend CLI OAuth credential files (Claude / Codex / Gemini).
675
+ "/.claude/.credentials.json",
676
+ "/.claude.json",
677
+ "/.codex/auth.json",
678
+ "/.gemini/gemini-credentials.json",
679
+ "/.gemini/oauth_creds.json",
680
+ "/.config/anthropic/",
649
681
  ];
650
682
  if (fragments.some((f) => lc.includes(f)))
651
683
  return true;
@@ -831,6 +863,13 @@ export function looksLikeSecretPath(raw) {
831
863
  /Library\/Keychains(\/|$)/i,
832
864
  /\.local\/share\/keyrings(\/|$)/i,
833
865
  /\.personal-agent\/(backups|whatsapp\/auth|secrets)(\/|$)/i,
866
+ // Backend CLI OAuth credential files (Claude / Codex / Gemini) +
867
+ // the Anthropic config dir.
868
+ /(^|\/)\.claude\.json$/i,
869
+ /\.claude\/\.credentials\.json$/i,
870
+ /\.codex\/auth\.json$/i,
871
+ /\.gemini\/(gemini-credentials|oauth_creds)\.json$/i,
872
+ /\.config\/anthropic(\/|$)/i,
834
873
  ];
835
874
  return patterns.some((r) => r.test(p));
836
875
  }
@@ -451,6 +451,12 @@ const API_RISK = {
451
451
  "PUT /api/observations/{*}/consume": RiskTier.Autonomous,
452
452
  "PATCH /api/observations/{*}/consume": RiskTier.Autonomous,
453
453
  "DELETE /api/observations/{*}/consume": RiskTier.Autonomous,
454
+ "POST /api/feedback": RiskTier.Autonomous,
455
+ "POST /api/feedback/consume": RiskTier.Autonomous,
456
+ // Read-only lesson-store overview for the dashboard Lessons settings page
457
+ // (FEEDBACK_LEARNING_LOOP_DESIGN.md §9 Phase 5). Summarises cap utilisation
458
+ // only — lesson prose was redaction-scrubbed at capture — so Autonomous.
459
+ "GET /api/feedback/lessons": RiskTier.Autonomous,
454
460
  // ── Notification ──
455
461
  "/api/notify": RiskTier.Autonomous,
456
462
  // ── External Service Proxy ──
@@ -797,13 +803,22 @@ const API_RISK = {
797
803
  "GET /api/skill-curation/signals": RiskTier.Autonomous,
798
804
  "GET /api/skill-curation/knowledge-map": RiskTier.Autonomous,
799
805
  "GET /api/skill-curation/proposals/": RiskTier.Autonomous,
800
- // Mutation endpoints are Autonomous the optimizer agent's runToken
801
- // (HMAC, one-time, scoped to a single run) is the auth surface, enforced
802
- // inside the route. Per design §2.1 the chokepoint applies every passing
803
- // proposal atomically; there are no per-proposal approve/reject/revert
804
- // routes. The only roll-back path is the system-driven auto-revert
805
- // (`auto-revert.ts`), which never crosses the HTTP boundary.
806
- "POST /api/skill-curation/runs": RiskTier.Autonomous,
806
+ // Run minting (`POST /runs`, exact) is Approve. In production this surface
807
+ // is unused the dispatcher's `materializeOptimizerWorkdir` mints the
808
+ // runId/runToken directly and never crosses the HTTP boundary (see the
809
+ // route handler comment). Leaving it Autonomous let any Bearer-less local
810
+ // caller (incl. a prompt-injected DM agent) mint a valid optimizer token
811
+ // once curation is opted in, then drive `/proposals` to self-author skill
812
+ // overlays — a least-privilege violation. Approve confines minting to the
813
+ // dashboard/operator; the legitimate optimizer reads its token from the
814
+ // workdir preamble, not this route.
815
+ "POST /api/skill-curation/runs": RiskTier.Approve,
816
+ // The proposal chokepoint and the per-run finalize stay Autonomous — both
817
+ // are gated by the optimizer's runToken (HMAC, scoped to a single run)
818
+ // enforced inside the route, and the legitimate optimizer agent reaches
819
+ // them via curl from its session workdir (no Bearer). Per design §2.1 the
820
+ // chokepoint applies every passing proposal atomically; the only roll-back
821
+ // path is the system-driven auto-revert (`auto-revert.ts`).
807
822
  "POST /api/skill-curation/proposals": RiskTier.Autonomous,
808
823
  "POST /api/skill-curation/runs/": RiskTier.Autonomous,
809
824
  // P22 §6.1 — settings + listing surfaces consumed by the dashboard.
@@ -229,6 +229,10 @@ export const IP_DENYLIST_CIDRS = Object.freeze([
229
229
  "100.64.0.0/10",
230
230
  "224.0.0.0/4",
231
231
  "0.0.0.0/8",
232
+ // IETF protocol assignments (RFC 6890) — includes the DNS64 well-known
233
+ // host 192.0.0.171/.170 used to discover the NAT64 prefix. Not globally
234
+ // routable; no legitimate browse target lives here.
235
+ "192.0.0.0/24",
232
236
  // IPv6 equivalents
233
237
  "::1/128",
234
238
  "::/128", // IPv6 unspecified — mirrors IPv4 0.0.0.0/8; routes to ::1 as a connect target on common stacks
@@ -374,8 +378,20 @@ export function matchesCidrDenylist(ip) {
374
378
  const bits = ipv6ToBigInt(ip);
375
379
  if (bits !== null) {
376
380
  const mask96 = ((1n << 96n) - 1n) << 32n; // high 96 bits
377
- const v4MappedPrefix = 0xffffn << 32n; // ::ffff:0:0
378
- if ((bits & mask96) === v4MappedPrefix) {
381
+ const v4MappedPrefix = 0xffffn << 32n; // ::ffff:0:0/96
382
+ // NAT64 well-known prefix `64:ff9b::/96` (RFC 6052) — on NAT64/DNS64
383
+ // networks the entire IPv4 internet is reachable through this prefix,
384
+ // so `64:ff9b::a9fe:a9fe` routes to 169.254.169.254 and
385
+ // `64:ff9b::a00:1` to 10.0.0.1. We must NOT block the whole /96
386
+ // (that would break all IPv4 browsing on such networks) — instead
387
+ // decode the embedded IPv4 (low 32 bits, same position as the
388
+ // v4-mapped form) and run it through the IPv4 deny ranges, so only
389
+ // metadata/private destinations are blocked. Network-specific NAT64
390
+ // prefixes (operator-chosen /32../64) are out of scope — they aren't
391
+ // a guessable SSRF target the way the well-known prefix is.
392
+ const nat64WellKnownPrefix = 0x0064ff9bn << 96n; // 64:ff9b::/96
393
+ const prefix96 = bits & mask96;
394
+ if (prefix96 === v4MappedPrefix || prefix96 === nat64WellKnownPrefix) {
379
395
  const embedded = Number(bits & 0xffffffffn);
380
396
  const dotted = [
381
397
  (embedded >>> 24) & 255,
@@ -2,7 +2,7 @@ import { accessSync, constants, existsSync, readdirSync } from "node:fs";
2
2
  import { readlink } from "node:fs/promises";
3
3
  import { createRequire } from "node:module";
4
4
  import { homedir, release } from "node:os";
5
- import { dirname, join } from "node:path";
5
+ import { delimiter, dirname, join } from "node:path";
6
6
  import { execFile } from "node:child_process";
7
7
  import { promisify } from "node:util";
8
8
  const execFileAsync = promisify(execFile);
@@ -504,12 +504,54 @@ async function isUnixProcessRunning(binaryPath, userDataDir) {
504
504
  return false;
505
505
  }
506
506
  }
507
+ /**
508
+ * Resolve the Windows PowerShell executable defensively.
509
+ *
510
+ * This is the same `powershell.exe → pwsh.exe` probe every other PS call
511
+ * site in the codebase performs (secret-client-factory.ts:findExecutableInPath,
512
+ * doctor.mjs, scripts/lib/read-api-token.mjs). On Windows desktop SKUs the
513
+ * in-box Windows PowerShell 5.1 (`powershell.exe`) is present, but on
514
+ * minimal / headless / Server-Core / Nano hosts — or future builds where
515
+ * 5.1 has been removed — only PowerShell 7+ (`pwsh.exe`) exists, and a
516
+ * hardcoded `powershell.exe` exec throws ENOENT (which the caller's catch
517
+ * swallows, silently reporting the managed Chromium as not-running).
518
+ *
519
+ * Prefer 5.1, fall back to 7+, else keep the default so the first exec
520
+ * surfaces a clear ENOENT rather than masking a misconfigured host.
521
+ */
522
+ function resolveWindowsPowerShell() {
523
+ const pathValue = process.env.PATH ?? "";
524
+ const exts = process.env.PATHEXT?.split(";").filter(Boolean) ?? [".EXE"];
525
+ const probe = (name) => {
526
+ const hasExt = /\.[A-Za-z0-9]+$/.test(name);
527
+ for (const dir of pathValue.split(delimiter)) {
528
+ if (!dir)
529
+ continue;
530
+ const candidates = hasExt ? [name] : exts.map((e) => `${name}${e}`);
531
+ for (const c of candidates) {
532
+ try {
533
+ accessSync(join(dir, c), constants.X_OK);
534
+ return true;
535
+ }
536
+ catch {
537
+ // keep scanning
538
+ }
539
+ }
540
+ }
541
+ return false;
542
+ };
543
+ return probe("powershell.exe")
544
+ ? "powershell.exe"
545
+ : probe("pwsh.exe")
546
+ ? "pwsh.exe"
547
+ : "powershell.exe";
548
+ }
507
549
  async function isWindowsProcessRunning(binaryPath, userDataDir) {
508
550
  const escapedBinary = binaryPath.replace(/'/g, "''");
509
551
  const escapedDir = userDataDir.replace(/'/g, "''");
510
552
  const command = `Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like '*${escapedBinary}*' -and $_.CommandLine -like '*--user-data-dir=${escapedDir}*' } | Select-Object -First 1`;
511
553
  try {
512
- const { stdout } = await execFileAsync("powershell.exe", [
554
+ const { stdout } = await execFileAsync(resolveWindowsPowerShell(), [
513
555
  "-NoProfile",
514
556
  "-Command",
515
557
  command,
@@ -3,6 +3,7 @@ import { mkdir } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { toSafeErrorMessage } from "../../logging.js";
6
+ import { resolveWin32Invocation } from "../../core/backends/cli-utils.js";
6
7
  const PROBE_TIMEOUT_MS = 10_000;
7
8
  /**
8
9
  * MCP protocol version we send in `initialize`. The three official clients
@@ -93,7 +94,32 @@ async function probeStdio(server, options, timeoutMs) {
93
94
  // required arrays, but the DB row can carry `args` as null, so only that
94
95
  // path is genuinely observable from tests.
95
96
  const env = buildStdioEnv(server.envKeys, options.secrets);
96
- const child = spawn(server.command, server.args ?? [], {
97
+ // MCP stdio commands are overwhelmingly npx/uvx/pnpm launchers, which
98
+ // resolve to .cmd/.ps1 batch shims on Windows. The earlier stopgap used
99
+ // `shell: process.platform === "win32"`, which let cmd.exe re-parse
100
+ // metacharacters in the registered command/args (a corruption + injection
101
+ // surface for any DB-registered server whose command/args contain
102
+ // %VAR%/&/|/^). Instead route through the same injection-safe path
103
+ // runLineCommand uses: resolve the bare name via PATHEXT and launch a
104
+ // resolved `.cmd`/`.bat` through an explicit, hand-escaped `cmd.exe`
105
+ // wrapper with windowsVerbatimArguments. POSIX is byte-identical
106
+ // (resolveWin32Invocation is win32-only; the block below never runs, and
107
+ // windowsVerbatimArguments:false is inert there). The taskkill /T
108
+ // parent-pid walk in killTree still reaps the added cmd.exe wrapper.
109
+ let spawnCommand = server.command;
110
+ let spawnArgs = server.args ?? [];
111
+ let windowsVerbatim = false;
112
+ /* c8 ignore start — Windows-only .cmd/.bat shim resolution, untestable on POSIX CI. */
113
+ if (process.platform === "win32") {
114
+ const win = resolveWin32Invocation(server.command, server.args ?? []);
115
+ if (win) {
116
+ spawnCommand = win.command;
117
+ spawnArgs = win.args;
118
+ windowsVerbatim = win.windowsVerbatimArguments;
119
+ }
120
+ }
121
+ /* c8 ignore stop */
122
+ const child = spawn(spawnCommand, spawnArgs, {
97
123
  cwd: server.cwd ?? sandboxCwd,
98
124
  env,
99
125
  stdio: ["pipe", "pipe", "pipe"],
@@ -104,13 +130,9 @@ async function probeStdio(server, options, timeoutMs) {
104
130
  // hidden-window helps avoid a flashing console for child binaries.
105
131
  detached: process.platform !== "win32",
106
132
  windowsHide: true,
107
- // MCP stdio commands are overwhelmingly npx/uvx/pnpm launchers, which
108
- // resolve to .cmd/.ps1 batch shims on Windows; those need a shell to
109
- // launch (shell:false spawn of a bare `npx` ENOENTs). POSIX keeps
110
- // shell:false — bare npx/node resolve via PATH+exec-bit there. Same
111
- // win32-gated pattern as scripts/run-node.mjs / bin/aitne.mjs spawns;
112
- // the taskkill /T parent-pid walk above reaps the added cmd.exe wrapper.
113
- shell: process.platform === "win32",
133
+ // The cmd.exe wrapper's args are pre-escaped for cmd.exe; tell Node not
134
+ // to re-quote them. Inert/false on POSIX and the direct-.exe path.
135
+ windowsVerbatimArguments: windowsVerbatim,
114
136
  });
115
137
  let settled = false;
116
138
  const stderrBuf = [];
@@ -13,7 +13,7 @@ import { z } from "zod";
13
13
  * contract — `chmod`, `chown`, destructive `git` flags. Allow mode skips
14
14
  * these per design, Safe mode keeps them.
15
15
  */
16
- export declare const DEFAULT_DISALLOWED_TOOLS: readonly ["Bash(rm -rf *)", "Bash(rm -rf /*)", "Bash(rm -rf ~*)", "Bash(rm -rf .*)", "Bash(rm -r *)", "Bash(rm -rf*)", "Bash(rm -rv*)", "Bash(rm -ri*)", "Bash(rm -rd*)", "Bash(rm -rI*)", "Bash(rm -fr*)", "Bash(rm -vr*)", "Bash(rm -ir*)", "Bash(rm -dr*)", "Bash(rm -Ir*)", "Bash(rm -R*)", "Bash(rm -fR*)", "Bash(rm -vR*)", "Bash(rm -iR*)", "Bash(rm -dR*)", "Bash(rm -IR*)", "Bash(rm --recursive*)", "Bash(rm --force --recursive*)", "Bash(rm --recursive --force*)", "Bash(sudo *)", "Bash(doas *)", "Bash(su *)", "Bash(curl * | sh*)", "Bash(curl * | bash*)", "Bash(wget * | sh*)", "Bash(wget * | bash*)", "Bash(bash <(*)*)", "Bash(sh <(*)*)", "Bash(bash<*)", "Bash(sh<*)", "Bash(eval *)", "Bash(source *)", "Bash(security *)", "Bash(secret-tool *)", "Bash(cmdkey *)", "Bash(certutil *)", "Bash(rundll32.exe *)", "Read(.env)", "Read(.env.*)", "Read(**/.env)", "Read(**/.env.*)", "Read(id_rsa*)", "Read(id_ed25519*)", "Read(~/.ssh/**)", "Read(~/.gnupg/**)", "Read(~/.aws/**)", "Read(~/.config/gcloud/**)", "Read(~/.config/gh/hosts.yml)", "Read(~/.netrc)", "Read(~/Library/Keychains/**)", "Read(~/.local/share/keyrings/**)", "Read(~/.personal-agent/backups/**)", "Read(~/.personal-agent/whatsapp/auth/**)", "Read(~/.personal-agent/secrets/**)", "Write(.env)", "Edit(.env)", "Write(.env.*)", "Edit(.env.*)", "Write(**/.env)", "Edit(**/.env)", "Write(**/.env.*)", "Edit(**/.env.*)", "Write(id_rsa*)", "Edit(id_rsa*)", "Write(id_ed25519*)", "Edit(id_ed25519*)", "Write(~/.ssh/**)", "Edit(~/.ssh/**)", "Write(~/.gnupg/**)", "Edit(~/.gnupg/**)", "Write(~/.aws/**)", "Edit(~/.aws/**)", "Write(~/.config/gcloud/**)", "Edit(~/.config/gcloud/**)", "Write(~/.config/gh/hosts.yml)", "Edit(~/.config/gh/hosts.yml)", "Write(~/.netrc)", "Edit(~/.netrc)", "Write(~/Library/Keychains/**)", "Edit(~/Library/Keychains/**)", "Write(~/.local/share/keyrings/**)", "Edit(~/.local/share/keyrings/**)", "Write(~/.personal-agent/backups/**)", "Edit(~/.personal-agent/backups/**)", "Write(~/.personal-agent/whatsapp/auth/**)", "Edit(~/.personal-agent/whatsapp/auth/**)", "Write(~/.personal-agent/secrets/**)", "Edit(~/.personal-agent/secrets/**)", "Bash(sqlite3 *)", "Bash(cp ~/Library/Application Support/Google/Chrome/*)", "Bash(cp ~/Library/Application Support/Chromium/*)", "Bash(cp ~/Library/Application Support/Microsoft Edge/*)", "Bash(cp ~/Library/Application Support/BraveSoftware/*)", "Bash(cp ~/Library/Application Support/Comet/*)", "Bash(cp ~/Library/Application Support/Perplexity Comet/*)", "Bash(cp ~/Library/Application Support/com.openai.atlas/*)", "Bash(cp ~/.config/google-chrome/*)", "Bash(cp ~/.config/chromium/*)", "Bash(cp ~/.config/microsoft-edge/*)", "Bash(cp ~/.config/BraveSoftware/*)", "Bash(cp ~/.config/Comet/*)", "Bash(cp ~/.var/app/com.google.Chrome/*)", "Bash(cp /mnt/c/Users/*)", "Bash(curl file://*)", "Read(~/Library/Application Support/Google/Chrome/**)", "Read(~/Library/Application Support/Chromium/**)", "Read(~/Library/Application Support/Microsoft Edge/**)", "Read(~/Library/Application Support/BraveSoftware/**)", "Read(~/Library/Application Support/Comet/**)", "Read(~/Library/Application Support/Perplexity Comet/**)", "Read(~/Library/Application Support/com.openai.atlas/**)", "Read(~/.config/google-chrome/**)", "Read(~/.config/chromium/**)", "Read(~/.config/microsoft-edge/**)", "Read(~/.config/BraveSoftware/**)", "Read(~/.config/Comet/**)", "Read(~/.var/app/com.google.Chrome/**)", "Read(/mnt/c/Users/**)", "Write(~/Library/Application Support/Google/Chrome/**)", "Edit(~/Library/Application Support/Google/Chrome/**)", "Write(~/Library/Application Support/Chromium/**)", "Edit(~/Library/Application Support/Chromium/**)", "Write(~/Library/Application Support/Microsoft Edge/**)", "Edit(~/Library/Application Support/Microsoft Edge/**)", "Write(~/Library/Application Support/BraveSoftware/**)", "Edit(~/Library/Application Support/BraveSoftware/**)", "Write(~/Library/Application Support/Comet/**)", "Edit(~/Library/Application Support/Comet/**)", "Write(~/Library/Application Support/Perplexity Comet/**)", "Edit(~/Library/Application Support/Perplexity Comet/**)", "Write(~/Library/Application Support/com.openai.atlas/**)", "Edit(~/Library/Application Support/com.openai.atlas/**)", "Write(~/.config/google-chrome/**)", "Edit(~/.config/google-chrome/**)", "Write(~/.config/chromium/**)", "Edit(~/.config/chromium/**)", "Write(~/.config/microsoft-edge/**)", "Edit(~/.config/microsoft-edge/**)", "Write(~/.config/BraveSoftware/**)", "Edit(~/.config/BraveSoftware/**)", "Write(~/.config/Comet/**)", "Edit(~/.config/Comet/**)", "Write(~/.var/app/com.google.Chrome/**)", "Edit(~/.var/app/com.google.Chrome/**)", "Write(/mnt/c/Users/**)", "Edit(/mnt/c/Users/**)", "Bash(cp ~/.personal-agent/chromium-*)", "Bash(mv ~/.personal-agent/chromium-*)", "Bash(tar ~/.personal-agent/chromium-*)", "Bash(zip ~/.personal-agent/chromium-*)", "Bash(rsync ~/.personal-agent/chromium-*)", "Bash(cp $HOME/.personal-agent/chromium-*)", "Bash(mv $HOME/.personal-agent/chromium-*)", "Bash(tar $HOME/.personal-agent/chromium-*)", "Bash(zip $HOME/.personal-agent/chromium-*)", "Bash(rsync $HOME/.personal-agent/chromium-*)", "Read(~/.personal-agent/chromium-sync/**)", "Read(~/.personal-agent/chromium-automation/**)", "Read(~/.personal-agent/chromium-automation-anon/**)", "Read(~/.personal-agent/chromium-automation-auth/**)", "Read(~/.personal-agent/chromium-automation-purchase/**)", "Write(~/.personal-agent/chromium-sync/**)", "Edit(~/.personal-agent/chromium-sync/**)", "Write(~/.personal-agent/chromium-automation/**)", "Edit(~/.personal-agent/chromium-automation/**)", "Write(~/.personal-agent/chromium-automation-anon/**)", "Edit(~/.personal-agent/chromium-automation-anon/**)", "Write(~/.personal-agent/chromium-automation-auth/**)", "Edit(~/.personal-agent/chromium-automation-auth/**)", "Write(~/.personal-agent/chromium-automation-purchase/**)", "Edit(~/.personal-agent/chromium-automation-purchase/**)", "CronCreate", "CronList", "CronDelete", "RemoteTrigger", "PushNotification", "Bash(chmod *)", "Bash(chown *)", "Bash(git push --force *)", "Bash(git push -f *)", "Bash(git reset --hard *)", "Bash(git clean *)"];
16
+ export declare const DEFAULT_DISALLOWED_TOOLS: readonly ["Bash(rm -rf *)", "Bash(rm -rf /*)", "Bash(rm -rf ~*)", "Bash(rm -rf .*)", "Bash(rm -r *)", "Bash(rm -rf*)", "Bash(rm -rv*)", "Bash(rm -ri*)", "Bash(rm -rd*)", "Bash(rm -rI*)", "Bash(rm -fr*)", "Bash(rm -vr*)", "Bash(rm -ir*)", "Bash(rm -dr*)", "Bash(rm -Ir*)", "Bash(rm -R*)", "Bash(rm -fR*)", "Bash(rm -vR*)", "Bash(rm -iR*)", "Bash(rm -dR*)", "Bash(rm -IR*)", "Bash(rm --recursive*)", "Bash(rm --force --recursive*)", "Bash(rm --recursive --force*)", "Bash(sudo *)", "Bash(doas *)", "Bash(su *)", "Bash(curl * | sh*)", "Bash(curl * | bash*)", "Bash(wget * | sh*)", "Bash(wget * | bash*)", "Bash(bash <(*)*)", "Bash(sh <(*)*)", "Bash(bash<*)", "Bash(sh<*)", "Bash(eval *)", "Bash(source *)", "Bash(security *)", "Bash(secret-tool *)", "Bash(cmdkey *)", "Bash(certutil *)", "Bash(rundll32.exe *)", "Read(.env)", "Read(.env.*)", "Read(**/.env)", "Read(**/.env.*)", "Read(id_rsa*)", "Read(id_ed25519*)", "Read(~/.ssh/**)", "Read(~/.gnupg/**)", "Read(~/.aws/**)", "Read(~/.config/gcloud/**)", "Read(~/.config/gh/hosts.yml)", "Read(~/.netrc)", "Read(~/Library/Keychains/**)", "Read(~/.local/share/keyrings/**)", "Read(~/.personal-agent/backups/**)", "Read(~/.personal-agent/whatsapp/auth/**)", "Read(~/.personal-agent/secrets/**)", "Read(~/.claude/.credentials.json)", "Read(~/.claude.json)", "Read(~/.codex/auth.json)", "Read(~/.gemini/gemini-credentials.json)", "Read(~/.gemini/oauth_creds.json)", "Read(~/.config/anthropic/**)", "Write(.env)", "Edit(.env)", "Write(.env.*)", "Edit(.env.*)", "Write(**/.env)", "Edit(**/.env)", "Write(**/.env.*)", "Edit(**/.env.*)", "Write(id_rsa*)", "Edit(id_rsa*)", "Write(id_ed25519*)", "Edit(id_ed25519*)", "Write(~/.ssh/**)", "Edit(~/.ssh/**)", "Write(~/.gnupg/**)", "Edit(~/.gnupg/**)", "Write(~/.aws/**)", "Edit(~/.aws/**)", "Write(~/.config/gcloud/**)", "Edit(~/.config/gcloud/**)", "Write(~/.config/gh/hosts.yml)", "Edit(~/.config/gh/hosts.yml)", "Write(~/.netrc)", "Edit(~/.netrc)", "Write(~/Library/Keychains/**)", "Edit(~/Library/Keychains/**)", "Write(~/.local/share/keyrings/**)", "Edit(~/.local/share/keyrings/**)", "Write(~/.personal-agent/backups/**)", "Edit(~/.personal-agent/backups/**)", "Write(~/.personal-agent/whatsapp/auth/**)", "Edit(~/.personal-agent/whatsapp/auth/**)", "Write(~/.personal-agent/secrets/**)", "Edit(~/.personal-agent/secrets/**)", "Write(~/.claude/.credentials.json)", "Edit(~/.claude/.credentials.json)", "Write(~/.claude.json)", "Edit(~/.claude.json)", "Write(~/.codex/auth.json)", "Edit(~/.codex/auth.json)", "Write(~/.gemini/gemini-credentials.json)", "Edit(~/.gemini/gemini-credentials.json)", "Write(~/.gemini/oauth_creds.json)", "Edit(~/.gemini/oauth_creds.json)", "Write(~/.config/anthropic/**)", "Edit(~/.config/anthropic/**)", "Bash(sqlite3 *)", "Bash(cp ~/Library/Application Support/Google/Chrome/*)", "Bash(cp ~/Library/Application Support/Chromium/*)", "Bash(cp ~/Library/Application Support/Microsoft Edge/*)", "Bash(cp ~/Library/Application Support/BraveSoftware/*)", "Bash(cp ~/Library/Application Support/Comet/*)", "Bash(cp ~/Library/Application Support/Perplexity Comet/*)", "Bash(cp ~/Library/Application Support/com.openai.atlas/*)", "Bash(cp ~/.config/google-chrome/*)", "Bash(cp ~/.config/chromium/*)", "Bash(cp ~/.config/microsoft-edge/*)", "Bash(cp ~/.config/BraveSoftware/*)", "Bash(cp ~/.config/Comet/*)", "Bash(cp ~/.var/app/com.google.Chrome/*)", "Bash(cp /mnt/c/Users/*)", "Bash(curl file://*)", "Read(~/Library/Application Support/Google/Chrome/**)", "Read(~/Library/Application Support/Chromium/**)", "Read(~/Library/Application Support/Microsoft Edge/**)", "Read(~/Library/Application Support/BraveSoftware/**)", "Read(~/Library/Application Support/Comet/**)", "Read(~/Library/Application Support/Perplexity Comet/**)", "Read(~/Library/Application Support/com.openai.atlas/**)", "Read(~/.config/google-chrome/**)", "Read(~/.config/chromium/**)", "Read(~/.config/microsoft-edge/**)", "Read(~/.config/BraveSoftware/**)", "Read(~/.config/Comet/**)", "Read(~/.var/app/com.google.Chrome/**)", "Read(/mnt/c/Users/**)", "Write(~/Library/Application Support/Google/Chrome/**)", "Edit(~/Library/Application Support/Google/Chrome/**)", "Write(~/Library/Application Support/Chromium/**)", "Edit(~/Library/Application Support/Chromium/**)", "Write(~/Library/Application Support/Microsoft Edge/**)", "Edit(~/Library/Application Support/Microsoft Edge/**)", "Write(~/Library/Application Support/BraveSoftware/**)", "Edit(~/Library/Application Support/BraveSoftware/**)", "Write(~/Library/Application Support/Comet/**)", "Edit(~/Library/Application Support/Comet/**)", "Write(~/Library/Application Support/Perplexity Comet/**)", "Edit(~/Library/Application Support/Perplexity Comet/**)", "Write(~/Library/Application Support/com.openai.atlas/**)", "Edit(~/Library/Application Support/com.openai.atlas/**)", "Write(~/.config/google-chrome/**)", "Edit(~/.config/google-chrome/**)", "Write(~/.config/chromium/**)", "Edit(~/.config/chromium/**)", "Write(~/.config/microsoft-edge/**)", "Edit(~/.config/microsoft-edge/**)", "Write(~/.config/BraveSoftware/**)", "Edit(~/.config/BraveSoftware/**)", "Write(~/.config/Comet/**)", "Edit(~/.config/Comet/**)", "Write(~/.var/app/com.google.Chrome/**)", "Edit(~/.var/app/com.google.Chrome/**)", "Write(/mnt/c/Users/**)", "Edit(/mnt/c/Users/**)", "Bash(cp ~/.personal-agent/chromium-*)", "Bash(mv ~/.personal-agent/chromium-*)", "Bash(tar ~/.personal-agent/chromium-*)", "Bash(zip ~/.personal-agent/chromium-*)", "Bash(rsync ~/.personal-agent/chromium-*)", "Bash(cp $HOME/.personal-agent/chromium-*)", "Bash(mv $HOME/.personal-agent/chromium-*)", "Bash(tar $HOME/.personal-agent/chromium-*)", "Bash(zip $HOME/.personal-agent/chromium-*)", "Bash(rsync $HOME/.personal-agent/chromium-*)", "Read(~/.personal-agent/chromium-sync/**)", "Read(~/.personal-agent/chromium-automation/**)", "Read(~/.personal-agent/chromium-automation-anon/**)", "Read(~/.personal-agent/chromium-automation-auth/**)", "Read(~/.personal-agent/chromium-automation-purchase/**)", "Write(~/.personal-agent/chromium-sync/**)", "Edit(~/.personal-agent/chromium-sync/**)", "Write(~/.personal-agent/chromium-automation/**)", "Edit(~/.personal-agent/chromium-automation/**)", "Write(~/.personal-agent/chromium-automation-anon/**)", "Edit(~/.personal-agent/chromium-automation-anon/**)", "Write(~/.personal-agent/chromium-automation-auth/**)", "Edit(~/.personal-agent/chromium-automation-auth/**)", "Write(~/.personal-agent/chromium-automation-purchase/**)", "Edit(~/.personal-agent/chromium-automation-purchase/**)", "CronCreate", "CronList", "CronDelete", "RemoteTrigger", "PushNotification", "Bash(chmod *)", "Bash(chown *)", "Bash(git push --force *)", "Bash(git push -f *)", "Bash(git reset --hard *)", "Bash(git clean *)"];
17
17
  /**
18
18
  * Shape of a "watched git repository" — projected from the unified
19
19
  * `repositories` table by `selectGitWatchedRepos` for legacy consumers
@@ -137,6 +137,12 @@ export declare const runtimeSettingsSchema: z.ZodObject<{
137
137
  dmStalenessStrict: z.ZodDefault<z.ZodBoolean>;
138
138
  proactiveForwardChannelTimelineEnabled: z.ZodDefault<z.ZodBoolean>;
139
139
  proactiveForwardForceFreshSession: z.ZodDefault<z.ZodBoolean>;
140
+ feedbackLearningEnabled: z.ZodDefault<z.ZodBoolean>;
141
+ feedbackPromotionThreshold: z.ZodDefault<z.ZodNumber>;
142
+ feedbackLessonMaxBytesGlobal: z.ZodDefault<z.ZodNumber>;
143
+ feedbackLessonMaxBytesPerAgent: z.ZodDefault<z.ZodNumber>;
144
+ feedbackLessonStaleDays: z.ZodDefault<z.ZodNumber>;
145
+ feedbackSignalRetentionDays: z.ZodDefault<z.ZodNumber>;
140
146
  agentDisplayName: z.ZodDefault<z.ZodString>;
141
147
  character: z.ZodDefault<z.ZodString>;
142
148
  timezone: z.ZodDefault<z.ZodString>;
@@ -281,7 +287,7 @@ export declare const runtimeSettingsSchema: z.ZodObject<{
281
287
  voiceTranscriptionPrimaryLanguage: z.ZodDefault<z.ZodNullable<z.ZodString>>;
282
288
  }, z.core.$strip>;
283
289
  export type RuntimeSettings = z.infer<typeof runtimeSettingsSchema>;
284
- export declare const RUNTIME_SETTING_KEYS: readonly ["slackOwnerUserId", "telegramOwnerChatId", "discordOwnerUserId", "whatsappEnabled", "whatsappOwnerPhone", "whatsappAuthDir", "googleCalendarId", "notionDatabaseIds", "primaryVaultPath", "primaryVaultName", "externalObsidianVaultPath", "externalObsidianVaultName", "externalObsidianWatch", "gitAccounts", "advisorEnabled", "advisorModel", "enforceReadToken", "maxConcurrentSessions", "maxReactiveSessions", "delegatedProxyMaxConcurrent", "delegatedTaskModeEnabled", "delegatedTaskMaxPerDay", "delegatedTaskDefaultMaxToolCalls", "delegatedTaskDefaultMaxBudgetUsd", "delegatedTaskDefaultTimeoutMs", "delegatedTaskHeavyEnabled", "delegatedTaskStructuredOutputEnabled", "delegatedTaskSubprocessPoolEnabled", "delegatedTaskSubprocessPoolTtlSeconds", "delegatedTaskCacheEnabled", "delegatedTaskCacheTtlSeconds", "delegatedTaskCacheMaxEntries", "executeTimeoutMinutes", "sessionTimeoutDmMinutes", "sessionTimeoutChannelMinutes", "sessionTimeoutDashboardMinutes", "historyInjectionMaxMessages", "historyInjectionMaxTokens", "historyOtherSurfaceWindowMinutes", "dmStalenessStrict", "proactiveForwardChannelTimelineEnabled", "proactiveForwardForceFreshSession", "agentDisplayName", "character", "timezone", "dayBoundaryHour", "monthlyReviewEnabled", "browserTaskMaxConcurrent", "browserTaskPendingQueueTimeoutMinutes", "browserTaskRespectQuietHours", "browserTaskHostnameDenylist", "hourlyCheckEnabled", "hourlyCheckIntervalMinutes", "hourlyCheckActiveStartHour", "hourlyCheckActiveEndHour", "hourlyCheckMinObservations", "hourlyCheckStage2Enabled", "hourlyCheckHeartbeatHours", "hourlyCheckLowSignalPendingCeiling", "hourlyCheckPrePassFreshnessMinutes", "authProbeDisabled", "authPreflightFreshnessMs", "schedulePollIntervalSeconds", "maxBriefingDelayMinutes", "maxNotificationsPerHour", "maxNotificationsPerDay", "quietHoursStart", "quietHoursEnd", "batchIntervalMinutes", "primaryPlatform", "defaultNotificationPlatforms", "disallowedTools", "allowedToolsOverride", "claudeExecutionPermissionMode", "codexExecutionPermissionMode", "geminiExecutionPermissionMode", "opencodeExecutionPermissionMode", "opencodeBaseUrl", "opencodeServerUsername", "obsidianDebounceSeconds", "gitPollIntervalSeconds", "gitPushOverdueMinutes", "gitProjectUpdateDebounceMinutes", "notionPollIntervalSeconds", "calendarPollIntervalSeconds", "gmailPollIntervalSeconds", "githubPollIntervalSeconds", "browserHistoryConsentAccepted", "browserHistoryBrowserOverrides", "browserHistoryCategories", "browserHistoryRetentionDays", "browserHistorySearchQueryRetentionDays", "browserHistoryLifecycle", "browserHistoryResearchDomainAllowlist", "browserHistoryResearchDomainDenylist", "mcpAutoProbeIntervalMinutes", "delegatedProbeIntervalMinutes", "enabledMailProviders", "mailPollIntervalSeconds", "mailIdleEnabled", "mailIdleInstabilityThreshold", "mailIdleFallbackRecoveryMinutes", "mailMaxMessagesPerPoll", "mailAuthFailureRetryHours", "hourlyObservationCharBudget", "prePassMaxAttemptsPerIntegration", "prePassBackoffMs", "prePassRetryEscalationTier", "prePassFanOutConcurrency", "prePassMaxBudgetUsdPerIntegration", "prePassMaxBudgetUsdPerRoutine", "prePassRetryOnPartial", "observationSummarizerEnabled", "observationSummarizerConcurrency", "observationSummarizerMaxCallsPerMinute", "observationSummarizerQueueLimit", "observationSummarizerTimeoutMs", "vipMailSenders", "outlookDeltaPageSize", "outlookGraphConcurrency", "imapReconnectBaseMs", "imapReconnectMaxMs", "autonomousDailyCostCapUsd", "autonomousMonthlyCostCapUsd", "primaryLanguage", "vaultMode", "useReviewDossiers", "useContextIndex", "voiceTranscriptionEnabled", "voiceTranscriptionPrimaryLanguage"];
290
+ export declare const RUNTIME_SETTING_KEYS: readonly ["slackOwnerUserId", "telegramOwnerChatId", "discordOwnerUserId", "whatsappEnabled", "whatsappOwnerPhone", "whatsappAuthDir", "googleCalendarId", "notionDatabaseIds", "primaryVaultPath", "primaryVaultName", "externalObsidianVaultPath", "externalObsidianVaultName", "externalObsidianWatch", "gitAccounts", "advisorEnabled", "advisorModel", "enforceReadToken", "maxConcurrentSessions", "maxReactiveSessions", "delegatedProxyMaxConcurrent", "delegatedTaskModeEnabled", "delegatedTaskMaxPerDay", "delegatedTaskDefaultMaxToolCalls", "delegatedTaskDefaultMaxBudgetUsd", "delegatedTaskDefaultTimeoutMs", "delegatedTaskHeavyEnabled", "delegatedTaskStructuredOutputEnabled", "delegatedTaskSubprocessPoolEnabled", "delegatedTaskSubprocessPoolTtlSeconds", "delegatedTaskCacheEnabled", "delegatedTaskCacheTtlSeconds", "delegatedTaskCacheMaxEntries", "executeTimeoutMinutes", "sessionTimeoutDmMinutes", "sessionTimeoutChannelMinutes", "sessionTimeoutDashboardMinutes", "historyInjectionMaxMessages", "historyInjectionMaxTokens", "historyOtherSurfaceWindowMinutes", "dmStalenessStrict", "proactiveForwardChannelTimelineEnabled", "proactiveForwardForceFreshSession", "feedbackLearningEnabled", "feedbackPromotionThreshold", "feedbackLessonMaxBytesGlobal", "feedbackLessonMaxBytesPerAgent", "feedbackLessonStaleDays", "feedbackSignalRetentionDays", "agentDisplayName", "character", "timezone", "dayBoundaryHour", "monthlyReviewEnabled", "browserTaskMaxConcurrent", "browserTaskPendingQueueTimeoutMinutes", "browserTaskRespectQuietHours", "browserTaskHostnameDenylist", "hourlyCheckEnabled", "hourlyCheckIntervalMinutes", "hourlyCheckActiveStartHour", "hourlyCheckActiveEndHour", "hourlyCheckMinObservations", "hourlyCheckStage2Enabled", "hourlyCheckHeartbeatHours", "hourlyCheckLowSignalPendingCeiling", "hourlyCheckPrePassFreshnessMinutes", "authProbeDisabled", "authPreflightFreshnessMs", "schedulePollIntervalSeconds", "maxBriefingDelayMinutes", "maxNotificationsPerHour", "maxNotificationsPerDay", "quietHoursStart", "quietHoursEnd", "batchIntervalMinutes", "primaryPlatform", "defaultNotificationPlatforms", "disallowedTools", "allowedToolsOverride", "claudeExecutionPermissionMode", "codexExecutionPermissionMode", "geminiExecutionPermissionMode", "opencodeExecutionPermissionMode", "opencodeBaseUrl", "opencodeServerUsername", "obsidianDebounceSeconds", "gitPollIntervalSeconds", "gitPushOverdueMinutes", "gitProjectUpdateDebounceMinutes", "notionPollIntervalSeconds", "calendarPollIntervalSeconds", "gmailPollIntervalSeconds", "githubPollIntervalSeconds", "browserHistoryConsentAccepted", "browserHistoryBrowserOverrides", "browserHistoryCategories", "browserHistoryRetentionDays", "browserHistorySearchQueryRetentionDays", "browserHistoryLifecycle", "browserHistoryResearchDomainAllowlist", "browserHistoryResearchDomainDenylist", "mcpAutoProbeIntervalMinutes", "delegatedProbeIntervalMinutes", "enabledMailProviders", "mailPollIntervalSeconds", "mailIdleEnabled", "mailIdleInstabilityThreshold", "mailIdleFallbackRecoveryMinutes", "mailMaxMessagesPerPoll", "mailAuthFailureRetryHours", "hourlyObservationCharBudget", "prePassMaxAttemptsPerIntegration", "prePassBackoffMs", "prePassRetryEscalationTier", "prePassFanOutConcurrency", "prePassMaxBudgetUsdPerIntegration", "prePassMaxBudgetUsdPerRoutine", "prePassRetryOnPartial", "observationSummarizerEnabled", "observationSummarizerConcurrency", "observationSummarizerMaxCallsPerMinute", "observationSummarizerQueueLimit", "observationSummarizerTimeoutMs", "vipMailSenders", "outlookDeltaPageSize", "outlookGraphConcurrency", "imapReconnectBaseMs", "imapReconnectMaxMs", "autonomousDailyCostCapUsd", "autonomousMonthlyCostCapUsd", "primaryLanguage", "vaultMode", "useReviewDossiers", "useContextIndex", "voiceTranscriptionEnabled", "voiceTranscriptionPrimaryLanguage"];
285
291
  export type RuntimeSettingKey = (typeof RUNTIME_SETTING_KEYS)[number];
286
292
  export declare const INTERNAL_RUNTIME_SETTING_KEYS: readonly ["enforceReadToken", "useReviewDossiers", "useContextIndex"];
287
293
  export type InternalRuntimeSettingKey = (typeof INTERNAL_RUNTIME_SETTING_KEYS)[number];
@@ -268,6 +268,12 @@ export const runtimeSettingsSchema = z.object({
268
268
  dmStalenessStrict: z.boolean().default(false),
269
269
  proactiveForwardChannelTimelineEnabled: z.boolean().default(true),
270
270
  proactiveForwardForceFreshSession: z.boolean().default(false),
271
+ feedbackLearningEnabled: z.boolean().default(true),
272
+ feedbackPromotionThreshold: z.number().int().min(1).max(10).default(2),
273
+ feedbackLessonMaxBytesGlobal: z.number().int().min(1024).max(32768).default(8192),
274
+ feedbackLessonMaxBytesPerAgent: z.number().int().min(512).max(16384).default(4096),
275
+ feedbackLessonStaleDays: z.number().int().min(7).max(365).default(60),
276
+ feedbackSignalRetentionDays: z.number().int().min(30).max(365).default(180),
271
277
  agentDisplayName: z.string().default(DEFAULT_AGENT_DISPLAY_NAME).refine((value) => validateAgentDisplayName(value) === null, { message: "PA_AGENT_DISPLAY_NAME must be a single line, 40 characters or fewer" }),
272
278
  /**
273
279
  * User-defined communication style / persona. See docs/design/15-character.md.
@@ -900,6 +906,12 @@ export const RUNTIME_SETTING_KEYS = [
900
906
  "dmStalenessStrict",
901
907
  "proactiveForwardChannelTimelineEnabled",
902
908
  "proactiveForwardForceFreshSession",
909
+ "feedbackLearningEnabled",
910
+ "feedbackPromotionThreshold",
911
+ "feedbackLessonMaxBytesGlobal",
912
+ "feedbackLessonMaxBytesPerAgent",
913
+ "feedbackLessonStaleDays",
914
+ "feedbackSignalRetentionDays",
903
915
  "agentDisplayName",
904
916
  "character",
905
917
  "timezone",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aitne/daemon",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Aitne daemon — long-running TypeScript service that hosts the event bus, scheduler, observers, safety layer, and HTTP API. Consumed by the `aitne` CLI; not intended for standalone use.",
5
5
  "homepage": "https://github.com/Aitne-sh/Aitne#readme",
6
6
  "bugs": {
@@ -66,7 +66,7 @@
66
66
  "telegraf": "^4.16.3",
67
67
  "tsdav": "^2.1.8",
68
68
  "zod": "^4.3.6",
69
- "@aitne/shared": "0.1.9"
69
+ "@aitne/shared": "0.1.10"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/better-sqlite3": "^7.6.13",