Skip to content

Open Items Register

Owner: El · Last reviewed: 2026-08-17

Purpose, and how this differs from the roadmap

This register holds things that must be resolved, verified, or decided — risks, unverified assumptions, security debt, legal questions, and contradictions between documents. Each entry names what it blocks, so nothing gates a client quote silently.

The roadmap holds planned work, sequenced over time. It answers what are we building and when.

Register Roadmap
A decision not yet made
A fact not yet verified
Security or legal debt
A contradiction between docs
A feature to build
A client deliverable

An item leaves this register in one of three ways: it is resolved and closed; it becomes an ADR (a decision was made); or it becomes a roadmap item (it turned out to be build work). It is never deleted silently — closed items move to the Closed Items register with a date, a reason and an outcome.

A Deferred item has not closed. It stays here, with its mitigation and the trigger that ends the deferral — a deferral without a trigger is a decision nobody made.

Scope: ABOS only. The Internal Portal and ContractAR keep their own registers in their own repositories.

Status values: Open · In progress · Blocked · Deferred · Closed IDs are permanent. Never reuse a number, even after closure.


A. Blocking the Greenhills quote

Nothing goes on paper until A1–A3 are answered. OI-001 in particular can turn a fixed-price build into a loss.

ID Item Owner Status
OI-001 AroFlo data completeness spike. Pull 90 days of real data. Are there reliable start/finish timestamps per job? Is job type a controlled field or free text? Free text means a classification mapping layer maintained forever. Duration-by-job-type cannot be built without this, and no modelling conjures it. El Open
OI-002 Metabase spike. Half day, local Docker, dummy data shaped like the canonical model, 2 GB memory limit. Build a number card, a trend line, a bar by job type. The memory figure sizes the shared host (ADR-0021 §2). El Open
OI-003 AGPL review. Embedding open-source Metabase in a closed commercial product routinely triggers legal review. Must be resolved before dashboard revenue is contracted. Not an engineering opinion — get it in writing. External / legal Open
OI-004 Clarify what Greenhills means by "approvals." Reporting on their existing approval process, or an assumption that we are building one? Very different quotes. El Open
OI-005 Get a number for "live." Client to state the acceptable data lag. 15 minutes is almost certainly enough and costs a fraction of the 2,000 calls/day AroFlo budget. El Open
OI-006 Verify the AroFlo reporting gap rather than assert it. "AroFlo has no comprehensive reporting" is exactly the claim a client repeats to their AroFlo rep. The defensible pitch is the cross-system join AroFlo cannot do. El Open

B. Time-sensitive — the window closes

ID Item Owner Status
OI-007 Greenhills before-state capture. Current invoice volume, manual touch time, rework rate, AroFlo↔Xero reconciliation duration. The window closes the moment anything goes live — after that, every savings claim is an estimate against an estimate. El Open
OI-008 Metric definitions signed off by the client before the first run. Redefining "exception" in month four silently invalidates months one to three, and it will not be noticed until a trend looks wrong. El Open
OI-009 Minutes-saved multiplier agreed at Blueprint and recorded. "38 hours returned" is a model, not a fact. When challenged, we point at their sign-off, not at our assumption. El Open

C. Blocking provisioning

ID Item Owner Status
OI-012 Shared host size, with Metabase overhead assumed rather than discovered (ADR-0021 §2, ADR-0023 §5). Depends on OI-002. El Blocked (OI-002)
OI-014 Tested restore. Posture is settled (ADR-0026); the restore test is the open item. Restore into a scratch container, diff row counts against source. First restore proven before the first paying client goes live. An untested restore is a hopeful cron job. El Open
OI-015 Stand up Bitwarden Teams and populate the shared collection per ADR-0027 — vault passwords, provider root access, MFA recovery codes. No dependency; can be done today. El + Lachlan Open
OI-036 AU-resident off-box backup target. Confirm Vultr Object Storage is available in the chosen AU region, with encryption at rest. El Open
OI-040 Canonical credential-name list in the repo (names only, never values) so the shared collection can be audited without opening it (ADR-0027 §10). El Open
OI-042 Scoped Cloudflare API token for the ADR-0024 dns role — DNS edit on the specific zone only, never the global API key. Stored in Ansible Vault under the core vault ID, not Bitwarden. El Open
OI-043 Build the ansible/ tree per ADR-0024. The directory does not yet exist in this repository; infra/ and inventory/ need reconciling against the decided layout. El + Lachlan Open

