Search/Have an AI Coding Agent Follow Branch and Commit Rules Without Breaking Releases

Have an AI Coding Agent Follow Branch and Commit Rules Without Breaking Releases

Use when an AI coding agent works in a version-controlled repository. It sets how to branch, test, write commits, and place temporary files, and how to write agent instructions that work across different AI tools, without breaking releases.

To use this AI rule
## Keep a single agent instruction file and check which part of the repo to change - Keep one canonical agent-instruction file. When a harness expects a different filename, point it at the canonical file with a symlink instead of duplicating the content: a second real file diverges over time and can break validators that treat the alternate path as a different artifact type. Preserve the symlink; do not let it be materialized back into a regular file. - One change may touch several surfaces at once — shipped product content, catalog or config metadata, and build or CLI code. Do not assume a change is "just code" or "just docs" without checking which surface owns each modified file, and edit the surface that owns the behavior rather than an adjacent one. - Treat the repository's own instruction files as authoring context for the repo. Any rule that must affect a shipped artifact at runtime belongs inside that artifact, not in the repo's instruction file, because end users run the artifact against their own instructions. ## Work on a feature branch and merge only through pull requests - Create a feature branch for any non-trivial change. If you are already on the correct branch for the task, keep using it; do not spawn extra branches or worktrees unless explicitly asked. - Route every change to the default branch through a pull request. Direct pushes or merges bypass validation and release checks and cause version drift that later needs multi-step recovery; rely on branch protection to enforce this rather than working around it. - Leave releases to release automation. Do not hand-bump release-owned version numbers or hand-author release notes in routine work, and use conventional commit titles so the automation can classify change intent. ## Run the full test suite and separate automated tests from evaluations - Run the full test suite after any change that affects parsing, conversion, output, or mechanical conventions. The local suite is the same one CI runs; there is no separate local-only lane you may skip. - Split checks by nature. Deterministic invariants — schema and frontmatter, path safety, output shape, greppable contracts — live in the automated suite and must pass in CI. Non-deterministic behavior such as judgment and restraint is validated by evaluation, not faked as a brittle string test. - When a reviewer finds a greppable invariant the suite missed, prefer tightening an existing guard over adding a new suite, and pin the smallest falsifiable unit — one token, path, or fixture that would have failed on the regressing change — rather than snapshotting a whole file body. ## Decide where temporary files go and keep plans and docs in the repo - Send throwaway scratch to OS temp by default: a per-run temporary directory the OS reclaims, for files that are consumed once and discarded. - For scratch that must survive across invocations, use a stable prefix owned by the current user instead of a random temp directory, so later runs can find it. Create the root privately (owner-only), reject it if it is a symlink or owned by another user, and keep one directory per run unless later runs intentionally enumerate sibling final artifacts. - Bind scratch to the working repository only when the artifact is genuinely inseparable from this repo or branch, is meant for the user to curate directly, or when a repo-relative path is itself core to the output. - Durable outputs — plans, specs, docs, final deliverables — belong in a repo-tracked location, never in either scratch tier. ## Use ASCII-only names and pipe-separated Markdown tables - Keep identifiers — file, command, and agent names — ASCII-only, because converters and regex patterns depend on it. - Write Markdown tables as pipe-delimited rows, never with box-drawing characters. - Unicode is fine in prose; prefer ASCII arrows (-> and <-) inside code blocks and terminal examples so copied commands stay portable. ## Choose the fix or feature commit prefix by what the change does - Choose the conventional prefix by what the change does, not by file type. Content living under a docs or skills directory can still be product code; reserve a docs prefix for files whose sole purpose is documentation. - When a fix and a feature prefix both seem to fit, default to fix: remedying broken or missing behavior is a fix even when implemented by adding code. Reserve the feature prefix for a capability the user could not previously accomplish where nothing was broken. Heuristic: if a regression test written today would have failed before the change, it is a fix. - Include the narrowest useful component scope — the skill, module, or area name — and never scope a commit to the whole project. Never add a breaking-change marker without explicit user confirmation, since it triggers an automatic major version bump the user may not want. ## Use relative paths so each shipped unit works in any AI tool - Keep each shippable unit self-contained: reference only files inside its own directory tree, using relative paths. Never traverse into a sibling unit or hardcode an absolute install path — install locations are versioned and unpredictable, and packaging copies each unit in isolation. Duplicate a shared file into each unit rather than depending across directories. - Do not rely on host-specific variables — skill-directory, session-id, or plugin-root substitutions — without a fallback that works when the value is empty or unresolved; several are populated on only one harness and are silently empty elsewhere. - For an executed shell command that runs a bundled script, make resolution deterministic: set an absolute base directory inline in the same command (shell state does not persist between calls) and reference the script from it, rather than a bare relative path that resolves against the user's project directory instead of the unit's. ## Write only checkable rules in agent instructions and sort review feedback before editing - Admit a line only when it states a falsifiable constraint, counters a known default tendency or observed shortcut, or supplies domain knowledge that changes a decision. Cut vague effort or quality language such as "be thorough"; replace it with an observable rule or drop it. Do not append motivational rationale to a directive that already stands on its own. - Repeat an instruction only at a demonstrated drift point where its placement changes whether it fires, and protect a genuinely required duplicate with a parity test. - Treat applying review feedback as a material revision: classify each item as Change, Verify, or Consider and edit only for Change items; fix each at its owning layer with the smallest mechanism; then reread the block and remove text the change made duplicated or obsolete. Reviewer wording is a hypothesis about the fix, not authority over it. ## Find project conventions in the loaded context instead of naming instruction files - When a unit must discover a project convention — issue tracker, commit format, lint command, scope limits — describe what to look for in the agent's already-loaded context, not which file to open. On the read path do not name instruction dotfiles: the host already injects the root instruction file, its filename differs per harness, and telling an agent to open named instruction files is the exact shape prompt-injection defenses flag. - Name a concrete file only where a context reference cannot express the need — writing a convention back to a target, or reading content a fresh subagent genuinely does not inherit. - Describe a capability by category ("the project's issue tracker, e.g. GitHub Issues, Linear, or Jira" and "whatever interface it exposes"), and never treat a missing binary, environment variable, or connector as proof the capability is unavailable. ## Compare file contents, not version numbers, to see if a session has your latest edit - After editing content that a long-running session loaded at startup, assume the session is still running the pre-edit copy. Caches capture state at load time, and edits within a release do not change a version number, so a matching version proves only that the cache came from this release, not that it captured your latest edit. - Confirm which copy is live by comparing the loaded file's content against your working copy, not by reading the version string. Identical means the running copy is current and trustworthy; differing means restart or use a fresh-load path before you trust a behavioral test. - Mechanical code paths — scripts, parsers, anything the test suite exercises — always run current source. Only the instruction and prose layer loaded at startup carries this staleness.