Compare commits

...

3 Commits

Author SHA1 Message Date
1e546585bc inbox-triage: prioritise actionable unread messages, add Correspondence folder 2026-03-03 09:19:14 +00:00
325976d70b up
Signed-off-by: Christoph Schmatzler <christoph@schmatzler.com>
2026-03-03 08:37:52 +00:00
b27fe54da4 flk
Signed-off-by: Christoph Schmatzler <christoph@schmatzler.com>
2026-03-03 08:24:57 +00:00
3 changed files with 48 additions and 43 deletions

36
flake.lock generated
View File

@@ -275,11 +275,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1772380461, "lastModified": 1772516620,
"narHash": "sha256-O3ukj3Bb3V0Tiy/4LUfLlBpWypJ9P0JeUgsKl2nmZZY=", "narHash": "sha256-2r4cKdqCVlQkvcTcLUMxmsmAYZZxCMd//w/PnDnukTE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f140aa04d7d14f8a50ab27f3691b5766b17ae961", "rev": "2b9504d5a0169d4940a312abe2df2c5658db8de9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -291,11 +291,11 @@
"homebrew-cask": { "homebrew-cask": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1772439873, "lastModified": 1772525111,
"narHash": "sha256-NXnj74KZqCLiCI+CtfFqwgTEi5F4vQMHLbWAm9Feu4o=", "narHash": "sha256-xqqLqPJHXYK50ZjW7p0ofT6boU6LiIGnWoIsb6ad0mY=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-cask", "repo": "homebrew-cask",
"rev": "731c37bb034dee809b81432ec61b56418c13cfff", "rev": "72a9ff9e157b0f19efd560874906d3ccfa10c4fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -307,11 +307,11 @@
"homebrew-core": { "homebrew-core": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1772440582, "lastModified": 1772520746,
"narHash": "sha256-nr2AHBbm+jf98hRkU7da91Cu3Ens7vUcxpInJSgzmb0=", "narHash": "sha256-sB5VMCCLTfh/olcKwEwybGTUdmHBGDQ8ewPiXnX+3HU=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-core", "repo": "homebrew-core",
"rev": "45884718aedc3bd76f076fc45cbcaaf595ca021b", "rev": "26adc1a764c0e4f6a4b4a85c6c5ef170a8254220",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -362,11 +362,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1772421337, "lastModified": 1772509932,
"narHash": "sha256-0hgWVusynMsB/gOv9QutPmVQpKxSIJ2u6CLI9QTKiZk=", "narHash": "sha256-g7j7SERi1w8En6XY+fmwopwd4kY6utX+OmZ5DAoUdG8=",
"owner": "numtide", "owner": "numtide",
"repo": "llm-agents.nix", "repo": "llm-agents.nix",
"rev": "1d3a236c67906c94ebd31d1ca852d53c4101e81c", "rev": "699cd7b1346ead916f0958b3dbe78dc32df459d6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -479,11 +479,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1772440699, "lastModified": 1772525000,
"narHash": "sha256-tcW640OBpMZPMHVYWj1moE6+pDwCWP+WqpgRQMKGvdE=", "narHash": "sha256-M7kpjimt0jdEQzmin6ptszf8ev7TVzibyZNSLaLquMM=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "14fc170c3962a2b5ca31b5c6fad98dff6f1e9548", "rev": "72b1d820cb0149b40a35aa077b4b6d60cd1b23c3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -643,11 +643,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1772401007, "lastModified": 1772495394,
"narHash": "sha256-YHykQg0h9hrlZGpMcywnaFzQ1Kn/5YNCCOSaaAl6z7Q=", "narHash": "sha256-hmIvE/slLKEFKNEJz27IZ8BKlAaZDcjIHmkZ7GCEjfw=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "d8be5ea4cd3bc363492ab5bc6e874ccdc5465fe4", "rev": "1d9b98a29a45abe9c4d3174bd36de9f28755e3ff",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -10,7 +10,7 @@
model = "anthropic/claude-opus-4-6"; model = "anthropic/claude-opus-4-6";
small_model = "anthropic/claude-haiku-4-5"; small_model = "anthropic/claude-haiku-4-5";
theme = "catppuccin"; theme = "catppuccin";
plugin = ["oh-my-opencode" "opencode-anthropic-auth"]; plugin = ["oh-my-opencode@3.10.0" "opencode-anthropic-auth"];
permission = { permission = {
read = { read = {
"*" = "allow"; "*" = "allow";

View File

@@ -15,6 +15,7 @@ Workflow:
1. Run `himalaya folder list` first and use those folders as the primary taxonomy. 1. Run `himalaya folder list` first and use those folders as the primary taxonomy.
2. Use this existing folder set as defaults when it fits: 2. Use this existing folder set as defaults when it fits:
- `INBOX` - `INBOX`
- `Correspondence`
- `Orders and Invoices` - `Orders and Invoices`
- `Payments` - `Payments`
- `Outgoing Shipments` - `Outgoing Shipments`
@@ -32,15 +33,18 @@ Workflow:
- When all IDs on the current page are in the reviewed set, advance to the next page. - When all IDs on the current page are in the reviewed set, advance to the next page.
- Stop when a page returns fewer results than the page size (end of folder) and all its IDs are in the reviewed set. - Stop when a page returns fewer results than the page size (end of folder) and all its IDs are in the reviewed set.
5. For each single envelope ID, do all checks before any move/delete: 5. For each single envelope ID, do all checks before any move/delete:
- Check envelope flags from the JSON listing (seen/answered/flagged) before reading.
- Read the message: `himalaya message read -f "<source>" <id>`. - Read the message: `himalaya message read -f "<source>" <id>`.
- If needed for classification, inspect attachments: `himalaya attachment download -f "<source>" <id> --dir /tmp/himalaya-triage`. - If needed for classification, inspect attachments: `himalaya attachment download -f "<source>" <id> --dir /tmp/himalaya-triage`.
- If attachments are downloaded, inspect them and `rm` the downloaded files from `/tmp/himalaya-triage` after use. - If attachments are downloaded, inspect them and `rm` the downloaded files from `/tmp/himalaya-triage` after use.
- Move: `himalaya message move -f "<source>" "<destination>" <id>`. - Move: `himalaya message move -f "<source>" "<destination>" <id>`.
- Delete: `himalaya message delete -f "<source>" <id>`. - Delete: `himalaya message delete -f "<source>" <id>`.
6. Classification precedence (higher rule wins on conflict): 6. Classification precedence (higher rule wins on conflict):
- Human communication — a message with freeform natural-language content written by a human, not templated or autogenerated. When in doubt whether a message is human or automated, leave it untouched. - **Actionable and unhandled** — if the message needs a reply, requires manual payment, needs a confirmation, or demands any human action, AND has NOT been replied to (no `answered` flag), leave it in the source folder untouched. This is the highest-priority rule: anything that still needs attention stays in `INBOX`.
- Human correspondence already handled — freeform natural-language messages written by a human that have been replied to (`answered` flag set): move to `Correspondence`.
- Human communication not yet replied to but not clearly actionable — when in doubt whether a human message requires action, leave it untouched.
- Clearly ephemeral automated/system message (alerts, bot/status updates, OTP/2FA, password reset codes, login codes) with no archival value: move to `Deleted Messages`. - Clearly ephemeral automated/system message (alerts, bot/status updates, OTP/2FA, password reset codes, login codes) with no archival value: move to `Deleted Messages`.
- Payment transaction correspondence (actual charge/payment confirmations, receipts, failed-payment notices, provider payment events such as Klarna/PayPal/Stripe): move to `Payments`. - Automatic payment transaction notifications (charge/payment confirmations, receipts, failed-payment notices, provider payment events such as Klarna/PayPal/Stripe) that are purely informational and require no action: move to `Payments`.
- Subscription renewal notifications (auto-renew reminders, "will renew soon", price-change notices without a concrete transaction) are operational alerts, not payment records: move to `Deleted Messages`. - Subscription renewal notifications (auto-renew reminders, "will renew soon", price-change notices without a concrete transaction) are operational alerts, not payment records: move to `Deleted Messages`.
- Installment plan activation notifications (e.g. Barclays "Ihr Ratenkauf wurde aktiviert") are operational confirmations, not payment records: move to `Deleted Messages`. - Installment plan activation notifications (e.g. Barclays "Ihr Ratenkauf wurde aktiviert") are operational confirmations, not payment records: move to `Deleted Messages`.
- "Kontoauszug verfügbar/ist online" notifications are availability alerts, not payment records: move to `Deleted Messages`. - "Kontoauszug verfügbar/ist online" notifications are availability alerts, not payment records: move to `Deleted Messages`.
@@ -59,8 +63,9 @@ Execution rules:
- Always use page size 20 for envelope listing (`-s 20`). - Always use page size 20 for envelope listing (`-s 20`).
- If any single-ID command fails, log the error and continue with the next unreviewed ID. - If any single-ID command fails, log the error and continue with the next unreviewed ID.
- Never skip reading message content before deciding. - Never skip reading message content before deciding.
- Keep decisions conservative: only route clearly ephemeral automated/system messages to `Deleted Messages`. - Keep decisions conservative: when in doubt about whether something needs action, leave it in `INBOX`.
- Never move or delete human communications via automation. - Never move or delete unhandled actionable messages.
- Never move human communications that haven't been replied to, unless clearly non-actionable.
- Define "processed" as "reviewed once in this run" (including intentionally untouched human messages). - Define "processed" as "reviewed once in this run" (including intentionally untouched human messages).
- Include only messages observed during this run's listings; if new mail arrives mid-run, leave it for the next run. - Include only messages observed during this run's listings; if new mail arrives mid-run, leave it for the next run.
- Report a compact action log at the end with: - Report a compact action log at the end with: