The runbook §6 section ordering was 6.1 → 6.4 → 6.2 → 6.3
because the v1.1 EXECUTE stage inserted §6.4 "Secret
rotation" (REQ-INB-21, commit 6067008) between §6.1
"Secret inventory" and §6.2 "Why we never commit secrets".
The non-monotonic ordering was filed as v1.1 backlog P1-1
(CI-LOG.md:217-218) and v1.1 explicitly deferred the fix
to a follow-up milestone. v1.2 was a 0/1 disposition so
the carry-forward is v1.3.
This commit restores the monotonic ordering:
- §6.1 Secret inventory (unchanged)
- §6.2 Secret rotation (renumbered from §6.4)
- §6.3 Why we never commit secrets (renumbered from §6.2)
- §6.4 Data-sovereignty posture (renumbered from §6.3)
Plus 4 cross-reference updates in the runbook body:
- line 509: "see §6.4 for the procedure" → "see §6.2 for the procedure"
- line 625: "§6.4 (new in v1.1)" → "§6.2 (new in v1.1, renumbered in v1.3 from §6.4)"
- line 767: "§6.4 documents" → "§6.2 documents"
- line 790: "§5.7 + §6.4" → "§5.7 + §6.2"
Verified: grep -n '^### 6\.' docs/operations-runbook.md
returns 4 sections in 6.1 → 6.2 → 6.3 → 6.4 order.
grep -n '§6\.' docs/operations-runbook.md returns no
stale §6.4 cross-references pointing at the old
"Secret rotation" position.
This commit closes v1.1 backlog item P1-1 (runbook §6
ordering, per CI-LOG.md:217-218).
---ci---
project: inboxos
phase: 1
milestone: v1.3
status: execute
tasks_completed: [T2.5]
candidates_closed: [REQ-INB-36]
backlog_closures:
v1_1_P1_1: REQ-INB-36
files_touched:
- docs/operations-runbook.md (4 heading renumbers + 4 cross-ref updates, lines 509, 511, 561, 568, 625, 767, 790)
---/ci---
InboxOS
Self-hosted personal ERP / CRM pipeline. A single Gmail inbox, polled over IMAP, archived to SeaweedFS, classified and extracted by a local LLM (Ollama), and written to NocoDB as structured records. Curated attachments are mirrored to Papra. No third-party SaaS touches PII.
Where to start
- Operations runbook —
docs/operations-runbook.md. System overview, service inventory, workflow operations, observability, failure modes, security, cost, glossary. The first thing to read on day 1 of incident response. - Extraction contract —
docs/extraction-contract.md. How a raw email becomes a NocoDB record. Source of truth for theinboxos:classify+inboxos:extract-<module>prompt family. - NocoDB schema —
docs/schemas.md. The four module tables (finance,crm,intel,promotions) and the Message-ID idempotency contract. - Gitea Actions setup —
docs/gitea-actions.md. Runner provisioning (including the second runner for live + historical parallelism), repo secrets, the Basic Auth model. - Pipelines —
pipelines/README.md. Flow diagrams, idempotency model, rollback procedure for the live and historical pipelines. - Papra write policy —
docs/papra-write-policy.md. When the pipeline writes to Papra (attachments + selected bodies), and why the first ship is dry-run.
Quick layout
inboxos/
├── README.md # this file
├── .env.example # placeholder env (no real secrets)
├── docker/
│ └── docker-compose.yml # self-hosted stack: gitea, runners, nocodb, seaweedfs, papra, ollama
├── .gitea/workflows/
│ ├── live-pipeline.yml # cron */5 * * * *, polls IMAP
│ ├── historical-pipeline.yml # workflow_dispatch, streams .mbox
│ └── ci-pr.yml # fast-tests + 100MB e2e + live Ollama smoke
├── pipelines/ # shared Python: common.py, live_pipeline.py, historical_pipeline.py, mbox_stream.py
├── .opencode/commands/ # version-controlled extraction prompts (prompt-as-code)
├── config/ # n8n config (legacy, no longer in use)
└── docs/ # this runbook + schemas + contracts + reports
Status
Phase 5 — Full Deployment. Parent goal: INB-1. Current phase issue: INB-7. The runbook in docs/operations-runbook.md is the canonical reference for ongoing operation.
Historical archive (Google Takeout .mbox)
The full Google Takeout .mbox export lives in SeaweedFS at the canonical S3 URI:
s3://inboxos/eml/historical/all-mail.mbox
That is the value to pass as the mbox_object_key workflow_dispatch input to historical-pipeline.yml. To verify it exists, run from any host with mc configured against the inboxos bucket:
mc ls --recursive inboxos/inboxos/ | grep '\.mbox$'
The historical pipeline streams this object message-by-message, UPSERTs each into NocoDB on Message-ID, and writes the raw .eml backup under s3://inboxos/eml/historical/<yyyy>/<mm>/<dd>/<Message-ID>.eml. See docs/operations-runbook.md §3.2 for the dispatch recipe and §4.4 for the full bucket layout.