D. Security debt — fix before it propagates

Ordered by how expensive each becomes if copied into the client-facing app.

ID Item Owner Status
OI-016 ALLOWED_EMAILS is not enforced on the live SSO callback path (Internal Portal). On the portal this is a bug. Replicated into a client-facing app it is one client seeing another client's approvals. Fix before the client review app is designed, so the pattern is not copied. El Open
OI-017 Do not reuse the portal JWT_SECRET for the client review app. Clients are not in the Microsoft 365 tenant; one shared secret across a client-facing surface means a leak crosses tenants. Separate identity, issued per tenant. El Open
OI-018 Approval records: append-only, never updated in place, with a content hash of the exact proposed action. If the payload changes after approval, the approval is void and the item re-queues. Without this, "the client approved it" is unprovable — and that is the sentence said to an insurer. El Open
OI-019 Approval expiry fails closed. Pending items need a notification path (email, Teams) and an expiry. On timeout: expire and re-queue. Never auto-approve. El Open
OI-020 Metabase patching task in the provisioning playbook (ADR-0023 §8, ADR-0024 §9). Pinned version plus a scheduled bump. Cost scales with dashboard-client count. El Open
OI-041 Microsoft 365 break-glass account — deferred, deliberately. Two global admins exist on Octopodia accounts, but both are working identities under the same conditional access policies, so a single bad policy could lock out both. Mitigation, in force now: both admins' MFA recovery codes in Bitwarden, ≥2 MFA methods per admin, and no tightening of conditional access policies until the break-glass account exists. Trigger: first paying client. (ADR-0027 §11) El Deferred
ID Item Owner Status
OI-021 Vanity-domain support clause in the service agreement. Accepting client vanity domains (ADR-0022 §5) puts their DNS in our uptime path. The agreement must name the Octopodia address as the supported one, with the vanity name offered as convenience. A liability boundary, not a naming detail. El Open
OI-022 "No review, no go" reflected in contract terms and liability caps before client use. The tagline is a commercial commitment, and OI-018 is the evidence artefact that backs it. El + Lachlan Open
OI-023 Data hosting region disclosure and consent in all client agreements (ADR-0008). The clause commits us to disclosing a region, not a vendor — which is what keeps provider switching open. El Open
OI-024 Bespoke dashboard cards priced with a maintenance component. They break when AroFlo changes a field, and someone has to fix them. Every one given away free is an annuity we pay. El Open
OI-052 Price dedicated hosting at its true cost. A dedicated box is not "another VPS". ADR-0030 makes it conditional on moving the control plane to its own host and standing up private networking (OI-046) — both one-off engineering costs that land the first time a client asks. Treat the request as a project, not a plan upgrade. El + Lachlan Open
OI-037 Approval-log retention floor disclosed in the service agreement. ADR-0026 sets a floor a client cannot request below. Holding client-adjacent data longer than a client might prefer must be disclosed, not discovered. El Open
OI-038 Monthly audit report — scope and price. Built on the approval log. Offering it converts retention from internal policy into a contractual commitment. Becomes a roadmap item once scoped. El + Lachlan Open
OI-039 Scope boundary of "no review, no go" in client-facing language. The commitment covers AI-generated actions; deterministic automation (scheduled syncs, provisioning) runs unapproved. A client could reasonably read the tagline as covering all automation, which would make the product unusable and the commitment unmeetable. Must be explicit in the agreement, not implied. El + Lachlan Open

