Delivery Protocol
On this page
You are NOT done when the code works. Every code change must complete this checklist before reporting completion to the user.
Preflight Checklist
Before starting any implementation task, verify all of the following. If any check fails, stop and report what is missing — do not write code.
-
Public visibility: verify the repository is publicly accessible (
glab project viewor the GitLab API). If private, check for a validvisibility_exceptionblock in.claude/CLAUDE.md(see security baseline). Refuse to work if no valid exception exists. -
Pre-push hook active:
git config core.hooksPathreturns.githooks. -
Commit signing configured:
git config commit.gpgsignreturnstrueandgit config user.signingkeyreturns a non-empty value.
Visibility failing is a refuse-and-report. The hook path and signing being unset
are local one-liners: set them (the key and email are in .claude/CLAUDE.md) and
say so — do not stop work over a config a single git config fixes.
Lint, fmt, and test cleanliness are the pre-push hook’s job, not a precondition
for starting work. A pre-existing warning is not your task unless the user says
so — fixing it in passing is scope growth. Missing or placeholder project docs
are surfaced by cargo xtask validate (mandatory-content), not by refusing to
start.
Architectural Recommendations
This protocol applies to a new external dependency or framework — not to an in-repo type, module, or helper pattern (for those: pick, and say why in one line).
-
Research current state of the art — search crates.io, official docs, and recent release notes. Do not rely on training data alone.
-
Compare your preferred option against at least two alternatives on maintenance activity, community adoption, security posture, and alignment with existing conventions (pure Rust, musl-compatible, AGPL-compatible license).
-
Present the comparison to the user before proceeding — do not unilaterally choose.
-
Write an ADR only when the choice is hard to reverse — a database, protocol, or framework. A crate that can be swapped in an afternoon does not need one.
Training data favors established projects, so verify the recommendation reflects the current landscape (the known stale defaults list). That is a reason to check, not a reason to prefer the newer option.
Library Usage
Before using any crate or library API for the first time in a project:
-
Read the actual documentation — docs.rs, the crate README, or
cargo doc. Do not assume API signatures, feature flags, or return types from training data. -
Verify the version — check
Cargo.toml/Cargo.lockfor the version in use. -
Check feature flags — confirm the features enabled in
Cargo.tomlinclude what you need. -
Test your assumptions — write a minimal test or check
cargo doc --document-private-itemsbefore building on top of an uncertain API.
Do not write code against an API you have not verified. The cost of reading docs first is minutes; the cost of debugging wrong assumptions is hours.
Debugging Protocol
-
Diagnose the root cause in source before proposing workarounds. Read the actual implementation that failed. Understand WHY, not just THAT. The fix must follow the diagnosis.
-
Do not defend a mental model against contradicting evidence — re-examine it. If evidence contradicts your theory, the theory is wrong. Rebuild from the evidence.
-
Read the actual source of third-party crates before declaring their behavior. "I think it works like X" is not acceptable — verify.
-
After 2 failed attempts at the same approach, stop and change approach. The approach is likely wrong, not the execution. This bounds repeating a strategy, not diagnosis — multi-attempt root-cause investigation is productive work.
-
Do not reference other projects unless the user directs you to. Sibling projects have different architectures and constraints.
Delivery Checklist
-
Create a GitLab issue (if none exists): search first (
glab issue list --search "keywords"); only create if none exists. -
Implement on a branch (
{type}/Preflight, recommendations, debugging, and the delivery checklist). -
Update documentation on the branch — see Documentation Update Checklist.
-
Format:
cargo fmt --all— the pre-push gate runscargo fmt --check --allfirst and rejects an unformatted tree instantly, before the slow stages. -
Commit & push: the pre-push hook runs the full battery (see testing).
-
Create MR:
glab mr createwithCloses #N(Relates to #Nfor a partial, non-final MR) — follow MR standards. -
Report the MR URL to the user.
Every todo list for a code task MUST include a final item: "Create issue, commit, push, open MR".
Documentation Update Checklist
Every code change that adds endpoints, tables, events, commands, or public API surface updates the first two below; the rest change only when the change alters what they say:
-
The project’s canonical service/API documentation in the Antora docs site (ROOT module pages, generated OpenAPI pages, etc.) — the primary destination for endpoint/table/event catalog updates.
-
The services page — keep it a concise INDEX that links out to the canonical docs above, NOT an unbounded catalog (agent context budget is finite — see Context Hygiene).
-
.claude/CLAUDE.md— feature status table, architecture summary as applicable. -
CHANGELOG.adoc— entry under== Unreleased. -
ADRs and user guides (AsciiDoc) as applicable.
Post-Merge Steps
-
Close the issue with a one-line closing comment (merge SHA + anything deferred).
-
Update the epic task list (if applicable).
-
Delete the local branch:
git branch -d feature/…. -
Prune remote refs:
git remote prune origin.
Plan Lifecycle
Plans are .adoc files created + linked BEFORE implementation. The plan authoring
rules and the canonical Status vocabulary are the single source of truth in
coding conventions. Four rules govern plan
quality and durability:
-
Plans live in the repo. The durable artifact is the committed in-repo
.adoc(in the project’s plans directory), under version control — never scratch markdown left outside the repo. -
A plan is Design + Scope, under ~300 lines, with ONE Status value. No per-issue status tables, MR numbers, or SHAs — GitLab owns tracking and git owns history, so a plan that mirrors them drifts and generates reconciliation churn. A plan that needs more than ~300 lines is a program: split it into issues. Status changes on start, completion, or deferral only.
-
Review is bounded: at most two rounds, verdict-first. The reviewer answers four questions and returns a verdict (
ship/no-ship). Asking for a verdict against a fixed rubric is what makes two rounds comparable; asking for "findings" makes a fresh reviewer produce findings forever.-
Conventions: does the plan conform to
.claude/rules/and the standards pages? -
Contextless-implementable: can an agent or human with no prior context implement it, fully per conventions, without asking anything? This is the bar a plan is measured against.
-
Pre-1.0 compatibility: does it add backward-compatibility scaffolding (shims, dual code paths, migration layers) for a surface that has not reached 1.0? Pre-1.0 breaking changes are allowed (see git workflow), so such scaffolding is cut. This question only ever removes content.
-
Readable: can a human consume the prose and structure, or is it a wall of text? Answered once and fixed once; it is not re-reviewed, because prose reshaping across rounds is exactly the churn the bound exists to stop.
A "no" on the first two is a blocker (the plan would produce wrong work) and is fixed in-plan. Everything else becomes a GitLab issue or is dropped — never fixed in-plan, because every in-plan fix adds surface for the next reviewer.
-
The plan must already pass all four questions in the author’s own judgment before it is handed to review. Review is a check, not a drafting stage; a plan written as a draft "for the reviewer to fix" is the failure the bound exists to prevent.
Round 1 is a fresh subagent given only the plan, the rules (told to read the
path-scoped ones too — coding-conventions, test-authoring — or the conformance
question is answered without the conventions it asks about), and the four
questions — never the authoring session’s context. Self-review from inside the
authoring context shares every blind spot the plan has, and a context-heavy author
will take the cheaper reading of "contextless" if the rule allows it. After round 1
the agent always presents the plan and the verdict to the user; the user, not the
verdict, decides between shipping and a second round — otherwise the author’s own
subagent is the only gate a plan ever passes. Round 2 is run by the human through
a different vendor’s model — the coding-agent harness cannot call another vendor,
so the agent’s job is to hand over the plan and the four questions and record what
comes back. Independence comes from the vendor, not the round count (thirty
same-model passes share one set of blind spots).
Record each round as round | vendor | resolved model | verdict under a
== Review log heading — the resolved model, not a tier alias, so the record stays
meaningful when vendors re-point names. Fix round-2 blockers, then ship; there is
no round 3.
* Plans freeze at implementation start. A deviation is a one-line dated erratum,
not a Design rewrite. One exception, for multi-unit plans: when a unit that has
not started yet depends on a Design section that no longer matches what was
built, correct that section to as-built and record the correction in the
erratum line. A later implementer reads the Design as their spec, so a stale
section plus an erratum is worse than a corrected section. The boundary that
keeps this from becoming the old living-spec churn: correct to as-built, never
redesign, and only sections a pending unit depends on. An improvement found
mid-execution is a GitLab issue or is dropped — never a new plan section, never
scope growth in the current change.
* Completion check. A one-line closing comment records the merge; it verifies
nothing. Before Status flips to Done, run cargo xtask plan-lint --done <plan>.
It blocks (exit 1) when a referenced issue is still open, a cited repo path does
not exist, a line still says "TBD" or "this MR", or the plan is nav-linked
anywhere but Archive; it advises (exit 3; --strict blocks) when the plan is over
the ~300-line cap, the review log has more than two rounds or none, the plan is
not nav-linked at all (a repo-only meta plan), or issue states could not be
verified because glab is unavailable. Every one of those is decidable, which is
why the check is a program and not an audit agent — the old Plan Completion Audit
caught the same things at the cost of an agent spawn per plan.
Context Hygiene
The information cascade has three tiers, each with a distinct owner — keep facts in exactly one:
-
Agent memory (machine-local, per-user): only what is true for THIS agent+project+user+machine — session scratch, local paths, this-user preferences. Never a work-stream tracker (status → GitLab work items). Audited by
cargo xtask audit-memory. -
.claude/rules/(synced, in-repo): durable, terse agent directives. Every agent inherits them. -
Antora docs site (canonical, human+agent): prose, rationale, project knowledge, ADRs, the service/API catalog.
One fact, one home. If the same fact lives in two places, they will drift. Pick the owner (usually the Antora site or the most specific rule) and make the other a pointer. The Documentation Update Checklist routes project knowledge to the docs site precisely so the agent context budget does not grow without bound.
Template Updates
Universal standards (this page and its siblings, the .claude/rules/ digests, the
git hooks) are maintained in the gadhs/templates/claude-quickstart template repo
and distributed as synced files. When the template updates, cargo xtask
check-docs reports DRIFT (read from version stamps: behind = older than the
template, just sync; edited = same version, local edits to restore). Repair both
the same way:
-
cargo xtask check-docs --fix --yes(add--allow-execfor hooks). -
Review:
git diff. -
Commit:
chore: sync universal standards to template vYYYY.N.
A template host that is unreachable / 5xx degrades to advisory SKIP. For
air-gapped/mirrored environments, set CLAUDE_TEMPLATE_URL to an internal mirror’s
raw base. An active sync-overrides entry tolerates an intentional divergence
(exit 3, advisory); an expired or unknown override blocks.
Template Feedback (the reverse channel)
Template Updates (above) is the one-way distribution channel; this is its
counterpart — how a template-level problem gets back UPSTREAM instead of being
silently worked around.
Micro vs macro — which problems escalate:
-
A problem in a synced surface (
.claude/rules/,docs/modules/standards/pages/,.githooks/, or any other.claude/sync-manifest.tomlentry) or a *template default is aclaude-quickstarttemplate issue — escalate. -
A purely project-local problem (the project’s own code, config, or docs) stays local.
-
A project-local workaround that fights a template default IS a template issue — escalate. Reaching for a local workaround against a synced default is itself the signal that the template, not the project, is wrong.
How to escalate (not by reaching into the template repo): ONE comment on the
standing "macro feedback / sharp edges" tracking issue in claude-quickstart,
batched per session (all findings in one comment) — never a new issue per
finding. This respects the "don’t consult sibling projects unless directed"
guardrail: escalation is a filed suggestion, not a silent edit of the upstream.
The channel. Downstream repos carry a maintainer-provisioned,
claude-quickstart-scoped project access token (CQS_CONTRIBUTION_TOKEN),
distributed as a CI/CD variable (verified working end-to-end). It gives a
downstream agent a recognizable bot identity, label/triage capability (a member
token can self-apply labels), and revocable, narrowly-scoped upstream access —
chosen over anonymous public-repo issue creation for identity, labeling, and
control. Provisioning and rotating the token is the maintainer’s action; the agent
uses the injected credential and self-applies agent-suggestion + needs-triage
when filing.