diff options
Diffstat (limited to '.agent/design.md')
| -rw-r--r-- | .agent/design.md | 71 |
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 |
