Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
70880bc
docs(saas): the tenant boundary was a deployment because the business…
claude Aug 8, 2026
d226230
docs(saas): "one seam" was true of the request path and false of the …
claude Aug 8, 2026
636c475
docs(saas): 10-50 seats per customer withdraws the cost argument and …
claude Aug 8, 2026
7eb6138
docs(saas): separate the arguments that are design from the ones that…
claude Aug 8, 2026
b799a46
docs(saas): pooled systems buy their safety above and below the stora…
claude Aug 8, 2026
4be19b9
docs(saas): "different customers on different versions" is four requi…
claude Aug 8, 2026
8c9bb5f
docs(saas): the interesting boundary was never the database
claude Aug 8, 2026
9e40de2
docs(saas): WS-29 — the plan becomes dispatchable
claude Aug 8, 2026
6afa48b
docs(saas): the brain now says the same thing in every doc that menti…
claude Aug 8, 2026
722cf2a
fix(MT-0a): a run's credentials were readable by every other run in t…
claude Aug 8, 2026
186342d
fix(MT-0b, MT-0d): a tenant could push to our monorepo and read our p…
claude Aug 8, 2026
87feb15
fix(MT-0c-1): the agents had a raw-SQL tool, and its guard was wrong …
claude Aug 8, 2026
5070a9d
feat(MT-1a, MT-1b): the tenant catalog, and a migration deliberately …
claude Aug 8, 2026
c88d7e3
feat(MT-1c): the ratchets — and building them found two paths the inv…
claude Aug 8, 2026
19305f6
feat(MT-1c, MT-1i): the binding seam, and five cross-org predicates
claude Aug 8, 2026
43083fd
docs(saas): mark MT-1 ticket status — what is built, what is staged, …
claude Aug 8, 2026
fca91e4
feat(MT-1e): a Redis client that cannot express an unprefixed key
claude Aug 8, 2026
0ba6ea1
docs(saas): MT-1e status, and the three Redis sites no ratchet can catch
claude Aug 8, 2026
7d7eba5
docs(saas): the execution runbook, and a 2.8x undercount corrected
claude Aug 9, 2026
817596b
fix(MT-1b): the two DB gate tests answered to a dotenv side-load, not…
vjvarada Aug 9, 2026
258ab6b
docs(work-plan): a board its own dispatch loop can read — the 2026-08…
vjvarada Aug 9, 2026
25534b6
docs(WS-29): pricing answered (D18), Mem0 decided (D17), H1 result re…
vjvarada Aug 9, 2026
a06be62
docs(specs): board records land in their owning specs; D11-era langua…
vjvarada Aug 9, 2026
74803aa
fix(MT-0a/0b): at-limit peek precedes the first-party gate; eval foll…
vjvarada Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Remove stale or contradictory text immediately.
Organisation: Fracktal Works
Project: CommandCenter v2 -- Headless, self-mutating agent orchestration platform
Runtime: MAF (Microsoft Agent Framework) native, plus the GitHub Copilot SDK as a second runtime for interactive coworker chat + the self-mutation sandbox. No LangGraph. No deepagents. No n8n.
Last updated: 2026-07-13
Last updated: 2026-08-09

## Purpose

