Architecture Decision Records
Why-decisions for major architectural choices. Each ADR captures context, decision, consequences, and (where relevant) alternatives considered. Append-only. Supersession gets a new ADR linking back, never an edit.
Index
| # | Title | Date | Status |
|---|---|---|---|
| ADR-001 | FM Inspector. Data-flow observability product | 2026-02 | Accepted |
| ADR-002 | Org Chat foundation | 2026-03 | Accepted |
| ADR-003 | Plugin SDK | 2026-03 | Accepted |
| ADR-004 | Chat: author-then-validate over planner-then-compile | 2026-04 | Accepted |
| ADR-005 | Chat DML two-step (dryRun + confirmation key + apply) | 2026-04 | Accepted |
| ADR-006 | Chat INSERT + pipeline A/B switch | 2026-04 | Accepted |
| ADR-007 | Async runtime fold (additive-optional, no schemaVersion bump) | 2026-04 | Accepted |
| ADR-008 | CSP + Named Credentials | 2026-04 | Accepted |
| ADR-009 | Org Chat surface strategy (one Apex × seven surfaces) | 2026-04 | Accepted |
| ADR-013 | Tool-calling + thread-state (provider-agnostic) | 2026-04 | Accepted |
| ADR-014 | INV-2 + REL-1 + deferrals (CDG-published-pipeline declined) | 2026-04 | Accepted |
| ADR-015 | REL-2 + tool-call badge + discovery-nudge custom-permission gate | 2026-04 | Accepted |
| ADR-016 | Phase H roadmap closeout | 2026-04 | Accepted |
ADRs 010, 011, 012 reserved (numbering holes from drafts that landed under different titles).
Reading order for new engineers
- ADR-002. Org Chat foundation. Why "chat with the data" works the way it does.
- ADR-004. Why the SOQL validator is the trust boundary, not the planner.
- ADR-007. The single-executor invariant. How async folds in without a second loop.
- ADR-009. Why one Apex facade serves seven surfaces.
- ADR-013. How tool-calling works without locking us to one vendor.
- ADR-014 + 015. Why introspection splits into INV-1 (on-demand) + INV-2 (nightly), and why discovery nudges are permset-gated.
Phase-H ADR digest
ADR-013. Tool-calling + thread-state
Decision. Provider-agnostic LLMToolCapableProvider extension interface. 4 canonical tools, single dispatcher.
Alternatives declined. OpenAI Assistants API + Vector Store. Reasons: vendor lock-in, per-customer multi-tenancy operational cost, sync-drift failure mode unfixable from Apex.
Consequence. Adding Vertex tomorrow is one Apex class. Same trust boundary as legacy single-shot. Server-side state stays in Salesforce Platform Cache.
ADR-014. INV-2 + REL-1 + deferrals
Decision. Two-layer introspection. INV-1 reads on-demand per turn. INV-2 harvests nightly into FM_Org_Inventory_Snapshot__c.
Alternatives declined. CDG-published external pipeline (introduced infrastructure dependency for what is in-Salesforce metadata).
Consequence. Pure-Apex collectors. Tooling Named Credential primary, session-id fallback. 8 KB per-turn cap.
ADR-015. REL-2 + tool-call badge + discovery-nudge
Decision. FMSoqlValidator accepts child subqueries (REL-2). UI shows tool-call badge when ADR-013 fires. Discovery nudges gated by FlowMason_Org_Chat_Discovery custom permission.
Why permset-gated nudges. Recon-vector mitigation. Default-on nudges would let a user iteratively probe the org's non-allowlisted SObject namespace by typing names.
ADR-016. Phase H roadmap closeout
Captures Phase H final state, enable order, residual backlog. Ready-for-listing checkpoint.
When to write an ADR
Write one when:
- Choosing between two non-trivial architectural options.
- Declining a popular approach (vendor SDK, framework, hosted service).
- Setting an invariant the codebase will rely on for years.
- Introducing a new trust boundary.