@aitne-sh/aitne 0.1.7 → 0.1.8
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/README.md +195 -829
- package/agent-assets/agent-profiles/_safety.md +49 -17
- package/agent-assets/agent-profiles/profile-importer.md +1 -1
- package/agent-assets/agent-profiles/routine.md +4 -3
- package/agent-assets/docs/concepts/agent-day.md +6 -1
- package/agent-assets/docs/concepts/auth-health.md +10 -1
- package/agent-assets/docs/concepts/backends-and-tiers.md +74 -40
- package/agent-assets/docs/concepts/costs-and-quotas.md +25 -5
- package/agent-assets/docs/concepts/delegated-mode.md +147 -68
- package/agent-assets/docs/concepts/memory-model.md +9 -4
- package/agent-assets/docs/concepts/observations.md +13 -1
- package/agent-assets/docs/concepts/process-keys.md +20 -5
- package/agent-assets/docs/concepts/routines.md +38 -20
- package/agent-assets/docs/concepts/safety-model.md +30 -13
- package/agent-assets/docs/concepts/skills.md +12 -7
- package/agent-assets/docs/features/integrations/calendar.md +1 -1
- package/agent-assets/docs/features/integrations/git.md +2 -2
- package/agent-assets/docs/features/integrations/github.md +9 -2
- package/agent-assets/docs/features/integrations/mail.md +1 -1
- package/agent-assets/docs/features/integrations/notion.md +34 -6
- package/agent-assets/docs/features/integrations/obsidian.md +7 -2
- package/agent-assets/docs/features/lifestyle/git.md +4 -7
- package/agent-assets/docs/features/lifestyle/receipts.md +17 -2
- package/agent-assets/docs/features/lifestyle/travel-bookings.md +15 -0
- package/agent-assets/docs/features/lifestyle/travel-time.md +7 -1
- package/agent-assets/docs/features/memory-files/agent-journal.md +2 -2
- package/agent-assets/docs/features/memory-files/projects.md +6 -0
- package/agent-assets/docs/features/memory-files/roadmap.md +5 -0
- package/agent-assets/docs/features/memory-files/today.md +1 -0
- package/agent-assets/docs/features/memory-files/user-profile.md +6 -0
- package/agent-assets/docs/features/messaging/bang-commands.md +20 -10
- package/agent-assets/docs/features/messaging/discord.md +12 -1
- package/agent-assets/docs/features/messaging/overview.md +10 -7
- package/agent-assets/docs/features/messaging/slack.md +13 -1
- package/agent-assets/docs/features/messaging/telegram.md +7 -1
- package/agent-assets/docs/features/messaging/whatsapp.md +12 -1
- package/agent-assets/docs/features/operations/activity-and-conversations.md +2 -2
- package/agent-assets/docs/features/operations/approvals.md +6 -0
- package/agent-assets/docs/features/operations/backend-routing.md +7 -0
- package/agent-assets/docs/features/operations/cost-tracking.md +6 -0
- package/agent-assets/docs/features/operations/notifications.md +6 -0
- package/agent-assets/docs/features/operations/schedule-approaching.md +22 -9
- package/agent-assets/docs/features/routines/custom-routines.md +10 -4
- package/agent-assets/docs/features/routines/evening-review.md +1 -1
- package/agent-assets/docs/features/routines/hourly-check.md +1 -1
- package/agent-assets/docs/features/routines/morning-routine.md +24 -15
- package/agent-assets/docs/features/routines/weekly-review.md +38 -12
- package/agent-assets/docs/features/wiki/commands.md +11 -0
- package/agent-assets/docs/features/wiki/overview.md +13 -3
- package/agent-assets/docs/getting-started/01-what-is-this.md +32 -11
- package/agent-assets/docs/getting-started/02-first-steps.md +17 -4
- package/agent-assets/docs/getting-started/03-what-can-this-do.md +21 -11
- package/agent-assets/docs/getting-started/04-first-day.md +14 -0
- package/agent-assets/docs/glossary.md +65 -12
- package/agent-assets/docs/guides/add-a-custom-routine.md +12 -0
- package/agent-assets/docs/guides/backup-and-restore.md +16 -2
- package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +6 -0
- package/agent-assets/docs/guides/build-your-wiki.md +14 -0
- package/agent-assets/docs/guides/change-which-model-handles-x.md +7 -0
- package/agent-assets/docs/guides/connect-a-new-mail-account.md +16 -0
- package/agent-assets/docs/guides/explore-with-trace-and-connect.md +6 -0
- package/agent-assets/docs/guides/import-knowledge-file.md +11 -0
- package/agent-assets/docs/guides/install-and-run.md +20 -4
- package/agent-assets/docs/guides/maintain-wiki-health.md +6 -0
- package/agent-assets/docs/guides/migrate-machines.md +13 -1
- package/agent-assets/docs/guides/multiple-wikis-for-multiple-domains.md +9 -0
- package/agent-assets/docs/guides/pause-the-agent.md +12 -4
- package/agent-assets/docs/guides/reinstall-cleanly.md +19 -4
- package/agent-assets/docs/guides/setup-wizard.md +20 -9
- package/agent-assets/docs/guides/switch-default-backend.md +10 -1
- package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +5 -0
- package/agent-assets/docs/reference/api.md +29 -1
- package/agent-assets/docs/reference/cli-commands.md +22 -3
- package/agent-assets/docs/reference/config.md +37 -5
- package/agent-assets/docs/reference/disallowed-tools.md +13 -0
- package/agent-assets/docs/reference/keyboard-shortcuts.md +13 -0
- package/agent-assets/docs/reference/process-keys.md +70 -20
- package/agent-assets/docs/reference/skills.md +27 -9
- package/agent-assets/docs/troubleshooting/auth-failed.md +7 -2
- package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +13 -1
- package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +10 -0
- package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +11 -0
- package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +9 -4
- package/agent-assets/docs/troubleshooting/observation-not-detected.md +12 -0
- package/agent-assets/docs/troubleshooting/quota-exhausted.md +7 -1
- package/agent-assets/docs/troubleshooting/wiki-ingest-full-blocked.md +5 -0
- package/agent-assets/docs/troubleshooting/wiki-write-failed.md +5 -0
- package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +1 -1
- package/agent-assets/optimizer-skills/skill-curation/SKILL.md +2 -2
- package/agent-assets/skills/agent-actions/SKILL.md +122 -0
- package/agent-assets/skills/attach/SKILL.md +1 -2
- package/agent-assets/skills/context/SKILL.md +36 -454
- package/agent-assets/skills/context/references/api.md +220 -0
- package/agent-assets/skills/context/references/required-frontmatter.md +73 -0
- package/agent-assets/skills/context/references/snapshot-files.md +103 -0
- package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +1 -1
- package/agent-assets/skills/docs-search/SKILL.md +13 -13
- package/agent-assets/skills/external-services/SKILL.delegated.claude.md +5 -7
- package/agent-assets/skills/external-services/SKILL.delegated.codex.md +5 -7
- package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +5 -7
- package/agent-assets/skills/external-services/SKILL.md +6 -259
- package/agent-assets/skills/external-services/SKILL.native.claude.md +1 -2
- package/agent-assets/skills/external-services/SKILL.native.codex.md +1 -2
- package/agent-assets/skills/external-services/SKILL.native.gemini.md +1 -2
- package/agent-assets/skills/external-services/references/calendar-apple.md +97 -0
- package/agent-assets/skills/external-services/references/calendar-google.md +72 -0
- package/agent-assets/skills/external-services/references/calendar-outlook.md +36 -0
- package/agent-assets/skills/external-services/references/github.md +17 -0
- package/agent-assets/skills/external-services/references/obsidian.md +49 -0
- package/agent-assets/skills/external-services/references/skills-crud.md +27 -0
- package/agent-assets/skills/gmail-lifestyle/SKILL.md +224 -0
- package/agent-assets/skills/gmail-lifestyle/references/receipts-api.md +93 -0
- package/agent-assets/skills/gmail-lifestyle/references/travel-bookings-api.md +75 -0
- package/agent-assets/skills/gmail-lifestyle/references/travel-time-api.md +59 -0
- package/agent-assets/skills/mail/SKILL.delegated.claude.md +1 -1
- package/agent-assets/skills/mail/SKILL.delegated.codex.md +1 -1
- package/agent-assets/skills/mail/SKILL.delegated.gemini.md +1 -1
- package/agent-assets/skills/mail/SKILL.md +9 -114
- package/agent-assets/skills/mail/SKILL.native.claude.md +1 -1
- package/agent-assets/skills/mail/SKILL.native.codex.md +1 -1
- package/agent-assets/skills/mail/SKILL.native.gemini.md +1 -1
- package/agent-assets/skills/mail/references/api.md +108 -0
- package/agent-assets/skills/mail/references/examples.md +70 -0
- package/agent-assets/skills/mail/references/providers.md +8 -8
- package/agent-assets/skills/managed-tasks/SKILL.md +472 -0
- package/agent-assets/skills/managed-tasks/references/errors.md +70 -0
- package/agent-assets/skills/managed-tasks/references/output-path.md +75 -0
- package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +86 -0
- package/agent-assets/skills/management-policy/SKILL.md +33 -105
- package/agent-assets/skills/management-policy/references/policy-workflow.md +101 -0
- package/agent-assets/skills/notify/SKILL.md +6 -78
- package/agent-assets/skills/notify/references/priority.md +60 -0
- package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
- package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
- package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
- package/agent-assets/skills/notion/SKILL.md +6 -10
- package/agent-assets/skills/notion/SKILL.native.claude.md +1 -2
- package/agent-assets/skills/notion/SKILL.native.codex.md +1 -2
- package/agent-assets/skills/notion/SKILL.native.gemini.md +1 -2
- package/agent-assets/skills/observations/SKILL.md +1 -6
- package/agent-assets/skills/project-doc/SKILL.md +1 -5
- package/agent-assets/skills/reading/SKILL.md +2 -2
- package/agent-assets/skills/roadmap/SKILL.md +37 -135
- package/agent-assets/skills/roadmap/references/api.md +100 -0
- package/agent-assets/skills/roadmap/references/cross-check.md +73 -0
- package/agent-assets/skills/roadmap/references/migration.md +56 -0
- package/agent-assets/skills/roadmap/references/preparation-timeline.md +2 -2
- package/agent-assets/skills/schedule/SKILL.md +52 -88
- package/agent-assets/skills/schedule/references/batch.md +93 -0
- package/agent-assets/skills/schedule/references/errors.md +214 -0
- package/agent-assets/skills/schedule/references/model-selection.md +96 -0
- package/agent-assets/skills/schedule/references/recurrence-rule.md +86 -0
- package/agent-assets/skills/schedule/references/recurring.md +185 -0
- package/agent-assets/skills/scheduled-managed-task/SKILL.md +13 -15
- package/agent-assets/skills/today/SKILL.md +27 -57
- package/agent-assets/skills/today/references/agent-plan-lifecycle.md +113 -0
- package/agent-assets/skills/user-interview/SKILL.md +12 -59
- package/agent-assets/skills/user-interview/references/op-briefing.md +51 -0
- package/agent-assets/skills/user-interview/references/op-morning.md +59 -0
- package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +1 -1
- package/agent-assets/skills/user-profile/SKILL.md +43 -63
- package/agent-assets/skills/user-profile/references/character-preferences.md +83 -0
- package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +28 -0
- package/agent-assets/skills/wiki/wiki-ask/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-compile/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-connect/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-graduate/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-ingest/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-lint/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-trace/SKILL.md +0 -1
- package/agent-assets/skills/wiki/wiki-vault-rules/SKILL.md +0 -1
- package/agent-assets/system-prompts/routine-fetch-window.md +68 -0
- package/agent-assets/system-prompts/skill-index-instruction.md +26 -0
- package/agent-assets/task-flows/_partials/calendar-acquire.google_calendar.md +18 -11
- package/agent-assets/task-flows/_partials/calendar-acquire.outlook_calendar.md +16 -9
- package/agent-assets/task-flows/_partials/capture-user-info.md +24 -0
- package/agent-assets/task-flows/_partials/confirm-subflow.md +68 -0
- package/agent-assets/task-flows/_partials/dm-intent.long-horizon.md +35 -0
- package/agent-assets/task-flows/_partials/dm-intent.project.md +391 -0
- package/agent-assets/task-flows/_partials/mail-acquire.gmail.md +20 -11
- package/agent-assets/task-flows/_partials/mail-acquire.outlook_mail.md +17 -9
- package/agent-assets/task-flows/_partials/notion-acquire.notion.md +18 -12
- package/agent-assets/task-flows/knowledge.import.md +1 -1
- package/agent-assets/task-flows/message.received.dm.md +13 -15
- package/agent-assets/task-flows/message.received.dm_first.md +10 -14
- package/agent-assets/task-flows/routine.custom.md +3 -1
- package/agent-assets/task-flows/routine.evening_review.md +39 -163
- package/agent-assets/task-flows/routine.fetch_window.md +17 -12
- package/agent-assets/task-flows/routine.hourly_check.md +16 -8
- package/agent-assets/task-flows/routine.hourly_check.triage.md +1 -1
- package/agent-assets/task-flows/routine.monthly_review.md +46 -4
- package/agent-assets/task-flows/routine.morning_routine_journal.md +113 -0
- package/agent-assets/task-flows/routine.morning_routine_today.md +673 -0
- package/agent-assets/task-flows/routine.roadmap_refresh.md +60 -15
- package/agent-assets/task-flows/routine.user_profile_sweep.md +9 -10
- package/agent-assets/task-flows/routine.weekly_review.md +285 -70
- package/agent-assets/task-flows/scheduled.dm.md +8 -8
- package/agent-assets/task-flows/scheduled.task.md +5 -5
- package/agent-assets/task-flows/setup.initial.md +165 -245
- package/agent-assets/task-flows/wiki.ingest_url.md +1 -1
- package/agent-assets/templates/_manifest.json +7 -7
- package/agent-assets/templates/dossiers/_index.md +1 -1
- package/agent-assets/templates/rules/journal-format.md +145 -38
- package/agent-assets/templates/user/expertise.md +4 -2
- package/agent-assets/templates/user/goals.md +4 -2
- package/agent-assets/templates/user/people.md +8 -2
- package/agent-assets/templates/user/personal.md +4 -2
- package/agent-assets/templates/user/work.md +4 -2
- package/bin/aitne.mjs +8 -1
- package/package.json +4 -4
- package/scripts/commands/doctor.mjs +52 -0
- package/scripts/commands/run-now.mjs +202 -0
- package/scripts/commands/verify.mjs +264 -0
- package/agent-assets/docs/features/routines/monthly-review.md +0 -65
- package/agent-assets/skills/management-task-modify/SKILL.md +0 -203
- package/agent-assets/skills/management-task-register/SKILL.md +0 -330
- package/agent-assets/skills/management-task-stop/SKILL.md +0 -166
- package/agent-assets/skills/receipts/SKILL.md +0 -134
- package/agent-assets/skills/travel/SKILL.md +0 -132
- package/agent-assets/skills/travel-time/SKILL.md +0 -158
- package/agent-assets/task-flows/routine.morning_routine.md +0 -322
- package/agent-assets/task-flows/routine.morning_routine_initial.md +0 -204
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
---
|
|
2
|
+
# dm-intent.project — Project DM-intent detection decision tree.
|
|
3
|
+
# Included from: message.received.dm.md (Step 4), message.received.dm_first.md
|
|
4
|
+
# (Step 4). The `context` skill is the WRITER (PUT / PATCH / archive); this
|
|
5
|
+
# partial carries the decision tree that the DM dispatcher applies before
|
|
6
|
+
# the writer runs.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Referenced from `message.received.dm`, `message.received.dm_first`, and
|
|
10
|
+
any other handler that wants to record project-state changes from a DM.
|
|
11
|
+
Identifies user messages about a named, ongoing workstream so the
|
|
12
|
+
handler can route them into `projects/<slug>.md` instead of letting the
|
|
13
|
+
fact bleed into the model's own scratch memory.
|
|
14
|
+
|
|
15
|
+
This block mirrors the shape of the "Long-horizon DM-intent detection"
|
|
16
|
+
partial so future durable-state domains (e.g. git, personal plans)
|
|
17
|
+
can copy the same pattern into their own skills.
|
|
18
|
+
|
|
19
|
+
**Signals (positive):**
|
|
20
|
+
- Named project + state verb: *"Project Alpha is now in review"*,
|
|
21
|
+
*"the migration project hit its first milestone"*, *"blocked on Y
|
|
22
|
+
for the reporting overhaul"*.
|
|
23
|
+
- New-project shape: *"let's start a project for X"*, *"I'm kicking
|
|
24
|
+
off …"*, *"track this as a project"*, *"add a new project"*. The
|
|
25
|
+
same shape in any other language counts — match on intent, not
|
|
26
|
+
surface vocabulary.
|
|
27
|
+
- Status / progress / blocker / decision phrasing tied to a
|
|
28
|
+
recognizable workstream the user has named before.
|
|
29
|
+
|
|
30
|
+
**Not signals — route elsewhere:**
|
|
31
|
+
- One-off task with a single deadline (*"remind me at 3pm to call …"*)
|
|
32
|
+
→ `schedule` skill.
|
|
33
|
+
- Long-horizon plan with a date or horizon but no named workstream
|
|
34
|
+
(*"going to Tokyo next month"*) → `roadmap` skill ("Long-horizon
|
|
35
|
+
DM-intent detection"). When BOTH apply (a project with a dated
|
|
36
|
+
milestone), run both flows — see "Tie-breakers" below.
|
|
37
|
+
- Pure user fact / preference (*"I work on the platform team"*) →
|
|
38
|
+
`user-profile` skill.
|
|
39
|
+
- Durable management rule with a recurring cadence (*"every morning,
|
|
40
|
+
X"*) → `management-policy` skill.
|
|
41
|
+
|
|
42
|
+
**Decision tree:**
|
|
43
|
+
|
|
44
|
+
1. **Existing or new? (Plus decline-marker pre-check.)**
|
|
45
|
+
- `GET /api/context/list/projects` and match the user's wording
|
|
46
|
+
against returned filenames (slug stem) and, if needed, against
|
|
47
|
+
the H1 / title of each candidate via
|
|
48
|
+
`GET /api/context/projects/<slug>`. If multiple candidates
|
|
49
|
+
match, prefer the one with the closest slug stem; if still
|
|
50
|
+
ambiguous, ask *"is this for `<slug-A>` or `<slug-B>`?"* before
|
|
51
|
+
writing.
|
|
52
|
+
- **Decline-marker pre-check (Goal 3 — never ask twice).** Before
|
|
53
|
+
classifying a no-match as new, compute the candidate slug and
|
|
54
|
+
read `agent/journal.md ## Declined Intents`:
|
|
55
|
+
```bash
|
|
56
|
+
curl -s "http://localhost:8321/api/context/agent/journal" \
|
|
57
|
+
| jq -r '.content // ""' \
|
|
58
|
+
| awk '/^## Declined Intents/{f=1;next} f && /^## /{exit} f'
|
|
59
|
+
```
|
|
60
|
+
(404 from the GET means the journal file does not yet exist →
|
|
61
|
+
no marker can exist → treat as "no marker present" and continue
|
|
62
|
+
to the no-match path.) If any line under that section contains
|
|
63
|
+
`create_project:<slug>` (the dedup_key shape — see §"Reply
|
|
64
|
+
branches" below), the user previously declined this exact
|
|
65
|
+
intent. The default behaviour is **skip silently** — do NOT
|
|
66
|
+
re-ask, do NOT schedule a confirm, do NOT write.
|
|
67
|
+
|
|
68
|
+
**Reversal-signal carve-out (rare).** If the user's current DM
|
|
69
|
+
contains an unambiguous reversal phrase for this exact intent,
|
|
70
|
+
treat the DM as a fresh affirmative. Run the
|
|
71
|
+
§"Decline-marker reversal" recipe below (remove the matching
|
|
72
|
+
marker line, then PUT the project file per Step 4). Pattern
|
|
73
|
+
shape: explicit verb of resumption + the topic + action
|
|
74
|
+
consent. Match on intent, not surface vocabulary — any
|
|
75
|
+
language qualifies.
|
|
76
|
+
|
|
77
|
+
Counts as reversal (do the recipe):
|
|
78
|
+
- *"actually let's start that LA project after all"*
|
|
79
|
+
- *"go ahead and track LA PM"*
|
|
80
|
+
- *"changed my mind, let's do it"*
|
|
81
|
+
|
|
82
|
+
Does NOT count as reversal (skip silently, marker stays):
|
|
83
|
+
- bare re-mention without an action verb: *"still thinking
|
|
84
|
+
about LA PM"*, *"made a bit of progress on LA"*
|
|
85
|
+
- status update on the topic without consent: *"LA classes
|
|
86
|
+
started"*, *"midterm was hard"*
|
|
87
|
+
- ambiguous "maybe" / non-commitment: *"maybe I'll track it
|
|
88
|
+
eventually"*, *"might revisit this later"*
|
|
89
|
+
|
|
90
|
+
The examples are English for prompt clarity only; recognise the
|
|
91
|
+
same shapes in any language the user writes in. Bias
|
|
92
|
+
conservative — when in doubt, skip silently and wait for a
|
|
93
|
+
clearer signal. A missed reversal costs nothing (user can
|
|
94
|
+
re-state explicitly); a false reversal silently overwrites a
|
|
95
|
+
deliberate "no".
|
|
96
|
+
|
|
97
|
+
2. **Existing match → append a dated bullet.** Default section is
|
|
98
|
+
`## Log` (or whatever section the file already uses for time-ordered
|
|
99
|
+
entries — match existing files' conventions; do not invent a parallel
|
|
100
|
+
section if one already exists).
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
curl -s -X PATCH http://localhost:8321/api/context/projects/<slug> \
|
|
104
|
+
-H 'Content-Type: application/json' \
|
|
105
|
+
-d '{"section": "log", "mode": "append", "content": "- 2026-04-30: <one-line summary>"}'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If the PATCH responds with `{"error": "section_not_found"}` (the
|
|
109
|
+
file pre-dates the convention), retry once with `mode:
|
|
110
|
+
"append_to_file"` and include the section header in the content:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -s -X PATCH http://localhost:8321/api/context/projects/<slug> \
|
|
114
|
+
-H 'Content-Type: application/json' \
|
|
115
|
+
-d '{"mode": "append_to_file", "content": "\n## Log\n- 2026-04-30: <one-line summary>"}'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For a **state change** (e.g. `active → on-hold`, milestone reached),
|
|
119
|
+
also rebuild the frontmatter `state` field via GET-merge-PUT — the
|
|
120
|
+
frontmatter parser is line-scalar so per-key PATCH is not available.
|
|
121
|
+
Bump `updated` to today on the same write.
|
|
122
|
+
|
|
123
|
+
**Cross-path cancellation.** If this existing-match write resolves
|
|
124
|
+
what was previously a "no match" → confirm path (i.e. a confirm row
|
|
125
|
+
was scheduled and the user has since clarified the project is the
|
|
126
|
+
same as an existing one), delete the pending confirm rows before
|
|
127
|
+
completing the write. See §"Reply branches" below.
|
|
128
|
+
|
|
129
|
+
3. **No match — schedule a confirm DM (do NOT ask inline).**
|
|
130
|
+
The universal "no topic-pivoting trailing question" rule in
|
|
131
|
+
`message.received.dm{,_first}.md` Step 3 forbids appending a
|
|
132
|
+
project-creation ask to a content-rich reply. Instead of inline
|
|
133
|
+
"Create project `<slug>`? (yes/no)" and waiting on the same DM
|
|
134
|
+
turn, schedule a `confirm:` sub-flow row for a natural follow-up
|
|
135
|
+
moment (default: next morning briefing slot, or `<current_time>
|
|
136
|
+
+ 4h` if the DM landed well before quiet hours):
|
|
137
|
+
|
|
138
|
+
**a. Pre-flight idempotency check.** Compute the dedup_key
|
|
139
|
+
`create_project:<slug>` and ensure no row is already pending
|
|
140
|
+
(Goal 3):
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
curl -s "http://localhost:8321/api/schedule?status=pending,running" \
|
|
144
|
+
| jq --arg k "create_project:<slug>" \
|
|
145
|
+
'[.items[] | select(.taskContext.confirm_dedup_key == $k)] | length'
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If the count is `≥ 1`, a confirm is already queued — do NOT
|
|
149
|
+
schedule a duplicate. Log to today.md `## Agent Log` and proceed:
|
|
150
|
+
```
|
|
151
|
+
- HH:MM [confirm] skipped create_project:<slug>: row already pending
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**b. Schedule the confirm.** Use the shape documented in
|
|
155
|
+
`scheduled.dm.md` §"Confirmation follow-up":
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
curl -s -X POST http://localhost:8321/api/schedule \
|
|
159
|
+
-H 'Content-Type: application/json' \
|
|
160
|
+
-d @- <<JSON
|
|
161
|
+
{
|
|
162
|
+
"time": "<next morning-briefing slot, or current_time + 4h — ISO 8601 with offset>",
|
|
163
|
+
"taskType": "dm_session",
|
|
164
|
+
"description": "confirm:create_project:<slug> — track <paraphrase> as a project?",
|
|
165
|
+
"tier": "medium",
|
|
166
|
+
"taskContext": {
|
|
167
|
+
"scheduledBy": "dm_handler.project_creation_gate",
|
|
168
|
+
"sub_flow": "confirm",
|
|
169
|
+
"confirm_id": "<short uuid v4 first 8 chars>",
|
|
170
|
+
"confirm_dedup_key": "create_project:<slug>",
|
|
171
|
+
"confirm_hint": "create project \"<slug>\"? (origin: <one-line paraphrase of user's DM>)",
|
|
172
|
+
"confirm_recent_window_hours": 24,
|
|
173
|
+
"confirm_attempt": 1,
|
|
174
|
+
"confirm_max_attempts": 2,
|
|
175
|
+
"confirm_defer_count": 0,
|
|
176
|
+
"confirm_max_defers": 3,
|
|
177
|
+
"confirm_decline_marker": {
|
|
178
|
+
"path": "agent/journal.md",
|
|
179
|
+
"section": "declined_intents",
|
|
180
|
+
"match": "create_project:<slug>"
|
|
181
|
+
},
|
|
182
|
+
"confirm_slot": {
|
|
183
|
+
"path": "projects/<slug>.md"
|
|
184
|
+
},
|
|
185
|
+
"importance": "low"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
JSON
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The `confirm_slot.path` (just the file path, no section / anchor)
|
|
192
|
+
makes the fire-time slot-filled probe abort if the project file
|
|
193
|
+
already exists by the time the confirm fires — covering the case
|
|
194
|
+
where the user volunteers an affirmative shape between scheduling
|
|
195
|
+
and fire.
|
|
196
|
+
|
|
197
|
+
**c. Do NOT inline-ask.** The DM reply must remain in the user's
|
|
198
|
+
thread per the universal rule. The confirm sub-flow will surface
|
|
199
|
+
the question at the next natural moment. Silently inferring a
|
|
200
|
+
slug and writing without confirmation remains forbidden.
|
|
201
|
+
|
|
202
|
+
4. **On confirmed creation → PUT the file.** Required + conventional
|
|
203
|
+
frontmatter and an H1:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
curl -s -X PUT http://localhost:8321/api/context/projects/<slug> \
|
|
207
|
+
-H 'Content-Type: application/json' \
|
|
208
|
+
-d @- <<'JSON'
|
|
209
|
+
{"content":"---\ntype: project\nslug: <slug>\nstate: active\nowner: shared\nstart: 2026-04-30\nupdated: 2026-04-30\n---\n# <Title>\n\n## Log\n- 2026-04-30: created via DM — <one-line origin>\n"}
|
|
210
|
+
JSON
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Add `due`, `stakeholders`, `next_milestone`, `tags` only when the
|
|
214
|
+
user supplied them. Do not invent values.
|
|
215
|
+
|
|
216
|
+
5. **Reply branches — how the user's response to a scheduled confirm
|
|
217
|
+
is handled.** When the confirm sub-flow fires (`scheduled.dm.md`
|
|
218
|
+
## Confirmation follow-up) and the user replies, the reply routes
|
|
219
|
+
through `message.received.dm.md` as usual; the dispatcher injects
|
|
220
|
+
`<conversation_history>` so the agent sees both the confirm DM and
|
|
221
|
+
the user's reply in the same turn. This gate is the writer for all
|
|
222
|
+
three branches; every branch is REQUIRED.
|
|
223
|
+
|
|
224
|
+
- **Affirmative** — user gave a clear positive answer to the
|
|
225
|
+
confirm question. Examples: *"yes"*, *"go ahead"*,
|
|
226
|
+
*"track it as X"*, *"sounds good"*, *"please do"*. Match on
|
|
227
|
+
intent, not surface vocabulary — recognise the same shape in
|
|
228
|
+
any language the user writes in. Execute the "On confirmed
|
|
229
|
+
creation → PUT the file" path in Step 4. Then run
|
|
230
|
+
§"Cross-path cancellation" below (delete any sibling confirm
|
|
231
|
+
rows with matching `confirm_dedup_key` so a parallel queued
|
|
232
|
+
row does not re-fire).
|
|
233
|
+
|
|
234
|
+
- **Counter-proposal** — user supplied new info ("call it
|
|
235
|
+
`la-pm` instead", "actually make it the syllabus dossier",
|
|
236
|
+
"rename it to `la-pm`").
|
|
237
|
+
Use the user's wording, not your original paraphrase:
|
|
238
|
+
re-compute the slug from the corrected wording, PUT the file,
|
|
239
|
+
then cancel pending confirm rows whose `confirm_dedup_key`
|
|
240
|
+
matches **either** the original or the new slug:
|
|
241
|
+
- `create_project:<original-slug>` — the chained-fire successor
|
|
242
|
+
inherits the original key, so this is the primary sweep.
|
|
243
|
+
- `create_project:<new-slug>` — a separate gate fire from an
|
|
244
|
+
earlier DM may have queued a confirm with the new slug (e.g.
|
|
245
|
+
the user previously paraphrased the same project differently
|
|
246
|
+
and that fire's confirm has not yet aborted). The fire-time
|
|
247
|
+
`slot-filled` probe would catch this (the project file now
|
|
248
|
+
exists), but a symmetric sweep here saves a wasted session.
|
|
249
|
+
|
|
250
|
+
Run the §"Cross-path cancellation" loop twice — once with each
|
|
251
|
+
key — or merge the two `select`s in jq.
|
|
252
|
+
|
|
253
|
+
- **Decline** — user wrote a clear negative answer to the
|
|
254
|
+
confirm question.
|
|
255
|
+
|
|
256
|
+
Counts as decline: *"no"*, *"don't bother"*, *"not now"*,
|
|
257
|
+
*"later"*, *"skip it"*, *"forget it"*, *"drop it"*.
|
|
258
|
+
|
|
259
|
+
Does NOT count as decline (treat as ambiguous → no DM action
|
|
260
|
+
this turn, marker NOT written, sweep NOT run; the chain's
|
|
261
|
+
softened re-check will handle it):
|
|
262
|
+
- non-answer continuations: *"hmm"*, *"not sure"*, *"I don't
|
|
263
|
+
know"*
|
|
264
|
+
- questions back to the agent: *"why are you asking?"*,
|
|
265
|
+
*"what would that involve?"* — these are clarification
|
|
266
|
+
requests, not declines
|
|
267
|
+
|
|
268
|
+
The examples are English for prompt clarity only; recognise
|
|
269
|
+
the same shapes in any language the user writes in. On a true
|
|
270
|
+
decline, do NOT write the project file. Two mandatory writes:
|
|
271
|
+
|
|
272
|
+
a. **Write the decline marker** to
|
|
273
|
+
`agent/journal.md ## Declined Intents`. Three cases — file
|
|
274
|
+
missing entirely, file present but section missing, file +
|
|
275
|
+
section both present — are handled in one read-then-branch
|
|
276
|
+
sequence:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# 1. GET. HTTP 404 means the journal file does not yet exist.
|
|
280
|
+
body=$(curl -sS -w '\n%{http_code}' "http://localhost:8321/api/context/agent/journal")
|
|
281
|
+
status=$(printf '%s\n' "$body" | tail -n1)
|
|
282
|
+
content=$(printf '%s\n' "$body" | sed '$d' | jq -r '.content // ""' 2>/dev/null)
|
|
283
|
+
|
|
284
|
+
marker_line='- 2026-05-12 [create_project:<slug>] user declined inline (DM)'
|
|
285
|
+
|
|
286
|
+
if [ "$status" = "404" ]; then
|
|
287
|
+
# Case A — file missing. CREATE_ONLY_PUT is enabled for
|
|
288
|
+
# agent/journal, so PUT creates the file in a single call.
|
|
289
|
+
# Include both the H1 and the Declined Intents section.
|
|
290
|
+
curl -s -X PUT "http://localhost:8321/api/context/agent/journal" \
|
|
291
|
+
-H 'Content-Type: application/json' \
|
|
292
|
+
-d "$(jq -n --arg m "$marker_line" '{content: "# Agent Journal\n\n## Declined Intents\n\($m)\n"}')"
|
|
293
|
+
elif printf '%s' "$content" | grep -q '^## Declined Intents'; then
|
|
294
|
+
# Case B — file + section present. Append a bullet to the
|
|
295
|
+
# existing section.
|
|
296
|
+
curl -s -X PATCH "http://localhost:8321/api/context/agent/journal" \
|
|
297
|
+
-H 'Content-Type: application/json' \
|
|
298
|
+
-d "$(jq -n --arg m "$marker_line" '{section:"declined_intents",mode:"append",content:$m}')"
|
|
299
|
+
else
|
|
300
|
+
# Case C — file present but section missing. append_to_file
|
|
301
|
+
# adds the section header + bullet to the end of the file.
|
|
302
|
+
curl -s -X PATCH "http://localhost:8321/api/context/agent/journal" \
|
|
303
|
+
-H 'Content-Type: application/json' \
|
|
304
|
+
-d "$(jq -n --arg m "$marker_line" '{mode:"append_to_file",content:"\n## Declined Intents\n\($m)\n"}')"
|
|
305
|
+
fi
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Use today's date (resolve via `<current_time>`) for the
|
|
309
|
+
marker line.
|
|
310
|
+
|
|
311
|
+
b. **Cancellation** — see §"Cross-path cancellation" below.
|
|
312
|
+
The decline must also delete any pending confirm rows with
|
|
313
|
+
the matching `confirm_dedup_key`, otherwise the chained-fire
|
|
314
|
+
successor will re-ask 24h later despite the explicit "no".
|
|
315
|
+
|
|
316
|
+
The decline marker is what the next DM-intent detection (Step 1
|
|
317
|
+
above) consults — without it, the next time the user mentions LA
|
|
318
|
+
PM master's, this gate would compute the same slug, see no
|
|
319
|
+
existing project, and schedule another confirm. The marker is
|
|
320
|
+
how Goal 3 ("never ask the same question twice") survives across
|
|
321
|
+
sessions.
|
|
322
|
+
|
|
323
|
+
**Decline-marker reversal.** When the user later volunteers an
|
|
324
|
+
unambiguously affirmative shape ("OK now let's start that LA
|
|
325
|
+
project after all", "actually go ahead and track LA PM") — either
|
|
326
|
+
inline in a fresh DM (the carve-out in Step 1) or as a reply to a
|
|
327
|
+
confirm DM — run this recipe instead of skipping:
|
|
328
|
+
|
|
329
|
+
1. GET `agent/journal.md`, parse the `## Declined Intents`
|
|
330
|
+
section, drop the line whose bracketed dedup_key matches
|
|
331
|
+
`create_project:<slug>`, and PATCH the section with
|
|
332
|
+
`mode: "replace"` carrying the rebuilt body (the other lines
|
|
333
|
+
preserved byte-for-byte). If the rebuilt section is empty,
|
|
334
|
+
replace with the empty string — `mode: "replace"` accepts an
|
|
335
|
+
empty `content` and leaves the heading in place.
|
|
336
|
+
2. Proceed with Step 4 (PUT the project file).
|
|
337
|
+
|
|
338
|
+
Without the reversal, a previously-declined project would stay
|
|
339
|
+
dormant forever.
|
|
340
|
+
|
|
341
|
+
**Cross-path cancellation (required for affirmative,
|
|
342
|
+
counter-proposal, and decline branches).** When this gate
|
|
343
|
+
commits durable state via ANY of the three branches above, sweep
|
|
344
|
+
pending confirm rows with the same dedup_key so a queued
|
|
345
|
+
successor does not re-fire:
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
curl -s "http://localhost:8321/api/schedule?status=pending,running" \
|
|
349
|
+
| jq -r --arg k "create_project:<slug>" \
|
|
350
|
+
'.items[] | select(.taskContext.confirm_dedup_key == $k) | .id' \
|
|
351
|
+
| while read -r id; do
|
|
352
|
+
curl -s -X DELETE "http://localhost:8321/api/schedule/$id" >/dev/null
|
|
353
|
+
done
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Apply this after the affirmative write, after the counter-proposal
|
|
357
|
+
write (with the ORIGINAL slug, not the corrected one), and after
|
|
358
|
+
the decline marker write. The cost is one GET plus zero-to-one
|
|
359
|
+
DELETE per write — bounded by "gate wrote something", which is
|
|
360
|
+
rare relative to inbound DM volume.
|
|
361
|
+
|
|
362
|
+
**Slug grammar (convention only — no API-level validation today):**
|
|
363
|
+
- match `^[a-z0-9][a-z0-9-]*[a-z0-9]$` (or a single `[a-z0-9]`)
|
|
364
|
+
- ≤ 64 chars
|
|
365
|
+
- equal to the filename stem
|
|
366
|
+
- avoid the reserved stems `_index`, `_active`
|
|
367
|
+
|
|
368
|
+
The context API does not currently reject malformed project slugs, so
|
|
369
|
+
the agent is the gate. A non-conforming slug will be written as-is and
|
|
370
|
+
later cause friction with the Obsidian Bases view (`_active.base`).
|
|
371
|
+
|
|
372
|
+
**Tie-breakers:**
|
|
373
|
+
- *Project AND long-horizon* — both can apply. A new project with a
|
|
374
|
+
dated milestone gets a `projects/<slug>.md` AND a roadmap entry.
|
|
375
|
+
Run both flows in the same turn; reuse the slug across them where
|
|
376
|
+
natural so the user can correlate the two.
|
|
377
|
+
- *Project AND user fact* — write the project state; do NOT also
|
|
378
|
+
write to `user/*.md` unless the message conveys a separate
|
|
379
|
+
identity / preference fact.
|
|
380
|
+
- *Project AND management policy* — if the user's wording is "from
|
|
381
|
+
now on, when X happens to project Y, do Z", that's a durable rule
|
|
382
|
+
→ `management-policy` skill, not this section. The policy file's
|
|
383
|
+
`linked.dossier` may still point at a `projects/<slug>.md`.
|
|
384
|
+
|
|
385
|
+
**What this section does NOT cover:**
|
|
386
|
+
- Inbox-derived project creation — that path runs in
|
|
387
|
+
`routine.morning_routine.md` Step 4 against `inbox/*` source files
|
|
388
|
+
with a different file-move semantic; do not duplicate it here.
|
|
389
|
+
- Roll-off / archive — when a project ends, flip `state: archived`
|
|
390
|
+
via GET-merge-PUT; do not delete the file. The `_active.base`
|
|
391
|
+
Obsidian view filters by `state`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mail-acquire.gmail
|
|
3
3
|
description: Acquire a Gmail message window per <acquisition-plan> row.
|
|
4
|
-
spec:
|
|
4
|
+
spec: docs/design/appendices/routine-data-acquisition.md §6.8 / §8.1
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Gmail acquisition
|
|
@@ -19,9 +19,16 @@ string `default` wherever the observation contract below references
|
|
|
19
19
|
`<accountId>`. Never invent an accountId from the message body — `default`
|
|
20
20
|
is the canonical placeholder.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
|
|
22
|
+
Submit every returned message — for a whole window in **one** call — via the
|
|
23
|
+
`mcp__aitne-observations__submit_observations` MCP tool when it is in your
|
|
24
|
+
allowed tools (preferred — the structured MCP transport carries
|
|
25
|
+
Unicode-bearing subjects/snippets that would deterministically trip
|
|
26
|
+
`curl … -d '{…}'` on the SDK's bash preflight). Build the tool input as
|
|
27
|
+
`{"observations":[…]}` with one entry per message; the response from the
|
|
28
|
+
upstream call IS the payload (do not summarise or rank).
|
|
29
|
+
|
|
30
|
+
If the MCP tool is unavailable (non-Claude session backend), fall back to
|
|
31
|
+
`POST http://localhost:8321/api/observations/batch` with the same envelope:
|
|
25
32
|
|
|
26
33
|
```json
|
|
27
34
|
{"observations":[
|
|
@@ -46,8 +53,8 @@ Field rules per element:
|
|
|
46
53
|
|
|
47
54
|
Do NOT compute the dedup hash — the server derives it from `(source, payload)`.
|
|
48
55
|
|
|
49
|
-
The
|
|
50
|
-
"fetched": N, "posted": N, "duplicates": N, "errors": N }`. Add each
|
|
56
|
+
The MCP tool and the batch endpoint return the same envelope: `{ "results":
|
|
57
|
+
[...], "fetched": N, "posted": N, "duplicates": N, "errors": N }`. Add each
|
|
51
58
|
field-count into your top-level totals. Per-item `results[*].status` values:
|
|
52
59
|
|
|
53
60
|
- `"created"` / `"modified"` — fresh or updated row; rolled into `posted`.
|
|
@@ -60,8 +67,8 @@ field-count into your top-level totals. Per-item `results[*].status` values:
|
|
|
60
67
|
`{type:"validation-error","integration":"gmail","account":"<accountId>","ref":"<ref>","detail":"<results[*].error>"}`
|
|
61
68
|
to `errors` and continue.
|
|
62
69
|
|
|
63
|
-
Cap each batch at 200 entries — split the window into multiple
|
|
64
|
-
upstream
|
|
70
|
+
Cap each batch at 200 entries — split the window into multiple
|
|
71
|
+
`submit_observations` (or POST) calls if the upstream returns more than that.
|
|
65
72
|
|
|
66
73
|
<!-- mode:direct:gmail -->
|
|
67
74
|
GET `http://localhost:8321/api/mail/<accountId>/messages<query>` where
|
|
@@ -72,7 +79,8 @@ GET `http://localhost:8321/api/mail/<accountId>/messages<query>` where
|
|
|
72
79
|
accepts `since` (ISO 8601 datetime), `limit`, `folder`, `q`,
|
|
73
80
|
`unreadOnly` — `days=…` is NOT recognised. The daemon returns
|
|
74
81
|
`{ "messages": [...] }`; map every message into the `observations[]`
|
|
75
|
-
array of a single `
|
|
82
|
+
array of a single `submit_observations` MCP tool call (or `POST
|
|
83
|
+
/api/observations/batch` fallback).
|
|
76
84
|
<!-- /mode:direct:gmail -->
|
|
77
85
|
|
|
78
86
|
<!-- mode:delegated-same:gmail -->
|
|
@@ -120,8 +128,9 @@ single user, so the task is account-implicit:
|
|
|
120
128
|
}
|
|
121
129
|
```
|
|
122
130
|
|
|
123
|
-
Map all items in `result.messages[]` into a single
|
|
124
|
-
`POST /api/observations/batch`
|
|
131
|
+
Map all items in `result.messages[]` into a single `submit_observations`
|
|
132
|
+
MCP tool call (or `POST /api/observations/batch` fallback when the MCP
|
|
133
|
+
tool is not available).
|
|
125
134
|
<!-- /mode:delegated-cross:gmail -->
|
|
126
135
|
|
|
127
136
|
<!-- mode:native:gmail -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mail-acquire.outlook_mail
|
|
3
3
|
description: Acquire an Outlook Mail message window per <acquisition-plan> row.
|
|
4
|
-
spec:
|
|
4
|
+
spec: docs/design/appendices/routine-data-acquisition.md §6.8 / §8.2
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Outlook Mail acquisition
|
|
@@ -30,8 +30,14 @@ The four non-disabled branches therefore split into two real flows:
|
|
|
30
30
|
this partial states the intent, not specific tool names. If no surface
|
|
31
31
|
is bound, record an error and continue.
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
`
|
|
33
|
+
Submit every returned message — for a whole window in **one** call — via the
|
|
34
|
+
`mcp__aitne-observations__submit_observations` MCP tool when it is in your
|
|
35
|
+
allowed tools (preferred — bypasses the SDK bash preflight which denies
|
|
36
|
+
Unicode-whitespace-bearing bodies). Build the tool input as
|
|
37
|
+
`{"observations":[…]}` with one entry per message.
|
|
38
|
+
|
|
39
|
+
If the MCP tool is unavailable (non-Claude session backend), fall back to
|
|
40
|
+
`POST http://localhost:8321/api/observations/batch` with the same envelope:
|
|
35
41
|
|
|
36
42
|
```json
|
|
37
43
|
{"observations":[
|
|
@@ -55,9 +61,10 @@ Field rules per element:
|
|
|
55
61
|
"date": ... } }` (providerId is `"default"` when no
|
|
56
62
|
`account` attribute)
|
|
57
63
|
|
|
58
|
-
The server computes the dedup hash from `(source, payload)`. The
|
|
59
|
-
endpoint
|
|
60
|
-
"posted": N, "duplicates": N, "errors": N }`. Per-item
|
|
64
|
+
The server computes the dedup hash from `(source, payload)`. The MCP tool
|
|
65
|
+
and the batch endpoint return the same envelope: `{ "results": [...],
|
|
66
|
+
"fetched": N, "posted": N, "duplicates": N, "errors": N }`. Per-item
|
|
67
|
+
`results[*].status`:
|
|
61
68
|
|
|
62
69
|
- `"created"` / `"modified"` — rolled into `posted`.
|
|
63
70
|
- `"duplicate"` — rolled into `duplicates`.
|
|
@@ -69,8 +76,8 @@ endpoint always returns `200` with `{ "results": [...], "fetched": N,
|
|
|
69
76
|
`{type:"validation-error","integration":"outlook_mail","account":"<accountId>","ref":"<ref>","detail":"<results[*].error>"}`
|
|
70
77
|
to `errors` and continue.
|
|
71
78
|
|
|
72
|
-
Cap each batch at 200 entries — split the window into multiple
|
|
73
|
-
upstream
|
|
79
|
+
Cap each batch at 200 entries — split the window into multiple
|
|
80
|
+
`submit_observations` (or POST) calls if the upstream returns more than that.
|
|
74
81
|
|
|
75
82
|
<!-- mode:direct:outlook_mail -->
|
|
76
83
|
GET `http://localhost:8321/api/mail/<accountId>/messages<query>` where
|
|
@@ -80,7 +87,8 @@ GET `http://localhost:8321/api/mail/<accountId>/messages<query>` where
|
|
|
80
87
|
accepts `since` (ISO 8601), `limit`, `folder`, `q`, `unreadOnly` — it
|
|
81
88
|
does NOT accept `days=…`. The daemon returns `{ "messages": [...] }`
|
|
82
89
|
regardless of the underlying provider; map every message into the
|
|
83
|
-
`observations[]` array of a single `
|
|
90
|
+
`observations[]` array of a single `submit_observations` MCP tool call
|
|
91
|
+
(or `POST /api/observations/batch` fallback).
|
|
84
92
|
<!-- /mode:direct:outlook_mail -->
|
|
85
93
|
|
|
86
94
|
<!-- mode:delegated-same:outlook_mail -->
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: notion-acquire.notion
|
|
3
3
|
description: Acquire recently-updated Notion pages per <acquisition-plan> row.
|
|
4
|
-
spec:
|
|
4
|
+
spec: docs/design/appendices/routine-data-acquisition.md §6.8 / §8.5
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Notion acquisition
|
|
@@ -10,8 +10,13 @@ For every `<fetch integration="notion" ...>` row in `<acquisition-plan>`,
|
|
|
10
10
|
take the branch below that matches the row's `mode` attribute. Notion rows
|
|
11
11
|
do not fan out per account — the dispatcher emits one row per workspace.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
`
|
|
13
|
+
Submit every returned page — for a whole window in **one** call — via the
|
|
14
|
+
`mcp__aitne-observations__submit_observations` MCP tool when it is in your
|
|
15
|
+
allowed tools (preferred — bypasses the SDK bash preflight). Build the
|
|
16
|
+
tool input as `{"observations":[…]}` with one entry per page.
|
|
17
|
+
|
|
18
|
+
If the MCP tool is unavailable (non-Claude session backend), fall back to
|
|
19
|
+
`POST http://localhost:8321/api/observations/batch` with the same envelope:
|
|
15
20
|
|
|
16
21
|
```json
|
|
17
22
|
{"observations":[
|
|
@@ -33,9 +38,10 @@ Field rules per element:
|
|
|
33
38
|
"raw": { "title": ..., "last_edited": ...,
|
|
34
39
|
"parent": ..., "url": ... } }`
|
|
35
40
|
|
|
36
|
-
The server computes the dedup hash from `(source, payload)`. The
|
|
37
|
-
endpoint
|
|
38
|
-
"posted": N, "duplicates": N, "errors": N }`. Per-item
|
|
41
|
+
The server computes the dedup hash from `(source, payload)`. The MCP tool
|
|
42
|
+
and the batch endpoint return the same envelope: `{ "results": [...],
|
|
43
|
+
"fetched": N, "posted": N, "duplicates": N, "errors": N }`. Per-item
|
|
44
|
+
`results[*].status`:
|
|
39
45
|
|
|
40
46
|
- `"created"` / `"modified"` — rolled into `posted`.
|
|
41
47
|
- `"duplicate"` — rolled into `duplicates`.
|
|
@@ -44,8 +50,8 @@ endpoint always returns `200` with `{ "results": [...], "fetched": N,
|
|
|
44
50
|
- `"validation_error"` — append `{type:"validation-error","integration":"notion","ref":"<ref>","detail":"<results[*].error>"}`
|
|
45
51
|
to `errors` and continue.
|
|
46
52
|
|
|
47
|
-
Cap each batch at 200 entries — split the window into multiple
|
|
48
|
-
upstream
|
|
53
|
+
Cap each batch at 200 entries — split the window into multiple
|
|
54
|
+
`submit_observations` (or POST) calls if the upstream returns more than that.
|
|
49
55
|
|
|
50
56
|
<!-- mode:direct:notion -->
|
|
51
57
|
GET `http://localhost:8321/api/notion/search<query>` where `<query>` is
|
|
@@ -58,8 +64,8 @@ sorted by `last_edited_time` descending; filter to entries whose
|
|
|
58
64
|
`last_edited_time` is at or after the window the `<fetch>` row's
|
|
59
65
|
window symbol implies (`updated_24h` → today's agent-day start,
|
|
60
66
|
`updated_1h` → the current hour boundary), then map every surviving
|
|
61
|
-
page into the `observations[]` array of a single
|
|
62
|
-
`POST /api/observations/batch`
|
|
67
|
+
page into the `observations[]` array of a single `submit_observations`
|
|
68
|
+
MCP tool call (or `POST /api/observations/batch` fallback).
|
|
63
69
|
<!-- /mode:direct:notion -->
|
|
64
70
|
|
|
65
71
|
<!-- mode:delegated-same:notion -->
|
|
@@ -104,8 +110,8 @@ body (substitute the row's `query` into `task`):
|
|
|
104
110
|
}
|
|
105
111
|
```
|
|
106
112
|
|
|
107
|
-
Map all items in `result.pages[]` into a single
|
|
108
|
-
`POST /api/observations/batch`
|
|
113
|
+
Map all items in `result.pages[]` into a single `submit_observations`
|
|
114
|
+
MCP tool call (or `POST /api/observations/batch` fallback).
|
|
109
115
|
<!-- /mode:delegated-cross:notion -->
|
|
110
116
|
|
|
111
117
|
<!-- mode:native:notion -->
|
|
@@ -112,7 +112,7 @@ curl -s -X PATCH http://localhost:8321/api/context/user/<topic> \
|
|
|
112
112
|
-H 'Content-Type: application/json' \
|
|
113
113
|
-d "$(jq -nc --arg s 'family' \
|
|
114
114
|
--arg c '- Sister (Sarah): two kids as of 2026-04
|
|
115
|
-
-
|
|
115
|
+
- Mother Yoko (1955–)' \
|
|
116
116
|
'{section:$s, mode:"append", content:$c}')"
|
|
117
117
|
```
|
|
118
118
|
|