@aitne-sh/aitne 0.1.0
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/LICENSE +21 -0
- package/README.md +464 -0
- package/agent-assets/agent-profiles/_safety.md +26 -0
- package/agent-assets/agent-profiles/conversational.md +33 -0
- package/agent-assets/agent-profiles/docs-qa.md +24 -0
- package/agent-assets/agent-profiles/observer.md +28 -0
- package/agent-assets/agent-profiles/profile-importer.md +63 -0
- package/agent-assets/agent-profiles/proxy.md +28 -0
- package/agent-assets/agent-profiles/routine.md +16 -0
- package/agent-assets/agent-profiles/task.md +18 -0
- package/agent-assets/docs/concepts/agent-day.md +88 -0
- package/agent-assets/docs/concepts/auth-health.md +75 -0
- package/agent-assets/docs/concepts/backends-and-tiers.md +126 -0
- package/agent-assets/docs/concepts/costs-and-quotas.md +103 -0
- package/agent-assets/docs/concepts/delegated-mode.md +223 -0
- package/agent-assets/docs/concepts/memory-model.md +118 -0
- package/agent-assets/docs/concepts/observations.md +80 -0
- package/agent-assets/docs/concepts/process-keys.md +89 -0
- package/agent-assets/docs/concepts/routines.md +108 -0
- package/agent-assets/docs/concepts/safety-and-execution.md +109 -0
- package/agent-assets/docs/concepts/safety-model.md +279 -0
- package/agent-assets/docs/concepts/skills.md +100 -0
- package/agent-assets/docs/features/integrations/calendar.md +92 -0
- package/agent-assets/docs/features/integrations/git.md +95 -0
- package/agent-assets/docs/features/integrations/github.md +170 -0
- package/agent-assets/docs/features/integrations/mail.md +106 -0
- package/agent-assets/docs/features/integrations/notion.md +69 -0
- package/agent-assets/docs/features/integrations/obsidian.md +71 -0
- package/agent-assets/docs/features/lifestyle/git.md +178 -0
- package/agent-assets/docs/features/lifestyle/reading.md +93 -0
- package/agent-assets/docs/features/lifestyle/receipts.md +71 -0
- package/agent-assets/docs/features/lifestyle/travel-bookings.md +44 -0
- package/agent-assets/docs/features/lifestyle/travel-time.md +52 -0
- package/agent-assets/docs/features/memory-files/agent-journal.md +105 -0
- package/agent-assets/docs/features/memory-files/projects.md +56 -0
- package/agent-assets/docs/features/memory-files/roadmap.md +61 -0
- package/agent-assets/docs/features/memory-files/schedule.md +112 -0
- package/agent-assets/docs/features/memory-files/today.md +73 -0
- package/agent-assets/docs/features/memory-files/user-profile.md +81 -0
- package/agent-assets/docs/features/messaging/dashboard-chat.md +93 -0
- package/agent-assets/docs/features/messaging/discord.md +50 -0
- package/agent-assets/docs/features/messaging/overview.md +111 -0
- package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +69 -0
- package/agent-assets/docs/features/messaging/slack.md +51 -0
- package/agent-assets/docs/features/messaging/telegram.md +63 -0
- package/agent-assets/docs/features/messaging/whatsapp.md +48 -0
- package/agent-assets/docs/features/operations/activity-and-conversations.md +105 -0
- package/agent-assets/docs/features/operations/approvals.md +58 -0
- package/agent-assets/docs/features/operations/backend-routing.md +62 -0
- package/agent-assets/docs/features/operations/cost-tracking.md +59 -0
- package/agent-assets/docs/features/operations/notifications.md +69 -0
- package/agent-assets/docs/features/operations/quiet-hours.md +106 -0
- package/agent-assets/docs/features/operations/schedule-approaching.md +60 -0
- package/agent-assets/docs/features/routines/custom-routines.md +101 -0
- package/agent-assets/docs/features/routines/evening-review.md +81 -0
- package/agent-assets/docs/features/routines/hourly-check.md +85 -0
- package/agent-assets/docs/features/routines/monthly-review.md +65 -0
- package/agent-assets/docs/features/routines/morning-routine.md +123 -0
- package/agent-assets/docs/features/routines/weekly-review.md +70 -0
- package/agent-assets/docs/getting-started/01-what-is-this.md +192 -0
- package/agent-assets/docs/getting-started/02-first-steps.md +80 -0
- package/agent-assets/docs/getting-started/03-what-can-this-do.md +110 -0
- package/agent-assets/docs/getting-started/04-first-day.md +287 -0
- package/agent-assets/docs/glossary.md +116 -0
- package/agent-assets/docs/guides/add-a-custom-routine.md +71 -0
- package/agent-assets/docs/guides/backup-and-restore.md +54 -0
- package/agent-assets/docs/guides/change-which-model-handles-x.md +47 -0
- package/agent-assets/docs/guides/connect-a-new-mail-account.md +59 -0
- package/agent-assets/docs/guides/import-knowledge-file.md +275 -0
- package/agent-assets/docs/guides/install-and-run.md +72 -0
- package/agent-assets/docs/guides/migrate-machines.md +52 -0
- package/agent-assets/docs/guides/pause-the-agent.md +65 -0
- package/agent-assets/docs/guides/reinstall-cleanly.md +52 -0
- package/agent-assets/docs/guides/setup-wizard.md +107 -0
- package/agent-assets/docs/guides/switch-default-backend.md +60 -0
- package/agent-assets/docs/reference/api.md +51 -0
- package/agent-assets/docs/reference/cli-commands.md +121 -0
- package/agent-assets/docs/reference/config.md +74 -0
- package/agent-assets/docs/reference/disallowed-tools.md +76 -0
- package/agent-assets/docs/reference/keyboard-shortcuts.md +39 -0
- package/agent-assets/docs/reference/process-keys.md +59 -0
- package/agent-assets/docs/reference/skills.md +50 -0
- package/agent-assets/docs/troubleshooting/auth-failed.md +57 -0
- package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +55 -0
- package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +54 -0
- package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +53 -0
- package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +75 -0
- package/agent-assets/docs/troubleshooting/observation-not-detected.md +57 -0
- package/agent-assets/docs/troubleshooting/quota-exhausted.md +57 -0
- package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +75 -0
- package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +71 -0
- package/agent-assets/optimizer-skills/skill-curation/SKILL.md +108 -0
- package/agent-assets/project-doc-templates/git-repo.md +21 -0
- package/agent-assets/project-doc-templates/project.md +38 -0
- package/agent-assets/skills/attach/SKILL.md +104 -0
- package/agent-assets/skills/context/SKILL.md +257 -0
- package/agent-assets/skills/context/curation.json +37 -0
- package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +13 -0
- package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +40 -0
- package/agent-assets/skills/docs-search/SKILL.md +176 -0
- package/agent-assets/skills/external-services/SKILL.delegated.claude.md +369 -0
- package/agent-assets/skills/external-services/SKILL.delegated.codex.md +349 -0
- package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +347 -0
- package/agent-assets/skills/external-services/SKILL.md +371 -0
- package/agent-assets/skills/mail/SKILL.delegated.claude.md +284 -0
- package/agent-assets/skills/mail/SKILL.delegated.codex.md +261 -0
- package/agent-assets/skills/mail/SKILL.delegated.gemini.md +255 -0
- package/agent-assets/skills/mail/SKILL.md +313 -0
- package/agent-assets/skills/mail/references/errors.md +17 -0
- package/agent-assets/skills/mail/references/providers.md +40 -0
- package/agent-assets/skills/mail/references/query-grammar.md +24 -0
- package/agent-assets/skills/management-policy/SKILL.md +307 -0
- package/agent-assets/skills/management-policy/curation.json +13 -0
- package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +16 -0
- package/agent-assets/skills/management-task-modify/SKILL.md +202 -0
- package/agent-assets/skills/management-task-register/SKILL.md +330 -0
- package/agent-assets/skills/management-task-stop/SKILL.md +166 -0
- package/agent-assets/skills/notify/SKILL.md +196 -0
- package/agent-assets/skills/notion/SKILL.delegated.claude.md +254 -0
- package/agent-assets/skills/notion/SKILL.delegated.codex.md +195 -0
- package/agent-assets/skills/notion/SKILL.delegated.gemini.md +194 -0
- package/agent-assets/skills/notion/SKILL.md +86 -0
- package/agent-assets/skills/observations/SKILL.md +234 -0
- package/agent-assets/skills/observations/curation.json +13 -0
- package/agent-assets/skills/observations/seeds/source-namespacing.seed.json +20 -0
- package/agent-assets/skills/project-doc/SKILL.md +86 -0
- package/agent-assets/skills/project-doc/curation.json +21 -0
- package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +25 -0
- package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +20 -0
- package/agent-assets/skills/reading/SKILL.md +198 -0
- package/agent-assets/skills/reading/references/reading-taste.md +197 -0
- package/agent-assets/skills/receipts/SKILL.md +134 -0
- package/agent-assets/skills/roadmap/SKILL.md +276 -0
- package/agent-assets/skills/roadmap/curation.json +13 -0
- package/agent-assets/skills/roadmap/references/horizon-tags.md +40 -0
- package/agent-assets/skills/roadmap/references/preparation-timeline.md +47 -0
- package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +16 -0
- package/agent-assets/skills/schedule/SKILL.md +228 -0
- package/agent-assets/skills/scheduled-managed-task/SKILL.md +392 -0
- package/agent-assets/skills/today/SKILL.md +198 -0
- package/agent-assets/skills/today/curation.json +21 -0
- package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +17 -0
- package/agent-assets/skills/today/seeds/section-shape.seed.json +17 -0
- package/agent-assets/skills/travel/SKILL.md +132 -0
- package/agent-assets/skills/travel-time/SKILL.md +149 -0
- package/agent-assets/skills/user-interview/SKILL.md +323 -0
- package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +94 -0
- package/agent-assets/skills/user-profile/SKILL.md +210 -0
- package/agent-assets/skills/user-profile/curation.json +29 -0
- package/agent-assets/skills/user-profile/seeds/learned-context-format.seed.json +14 -0
- package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +53 -0
- package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +27 -0
- package/agent-assets/task-flows/dashboard.docs_qa.md +43 -0
- package/agent-assets/task-flows/default.md +11 -0
- package/agent-assets/task-flows/git.branch.created.md +25 -0
- package/agent-assets/task-flows/git.lifecycle.poll.md +52 -0
- package/agent-assets/task-flows/git.local_ahead.stale.md +34 -0
- package/agent-assets/task-flows/git.merge_to_default.md +30 -0
- package/agent-assets/task-flows/git.project.refresh_architecture.md +100 -0
- package/agent-assets/task-flows/git.project.retemplate.md +73 -0
- package/agent-assets/task-flows/git.push.detected.md +32 -0
- package/agent-assets/task-flows/git.push.force_pushed.md +36 -0
- package/agent-assets/task-flows/git.tag.created.md +24 -0
- package/agent-assets/task-flows/github.assigned.md +43 -0
- package/agent-assets/task-flows/github.pull_request.review_requested.md +57 -0
- package/agent-assets/task-flows/github.security_alert.md +45 -0
- package/agent-assets/task-flows/github.workflow_run.failed.md +57 -0
- package/agent-assets/task-flows/knowledge.import.md +161 -0
- package/agent-assets/task-flows/message.received.dm.md +142 -0
- package/agent-assets/task-flows/message.received.dm_first.md +117 -0
- package/agent-assets/task-flows/message.received.md +14 -0
- package/agent-assets/task-flows/routine.custom.md +38 -0
- package/agent-assets/task-flows/routine.evening_review.md +323 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +405 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +400 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +404 -0
- package/agent-assets/task-flows/routine.hourly_check.md +184 -0
- package/agent-assets/task-flows/routine.hourly_check.triage.md +93 -0
- package/agent-assets/task-flows/routine.monthly_review.md +250 -0
- package/agent-assets/task-flows/routine.morning_routine.md +300 -0
- package/agent-assets/task-flows/routine.morning_routine_initial.md +184 -0
- package/agent-assets/task-flows/routine.roadmap_refresh.md +275 -0
- package/agent-assets/task-flows/routine.today_refresh.md +172 -0
- package/agent-assets/task-flows/routine.user_profile_sweep.md +242 -0
- package/agent-assets/task-flows/routine.weekly_review.md +247 -0
- package/agent-assets/task-flows/schedule.approaching.md +124 -0
- package/agent-assets/task-flows/scheduled.dm.md +391 -0
- package/agent-assets/task-flows/scheduled.task.md +141 -0
- package/agent-assets/task-flows/setup.initial.md +277 -0
- package/agent-assets/task-flows/setup.update.md +53 -0
- package/agent-assets/templates/README.md +85 -0
- package/agent-assets/templates/_index.md +39 -0
- package/agent-assets/templates/_manifest.json +103 -0
- package/agent-assets/templates/agent/journal.md +10 -0
- package/agent-assets/templates/agent/profile-questions.md +74 -0
- package/agent-assets/templates/context-index.md +42 -0
- package/agent-assets/templates/dossiers/_index.md +22 -0
- package/agent-assets/templates/dossiers/evening.md +23 -0
- package/agent-assets/templates/dossiers/hourly.md +23 -0
- package/agent-assets/templates/dossiers/monthly.md +23 -0
- package/agent-assets/templates/dossiers/morning.md +23 -0
- package/agent-assets/templates/dossiers/roadmap.md +23 -0
- package/agent-assets/templates/dossiers/weekly.md +23 -0
- package/agent-assets/templates/projects/_active.base +14 -0
- package/agent-assets/templates/projects/_index.md +29 -0
- package/agent-assets/templates/roadmap.md +15 -0
- package/agent-assets/templates/routines/_index.md +20 -0
- package/agent-assets/templates/routines/evening.md +22 -0
- package/agent-assets/templates/routines/hourly.md +30 -0
- package/agent-assets/templates/routines/monthly.md +25 -0
- package/agent-assets/templates/routines/morning.md +26 -0
- package/agent-assets/templates/routines/weekly.md +23 -0
- package/agent-assets/templates/rules/_index.md +19 -0
- package/agent-assets/templates/rules/journal-export.md +41 -0
- package/agent-assets/templates/rules/journal-format.md +61 -0
- package/agent-assets/templates/rules/management.md +48 -0
- package/agent-assets/templates/rules/mcp.md +40 -0
- package/agent-assets/templates/rules/policies/_index.md +22 -0
- package/agent-assets/templates/rules/redaction.md +30 -0
- package/agent-assets/templates/today.md +13 -0
- package/agent-assets/templates/user/_index.md +16 -0
- package/agent-assets/templates/user/expertise.md +7 -0
- package/agent-assets/templates/user/goals.md +7 -0
- package/agent-assets/templates/user/people.md +7 -0
- package/agent-assets/templates/user/personal.md +7 -0
- package/agent-assets/templates/user/profile.md +28 -0
- package/agent-assets/templates/user/work.md +7 -0
- package/bin/aitne.mjs +1096 -0
- package/package.json +78 -0
- package/personal-agent.mjs +39 -0
- package/scripts/browser.mjs +99 -0
- package/scripts/check-redaction-coverage.mjs +109 -0
- package/scripts/commands/audit.mjs +309 -0
- package/scripts/commands/doctor.mjs +437 -0
- package/scripts/commands/open.mjs +40 -0
- package/scripts/commands/setup.mjs +21 -0
- package/scripts/commands/uninstall.mjs +114 -0
- package/scripts/commands/update.mjs +96 -0
- package/scripts/commands/version.mjs +62 -0
- package/scripts/commands.md +0 -0
- package/scripts/lib/sqlite-loader.mjs +49 -0
- package/scripts/message-discipline-digest.mjs +535 -0
- package/scripts/poc/google-connector-inheritance/REPORT.md +197 -0
- package/scripts/poc/google-connector-inheritance/claude-sdk-probe.mjs +79 -0
- package/scripts/remint-roadmap-ids.mjs +257 -0
- package/scripts/rm-paths.mjs +22 -0
- package/scripts/run-node.mjs +223 -0
- package/scripts/smoke-obsidian-api.mjs +166 -0
- package/scripts/start.mjs +160 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
{context}
|
|
2
|
+
|
|
3
|
+
## Hourly Observation Review — Delegated Mode (Claude connectors)
|
|
4
|
+
|
|
5
|
+
Variant of `routine.hourly_check` selected when any of Gmail /
|
|
6
|
+
Google Calendar / Notion is `delegated` on the Claude backend. The
|
|
7
|
+
corresponding direct-mode signal paths (`MailPoller` mail:lifecycle,
|
|
8
|
+
`CalendarPoller` calendar:* + `schedule.approaching` emits, `NotionPoller`
|
|
9
|
+
notion:* observations) shut off under delegation; Step 0 below restores
|
|
10
|
+
coverage by fetching the same windows via MCP tools. The rest of the
|
|
11
|
+
decision workflow is identical to the direct variant.
|
|
12
|
+
|
|
13
|
+
> **Connector mode (Claude DM)**: `<integration_modes>` carries
|
|
14
|
+
> `<key>_delegated_to="<backend>"` for delegated keys. Same-backend
|
|
15
|
+
> (`=claude`) → use `mcp__claude_ai_*` natively. Cross-backend
|
|
16
|
+
> (`=codex` / `=gemini`) → route through `POST
|
|
17
|
+
> /api/integrations/<key>/exec` with a natural-language `task` and
|
|
18
|
+
> a JSON `outputSchema`; do NOT call `mcp__claude_ai_*` for that
|
|
19
|
+
> integration. The daemon enforces allowed-tools / destructive /
|
|
20
|
+
> deniedTools / cost / audit and validates the JSON. The
|
|
21
|
+
> `/api/notion/databases` label → UUID config dump is ungated in
|
|
22
|
+
> either mode — use it before any Notion read so your `task` prose
|
|
23
|
+
> carries a concrete data-source UUID.
|
|
24
|
+
|
|
25
|
+
The "Vault policy files" block appended to this prompt includes
|
|
26
|
+
`routines/hourly.md` — your canonical check list for this cadence.
|
|
27
|
+
The "Vault review context" block includes `context-index.md` and
|
|
28
|
+
`dossiers/hourly.md`; consult it before Step 1 and update the dossier's
|
|
29
|
+
Open items / Last run before finishing. Writes to `dossiers/<flow>.md`
|
|
30
|
+
MUST preserve the existing YAML frontmatter block (`---\ntype: dossier\nowner: agent\nupdated: <date>\n---`); prefer `PATCH` with a
|
|
31
|
+
section target to mutate a single block, and when doing a `PUT` full
|
|
32
|
+
rewrite keep the frontmatter and only refresh `updated:` — writes that
|
|
33
|
+
drop the frontmatter are rejected with 422.
|
|
34
|
+
Execute each `### <label>` entry in order, skipping any whose
|
|
35
|
+
precondition does not hold. The steps below are the built-in decision
|
|
36
|
+
framework for the observation-review step; additional checks the user
|
|
37
|
+
has added to the routine file run alongside them using the same
|
|
38
|
+
routing rules.
|
|
39
|
+
|
|
40
|
+
Fetch pending user-originated observations:
|
|
41
|
+
`GET /api/observations?pending=true&actor=user&limit=20`. Obsidian /
|
|
42
|
+
Git always feed that table; Notion only in direct mode.
|
|
43
|
+
Delegated signals arrive via Step 0 below.
|
|
44
|
+
|
|
45
|
+
### Execution budget
|
|
46
|
+
Target: 5–10 turns. If you reach 15 turns, wrap up current work and log.
|
|
47
|
+
Do NOT read roadmap.md, projects/*.md, or user/*.md unless an
|
|
48
|
+
observation warrants project-state context (e.g. references a project,
|
|
49
|
+
milestone, or deliverable — not merely a file edit in a watched repo).
|
|
50
|
+
|
|
51
|
+
### Default stance — silence + idempotence
|
|
52
|
+
Most hourly runs are silent bookkeeping: consume observations, update
|
|
53
|
+
today.md, log, done. The baseline assumption for every step below is
|
|
54
|
+
that the user does NOT want another notification and does NOT want a
|
|
55
|
+
new Agent Plan row unless this run has something genuinely new to add.
|
|
56
|
+
The morning routine is authoritative for the day's plan; your job is
|
|
57
|
+
to fold in new signals, not to re-plan. Two hard rules:
|
|
58
|
+
|
|
59
|
+
- **No duplicate Agent Plan rows / schedules.** Before appending to
|
|
60
|
+
`## Agent Plan` or calling `POST /api/schedule`, run the dedup
|
|
61
|
+
pre-check in Step 4. If a matching row/schedule already exists,
|
|
62
|
+
skip and log — never add a second one.
|
|
63
|
+
- **No duplicate notifications.** Before `POST /api/notify`, run the
|
|
64
|
+
dedup pre-check in Step 8. If the same item was already notified
|
|
65
|
+
earlier today, stay silent and log.
|
|
66
|
+
|
|
67
|
+
When in doubt, stay silent and log to `## Agent Log`.
|
|
68
|
+
|
|
69
|
+
### External services are read-only this hour
|
|
70
|
+
|
|
71
|
+
This routine reads external state for context — it does not push back. While running this hourly check, do **not**:
|
|
72
|
+
|
|
73
|
+
- Create / update / archive Notion pages or change Notion schema.
|
|
74
|
+
- Send / draft / move / tag mail.
|
|
75
|
+
- Create / update / delete calendar events.
|
|
76
|
+
- Open / merge / comment on GitHub PRs or issues.
|
|
77
|
+
|
|
78
|
+
External-source signals (`mail:*`, `notion:*`, `calendar:*`, `git:*`) reach you through `<observations>` and the delegated-sync-worker rows pulled in Step 0 below. Consume them, route to `today.md` / `projects/*.md` / the `roadmap_candidate` queue per the Decision Framework, but do **not** act back on the source system through the connector or the daemon `/exec` proxy. Outbound writes against external services belong in the morning routine, evening review, or DM-reply paths — `routine.hourly_check` is a silent bookkeeping pass.
|
|
79
|
+
|
|
80
|
+
This rule applies regardless of integration mode (same-backend delegated, cross-backend delegated). It is owned by the routine, so a session whose `notion` / `mail` / `external-services` skill body was dropped under same-backend delegation (because the connector covers the surface) still inherits the constraint.
|
|
81
|
+
|
|
82
|
+
### Decision Framework
|
|
83
|
+
|
|
84
|
+
#### Step 0 — Collect delegated-mode signals (replaces lost observations)
|
|
85
|
+
|
|
86
|
+
Run this step FIRST, before fetching `/api/observations`. The
|
|
87
|
+
delegated-sync-worker (0a / 0c) and the calendar reconcile route (0b)
|
|
88
|
+
write **real** `mail:lifecycle` / `notion:<db>` / `calendar:<id>`
|
|
89
|
+
observation rows server-side, so Step 1's `/api/observations` fetch
|
|
90
|
+
already includes them; Step 7's `/api/observations/consume` call still
|
|
91
|
+
applies — there are no "synthetic, row-less" Step 0 signals after
|
|
92
|
+
Phase 5. The only Step 0 output that does NOT flow through the
|
|
93
|
+
observations table is the imminent-meeting reminder (0b → EventBus
|
|
94
|
+
`schedule.approaching`), which the daemon DMs the user directly
|
|
95
|
+
without a DB row.
|
|
96
|
+
|
|
97
|
+
**Per-substep precondition.** Each `0[abc]` substep runs only when its
|
|
98
|
+
integration is `delegated`: 0a iff `gmail="delegated"`, 0b iff
|
|
99
|
+
`google_calendar="delegated"`, 0c iff `notion="delegated"`. In `direct`
|
|
100
|
+
/ `disabled` mode the corresponding poller (MailPoller / CalendarPoller
|
|
101
|
+
/ NotionPoller) is recording observations normally — Step 1's
|
|
102
|
+
`/api/observations` call sees them. Calendar additionally restores the
|
|
103
|
+
`schedule.approaching` emit path under direct mode.
|
|
104
|
+
|
|
105
|
+
**0a. Recent Gmail (delegated worker owns the drift snapshot).**
|
|
106
|
+
When `gmail="delegated"`, the daemon's `delegated-sync-worker` polls
|
|
107
|
+
Gmail on its own cadence (~30 min default, operator-tunable) and writes
|
|
108
|
+
coalesced `mail:lifecycle` observations server-side via the
|
|
109
|
+
`integration_snapshots` (`inbox:7d`) partition. Drafts the agent
|
|
110
|
+
created or labels the agent applied within the `integration_writes` TTL
|
|
111
|
+
window are pre-tagged `actor='agent'` so Step 1's
|
|
112
|
+
`GET /api/observations?actor=user` already excludes them. **Do NOT call
|
|
113
|
+
`/api/integrations/gmail/reconcile` from this step** — the route's
|
|
114
|
+
LLM-callable allowlist excludes the gmail partition for this reason: a
|
|
115
|
+
narrow `newer_than:1d` LLM fetch posted into the worker's 7d partition
|
|
116
|
+
would classify every prior 1-7d-old thread as `deleted` and trigger
|
|
117
|
+
ghost observations on the next worker tick.
|
|
118
|
+
|
|
119
|
+
If a downstream observation references a thread you want to read for
|
|
120
|
+
deeper context (e.g. an `mail:lifecycle` row in Step 1 looks
|
|
121
|
+
actionable), branch on `gmail_delegated_to`. Cross-backend reads are
|
|
122
|
+
dispatched through `/exec` with a natural-language intent — the
|
|
123
|
+
daemon's delegate composes the right MCP primitives (Codex
|
|
124
|
+
`read_email_thread`, Gemini `search` + `get` × N, custom MCP servers,
|
|
125
|
+
etc.) so you don't have to.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
curl -s -X POST http://localhost:8321/api/integrations/gmail/exec \
|
|
129
|
+
-H 'Content-Type: application/json' \
|
|
130
|
+
-d '{
|
|
131
|
+
"task": "Fetch every message in Gmail thread <THREAD_ID>. For each return from / subject / body / timestamp. Sort ascending by timestamp.",
|
|
132
|
+
"outputSchema": { "type": "object", "required": ["messages"], "properties": { "messages": { "type": "array", "items": { "type": "object", "required": ["from","subject","body","ts"] } } } },
|
|
133
|
+
"maxToolCalls": 7,
|
|
134
|
+
"cacheable": true
|
|
135
|
+
}'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
| `gmail_delegated_to` | Routing | How |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `claude` | same-backend | `mcp__claude_ai_Gmail__get_thread(threadId="<id>")` |
|
|
141
|
+
| `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/gmail/exec` with the task prose above |
|
|
142
|
+
|
|
143
|
+
The worker's snapshot covers the actor-attribution case the legacy
|
|
144
|
+
prompt used to call out: you do NOT need to cross-check the agent
|
|
145
|
+
journal for prior agent writes; the daemon's `integration_writes` row
|
|
146
|
+
does it for you.
|
|
147
|
+
|
|
148
|
+
**0b. Calendar drift detection (replaces `calendar:*` observations AND
|
|
149
|
+
the lost `schedule.approaching` emit path).** When
|
|
150
|
+
`google_calendar="delegated"`, branch on `google_calendar_delegated_to`,
|
|
151
|
+
run TWO fetches against the connector, and POST each result to the
|
|
152
|
+
daemon's reconcile chokepoint. The chokepoint computes the structural
|
|
153
|
+
diff against the prior snapshot, fires per-change side effects
|
|
154
|
+
(observations, `routine.today_refresh` auto-schedule, roadmap-refresh
|
|
155
|
+
trigger), and returns `{diff, sideEffects}` for you to reason over.
|
|
156
|
+
Cross-backend fetches go through `/exec` with a natural-language
|
|
157
|
+
`task` — the daemon's delegate picks the right primitive
|
|
158
|
+
(`list_events` / `listEvents` / `search_events` / custom MCP) so the
|
|
159
|
+
same prose works regardless of which backend currently owns Calendar.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
curl -s -X POST http://localhost:8321/api/integrations/google_calendar/exec \
|
|
163
|
+
-H 'Content-Type: application/json' \
|
|
164
|
+
-d '{
|
|
165
|
+
"task": "List every event on the primary calendar between <timeMin> and <timeMax>. Return up to <maxResults> with id, title, start, end, attendees.",
|
|
166
|
+
"outputSchema": { "type": "object", "required": ["events"], "properties": { "events": { "type": "array", "items": { "type": "object", "required": ["id","title","start","end"] } } } },
|
|
167
|
+
"cacheable": true
|
|
168
|
+
}'
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
| `google_calendar_delegated_to` | Routing | How |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| `claude` | same-backend | `mcp__claude_ai_Google_Calendar__list_events` |
|
|
174
|
+
| `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/google_calendar/exec` with the task prose above |
|
|
175
|
+
|
|
176
|
+
**Gemini-specific Calendar flow** (when `google_calendar_delegated_to=gemini`):
|
|
177
|
+
|
|
178
|
+
| Quirk | Effect | Workaround |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| `maxResults` is silently ignored | Result set bounded only by the time window + Google's per-list default | Cross-backend curl still passes `maxResults` (claude / codex honor it); accept the wider gemini result set |
|
|
181
|
+
| Default `attendeeResponseStatus = ["accepted","tentative","needsAction"]` drops declined events | Declined meetings invisible | Pass `attendeeResponseStatus=["declined"]` or the full set explicitly when you need them |
|
|
182
|
+
|
|
183
|
+
(The previous Gemini `updated`-field gap no longer applies under
|
|
184
|
+
reconcile: the daemon hashes the normalized payload on each call and
|
|
185
|
+
detects mid-horizon edits regardless of whether the connector surfaces
|
|
186
|
+
`updated`.)
|
|
187
|
+
|
|
188
|
+
Run TWO fetches with the same call shape, swapping only the time
|
|
189
|
+
window and `maxResults`. Same-backend form (Claude shown):
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
mcp__claude_ai_Google_Calendar__list_events(
|
|
193
|
+
calendarId="primary",
|
|
194
|
+
timeMin="<...>", timeMax="<...>",
|
|
195
|
+
maxResults=<...>,
|
|
196
|
+
)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- **Fetch 1 — imminent meeting window**: `timeMin=now-15min`, `timeMax=now+60min`, `maxResults=50`.
|
|
200
|
+
- **Fetch 2 — 24-hour change-detection window**: `timeMin=now`, `timeMax=now+24h`, `maxResults=250`.
|
|
201
|
+
|
|
202
|
+
POST each result to the reconcile chokepoint. The daemon normalises
|
|
203
|
+
event payloads server-side and re-hashes them to detect drift, so pass
|
|
204
|
+
the raw connector items verbatim — no `contentHash`, no per-item
|
|
205
|
+
hashing on your side:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Fetch 1 — imminent (windowKey="primary:imminent")
|
|
209
|
+
curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
|
|
210
|
+
-H 'Content-Type: application/json' \
|
|
211
|
+
-d '{
|
|
212
|
+
"windowKey": "primary:imminent",
|
|
213
|
+
"windowMin": "<now-15min UTC ISO>",
|
|
214
|
+
"windowMax": "<now+60min UTC ISO>",
|
|
215
|
+
"fetchedAt": "<now UTC ISO>",
|
|
216
|
+
"items": [<raw event objects from Fetch 1>]
|
|
217
|
+
}'
|
|
218
|
+
|
|
219
|
+
# Fetch 2 — 24h (windowKey="primary:24h")
|
|
220
|
+
curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
|
|
221
|
+
-H 'Content-Type: application/json' \
|
|
222
|
+
-d '{
|
|
223
|
+
"windowKey": "primary:24h",
|
|
224
|
+
"windowMin": "<now UTC ISO>",
|
|
225
|
+
"windowMax": "<now+24h UTC ISO>",
|
|
226
|
+
"fetchedAt": "<now UTC ISO>",
|
|
227
|
+
"items": [<raw event objects from Fetch 2>]
|
|
228
|
+
}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Each response carries:
|
|
232
|
+
|
|
233
|
+
- `diff.created` — events new to this window-key partition since the previous reconcile.
|
|
234
|
+
- `diff.modified` — events whose normalised hash changed (start/end/summary/location/attendees moved).
|
|
235
|
+
- `diff.deleted` — events present in the prior snapshot but absent now AND still inside the queried window. Items that simply slid out of the window are pruned silently and counted under `diff.prunedOutOfWindow`; do not treat those as deletions.
|
|
236
|
+
- `diff.unchanged` — count only, no item bodies returned. Most hourly runs are mostly-unchanged.
|
|
237
|
+
- `diff.isInitialSnapshot` — `true` on the first reconcile of this window-key partition (e.g. fresh install, after a clean reinstall, or after a long downtime). Treat as "no signal": skip all per-change actions for that fetch this run; the next tick returns real diffs.
|
|
238
|
+
- `sideEffects.scheduleApproachingEmitted` — array of `eventId`s the daemon's imminent-event-scheduler already published to the EventBus (DM dispatch is in flight). Skip notifying these — re-notifying duplicates the user-facing reminder.
|
|
239
|
+
- `sideEffects.observationsWritten` — count of `observations` rows the daemon coalesced from this diff. The downstream `/api/observations` fetch in Step 1 picks them up.
|
|
240
|
+
- `sideEffects.todayRefreshScheduled` / `todayRefreshPending` — whether the daemon queued a `routine.today_refresh` (or deferred until the morning lock releases). When `true`, you should NOT also rewrite `## User Schedule` from Step 4 — the auto-refresh will own that section.
|
|
241
|
+
- `sideEffects.roadmapRefreshTriggered` — whether the daemon enqueued a roadmap-refresh because a created/modified event landed beyond the 14-day horizon.
|
|
242
|
+
|
|
243
|
+
Use the diff response for downstream decisions:
|
|
244
|
+
|
|
245
|
+
- **Imminent (Fetch 1, ≤15 min away).** The daemon's imminent-event-scheduler emits `schedule.approaching` every 60s for any snapshot row whose `start` falls in `[now, now+15min]`. **Do NOT send a duplicate `POST /api/notify` for any `eventId` listed in `sideEffects.scheduleApproachingEmitted`** — the dispatcher is already running the DM. For events NOT in that array AND NOT already covered by a `## Agent Log` `[cal] ... — reminder sent` entry within the last hour AND NOT covered by a matching Agent Plan row firing in the next 20 minutes, fold into Step 8 trigger (b) "calendar change needing same-hour attention" for at most one `POST /api/notify`. Then append a line to `## Agent Log`: `- HH:MM [cal] "<summary>" starts HH:MM — reminder sent`.
|
|
246
|
+
- **15–60 min out (Fetch 1).** Information-only; do not notify.
|
|
247
|
+
- **24-hour horizon (Fetch 2).** Treat each `diff.created` / `diff.modified` / `diff.deleted` entry as a calendar observation for Steps 1–5. The daemon already wrote the matching `observations` row (counted in `sideEffects.observationsWritten`) AND, when the change lands inside today's local-day window, scheduled `routine.today_refresh` to rewrite `## User Schedule` autonomously. **Do NOT cross-reference the Fetch 2 result with `## User Schedule` text-by-text** — `diff.deleted` carries the deletion signal that the legacy text-scan used to derive, and double-rewriting User Schedule races the auto-refresh.
|
|
248
|
+
|
|
249
|
+
If either fetch returns `diff.isInitialSnapshot === true`, log
|
|
250
|
+
`- HH:MM [delegated-sync] calendar partition <windowKey> bootstrapped (no diff this run)` to ## Agent Log and skip the per-change actions for that fetch.
|
|
251
|
+
|
|
252
|
+
**Dedup against a truncated `## Agent Log`:** if `<today>` contains
|
|
253
|
+
`[...N earlier entries omitted ...]`, a prior reminder this day may be
|
|
254
|
+
hidden. Before sending any notify from this step, issue
|
|
255
|
+
`curl -s http://localhost:8321/api/context/today` once and scan the
|
|
256
|
+
full log for the item. Do NOT skip this check — duplicate 15-min
|
|
257
|
+
reminders within the same meeting are a reported UX regression.
|
|
258
|
+
|
|
259
|
+
**0c. Recent Notion edits (delegated worker owns the drift snapshot).**
|
|
260
|
+
When `notion="delegated"`, the daemon's `delegated-sync-worker` polls
|
|
261
|
+
Notion on its own cadence (~60 min default) and writes coalesced
|
|
262
|
+
`notion:<parentDatabase>` (or `notion:lifecycle` for workspace-rooted
|
|
263
|
+
pages) observations server-side via the `integration_snapshots`
|
|
264
|
+
(`recently_updated`) partition. The daemon hashes each page on
|
|
265
|
+
`{title, lastEditedTime, parentDatabase, propertiesSummaryHash,
|
|
266
|
+
relationsHash}`, so a property-only edit surfaces as `modified` even
|
|
267
|
+
without a body fetch. Pages the agent wrote within the
|
|
268
|
+
`integration_writes` TTL window are pre-tagged `actor='agent'` so Step
|
|
269
|
+
1's `GET /api/observations?actor=user` already excludes them. **Do NOT
|
|
270
|
+
call `/api/integrations/notion/reconcile` from this step** — the
|
|
271
|
+
route's LLM-callable allowlist excludes the notion partition for this
|
|
272
|
+
reason: a narrow `created_date_range:yesterday` LLM fetch posted into
|
|
273
|
+
the worker's 7d partition would classify every prior 1-7d-old page as
|
|
274
|
+
`deleted` and trigger ghost observations on the next worker tick.
|
|
275
|
+
|
|
276
|
+
If a downstream observation references a page you want to fetch the
|
|
277
|
+
full body for (e.g. a `notion:<db>` row in Step 1 needs context for
|
|
278
|
+
routing), branch on `notion_delegated_to`. The label→UUID map is
|
|
279
|
+
ungated under delegation (`/api/notion/databases` is a config dump, no
|
|
280
|
+
Notion API call) and remains useful when an observation identifies a
|
|
281
|
+
page by database label rather than UUID:
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
curl -s http://localhost:8321/api/notion/databases
|
|
285
|
+
# → { "databases": { "tasks": "<uuid>", "projects": "<uuid>", ... } }
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
| `notion_delegated_to` | Routing | Fetch tool |
|
|
289
|
+
|-----------------------|---------|------------|
|
|
290
|
+
| `claude` | same-backend | `mcp__claude_ai_Notion__notion-fetch(id="<page-url-or-uuid>")` |
|
|
291
|
+
| `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/notion/exec` with `{"task": "Fetch Notion page <UUID> with its block tree…", "outputSchema": …, "cacheable": true}` |
|
|
292
|
+
|
|
293
|
+
**Notion delegation coverage gap** (accepted): the worker's search uses
|
|
294
|
+
`created_date_range` (no `last_edited_time` filter exists upstream), so
|
|
295
|
+
pages created more than 7 days ago but edited within the last hour can
|
|
296
|
+
fall outside the worker's window; pages whose body / title don't match
|
|
297
|
+
the worker's `"updated"` query token may rank off the first 25 results
|
|
298
|
+
even when recently edited. Direct-mode `NotionPoller` covers both. If
|
|
299
|
+
the user notices missed Notion updates, flip the integration back to
|
|
300
|
+
`direct` mode.
|
|
301
|
+
|
|
302
|
+
**0d. Log the calendar collection summary** to ## Agent Log when Step
|
|
303
|
+
0b ran: `- HH:MM [delegated-sync] calendar <M> events (<K> imminent)`.
|
|
304
|
+
The daemon's `delegated-sync-worker` records its own gmail / notion
|
|
305
|
+
audit rows in `agent_actions` (queryable via `audit --type=delegated_sync`),
|
|
306
|
+
so no prompt-side log line is needed for those. Skip this whole step
|
|
307
|
+
if `google_calendar` is `direct` / `disabled` this run.
|
|
308
|
+
|
|
309
|
+
#### Steps 1–9 — identical to the direct variant
|
|
310
|
+
|
|
311
|
+
1. Group related observations before acting. One concise update beats many small patches.
|
|
312
|
+
2. Classify each observation with a category tag: work/ folders, employer
|
|
313
|
+
repos, Notion "Work" → `[work]`; coursework, study notes → `[study]`;
|
|
314
|
+
journals, hobby repos, fitness, medical → `[personal]`; home logistics
|
|
315
|
+
→ `[home]`. Default `[personal]` when ambiguous.
|
|
316
|
+
3. Read the day-type filter on line 2 of <today>. Map categories to focus
|
|
317
|
+
dimensions per the today skill's "Category → focus-dimension mapping".
|
|
318
|
+
Drop observations whose focus is `off` and log:
|
|
319
|
+
`- HH:MM [observations] skipped <n> item(s): <category> focus off`.
|
|
320
|
+
4. Route each surviving actionable observation to the right today.md section.
|
|
321
|
+
**Before writing a new row or scheduling anything, run the dedup
|
|
322
|
+
pre-check**:
|
|
323
|
+
- Scan `<today>` `## Agent Plan` for an existing row with HH:MM
|
|
324
|
+
within ±15 min AND overlapping subject/keywords. If found → skip
|
|
325
|
+
(log `- HH:MM [observations] skipped <item>: already planned`).
|
|
326
|
+
- Scan `<today>` `## User Tasks` for the same subject. If found →
|
|
327
|
+
skip (log `skipped: already in User Tasks`).
|
|
328
|
+
- For schedule registrations, also query:
|
|
329
|
+
`GET /api/schedule?status=pending,running` AND
|
|
330
|
+
`GET /api/recurring-schedules?enabled=true`.
|
|
331
|
+
If a pending/recurring item covers the same trigger → skip.
|
|
332
|
+
|
|
333
|
+
Only after dedup clears, route the observation:
|
|
334
|
+
- New TODO for the user → append to ## User Tasks with the row shape in the
|
|
335
|
+
context skill. Derive HH:MM from (a) deadline if known, (b) proximity
|
|
336
|
+
to a related calendar event, or (c) working-hours midpoint.
|
|
337
|
+
- New proactive reminder Claude should fire → append to ## Agent Plan AND
|
|
338
|
+
register the matching POST /api/schedule in the same turn. Agent Plan rows
|
|
339
|
+
and schedule entries are always in lock-step (see skill "User Tasks vs
|
|
340
|
+
Agent Plan → The Agent Plan contract").
|
|
341
|
+
- Day-time observation (git push, Step 0a/0b/0c sync, or `notion:*`
|
|
342
|
+
observation in direct mode) → append to ## Agent Notes.
|
|
343
|
+
5. Update projects/*.md when the observation materially changes project
|
|
344
|
+
state. Do NOT write to roadmap.md from hourly — for long-horizon
|
|
345
|
+
signals that don't belong in today.md but aren't yet strong enough
|
|
346
|
+
for direct roadmap edits (e.g. a user edited a vault note mentioning
|
|
347
|
+
a trip "sometime this summer", a far-future calendar event with an
|
|
348
|
+
unclear prep window), **queue them as `roadmap_candidate`
|
|
349
|
+
observations** via POST /api/observations (observations skill). The
|
|
350
|
+
next roadmap_refresh run consumes them and decides routing; this
|
|
351
|
+
hourly flow intentionally does not load the long-term-plan taxonomy
|
|
352
|
+
at all.
|
|
353
|
+
```
|
|
354
|
+
curl -s -X POST http://localhost:8321/api/observations \
|
|
355
|
+
-H 'Content-Type: application/json' \
|
|
356
|
+
-d '{"source":"roadmap_candidate:<subkind>","ref":"<stable-ref>","changeType":"created","actor":"agent","payload":{...}}'
|
|
357
|
+
```
|
|
358
|
+
`<subkind>` examples: `travel`, `calendar`, `vault`, `dm`.
|
|
359
|
+
6. Skip noise: journal-only edits, trivial formatting, auto-generated churn,
|
|
360
|
+
already-processed agent writes, deletion of auto-generated artifacts.
|
|
361
|
+
7. Mark processed observations consumed via POST /api/observations/consume.
|
|
362
|
+
Note: Step 0b imminent-meeting reminders are emitted on the EventBus
|
|
363
|
+
(`schedule.approaching`), not the observations table — those are
|
|
364
|
+
delivered as direct DMs and have no row to consume here.
|
|
365
|
+
8. Urgency gate for POST /api/notify — the default is SILENCE. At most
|
|
366
|
+
ONE call per run, and only after the dedup pre-check passes AND one
|
|
367
|
+
of (a)(b)(c) holds with its concrete threshold:
|
|
368
|
+
|
|
369
|
+
**Dedup pre-check (mandatory — skip `/api/notify` if any hit):**
|
|
370
|
+
- `<today>` `## Agent Log` contains a `notify sent` / `DM sent` /
|
|
371
|
+
`[cal] ... — reminder sent` entry for the same item within the
|
|
372
|
+
last 4 hours.
|
|
373
|
+
- The truncation marker `[...N earlier entries omitted ...]` appears
|
|
374
|
+
in `<today>` and you cannot rule out a same-day prior notification
|
|
375
|
+
from the truncated view. In that case `GET /api/context/today`
|
|
376
|
+
once for the full log before deciding.
|
|
377
|
+
- A matching pending `POST /api/schedule/dm` or Agent Plan row is
|
|
378
|
+
already going to fire for this item within the next 2 hours
|
|
379
|
+
(prefer the planned channel — don't pre-empt it).
|
|
380
|
+
|
|
381
|
+
**Positive triggers — at least one must hold with its threshold:**
|
|
382
|
+
(a) Hard deadline ≤ 2 hours away that the agent surfaced **this
|
|
383
|
+
hour** from new input (mail, DM, observation) AND the user has
|
|
384
|
+
not yet acted on it. **Self-set deadlines, course assignments,
|
|
385
|
+
class times, and items already in `today.md` ## User Tasks do
|
|
386
|
+
NOT qualify** — they fail the awareness gate (see notify skill
|
|
387
|
+
§ Universal user-facing message discipline § Awareness gate).
|
|
388
|
+
A 6-hour deadline is NOT urgent regardless.
|
|
389
|
+
(b) Inbound DM, Gmail (from Step 0a), or calendar change (from Step
|
|
390
|
+
0b) received in the last hour that needs a same-hour reply or
|
|
391
|
+
decision from the user. This is also where a Step 0b imminent
|
|
392
|
+
meeting (≤ 15 min) cleared for notification is delivered.
|
|
393
|
+
(c) Concrete failure / blocker / conflict the user would not
|
|
394
|
+
discover in time on their own (e.g. meeting moved onto an
|
|
395
|
+
existing slot; CI flagged a deploy the user triggered).
|
|
396
|
+
|
|
397
|
+
**Never urgency triggers** (log-only, no notify): "processed N
|
|
398
|
+
observations", Agent Plan / schedule reshuffles, context-file
|
|
399
|
+
updates, routine summaries of agent activity, roadmap candidates
|
|
400
|
+
queued, observations consumed.
|
|
401
|
+
|
|
402
|
+
When in doubt, stay silent and log.
|
|
403
|
+
9. Append one line to ## Agent Log even on no-op runs (Agent Log only — do
|
|
404
|
+
not echo as final text, do not send via notify):
|
|
405
|
+
`- HH:MM [observations] reviewed N items, added X tasks / Y plan rows, skipped Z`.
|