Quickstart
gndctrl works by annotating your repository with structured markers that any AI agent can read and enforce. No framework required — just a .gndctrl file and inline comments.
-
1
Create a
.gndctrlfile at your project rootDeclare your zones, their stability tiers, and which file paths they cover.
airspace: null version: "0.1.0" zones: PAYMENT: stability: sensitive type: [code, data] minimum_agent_class: heavy paths: - "src/billing/*" - "src/api/payment*" AUTH: stability: stable type: [code] paths: - "src/auth/*" UI: stability: active type: [design, code] paths: - "src/components/*" - "src/styles/*"airspace: PMT version: "0.1.0" master_ref: "../.gndctrl" zones: STRIPE_SYNC: stability: sensitive type: [code, data] minimum_agent_class: heavy deps: [AUTH://AUTH_CORE, PMT://WEBHOOK_HANDLER] paths: - "src/billing/stripe*" WEBHOOK_HANDLER: stability: stable type: [code] minimum_agent_class: medium deps: [AUTH://AUTH_CORE] paths: - "src/webhooks/*" -
2
Add zone markers to your files
Mark file regions with
@gndctrl:zoneSTART / END pairs. Tag non-obvious functions with@gndctrl:node.# @gndctrl:zone START | id=PAYMENT | stability=sensitive | deps=[AUTH_CORE] # @gndctrl:node id=PAYMENT.charge_user | risk=high | touches=[stripe_api,ledger] | crid=PMT-20260430-001 # @gndctrl:node note="Not idempotent — caller must hold a distributed lock before invoking." async def charge_user(user_id: str, amount_cents: int) -> Receipt: ... # @gndctrl:zone END | id=PAYMENT -
3
Configure your agent
Drop the agent contract into a
CLAUDE.md,AGENTS.md, or system prompt. The agent reads your.gndctrlat the start of each session and enforces zone rules automatically — no plugin or SDK required.
Marker syntax
gndctrl uses three layers of annotation. Each layer is additive — start with directory zones, add file markers where paths aren't enough, and add node markers on functions that need special handling.
Layer 1 — Directory zones (in .gndctrl)
The source of truth. Any file matching a zone's paths pattern automatically inherits that zone's stability and access rules. New files added to the path are captured automatically without touching any source files.
Layer 2 — File-level zone markers
Used when a file belongs to a zone the path pattern wouldn't catch, or when a single file spans multiple zones. Every START must have a matching END — the Auditor flags unclosed zones as integrity errors.
# @gndctrl:zone START | id=PAYMENT | stability=sensitive | deps=[AUTH_CORE] | type=code
# @gndctrl:zone meta | owner=adam | doc=.gndctrl#zones/payment
def process_payment(...):
...
# @gndctrl:zone END | id=PAYMENT
// @gndctrl:zone START | id=AUTH://AUTH_CORE | stability=stable | deps=[] | type=code
// @gndctrl:zone meta | owner=adam | doc=.gndctrl#zones/auth-core
export async function verifyToken(token: string): Promise<User> { ... }
// @gndctrl:zone END | id=AUTH://AUTH_CORE
// @gndctrl:zone START | id=CHI://DATA_PIPELINE | stability=active | deps=[AUTH://AUTH_CORE] | type=data
func ingestRecord(ctx context.Context, record Record) error { ... }
// @gndctrl:zone END | id=CHI://DATA_PIPELINE
/* @gndctrl:zone START | id=DSN://DESIGN_SYSTEM | stability=stable | deps=[] | type=design */
:root { --color-primary: #82e5b3; }
/* @gndctrl:zone END | id=DSN://DESIGN_SYSTEM */
Cross-airspace references use AIRSPACE://ZONE_ID syntax in fleet mode. Local references within the same airspace omit the prefix.
Layer 3 — Function-level node markers
The most granular layer. Place a node marker on any function that contains a workaround, a fragile dependency, or a non-obvious invariant. Every node marker requires a matching logbook entry keyed by its CRID.
# @gndctrl:node id=PAYMENT.reconcile | risk=high | touches=[ledger,webhook_queue,stripe_api] | crid=PMT-20260430-001
# @gndctrl:node note="Not idempotent. Caller must acquire distributed lock before invoking."
async def reconcile(event: dict) -> bool:
...
// @gndctrl:node id=AUTH://AUTH_CORE.verifyToken | risk=high | touches=[jwt_store] | crid=AUTH-20260430-001
export async function verifyToken(token: string): Promise<User> { ... }
// @gndctrl:node id=CHI://DATA_PIPELINE.ingestRecord | risk=medium | touches=[postgres,redis] | crid=CHI-20260430-001
func ingestRecord(ctx context.Context, record Record) error { ... }
Node marker field reference
| Field | Required | Values | Description |
|---|---|---|---|
| id | required | [AIRSPACE://]ZONE.fn |
Namespaced under parent zone. Airspace prefix required in fleet mode. |
| risk | required | low medium high critical |
Risk level for this specific function. |
| touches | optional | [system, ...] |
External systems this function reaches. Agents flag new touches they introduce. |
| note | optional | String | Short inline note surfaced to agents at pre-flight. Keep to one sentence. |
| crid | required if non-obvious | ZONE-YYYYMMDD-SEQ |
Links this marker to its logbook entry. See CRID format. |
| minimum_agent_class | optional | ultralight … super |
Override the zone-level class requirement for this specific function. |
Stability tiers
Six tiers govern how agents interact with each zone. Tiers apply identically in single and fleet mode. Cross-airspace dependencies inherit the stability rules of the zone they reference.
| Tier | Aviation equivalent | Agent behaviour |
|---|---|---|
| locked | Prohibited airspace | Agent must not modify. Surfaces proposed change as diff for human review only. Requires explicit human clearance before any action. |
| sensitive | Restricted airspace | Agent reads full zone doc and all dep chain docs. Surfaces a risk summary before proceeding. Denied if agent class is below minimum_agent_class. |
| stable | Approach controlled (Class C/D) | Agent reads full zone doc before structural changes. Flags cross-zone edits to the user before proceeding. |
| active | Controlled (Class E) | Normal development. Dependency check required for cross-zone changes. No additional restrictions. |
| experimental | Uncontrolled (Class G) | Agents operate freely. No dep check required. Right for early-stage or throwaway work. |
| deprecated | Decommissioned airspace | Flagged for removal. No new dependencies may point here. Agent suggests migration path instead of extending the zone. |
Zones may lower stability from master defaults during active development. A locked designation may never be raised without explicit human approval. Cross-airspace zones may only be overridden by the owning airspace.
Weight classes & providers
Every agent operating under gndctrl is assigned a weight class — borrowed from aviation's aircraft weight classification system. Weight class determines which zones an agent is cleared to enter. The spec is provider-agnostic: any agent from any provider can participate as long as it declares its class and follows the pre-flight protocol.
| Weight class | Aviation reference | Role | Current providers |
|---|---|---|---|
| Super | A380, An-225 | Frontier reasoning models. Reserved for locked zones and critical architectural decisions. |
Claude Opus |
| Heavy | 747, 777 | Large capable models. Standard for sensitive zones, complex planning, security review. |
Claude Sonnet |
| Medium | 737, A320 | Mid-size models. Code generation, UI work, standard active-zone tasks. |
Gemini, GPT-4o, Copilot |
| Light | Cessna 172 | Small fast models. Summaries, markdown updates, simple checks on experimental zones. |
Small local models (3B–7B) |
| Ultralight | Drone / glider | Scripted or rule-based agents. Audits, linting, file watching. No LLM required. | gndctrl Auditor, gndctrl Writer |
Weight class is a floor, not a ceiling. A heavier agent is always cleared to enter a lighter zone. Clearance is only denied when an agent's class falls below a zone's minimum_agent_class.
In multi-agent environments, the scheduler holds a task until a sufficiently capable agent is free — or escalates to human to decide whether to override. This makes parallel development safe across mixed-provider fleets running Claude, Gemini, Codex, and local models side by side.
Adding a new provider
Any agent that can read a .gndctrl file and follow the pre-flight protocol qualifies. Declare the weight class in the agent's system prompt or configuration. The spec does not require a specific API or SDK — it is a documentation and annotation standard that any tool can implement.
.gndctrl schema
The .gndctrl file is a YAML document at your project root. It declares your zone registry, stability tiers, dependency graph, and project conventions.
Single mode
One project, one file, no fleet overhead. airspace is null or omitted.
airspace: null
version: "0.1.0"
project:
name: my-project
description: "Short description"
architecture: "Single-page app, FastAPI backend, SQLite"
zones:
PAYMENT:
stability: sensitive
type: [code, data]
minimum_agent_class: heavy
deps: [AUTH]
paths:
- "src/billing/*"
- "src/api/payment*"
gotchas:
- "Stripe webhook events are not idempotent — see logbook PMT-20260430-001"
AUTH:
stability: stable
type: [code]
minimum_agent_class: medium
deps: []
paths:
- "src/auth/*"
UI:
stability: active
type: [design, code]
deps: []
paths:
- "src/components/*"
- "src/styles/*"
decision_log: []
known_solutions: []
Fleet mode
Multiple projects with a master .gndctrl at the platform level. Each project declares an airspace ID and a master_ref. Cross-airspace deps use AIRSPACE://ZONE_ID syntax.
# platform/.gndctrl — fleet master
version: "0.1.0"
platform:
name: my-platform
airspaces:
- id: PMT
path: payment-service/
description: Payment processing service
- id: AUTH
path: auth-service/
description: Auth and session management
- id: CHI
path: chisel-app/
description: Main application
tool_registry:
- name: stripe-sdk
version: "^5.0"
approved: true
- name: jose
version: "^5.0"
approved: true
known_solutions: []
# payment-service/.gndctrl
airspace: PMT
version: "0.1.0"
master_ref: "../.gndctrl"
project:
name: payment-service
description: "Stripe integration and billing"
zones:
STRIPE_SYNC:
stability: sensitive
type: [code, data]
minimum_agent_class: heavy
deps: [AUTH://AUTH_CORE, PMT://WEBHOOK_HANDLER]
paths:
- "src/billing/stripe*"
- "src/billing/reconcile*"
WEBHOOK_HANDLER:
stability: stable
type: [code]
minimum_agent_class: medium
deps: [AUTH://AUTH_CORE]
paths:
- "src/webhooks/*"
decision_log: []
Zone type values
| Type | Covers |
|---|---|
| code | Logic, functions, API handlers — the default |
| design | UI components, design tokens, style rules |
| data | Schemas, migrations, models, seed data |
| config | Environment, infrastructure, secrets management |
| docs | Documentation, changelogs, specification files |
CRID format
A Control Record ID (CRID) is an immutable identifier that ties a @gndctrl:node marker permanently to its logbook entry. Once assigned, a CRID never changes — even as the logbook entry is updated over time.
Format
# Single mode
ZONE_ABBREV-YYYYMMDD-SEQ
PMT-20260430-001 ← PAYMENT zone, 2026-04-30, first entry
AUTH-20260430-001 ← AUTH zone
UI-20260501-001 ← UI zone, next day
# Fleet mode
AIRSPACE-ZONE_ABBREV-YYYYMMDD-SEQ
PMT-STR-20260430-001 ← Payment airspace, STRIPE zone
AUTH-AUTH-20260430-001 ← Auth airspace, AUTH_CORE zone
CHI-DAT-20260430-001 ← Chisel airspace, DATA zone
Logbook directory structure
logbook/
├── PMT-20260430-001-stripe-retry-workaround.md
├── AUTH-20260430-001-session-edge-case.md
└── UI-20260501-001-token-cascade-order.md
Filenames are prefixed with the CRID for instant sortability. The Auditor validates that every CRID referenced in a node marker has a matching logbook entry — missing entries are flagged as integrity violations.
Logbook entry format
# Stripe Retry Workaround
**CRID:** PMT-STR-20260430-001
**Zone:** PMT://STRIPE_SYNC
**Node:** PMT://STRIPE_SYNC.reconcile_payment
**Stability:** sensitive
**Created:** 2026-04-30
**Last updated:** 2026-04-30
**Status:** unreviewed
## Changelog
| Date | Author | Change |
|------|--------|--------|
| 2026-04-30 | Claude Sonnet | Initial documentation |
## What this does
## Why it exists (the non-obvious part)
## What breaks if you change it
## Safe modification path
Agent contract
Drop this into your agent's system prompt, CLAUDE.md, AGENTS.md, or equivalent configuration file. Any agent that can follow these instructions participates in gndctrl governance — no SDK or plugin required.
## gndctrl Protocol
You are operating in a gndctrl-governed codebase.
Before modifying any code:
1. Identify your weight class (Super / Heavy / Medium / Light / Ultralight)
2. Read the .gndctrl file at the project root
3. Identify which zones the task touches
4. Check each zone's minimum_agent_class — if your class is insufficient, do not
proceed. Report the required class and hold for a heavier agent or human override.
5. Load the zone's documentation and stability tier
6. For sensitive or locked zones: read all deps[] zone docs before proceeding
7. In fleet mode: for cross-airspace deps, load that airspace's .gndctrl first
8. Issue a clearance brief: your class, authorised zones, any denied zones, active
stability constraints, and relevant logbook CRIDs
When you encounter a @gndctrl:node marker:
- Read the risk level before modifying the function
- Check touches[] — if you are adding new system touches, flag it to the user
- Do not change a function's external signature without reading all zones that depend on it
- Load the corresponding logbook entry (matched by crid=)
When you implement a workaround or non-obvious function:
- Place a @gndctrl:node marker with a new CRID
- Create the matching logbook entry in /logbook before the task is complete
- The Auditor will flag CRIDs without logbook entries as integrity violations
You must NEVER:
- Enter a zone requiring a higher weight class than your own
- Modify code in a locked zone without explicit human clearance
- Write to another airspace's locked or sensitive zone without cross-airspace clearance
- Add a dependency on a deprecated zone
- Introduce a library not in the tool registry without flagging it first
- Leave a @gndctrl:zone START marker without a matching END marker
GitHub & download
gndctrl is currently in private pre-release. The spec, CLI, and GitHub Action are under active development.
Planned release artefacts
| Artefact | Status | Description |
|---|---|---|
| gndctrl-spec | draft | The open standard — zone marker format, .gndctrl schema, stability tiers, fleet mode |
| gndctrl CLI | planned | gndctrl init / audit / preflight / export |
| GitHub Action | planned | Block PRs touching locked zones — single mode and fleet mode |
| Provider adapters | planned | Claude Code, Gemini CLI, Codex, Copilot compatibility templates |
Using the spec today
You don't need the CLI to start. Create a .gndctrl file, add zone markers to your files, and drop the agent contract into your agent's configuration. The spec is the product — the CLI and GitHub Action make adoption easier at scale.