Skip to content
Draft
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
176 changes: 143 additions & 33 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,154 @@
<!-- gitnexus:start -->
# GitNexus — Code Intelligence
# Dev Plane Engineering Contract

This project is indexed by GitNexus as **dev-plane** (5801 symbols, 16255 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
This file is the repository-wide contract for human and AI contributors. Keep implementation-specific playbooks in skills or docs; keep durable engineering rules here.

> Index stale? Run `node .gitnexus/run.cjs analyze` from the project root — it auto-selects an available runner. No `.gitnexus/run.cjs` yet? `npx gitnexus analyze` (npm 11 crash → `npm i -g gitnexus`; #1939).
## Mission and authority boundaries

## Always Do
Dev Plane is the orchestration authority for task/run lifecycle, isolated workspaces, agent assignment, approvals, evidence, verification state, review policy, landing, and release gating.

- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
- **MUST run `detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: `detect_changes({scope: "compare", base_ref: "main"})`.
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
- When exploring unfamiliar code, use `query({search_query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `context({name: "symbolName"})`.
- For security review, `explain({target: "fileOrSymbol"})` lists taint findings (source→sink flows; needs `analyze --pdg`).
The repository remains authoritative for how its code is built and verified. Do not move repository-specific build semantics into the control plane when they can remain behind `devplane.yaml`, Make, Cargo, npm, Dagger, or another repo-native command.

## Never Do
Interactive clients such as ACP adapters or `devx` are clients of Dev Plane. They may own protocol negotiation, auth, session UX, streaming, permission prompts, attach/resume, and cancel. They must not become a second orchestration authority.

- NEVER edit a function, class, or method without first running `impact` on it.
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
- NEVER rename symbols with find-and-replace — use `rename` which understands the call graph.
- NEVER commit changes without running `detect_changes()` to check affected scope.
## Non-negotiable invariants

## Resources
1. **Exact-revision evidence.** Verification evidence is valid only for the exact candidate HEAD it was produced against. A new commit invalidates prior revision-bound evidence. Preserve `EvidenceBundle.ValidateHead` semantics.
2. **Repository-native verification.** Agent claims are never proof. Required verification is the command declared by this repository and/or CI.
3. **Fail closed on permissions.** Unsupported, ambiguous, or denied permission escalation must not silently become approval.
4. **Isolated work.** Parallel implementation work uses isolated worktrees/containers. Do not let multiple agents mutate one working tree.
5. **Smallest safe change.** Prefer minimal behavior-preserving changes over opportunistic refactors.
6. **Regression proof.** For behavior changes and bug fixes, add a failing regression test first when practical, then implement the smallest fix and rerun the relevant suite.
7. **No weakened gates.** Never make CI green by deleting assertions, skipping tests, broadening mocks, downgrading required fixtures, or marking required checks optional.
8. **No fake integration evidence.** If a task requires PostgreSQL, NATS, a browser, a real provider, or another concrete fixture, a mock/substitute does not satisfy that requirement.
9. **Risk determines review.** Security, auth, policy, tenancy, migrations, landing, deployment, and control-plane invariants receive stricter verification and review than docs or isolated presentation changes.
10. **Git is code truth; Dev Plane is execution truth.** Git records what changed. Dev Plane records what task/run verified which revision. Do not conflate the two.

| Resource | Use for |
|----------|---------|
| `gitnexus://repo/dev-plane/context` | Codebase overview, check index freshness |
| `gitnexus://repo/dev-plane/clusters` | All functional areas |
| `gitnexus://repo/dev-plane/processes` | All execution flows |
| `gitnexus://repo/dev-plane/process/{name}` | Step-by-step execution trace |
## Standard workflow

## CLI
For non-trivial changes:

| Task | Read this skill file |
|------|---------------------|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
1. Read the issue/task and identify explicit acceptance criteria.
2. Inspect `devplane.yaml` and the relevant code/tests.
3. For unfamiliar code, use GitNexus to identify execution flows and blast radius before editing symbols.
4. Create or use an isolated worktree/workspace.
5. Reproduce the failure or encode the desired behavior in a test before the implementation when the change affects behavior.
6. Implement the smallest safe change.
7. Run the narrowest relevant verification first, then escalate through the verification ladder required by the changed surface.
8. Run GitNexus change detection before handoff/commit when GitNexus is available.
9. Bind reported evidence to the exact HEAD that was verified.
10. Use independent review for medium/high-risk logic and all surfaces required by `devplane.yaml`.
11. Treat repository CI as the final automated merge authority.

<!-- gitnexus:end -->
## Canonical verification ladder

Use `bash scripts/verify.sh <profile>` locally and in automation. Profiles are cumulative only where explicitly documented by the script.

- `static` — Go lint/vet, web lint + typecheck, SDK typecheck.
- `test` — Go/SDK tests plus web tests.
- `build` — production builds.
- `standard` — static + test + build. This is the normal pre-PR contract.
- `race` — standard + Go race tests.
- `integration` — race + credential/fixture-backed integration tests.
- `live` — integration + live end-to-end gates; requires the documented external credentials/services.

Do not substitute a lower profile for a higher profile required by `devplane.yaml`, the task acceptance criteria, or CI.

## Risk and review policy

Use the repository contract in `devplane.yaml` as the machine-readable source of truth. As a default mental model:

- Low risk: docs/comments/presentation-only changes — deterministic checks may be sufficient.
- Medium risk: ordinary business logic/refactors — independent review is preferred.
- High risk: auth, permissions, policies, repository protocol, evidence/verification, security scanning, migrations, CI/landing/release — require the repository's full gate plus independent review and any declared human approval.
- Critical/destructive operations: preserve explicit human approval and fail closed.

Do not infer that a change is low risk merely because the diff is small.

## GitNexus workflow

GitNexus is the code-intelligence layer, not the engineering constitution.

When GitNexus is available:

- Before modifying an existing function, class, or method, run upstream impact analysis for the symbol and note the blast radius.
- For unfamiliar behavior, use GitNexus execution-flow queries/context before grep-only exploration.
- Treat HIGH or CRITICAL impact as a signal to narrow scope and increase verification/review.
- Before handoff/commit, run change detection against the intended base (normally `main`) and confirm only expected symbols/flows changed.
- Use GitNexus rename/refactor operations rather than textual find-and-replace for symbol renames.

Detailed GitNexus procedures live under `.claude/skills/gitnexus/`.

If GitNexus is unavailable in the execution environment, do not fabricate its results. State the limitation, keep the change narrow, and rely on repository tests/CI and independent review before merge.

## Repository commands

Prefer checked-in commands over ad hoc equivalents.

Development and services:

```bash
make dev
make docker-up
make docker-down
make docker-logs
```

Verification:

```bash
bash scripts/verify.sh static
bash scripts/verify.sh test
bash scripts/verify.sh build
bash scripts/verify.sh standard
bash scripts/verify.sh race
bash scripts/verify.sh integration
bash scripts/verify.sh live
```

Useful narrower targets include:

```bash
make test-api
make test-cli
make test-worker
make test-packages
make lint-go
make lint-web
make build-api
make build-cli
make build-worker
make build-runner
make build-web
```

Database and code generation:

```bash
make migrate
make db-status
make gen-db
```

Destructive targets such as `make db-reset` and `make docker-down-volumes` require explicit awareness of their destructive effect.

## Definition of done

A change is not complete merely because code was edited or an agent says it is complete. Before handoff, provide evidence for all applicable items:

- Acceptance criteria are implemented.
- Regression/behavior tests cover the changed behavior when applicable.
- The required verification profile passes for the exact HEAD being handed off.
- Required real fixtures (for example PostgreSQL or browser/system tests) were actually exercised.
- GitNexus change detection is clean/expected when available.
- High-risk paths received the independent review / human approval required by `devplane.yaml`.
- No required gate was skipped, weakened, or replaced by a non-equivalent substitute.
- The working tree/workspace is clean enough for a deterministic handoff.

## Never do

- Do not claim tests passed unless they were run against the reported revision.
- Do not merge or promote based on evidence from an older HEAD.
- Do not silently reinterpret acceptance criteria to fit the implementation.
- Do not hide failures as "pre-existing" without evidence.
- Do not add another orchestration path when the requirement belongs in Dev Plane, the repository contract, or an existing adapter.
- Do not duplicate long-lived policy across `AGENTS.md`, `CLAUDE.md`, editor config, and shell prompts. Keep `AGENTS.md` canonical and make tool-specific files point here.
45 changes: 4 additions & 41 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,7 @@
<!-- gitnexus:start -->
# GitNexus — Code Intelligence
# Claude Code Instructions

This project is indexed by GitNexus as **dev-plane** (5801 symbols, 16255 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
`AGENTS.md` is the canonical repository-wide engineering contract. Read and follow it before making changes.

> Index stale? Run `node .gitnexus/run.cjs analyze` from the project root — it auto-selects an available runner. No `.gitnexus/run.cjs` yet? `npx gitnexus analyze` (npm 11 crash → `npm i -g gitnexus`; #1939).
Claude-specific implementation playbooks live under `.claude/skills/`. In particular, use `.claude/skills/gitnexus/` for GitNexus exploration, impact analysis, debugging, refactoring, and change-detection procedures.

## Always Do

- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
- **MUST run `detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: `detect_changes({scope: "compare", base_ref: "main"})`.
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
- When exploring unfamiliar code, use `query({search_query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `context({name: "symbolName"})`.
- For security review, `explain({target: "fileOrSymbol"})` lists taint findings (source→sink flows; needs `analyze --pdg`).

## Never Do

- NEVER edit a function, class, or method without first running `impact` on it.
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
- NEVER rename symbols with find-and-replace — use `rename` which understands the call graph.
- NEVER commit changes without running `detect_changes()` to check affected scope.

## Resources

| Resource | Use for |
|----------|---------|
| `gitnexus://repo/dev-plane/context` | Codebase overview, check index freshness |
| `gitnexus://repo/dev-plane/clusters` | All functional areas |
| `gitnexus://repo/dev-plane/processes` | All execution flows |
| `gitnexus://repo/dev-plane/process/{name}` | Step-by-step execution trace |

## CLI

| Task | Read this skill file |
|------|---------------------|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |

<!-- gitnexus:end -->
Do not duplicate durable repository policy in this file. If a general engineering rule changes, update `AGENTS.md` instead.
70 changes: 70 additions & 0 deletions devplane.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
version: 1

commands:
doctor: go version && node --version && docker --version
dev: make dev
logs: make docker-logs

verification:
fast:
command: bash scripts/verify.sh static
timeout_seconds: 600
changed:
command: bash scripts/verify.sh standard
timeout_seconds: 1800
full:
command: bash scripts/verify.sh race
timeout_seconds: 2400
postgres:
command: cd packages/db && test -n "$POSTGRES_TEST_DATABASE_URL" && go test ./... -run TestRunMigrationsPostgres -v
timeout_seconds: 600
integration:
command: bash scripts/verify.sh integration
timeout_seconds: 3000
live:
command: bash scripts/verify.sh live
timeout_seconds: 3600

work:
isolation: worktree
max_parallel_cost: 4
require_clean_handoff: true

review:
independent: true
exact_head: true

risk:
- paths:
- packages/db/migrations/**
level: high
requires:
- full
- postgres
- independent_review
- human_approval

- paths:
- packages/repoprotocol/**
- packages/verifier/**
- packages/readiness/**
- packages/reviewer/**
- packages/policies/**
- packages/securityscan/**
- apps/api/internal/auth/**
level: high
requires:
- full
- independent_review
- human_approval

- paths:
- devplane.yaml
- scripts/verify.sh
- .github/workflows/**
- docker-compose.yml
level: high
requires:
- full
- independent_review
- human_approval
62 changes: 62 additions & 0 deletions packages/repoprotocol/repository_contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package repoprotocol

import (
"os"
"reflect"
"testing"
)

func TestRepositoryContractParsesAndPreservesSafetyDefaults(t *testing.T) {
raw, err := os.ReadFile("../../devplane.yaml")
if err != nil {
t.Fatalf("read repository contract: %v", err)
}

cfg, err := ParseConfigYAML(raw)
if err != nil {
t.Fatalf("ParseConfigYAML(devplane.yaml) error = %v", err)
}

if cfg.Work.Isolation != IsolationWorktree {
t.Fatalf("work isolation = %q, want %q", cfg.Work.Isolation, IsolationWorktree)
}
if !cfg.Work.RequireCleanHandoff {
t.Fatal("require_clean_handoff = false, want true")
}
if !cfg.Review.Independent {
t.Fatal("review.independent = false, want true")
}
if !cfg.Review.ExactHead {
t.Fatal("review.exact_head = false, want true")
}

for _, name := range []string{"fast", "changed", "full", "postgres", "integration", "live"} {
if _, ok := cfg.Verification[name]; !ok {
t.Fatalf("verification profile %q is missing", name)
}
}

migrationGates := cfg.RequiredGatesForPaths([]string{"packages/db/migrations/999_example.sql"})
wantMigrationGates := []string{"full", "postgres", GateIndependentReview, GateHumanApproval}
if !reflect.DeepEqual(migrationGates, wantMigrationGates) {
t.Fatalf("migration gates = %#v, want %#v", migrationGates, wantMigrationGates)
}

protocolGates := cfg.RequiredGatesForPaths([]string{"packages/repoprotocol/protocol.go"})
wantProtocolGates := []string{"full", GateIndependentReview, GateHumanApproval}
if !reflect.DeepEqual(protocolGates, wantProtocolGates) {
t.Fatalf("repository protocol gates = %#v, want %#v", protocolGates, wantProtocolGates)
}

workflowGates := cfg.RequiredGatesForPaths([]string{".github/workflows/ci.yml"})
wantWorkflowGates := []string{"full", GateIndependentReview, GateHumanApproval}
if !reflect.DeepEqual(workflowGates, wantWorkflowGates) {
t.Fatalf("workflow gates = %#v, want %#v", workflowGates, wantWorkflowGates)
}

contractGates := cfg.RequiredGatesForPaths([]string{"devplane.yaml", "scripts/verify.sh"})
wantContractGates := []string{"full", GateIndependentReview, GateHumanApproval}
if !reflect.DeepEqual(contractGates, wantContractGates) {
t.Fatalf("contract gates = %#v, want %#v", contractGates, wantContractGates)
}
}
Loading
Loading