summaryrefslogtreecommitdiff
path: root/.agent/design.md
diff options
context:
space:
mode:
Diffstat (limited to '.agent/design.md')
-rw-r--r--.agent/design.md71
1 files changed, 71 insertions, 0 deletions
diff --git a/.agent/design.md b/.agent/design.md
new file mode 100644
index 0000000..f17a80b
--- /dev/null
+++ b/.agent/design.md
@@ -0,0 +1,71 @@
+# Architecture — modal-shell
+
+## Overview
+
+modal-shell is a three-layer system:
+
+```
+[ ms dispatcher ] → [ mode file ] → [ base.sh + runtime ]
+```
+
+1. **`ms`** — dumb dispatcher. Reads `modes/` directory, matches argument to filename, executes.
+2. **Mode files** — encode intent. Each sources `base.sh` and then does exactly one thing.
+3. **`base.sh`** — shared environment foundation. Sets `PROJECT_ROOT`, loads secrets, configures toolchain.
+
+## Component Map
+
+| Component | Role |
+|---|---|
+| `ms` | Dispatcher. Lists modes if no arg. Exits non-zero on unknown mode. |
+| `modes/base.sh` | Foundation. Sourced by all modes. Never executed directly. |
+| `modes/db.sh` | Opens an interactive database shell. |
+| `modes/build.sh` | Runs the build pipeline to completion. |
+| `modes/reset.sh` | Destroys and rebuilds the environment. Requires confirmation. |
+| `modes/logs.sh` | Streams runtime logs. |
+| `.envrc` | direnv hook. Sources `base.sh` automatically on `cd`. |
+
+## Composition Model
+
+Every mode follows this pattern:
+
+```sh
+#!/usr/bin/env bash
+set -euo pipefail
+source "$(dirname "$0")/base.sh"
+
+# mode-specific logic here
+```
+
+Modes do not call other modes. Modes do not share state with each other. If two modes need the same sub-behavior, that behavior belongs in `base.sh`.
+
+## Data Flow
+
+```
+user: ms db
+ ms → finds modes/db.sh
+ modes/db.sh → source base.sh (sets PROJECT_ROOT, loads env)
+ modes/db.sh → exec psql / mysql / redis-cli (as configured in base.sh)
+ user lands in DB shell with correct credentials
+```
+
+## Secrets
+
+Secrets are never stored in files. `base.sh` loads them at runtime via:
+- `op run --` (1Password CLI) — preferred
+- `doppler run --` — alternative
+- `.env` file sourced locally — acceptable for non-sensitive local dev only, never committed
+
+## Adding a New Mode
+
+1. Create `modes/<name>.sh`
+2. Start with the standard header (shebang + `set -euo pipefail` + `source base.sh`)
+3. Implement the mode
+4. Add a brief comment at the top describing intent
+5. If destructive: add a confirmation prompt before proceeding
+6. Run `bash -n modes/<name>.sh` to verify syntax
+7. Update `worklog.md`
+
+## ADRs
+
+See `docs/adr/` for decisions on:
+- [ADR-001](../docs/adr/001-mode-as-intent.md) — Mode-as-intent architecture