Imported from cascode-ai/analog-canvas (
AGENTS.md). Install upstream withnpx skills add cascode-ai/analog-canvas. Copyright stays with the author.
Agent Working Rules
Treat the repository as an engineering project: bounded targets, explicit
ownership, risk-proportional validation, and decisions recorded where the work
is. What a change did and why is stated in its commit message, which travels
with the diff through git log, git blame, and the pull request.
Notes you keep while working — scratch plans, checklists, drafts — belong in
the untracked plan/ directory. They are a local working area and are not
published.
Development and Delivery
The cadence is local iteration followed by a delivered pull request. A request to change the editor proceeds through both stages unless the user explicitly asks for local-only work or a branch backup instead of publication.
- Local iteration. Continue the current local batch branch, or create
codex/local-batchfrom currentmainwhen starting a new batch. Usepnpm devfor feedback and focused checks for each bounded target. Keep separate, explanatory local commits for separate targets. A completed local target ends with its commit and validation, then proceeds to Delivery unless the user limited the request to local work. A branch pushed only for backup is not a delivery. - Delivery. Open one pull request for the completed change or batch, run
the mainline delivery gate, queue it for merge, wait for the required
checks in the merge queue, and verify Production. Every non-documentation merge to
mainfollows this one route. Batching is optional. A change means one independently useful feature, fix, or improvement; supporting tests, repair commits, files, and formatting do not count as extra changes. Prepare any intended release version before merging.
Keep a short working list in plan/local-batch.md while a batch is in
progress: the branch, completed changes and count, validation still needed,
and current stage. Read it when continuing the batch and reconcile it with
local commit messages; commit count alone is not a change count. Start the next
list after the batch is delivered. Decisions and validation that must survive
delivery belong in the commits and pull request. A squash merge's description
must preserve the target summary, test impact, validation, and unresolved
limitations.
Operating Discipline
Before starting a target:
- Run
git status --short --branchfrom the repository root. - Audit dirty state by ownership:
- Proceed normally when the worktree is clean.
- When it is dirty, identify whether each changed path belongs to the current target, the user, another worker, or an earlier target.
- Unrelated dirty paths do not automatically block work.
- Stop before editing when dirty paths overlap the target's owned files, ownership is unclear, or a dirty shared contract affects the target.
- Say so in the commit message when proceeding with unrelated dirty files present.
- Identify the target owner, goal, expected files, shared dependencies, and validation surface.
- Read
README.mdand any closer domain instructions. - Review validation intent before editing:
- Run
pnpm gate:plan -- --path <expected-path>for the expected owned paths when practical. - Expand the selected commands and identify platform, release, generated- artifact, and golden-state assumptions.
- State which gates you chose, and why, in the commit message.
- Run
Before Editing
Know the boundary of the target before editing tracked files: the goal, which paths it owns, what the dirty state means for it, and which shared contracts it touches. Hold that in a local note if it helps; the repository does not require a file for it.
Do not edit outside the target's boundary without deciding, deliberately, that the boundary has moved.
During Work
-
Keep each target small and reviewable; exclude unrelated cleanup.
-
Define a target by one ownership and validation boundary, not by every visible symptom. Closely related micro-fixes that share files, contracts, and validation belong in one target; independent changes do not.
-
Protect shared contracts, generated artifacts, binary assets, and user-owned work unless the target explicitly claims them.
-
Decide deliberately before expanding scope or taking on a new dependency, and say so in the commit.
-
Regenerate the advisory gate plan from the real diff with
pnpm gate:plan -- --base <base-ref>before expensive validation. If the actual selection differs materially from the gates you chose, revisit the choice before proceeding. -
For local iteration, plan and validate the current target's delta rather than repeatedly treating the accumulated batch as a new change. Start with focused unit/browser checks directly. Run
pnpm gate:preflight -- --base <target-base>before executing selected affected, build, or release gates, and usepnpm gate:affected -- --base <target-base>for the bounded gates the target needs. The Test-Impact check reads commit messages, so check its declaration after committing. A plannedfull-deliverygate is owed at batch delivery; it is not an instruction to rerun full delivery after each local edit. Run broader local checks earlier when the target's actual risk requires them. -
Prefer the smallest deterministic validation that covers changed behavior, direct dependencies, and credible failure risks.
-
Add tests when behavior changes, a regression needs protection, or a contract is best demonstrated automatically. Do not add tests that merely restate an implementation.
-
Declare test impact in the commit that changes implementation code, using a trailer:
Test-Impact: tests-updated Test-Impact: no-test-change — <evidence behavior is unchanged or protected>pnpm test:impact -- --base <base-ref>cross-checks the claim against the diff:tests-updatedrequires a changed test file, andno-test-changerequires that none changed plus its evidence. CI runs the same check. Seedocs/testing/README.mdand its contract matrix. -
Keep one primary test layer per behavior. A test mentioning retired input is not automatically dead: retain reachable rejection, migration, history, and safety boundaries until their replacement is explicit.
-
Do not run a full suite by default. Expand from focused checks when the change crosses shared contracts or subsystems, carries broader risk, or a project gate requires it.
-
Use
pnpm test:local <test-paths>for affected unit contracts andpnpm test:e2e:local <spec-paths> [--grep <pattern>]for affected browser behavior. Both commands cap local concurrency. -
Use
pnpm verify:branchwhen a completed branch crosses enough workspace boundaries to justify static checks, all unit tests, one build, and the production smoke check. It is not the mainline delivery gate. -
Production incident exception. While production is broken, restoring service outranks the delivery route: pushing straight to
mainis allowed, and so is any shortcut that shortens the outage. This is written down because the alternative is worse — a rule that forbids it is a rule people break while panicking, and a broken rule protects nothing. Two conditions make it a route rather than a hole: it applies only while service is actually degraded, not to a change someone is merely in a hurry about; and once service is back, the bypass gets a written record — what was broken, what was pushed, and which checks were skipped — in the follow-up commit or PR. The record is the point. A bypass nobody wrote down is indistinguishable from a bypass nobody noticed. -
Gate planning selects validation obligations. Shared-core changes, gate-policy changes, and unclassified non-documentation paths require the full fallback when delivering the batch; bounded changes use selected focused checks. Batching never authorizes skipping a required GitHub check.
-
Report unresolved questions in the commit message or a review note; do not leave them only in an untracked working note.
Circuit Asset Rules
- For accepted Symbol geometry or pin-position changes, historical drawing layouts and routes may be left for manual repair. Do not audit or repair every old design as a prerequisite to completing the current change, or add a general migration/compatibility layer just to preserve old layouts. A small one-off repair script is appropriate when concrete affected cases can be fixed by a few clear, deterministic rules with little effort; otherwise leave them for a human. Record known impacts with the change.
- Keep each circuit fixture in its own
netlists/<circuit-name>/directory. - Preserve explicit
.subcktinterfaces and instance pin order. Interface changes are shared-contract changes and require checking every caller. - Keep local model files beside the netlist that includes them unless a target intentionally introduces a shared model library.
- Do not claim electrical correctness from syntax inspection alone. If the target changes electrical behavior, name the simulator, models, analyses, corners, and acceptance criteria used—or record why simulation is blocked.
- Never silently replace foundry or vendor model data with illustrative values. Label topology-only fixtures and simplified models clearly.
After Work
Before considering a local target complete:
- Run the validation the target's risk calls for. A full suite is required only when justified by breadth, risk, or project policy.
- At minimum, run
git diff --checkandgit status --short --branch. - Review the diff, stage only intended files, and commit locally on the batch branch. Update the batch working list. Push and merge belong to Delivery; a local target can be complete while its batch awaits publication.
- Write the commit message so it stands alone: what changed, why, the
validation that backs it, and the
Test-Impact:trailer. State anything a reader would otherwise have to reconstruct — a defect's root cause, a contract that moved, or work deliberately left out. - Do not automatically extract a reusable lesson. When a human asks, draft a
candidate under
docs/experience/with supporting evidence for the human to accept, edit, or reject.
Mainline Delivery Gate
Focused validation is the normal local development loop. Run this delivery gate when the accumulated batch is ready for Production, using the entire batch relative to its mainline base. Delivery keeps full unit, release, and performance protection for the implementation batch while the browser layer is selected by impact.
Every non-documentation merge deploys directly to the public site. A v*
release tag or manual dispatch may redeploy a selected commit only when that
commit is already on main; see Deployment rationale and
docs/deployment.md.
Before a non-document change is merged or pushed to main:
- Start from a clean dependency state with
pnpm install --frozen-lockfile. Runpnpm setup:e2eonce on a machine that does not yet have the matching Playwright Chromium installation. - Run
pnpm gate:preflight -- --base <base-ref>. - Run
pnpm gate:affected -- --base <base-ref>when the plan selects bounded affected gates. When it selectsfull-delivery, run the target's focused checks locally and let the required merge-queue checks own the single broad core run plus the mapped browser contracts. Do not run the same full suite both locally and remotely just because publication is next. Runpnpm gate:fulllocally when actual risk cannot be represented by the browser map, when it calls for pre-push full evidence, or when remote CI is unavailable. - Push a review branch, open the pull request and run
gh pr merge <number>right away. On the pull request itself CI only plans the change scope and checks the Test-Impact trailers; its two required checks are skipped, which GitHub counts as passing. The merge queue then runs them once, on the candidate merged with currentmain, and squash-merges it when both pass.Core contractsruns static contracts, the complete unit/module suite, and the release/performance checks on one shared runner.Browser testsruns only the mapped affected specs, or a small insertion/runtime fallback for an unmapped product path. A branch needs a manual update only when it conflicts withmain, not merely becausemainmoved. CI has no full browser audit and runs nothing on a schedule;pnpm test:e2eruns every spec locally when a change needs it. - If a queue check fails, the pull request leaves the queue. Keep the target
active: inspect its log, repair the reported cause, push, and queue it
again. A successful
git pushis not a completed delivery.
Do not bypass the gate by weakening, skipping, or deleting a failing check. When a test or golden is obsolete, demonstrate that the accepted behavior is preserved and update the contract deliberately. If the check cannot run in the local environment, record the limitation and require the remote green result.
Where the Record Lives
The automatic per-target loop is:
bounded target -> implementation -> validation -> commit that explains itself
The cross-target experience layer is human-triggered:
human reviews commits, failures, or review notes
-> human requests extraction
-> Agent drafts an evidence-backed candidate lesson
-> human accepts, edits, or rejects it
Git owns the record. A commit message owns the intent, the reasoning, the
validation, and the test-impact declaration for exactly the change it carries,
so the two can never drift apart. An experience note under docs/experience/
owns only a transferable judgment supported by evidence, and a human decides
whether something is a lesson.
Working notes under plan/ are untracked. They are yours while a target is in
flight; anything that matters afterwards belongs in the commit.
Boundary and Hygiene Rules
- Do not mix unrelated targets in one commit.
- Do not mix reusable workflow changes with project artifacts unless the commit explains why they must land together.
- Do not use model confidence as the only quality gate when deterministic validation or human review is available.
- Do not add or run unnecessary content-hash checks. SHA256 verification is prohibited unless a concrete security or integrity requirement makes it essential; ordinary build provenance, deployment and functional acceptance must not grow repeated payload hashing steps.
- Do not delete review notes or open questions to make the repository appear clean. Unresolved work is reported, not tidied away.
