Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .config/starship.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
format = "$directory$git_branch$git_status$package$ocaml$zig$rust$bun$nodejs$deno$perl$python$golang$java$kotlin$lua$php$ruby$haskell$elixir$erlang$julia$nim$rlang$swift$terraform$docker_context$cmd_duration$line_break$character"
add_newline = false
scan_timeout = 50
command_timeout = 2000

[directory]
style = "bold cyan"
Expand Down Expand Up @@ -34,6 +35,7 @@ style = "bold yellow"

[zig]
style = "bold #f7a41d"
detect_files = [".tool-versions", "build.zig", "build.zig.zon"]

[rust]
style = "bold red"
Expand All @@ -53,6 +55,7 @@ style = "bold magenta"

[python]
style = "bold yellow"
detect_files = [".tool-versions", ".python-version", "requirements.txt", "pyproject.toml", "setup.py", "Pipfile", "poetry.lock"]

[golang]
style = "bold cyan"
Expand Down
46 changes: 44 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,40 @@ Execution pattern:
- Before creating any new `*.zig` file, read `docs/ZIG_RULES.md` and follow its rules first.
- When writing or reviewing any Zig code that calls `conn.query()`: verify `.drain()` is present in the same function before `deinit()`. Run `make check-pg-drain` to confirm. Use `conn.exec()` instead whenever no result rows are needed.
- For date-time entries in docs/notes, use format `Feb 02, 2026: 10:30 AM`.
- Any edit touching `schema/*.sql`, `schema/embed.zig`, or the migration array in `src/cmd/common.zig` — even a one-line fix — invokes the `Schema Table Removal Guard` (section below). No exceptions.

## Schema Table Removal Guard (pre-v2.0.0)

This guard fires on ACTIONS, not lifecycle phases. It runs every time, regardless of whether you are in PLAN, EXECUTE, a bug fix, or an ad-hoc SQL edit.

**Trigger — before any of these, you MUST run `cat VERSION` and state the result in your user-facing message:**

- Creating, editing, or deleting any file under `schema/*.sql`.
- Editing `schema/embed.zig` (adding or removing an `@embedFile` constant).
- Editing the canonical migration array in `src/cmd/common.zig`.
- Writing the tokens `DROP TABLE`, `ALTER TABLE`, or `SELECT 1;` into any SQL file.
- Accepting a spec dimension that prescribes a "DROP migration", "ALTER migration", or "version marker".

**If `cat VERSION` < 2.0.0 (teardown-rebuild era):**

- To remove a table: (1) `rm schema/NNN_foo.sql`, (2) remove the `@embedFile` constant from `schema/embed.zig`, (3) remove the matching entry from the canonical migration array in `src/cmd/common.zig` and update the array length + any index-based tests.
- **Forbidden:** `ALTER TABLE`, `DROP TABLE`, `SELECT 1;` placeholders, version-marker files with comment-only content, or any "keep the file for slot numbering" pattern. Migration slot numbers are not sacred pre-v2.0; gaps are fine because the DB is wiped on every rebuild.
- **If a spec conflicts with this rule, AMEND THE SPEC before execution.** The spec is an instance; this rule is the constant.

**If `cat VERSION` >= 2.0.0 (production-data era):**

- Use proper `ALTER`/`DROP` migrations in new numbered files. The pre-v2.0 teardown branch is no longer valid.

**State the guard output explicitly** in your user-facing message before the edit, in this format:

```
SCHEMA GUARD: VERSION=0.5.0 (<2.0.0) → full teardown branch.
Deleting: schema/008_harness_control_plane.sql
Removing: schema.harness_control_plane_sql from embed.zig
Removing: version 8 entry from canonicalMigrations()
```

Skipping the guard output is a rule violation even if the edit itself is correct. If the user issues an explicit override, print `SCHEMA GUARD: SKIPPED per user override (reason: ...)` so the bypass is visible in the log.

## Specification Standards