F. Cross-repository corrections

ID Item Owner Status
OI-044 octopodia-portal/docs/business/INFRASTRUCTURE.md says "EU by default." Directly contradicts ADR-0008. This document feeds client agreement language, so the contradiction has commercial consequences. Also carries a stale Trigger.dev reference and a multi-tenant connector claim inconsistent with ADR-0023. El Open
OI-045 octopodia-portal/docs/products/ai-employee/VPS-SETUP.md specifies Hetzner and EU regions, manual provisioning, and snapshot "golden image" cloning — all superseded by ADR-0008, ADR-0021 and ADR-0024. Correct or clearly mark as historical. El Open

G. Decisions still to make

ID Item Owner Status
OI-029 Approval granularity: per action or per batch. Per-action is defensible and will exhaust a client receiving forty invoices a day. El + Lachlan Open
OI-030 Does Greenhills get Metabase logins, or only curated views? Shapes how defensively the serving layer is modelled. Current lean: curated, since interactive embedding is Pro-tier and bills per signed-in viewer. El Open
OI-031 Live numbers or a monthly snapshot for Octopodia's own value reporting? El + Lachlan Open
OI-032 Ratify the reporting and dashboard ADR (docs/adr/DRAFT-reporting-and-dashboards.md). Blocked on OI-001, OI-002, OI-003. El + Lachlan Blocked

H. Watch items — deliberately not now

ID Item Revisit when Status
OI-033 DuckDB-WASM + Parquet for the native headline layer. No backend, no JVM, no AGPL question, no per-tenant CVE patching. Costs: the whole file lands in the browser so row-level access control is impossible; snapshot not stream; charting becomes our build. After Greenhills ships. Serving views export to Parquet either way. Watch
OI-034 Control-plane migration to its own host. Triggers per ADR-0025 §3. On trigger Watch
OI-035 Interactive Metabase embedding (Pro tier). Unlocks client self-serve querying and white labelling; bills per signed-in viewer. If self-serve becomes a sales blocker Watch
OI-046 Tailscale / private networking. Deferred per ADR-0021 §6. A second host — this is now the binding trigger (ADR-0030): brain-to-registry becomes a real network hop and must not cross the public internet. Also: a third person needing shell access, or the public SSH port ceasing to be acceptable. Watch
OI-047 Tenant migration runbook — shared host → dedicated host. Not yet written. Sequence: lower {tenant}.app TTL to 60s a day ahead → provision tenant stack on the new box → restore from per-tenant dump (ADR-0026) → verify → stop writes on old → final incremental sync → move the CNAME → hold the old stack cold for a rollback window → restore TTL. Caddy on the new host must know the hostname before the CNAME moves, or the certificate request fails. Write it before the first migration, not during. El Open
OI-048 Monitoring: what runs behind console.octopodia.com.au/health. A core_stack decision, deliberately deferred. The constraint is already fixed: on-box monitoring covers container state and metrics, but uptime checking must be external — an on-box monitor cannot report that the box is down. Sentry already covers error alerting. El + Lachlan Open
OI-049 Brain statelessness must be enforced, not assumed. ADR-0030 makes replicas safe only while the brain holds nothing that outlives a request — in particular LangGraph checkpoints must persist to the tenant's Postgres, never local disk or memory. Verify when the brain is built; a violation is invisible on one host and corrupting on two. El Open
OI-050 Reconciliation pass to report brain version per host. Version skew across hosts is behaviour that differs by which box a tenant sits on, with nothing appearing broken (ADR-0030). Needs to be visible, not inferred. El Open
OI-051 Split the core_stack role by scope. ADR-0030 divides it into per-host components (Caddy, brain replica) and global ones (registry, Console). The current single stub role encodes the old assumption. El + Lachlan Open

Closed items live in the Closed Items register.