faberun 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/bin/faberun.mjs +25 -0
- package/integrations/claude-code/statusline-bench.sh +42 -0
- package/integrations/claude-code/statusline.sh +80 -0
- package/package.json +33 -0
- package/skills/faberun/SKILL.md +24 -0
- package/skills/faberun/references/contract.md +380 -0
- package/skills/faberun/references/engineering.md +29 -0
- package/skills/faberun/references/handoffs.md +26 -0
- package/skills/faberun/references/operations.md +184 -0
- package/skills/faberun/references/rules.md +35 -0
- package/skills/faberun/references/workflow.md +23 -0
- package/skills/init-agentkit/SKILL.md +108 -0
- package/skills/init-agentkit/scripts/install-agentkit.sh +127 -0
- package/skills/init-agentkit/templates/.claude/commands/create-adr.md +44 -0
- package/skills/init-agentkit/templates/.github/workflows/quality.yml +43 -0
- package/skills/init-agentkit/templates/.sentrux/baseline.json +9 -0
- package/skills/init-agentkit/templates/.sentrux/rules.toml +21 -0
- package/skills/init-agentkit/templates/AGENTS.md +110 -0
- package/skills/init-agentkit/templates/docs/ABSTRACTIONS.md +30 -0
- package/skills/init-agentkit/templates/docs/ARCHITECTURE.md +31 -0
- package/skills/init-agentkit/templates/docs/GETTING-STARTED.md +44 -0
- package/skills/init-agentkit/templates/docs/VISION.md +33 -0
- package/skills/init-agentkit/templates/docs/adr/0001-record-architecture-decisions.md +36 -0
- package/skills/init-agentkit/templates/docs/adr/0002-root-managed-ai-guidance.md +37 -0
- package/skills/init-agentkit/templates/docs/adr/0003-sentrux-structural-quality-gates.md +49 -0
- package/skills/init-agentkit/templates/docs/adr/README.md +52 -0
- package/skills/init-agentkit/templates/docs/sentrux.md +66 -0
- package/skills/init-agentkit/templates/githooks/commit-msg +22 -0
- package/skills/init-agentkit/templates/githooks/pre-commit +32 -0
- package/src/campaign/brief.mjs +394 -0
- package/src/campaign/chain.mjs +555 -0
- package/src/campaign/handoff.mjs +516 -0
- package/src/campaign/index.mjs +300 -0
- package/src/campaign/journal.mjs +347 -0
- package/src/campaign/layout.mjs +51 -0
- package/src/campaign/metrics-evals.mjs +25 -0
- package/src/campaign/metrics.mjs +517 -0
- package/src/campaign/projection.mjs +250 -0
- package/src/campaign/record.mjs +102 -0
- package/src/campaign/unpark.mjs +56 -0
- package/src/cli/brand.mjs +205 -0
- package/src/cli/campaign.mjs +730 -0
- package/src/cli/contract.mjs +67 -0
- package/src/cli/init.mjs +170 -0
- package/src/cli/launch.mjs +239 -0
- package/src/cli/seat.mjs +139 -0
- package/src/cli/setup.mjs +294 -0
- package/src/cli/skills.mjs +105 -0
- package/src/cli/update.mjs +216 -0
- package/src/cli.mjs +525 -0
- package/src/contract/articles.mjs +12 -0
- package/src/contract/assert.mjs +162 -0
- package/src/contract/definition-of-done.mjs +97 -0
- package/src/contract/final-verification.mjs +96 -0
- package/src/contract/index.mjs +641 -0
- package/src/contract/judge-envelope.mjs +25 -0
- package/src/contract/review-modes.mjs +151 -0
- package/src/contract/runtime.mjs +204 -0
- package/src/contract/schema-version.mjs +25 -0
- package/src/contract/scope-findings.mjs +77 -0
- package/src/contract/snapshot.mjs +639 -0
- package/src/contract/task-packet.mjs +495 -0
- package/src/contract/untrusted.mjs +75 -0
- package/src/contract/verification.mjs +185 -0
- package/src/contract/worker-result.mjs +138 -0
- package/src/engine/assignment.mjs +63 -0
- package/src/engine/backoff.mjs +492 -0
- package/src/engine/bulk-read.mjs +361 -0
- package/src/engine/cancel.mjs +177 -0
- package/src/engine/detach.mjs +101 -0
- package/src/engine/dispatch.mjs +752 -0
- package/src/engine/failover.mjs +192 -0
- package/src/engine/gate.mjs +183 -0
- package/src/engine/judge-gate.mjs +517 -0
- package/src/engine/lifecycle.mjs +772 -0
- package/src/engine/live-preflight.mjs +299 -0
- package/src/engine/mutation.mjs +146 -0
- package/src/engine/notify-queue.mjs +327 -0
- package/src/engine/process-identity.mjs +72 -0
- package/src/engine/process.mjs +774 -0
- package/src/engine/prompts.mjs +289 -0
- package/src/engine/recover.mjs +300 -0
- package/src/engine/result-file.mjs +222 -0
- package/src/engine/resume.mjs +635 -0
- package/src/engine/retry.mjs +334 -0
- package/src/engine/review.mjs +228 -0
- package/src/engine/run-command.mjs +287 -0
- package/src/engine/run-identity.mjs +411 -0
- package/src/engine/runtime-discovery.mjs +235 -0
- package/src/engine/scheduler.mjs +526 -0
- package/src/engine/scope.mjs +378 -0
- package/src/engine/settle.mjs +207 -0
- package/src/engine/state.mjs +148 -0
- package/src/engine/supervise.mjs +713 -0
- package/src/engine/verify.mjs +167 -0
- package/src/harnesses/agy/index.mjs +62 -0
- package/src/harnesses/catalogue.mjs +509 -0
- package/src/harnesses/claude/index.mjs +90 -0
- package/src/harnesses/codex/index.mjs +87 -0
- package/src/harnesses/dsh/closed-packet.patch.yml +42 -0
- package/src/harnesses/dsh/index.mjs +210 -0
- package/src/harnesses/dsh/runner.mjs +259 -0
- package/src/harnesses/exec-jsonl/index.mjs +788 -0
- package/src/harnesses/index.mjs +508 -0
- package/src/harnesses/protocol.mjs +531 -0
- package/src/harnesses/replay/bin.mjs +386 -0
- package/src/harnesses/replay/index.mjs +238 -0
- package/src/harnesses/zcode/index.mjs +276 -0
- package/src/host/config.mjs +87 -0
- package/src/host/home.mjs +149 -0
- package/src/host/package.mjs +23 -0
- package/src/host/preflight.mjs +520 -0
- package/src/host/tool-policy-decisions.mjs +341 -0
- package/src/host/tool-policy-hook.mjs +270 -0
- package/src/notify/index.mjs +359 -0
- package/src/notify/os-macos.mjs +81 -0
- package/src/repo/declared-paths.mjs +220 -0
- package/src/repo/integrate.mjs +546 -0
- package/src/repo/scope-closure.mjs +665 -0
- package/src/repo/signal-block.mjs +16 -0
- package/src/repo/signal.mjs +222 -0
- package/src/repo/source-identity.mjs +295 -0
- package/src/repo/workspace.mjs +557 -0
- package/src/repo/worktree.mjs +352 -0
- package/src/report/final.mjs +200 -0
- package/src/report/metrics-report.mjs +99 -0
- package/src/report/next.mjs +383 -0
- package/src/report/render.mjs +716 -0
- package/src/run/disk-gc.mjs +251 -0
- package/src/run/lock.mjs +329 -0
- package/src/run/node-store.mjs +62 -0
- package/src/run/operations.mjs +286 -0
- package/src/run/store.mjs +187 -0
- package/src/run/usage.mjs +337 -0
- package/src/seat/harnesses.mjs +83 -0
- package/src/seat/index.mjs +239 -0
- package/src/seat/tmux.mjs +208 -0
- package/src/util.mjs +0 -0
- package/src/web/api.mjs +371 -0
- package/src/web/boundary.mjs +88 -0
- package/src/web/index.html +299 -0
- package/src/web/server.mjs +552 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Workflow: worktrees, commits, scope
|
|
2
|
+
|
|
3
|
+
**Detach and resume.** `run --detach <contract.json>` forks a controller that
|
|
4
|
+
outlives this session; if it dies before the run is terminal, the next
|
|
5
|
+
`resume --detach <run-dir>` takes over its stale lock and adopts or restarts
|
|
6
|
+
whatever it left running. `maxParallel` above one dispatches every ready node
|
|
7
|
+
concurrently, each in its own attempt worktree; integration stays serialized.
|
|
8
|
+
The target repo must ignore `.runs/`.
|
|
9
|
+
|
|
10
|
+
**Resume, do not restart.** A node marked `running` with no runner process is
|
|
11
|
+
an orphan. `resume --detach <run-dir>` re-judges finished work instead of
|
|
12
|
+
re-implementing it; take a new run id only when routing or the graph changes.
|
|
13
|
+
|
|
14
|
+
Never overwrite an existing run directory; choose a new run id. One controller
|
|
15
|
+
lock per run directory. Treat `STATUS.md` and node JSON as state; logs are
|
|
16
|
+
diagnostics. Attempt worktrees, sealing commits, integration, and the lock
|
|
17
|
+
mechanics: [operations.md](operations.md).
|
|
18
|
+
|
|
19
|
+
**Name things for what they do.** A campaign, run, phase or node id says
|
|
20
|
+
what the work is (`become-faberun-2-cli-product`, `brand-and-banner`), never
|
|
21
|
+
only when it ran; a date is a tie-break suffix, not the meaning. An operator
|
|
22
|
+
reading `.runs/`, a branch list or a `HANDOFF.md` must understand the campaign
|
|
23
|
+
without opening it.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: init-agentkit
|
|
3
|
+
description: Installs the docs + agent kit into a repository - canonical AGENTS.md with CLAUDE.md/GEMINI.md/CURSOR.md symlinks, docs/ (VISION, ARCHITECTURE, ABSTRACTIONS, GETTING-STARTED), ADRs with template and index, Sentrux structural quality gate (.sentrux/rules.toml + baseline), CI, a create-adr slash command, and githooks. Use when the user says "install the agent kit", "init-agentkit", "set up docs/ADR/sentrux", or wants to bootstrap engineering standards in a new repo.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# init-agentkit
|
|
7
|
+
|
|
8
|
+
Bootstraps the **docs + agent kit** in a repository. Structural gate by
|
|
9
|
+
[Sentrux](https://github.com/sentrux/sentrux). The playbook consolidates what is in
|
|
10
|
+
use in [phai](https://github.com/feliperun/phai) and
|
|
11
|
+
[cueme](https://github.com/feliperun/cueme).
|
|
12
|
+
|
|
13
|
+
## What it installs
|
|
14
|
+
|
|
15
|
+
| Artifact | Role |
|
|
16
|
+
|----------|------|
|
|
17
|
+
| `AGENTS.md` | Canonical playbook (minimum-code rules, repository rules, workflow, gates, gotchas) |
|
|
18
|
+
| `CLAUDE.md` `GEMINI.md` `CURSOR.md` `AGENT.md` | **symlinks** → `AGENTS.md` (single source) |
|
|
19
|
+
| `docs/VISION.md` `ARCHITECTURE.md` `ABSTRACTIONS.md` `GETTING-STARTED.md` | base docs |
|
|
20
|
+
| `docs/adr/` | ADRs with `README.md` (template + index + status lifecycle) |
|
|
21
|
+
| `docs/adr/0001..0003` | meta-ADRs documenting the kit itself |
|
|
22
|
+
| `docs/sentrux.md` | structural quality gate reference |
|
|
23
|
+
| `.sentrux/rules.toml` | absolute limits (`sentrux check`) |
|
|
24
|
+
| `.sentrux/baseline.json` | anti-regression reference (`sentrux gate`) |
|
|
25
|
+
| `.claude/commands/create-adr.md` | slash command that creates a numbered ADR and updates the index |
|
|
26
|
+
| `.github/workflows/quality.yml` | CI: typecheck + test + sentrux |
|
|
27
|
+
| `githooks/pre-commit` | local hook: secrets scan + sentrux check/gate |
|
|
28
|
+
| `githooks/commit-msg` | validates Conventional Commits |
|
|
29
|
+
|
|
30
|
+
## Before running: ask which compatibility rule applies
|
|
31
|
+
|
|
32
|
+
Rule 1 of the generated `AGENTS.md` ships in two variants, and the choice changes how
|
|
33
|
+
every future agent treats published contracts. **Always ask the user before running
|
|
34
|
+
the installer** — do not pick a default silently:
|
|
35
|
+
|
|
36
|
+
| Variant | Rule 1 | Fits |
|
|
37
|
+
|---------|--------|------|
|
|
38
|
+
| `--greenfield` (default) | *Do not preserve backward compatibility.* Obsolete paths are removed, not wrapped in compatibility layers. | New projects with no published consumers. Keeps a greenfield codebase free of dead weight. |
|
|
39
|
+
| `--stable` | Published surfaces (public API, CLI contract, persisted format, integrations) stay compatible; breaking one needs a migration path and a `feat!:` / `BREAKING CHANGE:` commit. Unpublished internals are still removed freely. | Anything with real consumers, a released package, or production data. |
|
|
40
|
+
|
|
41
|
+
Ask with a two-option question ("greenfield: break freely" vs. "stable: preserve
|
|
42
|
+
published contracts"), then pass the matching flag. The installer prints the selected
|
|
43
|
+
variant before writing.
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# from the target repo directory (or pass the path):
|
|
49
|
+
~/.agents/skills/init-agentkit/scripts/install-agentkit.sh [target-dir]
|
|
50
|
+
|
|
51
|
+
# compatibility rule (ask the user first — see above):
|
|
52
|
+
install-agentkit.sh --greenfield # break freely (default)
|
|
53
|
+
install-agentkit.sh --stable # preserve published contracts
|
|
54
|
+
|
|
55
|
+
# preview without writing:
|
|
56
|
+
install-agentkit.sh --dry-run
|
|
57
|
+
|
|
58
|
+
# overwrite existing files (default: never overwrites, only warns):
|
|
59
|
+
install-agentkit.sh --force
|
|
60
|
+
|
|
61
|
+
# skip git hook installation:
|
|
62
|
+
install-agentkit.sh --no-hooks
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The installer:
|
|
66
|
+
|
|
67
|
+
1. Detects the **project name** (repo basename) and the **stack**
|
|
68
|
+
(`package.json`→node, `Cargo.toml`→rust, `pyproject.toml`→python) to fill in
|
|
69
|
+
the check commands in `AGENTS.md` and CI, and resolves rule 1 from the selected
|
|
70
|
+
variant.
|
|
71
|
+
2. Copies the templates **without overwriting** existing files (use `--force`).
|
|
72
|
+
3. Creates the `CLAUDE.md`/`GEMINI.md`/`CURSOR.md`/`AGENT.md` symlinks → `AGENTS.md`.
|
|
73
|
+
4. If the `sentrux` CLI is installed, runs `sentrux gate --save .` to generate the
|
|
74
|
+
real `baseline.json`; otherwise leaves a placeholder with instructions.
|
|
75
|
+
5. Installs the hooks via `core.hooksPath` (never touches `.git/hooks` directly).
|
|
76
|
+
6. Is **idempotent** — running it again only fills in what is missing.
|
|
77
|
+
|
|
78
|
+
## After installing
|
|
79
|
+
|
|
80
|
+
1. Fill in the `TODO`s in `docs/VISION.md` and `docs/ARCHITECTURE.md` (the rest is
|
|
81
|
+
generic structure that fits any repo).
|
|
82
|
+
2. Install the Sentrux CLI and run `sentrux gate --save .` if no baseline was
|
|
83
|
+
generated yet (see `docs/sentrux.md`).
|
|
84
|
+
3. Fill in the **gotchas** section of `AGENTS.md` as failures surface — it is the
|
|
85
|
+
highest-value part of the file.
|
|
86
|
+
4. Commit everything as a single `chore: bootstrap agent kit (init-agentkit)`.
|
|
87
|
+
5. Enable the gate in CI (the workflow ships ready; adjust the Sentrux version).
|
|
88
|
+
|
|
89
|
+
## Conventions
|
|
90
|
+
|
|
91
|
+
- **`AGENTS.md` is the single source** of guidance; never edit the symlinks.
|
|
92
|
+
- **ADRs are immutable**: one decision per file, `NNNN-title.md`, monotonic
|
|
93
|
+
numbering; an active ADR is never edited — supersede it.
|
|
94
|
+
- **Sentrux is a ratchet**: thresholds only tighten; loosening requires a
|
|
95
|
+
superseding ADR. Boy Scout Rule — every file you touch leaves with an
|
|
96
|
+
equal-or-better score.
|
|
97
|
+
- **E2E is mandatory** for key features or user-visible changes; unit tests do not
|
|
98
|
+
replace it.
|
|
99
|
+
- **Never `--no-verify`**; never silence a rule to pass the gate.
|
|
100
|
+
- **Destructive actions** (merge, force-push, schema drop) require explicit human
|
|
101
|
+
sign-off in the moment — the agent hands off to the user instead of routing
|
|
102
|
+
around it.
|
|
103
|
+
|
|
104
|
+
## References
|
|
105
|
+
|
|
106
|
+
- Gate: [Sentrux](https://github.com/sentrux/sentrux)
|
|
107
|
+
- Applied in: [phai](https://github.com/feliperun/phai),
|
|
108
|
+
[cueme](https://github.com/feliperun/cueme)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# init-agentkit — installs the docs + agent kit into a repo.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# install-agentkit.sh [target-dir] # default: cwd
|
|
7
|
+
# install-agentkit.sh --dry-run # preview without writing
|
|
8
|
+
# install-agentkit.sh --force # overwrite existing files
|
|
9
|
+
# install-agentkit.sh --no-hooks # skip git hook installation
|
|
10
|
+
# install-agentkit.sh --stable # compatibility-preserving rule 1
|
|
11
|
+
# install-agentkit.sh --greenfield # break-freely rule 1 (default)
|
|
12
|
+
#
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
TEMPLATES="$SCRIPT_DIR/../templates"
|
|
17
|
+
SENTRUX_VERSION_DEFAULT="v0.5.7"
|
|
18
|
+
|
|
19
|
+
DRY_RUN=0; FORCE=0; NO_HOOKS=0; TARGET=""; VARIANT="greenfield"
|
|
20
|
+
for arg in "$@"; do
|
|
21
|
+
case "$arg" in
|
|
22
|
+
--dry-run) DRY_RUN=1 ;;
|
|
23
|
+
--force) FORCE=1 ;;
|
|
24
|
+
--no-hooks) NO_HOOKS=1 ;;
|
|
25
|
+
--stable) VARIANT="stable" ;;
|
|
26
|
+
--greenfield) VARIANT="greenfield" ;;
|
|
27
|
+
-*) echo "unknown flag: $arg" >&2; exit 2 ;;
|
|
28
|
+
*) TARGET="$arg" ;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
TARGET="${TARGET:-$(pwd)}"
|
|
32
|
+
TARGET="$(cd "$TARGET" && pwd)"
|
|
33
|
+
|
|
34
|
+
# colors
|
|
35
|
+
G='\033[32m'; Y='\033[33m'; B='\033[34m'; R='\033[31m'; D='\033[2m'; C='\033[36m'; Z='\033[0m'
|
|
36
|
+
say(){ printf "%b\n" "${2:-}$1$Z"; }
|
|
37
|
+
|
|
38
|
+
[ -d "$TEMPLATES" ] || { say "templates not found: $TEMPLATES" "$R"; exit 1; }
|
|
39
|
+
|
|
40
|
+
# --- repo context --------------------------------------------------------
|
|
41
|
+
PROJECT="$(basename "$(git -C "$TARGET" rev-parse --show-toplevel 2>/dev/null || echo "$TARGET")")"
|
|
42
|
+
DATE="$(date +%F)"
|
|
43
|
+
SENTRUX_VERSION="${SENTRUX_VERSION:-$SENTRUX_VERSION_DEFAULT}"
|
|
44
|
+
|
|
45
|
+
# stack → check suite
|
|
46
|
+
if [ -f "$TARGET/package.json" ]; then CHECK_SUITE="npm run typecheck && npm test"
|
|
47
|
+
elif [ -f "$TARGET/Cargo.toml" ]; then CHECK_SUITE="cargo check && cargo test"
|
|
48
|
+
elif [ -f "$TARGET/pyproject.toml" ];then CHECK_SUITE="ruff check . && pytest"
|
|
49
|
+
else CHECK_SUITE="echo 'TODO: define the check suite (typecheck + test)'"; fi
|
|
50
|
+
|
|
51
|
+
say "\n🏗 init-agentkit → $PROJECT${DRY_RUN:+}" "$C"
|
|
52
|
+
say " target: $TARGET" "$D"
|
|
53
|
+
say " stack check: $CHECK_SUITE" "$D"
|
|
54
|
+
say " compatibility rule: $VARIANT" "$D"
|
|
55
|
+
say " sentrux: $SENTRUX_VERSION$( [ $DRY_RUN = 1 ] && echo ' (dry-run)')\n" "$D"
|
|
56
|
+
|
|
57
|
+
# escape & and \ for the sed replacement side
|
|
58
|
+
esc(){ printf '%s' "$1" | sed -e 's/[&\\]/\\&/g'; }
|
|
59
|
+
# drop the unselected <!-- variant:NAME:start/end --> block, then the surviving markers
|
|
60
|
+
DROP="$( [ "$VARIANT" = stable ] && echo greenfield || echo stable )"
|
|
61
|
+
variant(){ sed -e "/<!-- variant:$DROP:start -->/,/<!-- variant:$DROP:end -->/d" \
|
|
62
|
+
-e "/<!-- variant:$VARIANT:start -->/d" \
|
|
63
|
+
-e "/<!-- variant:$VARIANT:end -->/d"; }
|
|
64
|
+
subst(){ sed -e "s|{{PROJECT}}|$(esc "$PROJECT")|g" -e "s|{{DATE}}|$(esc "$DATE")|g" \
|
|
65
|
+
-e "s|{{SENTRUX_VERSION}}|$(esc "$SENTRUX_VERSION")|g" \
|
|
66
|
+
-e "s|{{CHECK_SUITE}}|$(esc "$CHECK_SUITE")|g" | variant; }
|
|
67
|
+
|
|
68
|
+
# --- copy templates (never overwriting, unless --force) -----------------------
|
|
69
|
+
copied=0; skipped=0
|
|
70
|
+
while IFS= read -r src; do
|
|
71
|
+
rel="${src#"$TEMPLATES"/}"
|
|
72
|
+
dest="$TARGET/$rel"
|
|
73
|
+
if [ -e "$dest" ] && [ "$FORCE" = 0 ]; then
|
|
74
|
+
say " = $rel (exists, kept)" "$D"; skipped=$((skipped+1)); continue
|
|
75
|
+
fi
|
|
76
|
+
if [ "$DRY_RUN" = 1 ]; then
|
|
77
|
+
say " + $rel" "$G"; copied=$((copied+1)); continue
|
|
78
|
+
fi
|
|
79
|
+
mkdir -p "$(dirname "$dest")"
|
|
80
|
+
subst < "$src" > "$dest"
|
|
81
|
+
say " + $rel" "$G"; copied=$((copied+1))
|
|
82
|
+
done < <(find "$TEMPLATES" -type f)
|
|
83
|
+
|
|
84
|
+
# --- guidance symlinks → AGENTS.md --------------------------------------------
|
|
85
|
+
say "\n② Guidance symlinks → AGENTS.md" "$B"
|
|
86
|
+
for f in CLAUDE.md GEMINI.md CURSOR.md AGENT.md; do
|
|
87
|
+
link="$TARGET/$f"
|
|
88
|
+
# relative target: one ../ per directory level below the repo root
|
|
89
|
+
case "$f" in */*) dest="../AGENTS.md" ;; *) dest="AGENTS.md" ;; esac
|
|
90
|
+
if [ -L "$link" ] && [ "$(readlink "$link")" = "$dest" ]; then
|
|
91
|
+
say " = $f (ok)" "$D"; continue
|
|
92
|
+
fi
|
|
93
|
+
if [ -e "$link" ] && [ ! -L "$link" ] && [ "$FORCE" = 0 ]; then
|
|
94
|
+
say " ! $f exists (real file) — use --force to replace it with a symlink" "$Y"; continue
|
|
95
|
+
fi
|
|
96
|
+
if [ "$DRY_RUN" = 0 ]; then
|
|
97
|
+
mkdir -p "$(dirname "$link")"
|
|
98
|
+
( cd "$(dirname "$link")" && rm -f "$(basename "$f")" && ln -s "$dest" "$(basename "$f")" )
|
|
99
|
+
fi
|
|
100
|
+
say " + $f → $dest" "$G"
|
|
101
|
+
done
|
|
102
|
+
|
|
103
|
+
# --- git hook via core.hooksPath --------------------------------------------
|
|
104
|
+
if [ "$NO_HOOKS" = 0 ] && git -C "$TARGET" rev-parse --git-dir >/dev/null 2>&1; then
|
|
105
|
+
say "\n③ Git hook (core.hooksPath=githooks)" "$B"
|
|
106
|
+
if [ "$DRY_RUN" = 0 ]; then
|
|
107
|
+
chmod +x "$TARGET"/githooks/* 2>/dev/null || true
|
|
108
|
+
git -C "$TARGET" config core.hooksPath githooks
|
|
109
|
+
fi
|
|
110
|
+
say " + pre-commit (secrets + sentrux) and commit-msg (Conventional Commits) active" "$G"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# --- sentrux baseline -----------------------------------------------------
|
|
114
|
+
say "\n④ Sentrux baseline" "$B"
|
|
115
|
+
if command -v sentrux >/dev/null 2>&1; then
|
|
116
|
+
if [ "$DRY_RUN" = 0 ]; then
|
|
117
|
+
( cd "$TARGET" && sentrux gate --save . ) && say " + baseline.json generated" "$G" \
|
|
118
|
+
|| say " ! sentrux gate --save failed — generate it manually" "$Y"
|
|
119
|
+
else say " + would run: sentrux gate --save ." "$G"; fi
|
|
120
|
+
else
|
|
121
|
+
say " ! sentrux CLI missing — baseline.json is a placeholder; install it and run 'sentrux gate --save .' (docs/sentrux.md)" "$Y"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
say "\n────────────────────────────────────────" "$D"
|
|
125
|
+
say "✅ agent kit installed: $copied created, $skipped kept$( [ $DRY_RUN = 1 ] && echo ' (dry-run)')" "$G"
|
|
126
|
+
say " next: fill in the TODOs in docs/VISION.md and docs/ARCHITECTURE.md," "$D"
|
|
127
|
+
say " commit as 'chore: bootstrap agent kit (init-agentkit)'\n" "$D"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new Architecture Decision Record under docs/adr/
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Create a new ADR in `docs/adr/` documenting a structural decision for {{PROJECT}}.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. **Read [docs/adr/README.md](../../docs/adr/README.md)** for the format, lifecycle rules, and the current index. Note the next available number (max existing + 1, four-digit zero-padded).
|
|
10
|
+
|
|
11
|
+
2. **Confirm the decision is ADR-worthy.** ADRs document:
|
|
12
|
+
- New dependencies that change the surface area (new backend, new external service, new provider).
|
|
13
|
+
- Storage strategy or schema convention changes.
|
|
14
|
+
- New platform target or distribution channel.
|
|
15
|
+
- Core abstractions (new trait/protocol, new domain model, change to a central store).
|
|
16
|
+
- Hosting or secrets strategy changes.
|
|
17
|
+
- Cross-cutting patterns future contributors must follow.
|
|
18
|
+
|
|
19
|
+
ADRs do **not** document bug fixes, behavior-preserving refactors, dependency version bumps, or formatting changes. If the change is one of those, do not create an ADR — explain why and stop.
|
|
20
|
+
|
|
21
|
+
3. **Gather the inputs** before writing. Ask the user (or read context) for:
|
|
22
|
+
- A short title (≤ 70 chars).
|
|
23
|
+
- The forces / constraints that led to the decision (context).
|
|
24
|
+
- The decision in one or two sentences.
|
|
25
|
+
- At least two alternatives considered, with the chosen one marked.
|
|
26
|
+
- Consequences — what gets easier, what gets harder, what invariants the codebase must now hold, what would trigger re-evaluation.
|
|
27
|
+
|
|
28
|
+
4. **Create the file** at `docs/adr/NNNN-short-title.md` using the template from [docs/adr/0000-template.md](../../docs/adr/0000-template.md). Use `kebab-case` for the slug. Frontmatter:
|
|
29
|
+
- `id: "NNNN"` (four-digit, quoted)
|
|
30
|
+
- `status: active` (new ADRs default to `active` when the decision has been made; use `proposed` only if it's still under discussion)
|
|
31
|
+
- `date: YYYY-MM-DD` (today)
|
|
32
|
+
- Omit `superseded_by` unless this ADR supersedes a previous one (in which case also update the previous ADR to `status: superseded` + `superseded_by` link in the same commit).
|
|
33
|
+
|
|
34
|
+
5. **Update the index** in [docs/adr/README.md](../../docs/adr/README.md): add a row to the index table at the bottom in numeric order.
|
|
35
|
+
|
|
36
|
+
6. **Update [docs/ARCHITECTURE.md](../../docs/ARCHITECTURE.md) if the decision changes the active architecture state.** ARCHITECTURE.md reflects active decisions only — a superseded decision must be replaced, not appended.
|
|
37
|
+
|
|
38
|
+
7. **Commit in a single Conventional Commit** with the rest of the change that implements the decision:
|
|
39
|
+
```
|
|
40
|
+
docs(adr): NNNN <short title>
|
|
41
|
+
```
|
|
42
|
+
or as part of a `feat:` / `refactor:` commit if landing the implementation in the same change.
|
|
43
|
+
|
|
44
|
+
8. **Never edit an active ADR.** If the decision changes, create a new ADR that supersedes the previous one and update the previous ADR's frontmatter only to record `status: superseded` and `superseded_by`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: quality
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
quality:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0 # gate needs the merge base
|
|
15
|
+
|
|
16
|
+
# --- Stack toolchain (adjust to your project) -------------------------
|
|
17
|
+
# node:
|
|
18
|
+
- uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: "22.13"
|
|
21
|
+
- run: npm ci
|
|
22
|
+
# ----------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
- name: Type + test
|
|
25
|
+
run: |
|
|
26
|
+
{{CHECK_SUITE}}
|
|
27
|
+
|
|
28
|
+
- name: Install Sentrux
|
|
29
|
+
env:
|
|
30
|
+
SENTRUX_VERSION: {{SENTRUX_VERSION}}
|
|
31
|
+
run: |
|
|
32
|
+
mkdir -p "$HOME/.sentrux/bin"
|
|
33
|
+
curl -fsSL "https://github.com/sentrux/sentrux/releases/download/${SENTRUX_VERSION}/sentrux-linux-x86_64" \
|
|
34
|
+
-o "$HOME/.sentrux/bin/sentrux"
|
|
35
|
+
chmod +x "$HOME/.sentrux/bin/sentrux"
|
|
36
|
+
echo "$HOME/.sentrux/bin" >> "$GITHUB_PATH"
|
|
37
|
+
|
|
38
|
+
- name: Sentrux check (absolute rules)
|
|
39
|
+
run: sentrux check .
|
|
40
|
+
|
|
41
|
+
- name: Sentrux gate (no regression)
|
|
42
|
+
if: github.event_name == 'pull_request'
|
|
43
|
+
run: sentrux gate .
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "PLACEHOLDER — replace by running `sentrux gate --save .` at the repo root with the Sentrux CLI installed (see docs/sentrux.md). Commit the real baseline.",
|
|
3
|
+
"_generated_by": "init-agentkit placeholder",
|
|
4
|
+
"quality_signal": null,
|
|
5
|
+
"coupling_score": null,
|
|
6
|
+
"cycle_count": 0,
|
|
7
|
+
"god_file_count": 0,
|
|
8
|
+
"complex_fn_count": 0
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Sentrux architectural constraints for {{PROJECT}}.
|
|
2
|
+
#
|
|
3
|
+
# Ratchet against the current layout. Tighten thresholds as the codebase grows —
|
|
4
|
+
# never loosen without an ADR (see docs/adr/0003-sentrux-structural-quality-gates.md).
|
|
5
|
+
#
|
|
6
|
+
# Run `sentrux check .` locally before pushing.
|
|
7
|
+
# Run `sentrux gate --save .` before starting a refactor;
|
|
8
|
+
# run `sentrux gate .` before committing it.
|
|
9
|
+
|
|
10
|
+
[constraints]
|
|
11
|
+
# No import cycles.
|
|
12
|
+
max_cycles = 0
|
|
13
|
+
|
|
14
|
+
# Keep coupling healthy as the module count grows.
|
|
15
|
+
max_coupling = "B"
|
|
16
|
+
|
|
17
|
+
# Per-function cyclomatic complexity ceiling.
|
|
18
|
+
max_cc = 25
|
|
19
|
+
|
|
20
|
+
# Flag new god files early while the repo is small.
|
|
21
|
+
no_god_files = true
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# AGENTS.md — {{PROJECT}}
|
|
2
|
+
|
|
3
|
+
> [Architecture](docs/ARCHITECTURE.md) · [Abstractions](docs/ABSTRACTIONS.md) · [Vision](docs/VISION.md) · [Getting Started](docs/GETTING-STARTED.md) · [ADRs](docs/adr/README.md) · [Sentrux](docs/sentrux.md)
|
|
4
|
+
|
|
5
|
+
Write the minimum code that runs. No fluff, no gold-plating.
|
|
6
|
+
|
|
7
|
+
<!-- variant:greenfield:start -->
|
|
8
|
+
- Do not preserve backward compatibility. Remove obsolete paths instead of adding
|
|
9
|
+
compatibility layers, fallbacks, or migrations.
|
|
10
|
+
<!-- variant:greenfield:end -->
|
|
11
|
+
<!-- variant:stable:start -->
|
|
12
|
+
- Preserve backward compatibility for anything already published — public APIs, CLI
|
|
13
|
+
contracts, persisted formats, integrations. Breaking one requires a migration path
|
|
14
|
+
and a `feat!:` / `BREAKING CHANGE:` commit. Everything not yet published is fair
|
|
15
|
+
game: remove obsolete internal paths instead of adding compatibility layers.
|
|
16
|
+
<!-- variant:stable:end -->
|
|
17
|
+
- Choose the simplest implementation that fully meets the current requirements.
|
|
18
|
+
Avoid speculative abstractions, configuration, and indirection.
|
|
19
|
+
- Grow the system in layers. Start from the smallest version that works end to end,
|
|
20
|
+
and add each new capability on top of a product that already works. Never trade a
|
|
21
|
+
working product for unfinished complexity.
|
|
22
|
+
- Keep components modular and concerns clearly separated.
|
|
23
|
+
- Prefer established, well-maintained libraries when they reduce overall complexity
|
|
24
|
+
or improve reliability. Do not reimplement common functionality without a clear reason.
|
|
25
|
+
- Lean on the dependencies already in the project before writing your own
|
|
26
|
+
implementation or adding packages. Do not assume a library lacks a capability
|
|
27
|
+
without checking its documentation and types.
|
|
28
|
+
- Make architectural decisions for the long term. Do not accept a stopgap that only
|
|
29
|
+
works for now and is meant to be replaced later.
|
|
30
|
+
- Study how established products solve the problem before designing a solution. Adopt
|
|
31
|
+
their proven patterns and conventions rather than inventing an approach from scratch.
|
|
32
|
+
|
|
33
|
+
## Repository rules
|
|
34
|
+
|
|
35
|
+
- **`AGENTS.md` is the single source of guidance.** `CLAUDE.md`, `GEMINI.md`,
|
|
36
|
+
`CURSOR.md` and `AGENT.md` are symlinks to it.
|
|
37
|
+
Never edit a symlink; never let one drift into a real file.
|
|
38
|
+
- **Continuity beats restart.** Before starting new work, check `.runs/` and the
|
|
39
|
+
managed signal block at the bottom of this file: an active campaign or a
|
|
40
|
+
non-terminal run is work to continue — read its `HANDOFF.md`/`STATUS.md`,
|
|
41
|
+
re-attach the session, and `resume` or `supervise` — not to redo.
|
|
42
|
+
- **Never commit secrets.** Tokens, credentials, and service-account JSON stay in a
|
|
43
|
+
secret manager or a gitignored `.env`. The `pre-commit` hook scans the staged diff;
|
|
44
|
+
do not work around it.
|
|
45
|
+
- **No personal or production-derived data in source**, migrations, fixtures, tests,
|
|
46
|
+
or docs. Committed fixtures are synthetic. User-specific values belong in runtime
|
|
47
|
+
configuration.
|
|
48
|
+
- **Never expose internals to users.** No stack traces, internal URLs, or env var
|
|
49
|
+
names in user-facing copy.
|
|
50
|
+
- **Conventional Commits required.** `feat:`, `fix:`, `docs:`, `refactor:`, `test:`,
|
|
51
|
+
`chore:`. One logical change per commit; one bounded scope per PR. Release tooling
|
|
52
|
+
parses them — a break in a published contract ships as `feat!:` or carries a
|
|
53
|
+
`BREAKING CHANGE:` footer, never as a plain `feat:`.
|
|
54
|
+
- **Never `--no-verify`.** If a hook blocks, fix the underlying issue.
|
|
55
|
+
- **Code, comments, and identifiers in English.** Surgical changes — no opportunistic
|
|
56
|
+
refactors in feature PRs, no suppression comments to silence a linter.
|
|
57
|
+
- **Shell scripts** run under `set -euo pipefail` and are idempotent — re-running
|
|
58
|
+
completes what is missing instead of duplicating or destroying.
|
|
59
|
+
|
|
60
|
+
## Workflow
|
|
61
|
+
|
|
62
|
+
- Check `docs/adr/` before any structural choice. Branch from `main`.
|
|
63
|
+
- **TDD for behavior changes**: red → green → refactor → commit. Bug fixes start with
|
|
64
|
+
a failing regression test. Exception: pure docs, formatting, or copy changes.
|
|
65
|
+
- **E2E for key features**: any user-visible change to a primary workflow adds or
|
|
66
|
+
updates a deterministic E2E scenario, isolated from real data and credentials.
|
|
67
|
+
Unit tests do not replace it.
|
|
68
|
+
- **ADRs** live in `docs/adr/`, one decision per file, created in the same commit as
|
|
69
|
+
the code (`/create-adr`). Never edit an active ADR — supersede it. Required for a
|
|
70
|
+
new dependency that changes surface area, a storage or schema convention, a core
|
|
71
|
+
abstraction, a hosting or secrets strategy, or a cross-cutting pattern. Not for
|
|
72
|
+
behavior-preserving fixes, refactors, version bumps, or copy tweaks. After a
|
|
73
|
+
structural change, update `docs/ARCHITECTURE.md` in the same commit — it reflects
|
|
74
|
+
**active** decisions only.
|
|
75
|
+
- **Destructive actions** — merging, force-pushing, changing repository permissions,
|
|
76
|
+
dropping schema, deleting data — require explicit human sign-off in the moment.
|
|
77
|
+
An agent that hits this gate hands off to the user rather than routing around it.
|
|
78
|
+
|
|
79
|
+
## Gates
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
{{CHECK_SUITE}} # types + tests
|
|
83
|
+
sentrux check . # absolute limits (.sentrux/rules.toml)
|
|
84
|
+
sentrux gate . # no structural regression vs .sentrux/baseline.json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
CI mirrors this (`.github/workflows/quality.yml`). Before touching existing files run
|
|
88
|
+
`sentrux gate --save .` to capture the baseline; before committing run `sentrux gate .`
|
|
89
|
+
— degradation on a touched file means refactor, not commit. New files pass
|
|
90
|
+
`sentrux check .` clean. **Never silence a rule to pass** — the gate is a ratchet, and
|
|
91
|
+
every file you touch leaves with an equal-or-better score.
|
|
92
|
+
|
|
93
|
+
Done means: gates pass locally, CI is green, no secrets or personal data in the diff,
|
|
94
|
+
`README.md` updated if a public contract changed, ADR written if a structural decision
|
|
95
|
+
was made.
|
|
96
|
+
|
|
97
|
+
## {{PROJECT}} gotchas
|
|
98
|
+
|
|
99
|
+
Record every failure that cost real debugging time, with the invariant that prevents
|
|
100
|
+
it and a link to the ADR or code that must not be undone. Highest-value part of this
|
|
101
|
+
file — keep appending.
|
|
102
|
+
|
|
103
|
+
- _(none yet)_
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
Adapted from [Marcos Hernanz](https://x.com/MarcosHernanz/status/2083954734487212511).
|
|
108
|
+
Structural gate by [Sentrux](https://github.com/sentrux/sentrux).
|
|
109
|
+
`CLAUDE.md`, `GEMINI.md`, `CURSOR.md` and `AGENT.md`
|
|
110
|
+
are symlinks to this file — edit `AGENTS.md` only.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Abstractions
|
|
2
|
+
|
|
3
|
+
> The vocabulary of this codebase: the core types/modules and the contracts
|
|
4
|
+
> between them. Read this before adding a new module — reuse an abstraction
|
|
5
|
+
> before inventing one.
|
|
6
|
+
|
|
7
|
+
## Core layers
|
|
8
|
+
|
|
9
|
+
TODO — name each layer (e.g. transport / domain / lib) and its single responsibility.
|
|
10
|
+
|
|
11
|
+
## External systems
|
|
12
|
+
|
|
13
|
+
TODO — every system this repo talks to, and the boundary type that wraps it.
|
|
14
|
+
|
|
15
|
+
## Contracts & invariants
|
|
16
|
+
|
|
17
|
+
TODO — the rules that must always hold (validation points, error/UX contracts).
|
|
18
|
+
|
|
19
|
+
## Quality & governance
|
|
20
|
+
|
|
21
|
+
- Structural limits live in `.sentrux/rules.toml`; regression baseline in `.sentrux/baseline.json`.
|
|
22
|
+
- Architecture decisions are recorded as [ADRs](adr/README.md).
|
|
23
|
+
|
|
24
|
+
## Adding a new module — checklist
|
|
25
|
+
|
|
26
|
+
- [ ] Does an existing abstraction already cover this? Reuse it.
|
|
27
|
+
- [ ] Inputs/outputs validated at the boundary.
|
|
28
|
+
- [ ] Unit tests close to the change.
|
|
29
|
+
- [ ] `sentrux gate .` shows no degradation.
|
|
30
|
+
- [ ] ADR if it introduces a cross-cutting pattern or external dependency.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
> Current-state summary. ADRs in [adr/](adr/README.md) hold the history and the
|
|
4
|
+
> *why*; this file reflects only **active** decisions. Update it in the same
|
|
5
|
+
> commit as any structural change.
|
|
6
|
+
|
|
7
|
+
## High-level flow
|
|
8
|
+
|
|
9
|
+
TODO — diagram or prose of the main request/data path.
|
|
10
|
+
|
|
11
|
+
## Components
|
|
12
|
+
|
|
13
|
+
TODO — the major modules and their responsibilities.
|
|
14
|
+
|
|
15
|
+
## Runtime & hosting
|
|
16
|
+
|
|
17
|
+
TODO — where it runs, how it's deployed.
|
|
18
|
+
|
|
19
|
+
## Observability & quality
|
|
20
|
+
|
|
21
|
+
- Type checks + tests run on every push (see [Getting Started](GETTING-STARTED.md)).
|
|
22
|
+
- Structural health gated by [Sentrux](sentrux.md).
|
|
23
|
+
- Errors/telemetry: TODO.
|
|
24
|
+
|
|
25
|
+
## Security model
|
|
26
|
+
|
|
27
|
+
TODO — authn/authz, secret handling, data sensitivity.
|
|
28
|
+
|
|
29
|
+
## Related docs
|
|
30
|
+
|
|
31
|
+
- [Vision](VISION.md) · [Abstractions](ABSTRACTIONS.md) · [ADRs](adr/README.md) · [Sentrux](sentrux.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- TODO — runtime/toolchain versions.
|
|
6
|
+
- [Sentrux CLI](sentrux.md#install) for the structural quality gate.
|
|
7
|
+
|
|
8
|
+
## Quick start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# TODO: install deps
|
|
12
|
+
# TODO: configure secrets (.env from .env.example)
|
|
13
|
+
# TODO: run locally
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Daily commands
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
{{CHECK_SUITE}} # types + tests
|
|
20
|
+
sentrux check . # architectural rules
|
|
21
|
+
sentrux gate . # no structural regression
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Worktree workflow
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Create a worktree for a task (keeps main clean):
|
|
28
|
+
git worktree add ../{{PROJECT}}-<task> -b <dev>/<issue>-<slug>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Documentation map
|
|
32
|
+
|
|
33
|
+
- [Vision](VISION.md) — why this exists
|
|
34
|
+
- [Architecture](ARCHITECTURE.md) — current-state structure
|
|
35
|
+
- [Abstractions](ABSTRACTIONS.md) — the vocabulary
|
|
36
|
+
- [ADRs](adr/README.md) — decision history
|
|
37
|
+
- [Sentrux](sentrux.md) — the quality gate
|
|
38
|
+
- [AGENTS.md](../AGENTS.md) — the contributor/agent playbook
|
|
39
|
+
|
|
40
|
+
## First contribution checklist
|
|
41
|
+
|
|
42
|
+
- [ ] Read [AGENTS.md](../AGENTS.md).
|
|
43
|
+
- [ ] Run the check suite locally and confirm it's green.
|
|
44
|
+
- [ ] `sentrux gate --save .` before touching existing files.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# {{PROJECT}} — Product Vision
|
|
2
|
+
|
|
3
|
+
> TODO: replace the placeholders below with the real vision. Keep it short and
|
|
4
|
+
> opinionated — this is the "why", not the "how".
|
|
5
|
+
|
|
6
|
+
## Why this, why now
|
|
7
|
+
|
|
8
|
+
TODO — the moment that makes this worth building.
|
|
9
|
+
|
|
10
|
+
## The problem
|
|
11
|
+
|
|
12
|
+
TODO — who hurts, and how, today.
|
|
13
|
+
|
|
14
|
+
## The insight
|
|
15
|
+
|
|
16
|
+
TODO — the non-obvious bet this project makes.
|
|
17
|
+
|
|
18
|
+
## Principles
|
|
19
|
+
|
|
20
|
+
- TODO — a constraint you will not trade away.
|
|
21
|
+
- TODO — a default you optimize for.
|
|
22
|
+
|
|
23
|
+
## Near-term horizon
|
|
24
|
+
|
|
25
|
+
TODO — what "done" looks like for the next milestone.
|
|
26
|
+
|
|
27
|
+
## Non-goals (for now)
|
|
28
|
+
|
|
29
|
+
- TODO — what you are explicitly not building yet.
|
|
30
|
+
|
|
31
|
+
## Related docs
|
|
32
|
+
|
|
33
|
+
- [Architecture](ARCHITECTURE.md) · [Abstractions](ABSTRACTIONS.md) · [ADRs](adr/README.md)
|