Expand Down Expand Up @@ -264,8 +298,13 @@ Required outputs:
- [ ] **`zombiectl` CLI changes** — does this change require new subcommands, flags, or output format changes in the npm CLI? If yes, note that the project manager must approve CLI surface changes (create a skill ticket if needed).
- [ ] **User-facing doc changes** — do docs at `docs.usezombie.com` need updating? If yes, list pages.
- [ ] **Release notes** — will this ship as a version bump? If yes, note the version (minor for features, patch for fixes) and update `/Users/kishore/Projects/docs/changelog.mdx` with a new `<Update>` block during CHORE(close).
- [ ] **Schema changes** — does this change add/modify/remove database tables, columns, or constraints? If yes: (a) each new SQL file must be ≤100 lines and single-concern (one table or one logical group), (b) update `schema/embed.zig` and `src/cmd/common.zig` migration array, (c) verify `docs/SCHEMA_CONVENTIONS.md` is followed. Full teardown-rebuild is allowed until v0.5.0 — no ALTER migrations needed.
- [ ] **Schema teardown (pre-production only)** — if removing tables before first production deploy: edit `CREATE TABLE` source files directly (no DROP migrations). When all tables in a file are removed, keep the file as a version marker with a comment (`-- MN_WS: removed. Kept as version marker.`). Never delete migration files — later migrations depend on slot numbering. See `docs/greptile-learnings/RULES.md` rule 41.
- [ ] **Schema changes** — does this change add/modify/remove database tables, columns, or constraints? If yes: (a) each new SQL file must be ≤100 lines and single-concern (one table or one logical group), (b) update `schema/embed.zig` and `src/cmd/common.zig` migration array, (c) verify `docs/SCHEMA_CONVENTIONS.md` is followed.
- [ ] **Schema teardown** — if the change removes or modifies tables, invoke the `Schema Table Removal Guard` section (above, near Oracle Operational Defaults) and print its output in PLAN before any file edit. The guard is action-triggered and also fires at EXECUTE regardless of whether it ran here.
- [ ] **Spec-vs-rules conflict check** — before executing a spec's prescribed approach, test it against AGENTS.md and `docs/greptile-learnings/RULES.md`. If the spec conflicts with a rule, **amend the spec first**, then execute. Common traps:
- Spec prescribes a DROP/ALTER migration or `SELECT 1;` marker while `cat VERSION` < 2.0.0 → violates the `Schema Table Removal Guard`. Correct approach: fully delete SQL file + embed entry + migration array entry.
- Spec says "remove endpoints" without returning 410 while `cat VERSION` >= 2.0.0 → violates **RULE EP4**. Correct approach: return HTTP 410 Gone with a named error code, not 404. (Pre-v2.0: bare 404 is allowed per RULE EP4 carve-out.)
- Spec prescribes `conn.query()` without `.drain()` → violates the zig-pg-drain rule. Use `conn.exec()` or add `.drain()`.
- **Spec is an instance, rules are the constant.** Never silently execute a spec that violates an authoritative rule.

Restrictions:

Expand All @@ -283,6 +322,8 @@ Exit criteria:

**Before writing any Zig code**, additionally read `docs/ZIG_RULES.md`. It contains Zig-specific patterns (drain/dupe lifecycle, cross-compile verification, TLS transport, memory safety) that RULES.md references but does not duplicate.

**Before editing any file under `schema/`, `schema/embed.zig`, or the migration array in `src/cmd/common.zig`, invoke the `Schema Table Removal Guard` (top of this file) and print its output in the user-facing message.** This fires even if the guard already ran at PLAN, and even if the edit is prescribed by a spec — no exceptions.

Required outputs:

- Minimal, scoped file edits.
Expand Down Expand Up @@ -390,6 +431,7 @@ Required outputs:
- Spec moved from `docs/v1/active/` to `docs/v1/done/` (only if fully complete).
- Spec move committed on the feature branch.
- **Release doc updated** in `/Users/kishore/Projects/docs/changelog.mdx` for every milestone/workstream completion. Add a new `<Update>` MDX block — do NOT create `docs/v*/ship/` files.
- **Ripley's Log written** in `docs/v2/agent-docs/RIPLEYS_LOG_{MMM}_{DD}_{HH_MM}.md` (example: `RIPLEYS_LOG_APR_12_15_30.md`). A first-person, dated session log of decisions made, assumptions surfaced, dead ends, trade-offs considered, and follow-ups deferred — the things that don't belong in commit messages or the spec but matter for the next agent picking up the thread. Commit alongside the spec move. Required for every non-trivial CHORE(close), not optional.
- **Orphan sweep completed** (Rule 30). For every renamed/deleted/changed symbol in the branch, verify zero non-historical references remain across schema, Zig, JS, tests, and docs. This is a hard gate — do not open the PR with stale references.

#### Release Doc Generation
Expand Down
38 changes: 16 additions & 22 deletions docs/greptile-learnings/RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,10 @@ Reference a rule as `RULE NDC`, `RULE OWN`, etc.
**Tags:** zig, js, testing
**Ref:** M3_001 agentmail domain was .to in prod, .dev in tests, .com in spec docs.

## RULE ERH — Every ERR_* code must have a hint() entry
## RULE ERH — ~~Every ERR_* code must have a hint() entry~~ ELIMINATED (M16_001)

**Rule:** When adding an error code to codes.zig, add a corresponding hint() entry with actionable operator guidance.
**Why:** Error codes without hints are useless in production diagnostics.
**Status:** ELIMINATED by M16_001 — Entry struct requires `.hint` field; comptime asserts `hint.len > 0`.
**Tags:** zig
**Ref:** M3_001 ERR_TOOL_API_FAILED and others added without hints — caught in review.

## RULE DRV — Don't derive values by slicing related fields

Expand All @@ -289,19 +287,19 @@ Reference a rule as `RULE NDC`, `RULE OWN`, etc.
**Tags:** zig
**Ref:** M3_001 HMAC version "v0" derived by slicing "v0=" prefix — fixed with explicit hmac_version field.

## RULE SCH — Pre-v2.0 schema removal: delete contents, keep SELECT 1
## RULE SCH — Pre-v2.0 schema removal: full teardown, no markers, no DROP

**Rule:** While `cat VERSION` < 2.0.0 (teardown-rebuild era), remove tables by replacing file contents with `SELECT 1;`. After VERSION >= 2.0.0 (production data exists), use proper ALTER/DROP migrations. `make test` validates every migration produces at least one statement.
**Why:** Migration runner replays from scratch. Every file must produce at least one valid SQL statement — `make test` catches empty/broken files without needing a DB.
**Rule:** While `cat VERSION` < 2.0.0 (teardown-rebuild era), removing tables MUST be a full teardown: (1) delete the SQL file (`rm schema/NNN_foo.sql`), (2) remove the `@embedFile` constant from `schema/embed.zig`, (3) remove the migration array entry from `src/cmd/common.zig` and update its array length + any index-based tests. Never write ALTER TABLE, DROP TABLE, or `SELECT 1;` placeholders. Never keep version-marker files. Migration slot numbers are not sacred pre-v2.0 — the DB is wiped on every rebuild, and gaps in numbering are fine. After VERSION >= 2.0.0, switch to proper ALTER/DROP migrations in new numbered files.
**Why:** Markers accumulate dead code and still force CI to splitter-parse them. Pre-v2.0 there is zero production data to protect; full removal is cleaner and leaves no false grep hits or stale migration slots.
**Tags:** sql, process
**Ref:** M10_001 comment-only version markers failed CI; apostrophe in "slots" opened unterminated string literal in splitter.
**Ref:** M17_001 harness teardown — supersedes prior "replace with `SELECT 1;`" guidance. Under the old rule, M10_001 comment-only markers broke CI (apostrophe in "slots" opened unterminated string in splitter); full deletion avoids the marker problem entirely.

## RULE EP4 — Removed endpoints return 410 Gone, not 404
## RULE EP4 — Removed endpoints return 410 Gone, not 404 (post-v2.0 only)