Expand All @@ -93,14 +93,32 @@ Copilot SDK sandboxes.
1. No in-app agent/skill *code* editing -- all code authoring is VS Code + Git. The Workflows app (`/workflows`) is the sanctioned exception-by-design: workflows are DB-persisted configuration orchestrating code-authored agents, compiled to MAF Workflows (ADR-028; spec ai-company-brain/specs/workflows_app.md) -- not generated agent code, not a second runtime
2. No credentials in agent or skill repos -- Integration Registry holds all secrets
3. Self-mutation max_mutation_attempts = 1 per failure event
- ⚠️ **DEV-ONLY / must be replaced before production:** native MAF agents (local_path, no own remote) currently land approved self-mutations by opening a PR against THIS Command Center monorepo. This is fine only while all agents are first-party and Command Center is WIP. It MUST be swapped for a tenant-isolated mechanism before any multi-tenant/customer deployment — third parties must never push to the shared monorepo. See `docs/DESIGN_LIMITATION_native_maf_mutation.md`.
- ⚠️ **DEV-ONLY / must be replaced before production:** native MAF agents (local_path, no own remote) currently land approved self-mutations by opening a PR against THIS Command Center monorepo. This is fine only while all agents are first-party and Command Center is WIP. It MUST be swapped for a tenant-isolated mechanism before any multi-tenant/customer deployment — third parties must never push to the shared monorepo. See `docs/DESIGN_LIMITATION_native_maf_mutation.md`. **This is now ticketed as `saas_multitenancy.md` MT-0b (WS-29) and is a HARD BLOCKER before customer #2** — the cheapest sufficient fix is a config gate defaulting to disabled, not a redesign.
4. No autonomous writes to source systems until Action Broker is live
5. Git is the single source of truth for all agent artefacts
6. MAF is the PRIMARY native agent runtime. The Copilot SDK is the supported second runtime for interactive coworker chat (Tier 1.5, /copilot/chat, BYOK-routed through the gateway) and the self-mutation sandbox -- not a general execution path for event-driven specialist agents
7. No Theia / browser IDE
8. Source systems are authoritative -- CommandCenter is a read-mostly mirror
9. New event-driven / specialist-agent execution features default to MAF paths; the Copilot-SDK runtime is reserved for interactive chat + mutation (both gateway-routed), not new autonomous execution entrypoints
10. **All gateway endpoints require auth, by construction rather than by opting in.** `require_authenticated` is attached app-wide at the `FastAPI(dependencies=[…])` level, so a route added tomorrow is covered without anyone remembering; `PUBLIC_ROUTES` is the exemption list and every entry authenticates itself another way. **Before building or modifying ANY app, read `ai-company-brain/specs/user_management_contract.md`** — the ten binding rules for identity, membership and authorization, each one learned by breaking it. In particular: never navigate the browser directly at the gateway (it carries no credentials), never add a route to `PUBLIC_ROUTES` to make it reachable, and never take the acting identity from a query parameter or request body.
10. **All gateway endpoints require auth, by construction rather than by opting in.** `require_authenticated` is attached app-wide at the `FastAPI(dependencies=[…])` level, so a route added tomorrow is covered without anyone remembering; `PUBLIC_ROUTES` is the exemption list and every entry authenticates itself another way. **Before building or modifying ANY app, read `ai-company-brain/specs/user_management_contract.md`** — the ten binding rules for identity, membership and authorization, each one learned by breaking it. In particular: never navigate the browser directly at the gateway (it carries no credentials), never add a route to `PUBLIC_ROUTES` to make it reachable, and never take the acting identity from a query parameter or request body — **nor the acting TENANT, which is R11, added 2026-08-08 with D15; the tenant comes from the authenticated session or a tenant-scoped API key and from nowhere else.** The contract carries **eleven** rules, not ten.
11. **Multi-tenancy is `organization_id` + Postgres RLS, and it is NOT built yet.**
The tenant boundary was re-taken on 2026-08-08 (**D15**, board **WS-29**, spec
`ai-company-brain/specs/saas_multitenancy.md`): a tenant is a **row** isolated by
`FORCE ROW LEVEL SECURITY` bound at the `get_db()` seam; a deployment is a
*placement*, not a boundary. This **supersedes `tenancy_and_visibility.md` §1 and §6**
(one-deployment-per-tenant) — **§2–§5 of that document, the private → Center → org
visibility ladder, are unchanged and still binding.** Before building anything that
persists tenant data: read `saas_multitenancy.md` §1 and §11, and
`saas_multitenancy_implementation.md` for the shapes. Two rules bind today, ahead of
the build: **never introduce a second scoping doctrine** (tenant isolation is
`organization_id`; visibility inside a tenant stays `email | group:<slug> | org`), and
**never give an agent a raw-SQL tool or a database connection** — §0.9.3 makes that a
condition on the whole tenancy decision, not a nicety. Board rule **R5**
(`ai-company-brain/work_plan.md` §1, owner-directed 2026-08-09) binds every PR
tenant-ready by construction while WS-29 is in flight: new persisted tables satisfy
the tenant-coverage gate (or are exempted with a reason), no new database-connection
or Redis sites outside the seam/wrapper, and session acquisition stays on the seam
idiom so the H2 conversion remains mechanical.

## Global Conventions

Expand Down
2 changes: 1 addition & 1 deletion COMPETITIVE_COMPARISON.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Legend: ✅ real / mature · ◑ partial or default-off · ⚠️ designed-but-n
| Cost tracking | ◑ was silently $0 (now reports unknown) | ✅ per-turn cost + `/usage`/`/insights` | ◑ |
| Self-mutation / self-heal | ◑ Copilot Docker sandbox patches broken repos (partial reach) | ◑ skills self-heal during use | ✖ |
| Audit log | ✅ append-only (but sync on async loop) | ◑ structured logs | ◑ |
| Multi-tenancy / org RBAC | ⚠️ designed; auth "never rejects" today | ✖ single-user by design | ✖ single-user by design |
| Multi-tenancy / org RBAC | ⚠️ in build: default-deny auth SHIPPED (BO-2 closed); row-level multi-tenancy in flight as WS-29 (D15 — organization_id + RLS; H1 scratch-verified 2026-08-09) | ✖ single-user by design | ✖ single-user by design |

---

Expand Down
Loading
Loading