**Rule:** Intentionally removed endpoints return HTTP 410 Gone with a named error code, not 404.
**Why:** 410 signals permanent intentional removal to clients and monitors; 404 implies a routing error.
**Rule:** While `cat VERSION` < 2.0.0 (teardown-rebuild era), removed endpoints MAY simply 404 — API drift is allowed because there are no stable external clients. Do NOT write 410 Gone stubs for pre-v2.0 removals; they are ceremony without value. Once VERSION >= 2.0.0, intentionally removed endpoints MUST return HTTP 410 Gone with a named error code 404 implies a routing error to monitors and clients, 410 signals permanent intentional removal.
**Why:** Pre-v2.0 mirrors the schema teardown policy (RULE SCH) — we tear down DB + APIs freely because nobody downstream is pinned to them. Post-v2.0, 410 becomes load-bearing for client behavior and deprecation signals.
**Tags:** zig, api
**Ref:** M10_001 all /v1/runs/* and /v1/specs return ERR_PIPELINE_V1_REMOVED 410.
**Ref:** M10_001 shipped /v1/runs/* + /v1/specs as 410 stubs before this rule was scoped. M17_001 removed /v1/harness/* and /v1/agents/{id} as bare 404s under the pre-v2.0 carve-out.

## RULE FXS — Fixed-size scan buffers are security bypasses

Expand All @@ -324,12 +322,10 @@ Reference a rule as `RULE NDC`, `RULE OWN`, etc.
**Tags:** zig
**Ref:** M6_001 content scanner returned .truncated but eventTypeForScan mapped it to null — no event fired.

## RULE BRQ — Large comptime loops need @setEvalBranchQuota
## RULE BRQ — ~~Large comptime loops need @setEvalBranchQuota~~ ELIMINATED (M16_001)

**Rule:** Add `@setEvalBranchQuota(N)` as the first line of any `comptime {}` block that iterates over a registry table with string comparison. Formula: `N ≈ code_count × table_size × avg_string_len`, round to next power-of-ten. Add a comment with the math.
**Why:** Default quota is 1000. 130 codes × 131 entries × char-by-char `std.mem.eql` = ~2.2M comparisons — blows the quota silently with "evaluation exceeded 1000 backwards branches".
**Tags:** zig, comptime, testing
**Ref:** M11_001 m11_001_coverage_test.zig — comptime exhaustive coverage for error code registry.
**Status:** ELIMINATED by M16_001 — no cross-file comptime loop. Validation is inside error_registry.zig with its own quota.
**Tags:** zig, comptime

## RULE EMB — @embedFile cannot cross src/ boundary

Expand All @@ -338,12 +334,10 @@ Reference a rule as `RULE NDC`, `RULE OWN`, etc.
**Tags:** zig, comptime, testing
**Ref:** M11_001 §3.1 — OpenAPI ErrorBody validation moved to scripts/check_openapi_errors.py + make check-openapi-errors.

## RULE SNT — Registry sentinels must be distinct from real entries
## RULE SNT — ~~Registry sentinels must be distinct from real entries~~ ELIMINATED (M16_001)

**Rule:** In any code registry with a fallback sentinel (e.g. `UNKNOWN_ENTRY`), the sentinel's key field must NOT match any real registered entry. Use a distinct value that cannot appear in the real table. Add a test that verifies the sentinel is absent from the table.
**Why:** A sentinel whose code matches a real entry causes tests to silently pass with wrong semantics and breaks comptime coverage gates that assume the sentinel is outside the table.
**Tags:** zig, error-handling, design
**Ref:** M11_001 error_table.zig — UNKNOWN_ENTRY.code was "UZ-INTERNAL-001" (real 503 entry), renamed to "UZ-UNKNOWN" (distinct sentinel).
**Status:** ELIMINATED by M16_001 — UNKNOWN sentinel is defined outside REGISTRY; comptime assertion prevents collision.
**Tags:** zig, error-handling

## RULE SSM — Use StaticStringMap for O(1) static registry lookup

Expand Down
Loading