{"playbook":"Engineering","url":"https://agentwranglers.se/playbook/engineering","updated":"2026-10-21","license":"https://creativecommons.org/licenses/by/4.0/","credit":"Required by the licence: credit Agent Wranglers with a link to the rule or playbook you used.","how":"Each rule's How text is on its own page: add .md to its url.","rules":[{"chapter":"Rules as code","name":"Check every rule in code","level":"Recommended","rule":"Every rule a project follows must have a check in code that anyone can run again and that ends in a plain pass or fail.","check":"Break one rule on purpose. The check fails, names the place, and exits with a code other than zero.","measured":"On a reference site, the first full run of the checks found 678 sideways-scrolling failures. One CSS line in a new menu caused all of them, and the menu had looked fine in screenshots.","url":"https://agentwranglers.se/playbook/engineering/rules-as-code/check-every-rule-in-code","related":["/playbook/ai-assisted-development/measuring-and-improving/check-repeated-mistakes","/playbook/operations/incidents/blameless-postmortems","/playbook/adversarial-testing/rules-of-engagement/fix-becomes-check","/playbook/infrastructure/policy-as-code/policy-on-the-plan","/playbook/compliance/scope-and-ownership/obligations-register","/playbook/compliance/controls-and-evidence/control-register","/playbook/html-css/checks-in-code/style-linter","/playbook/html-css/checks-in-code/one-exceptions-list"],"sources":[]},{"chapter":"Rules as code","name":"Run one check of everything before every deploy","level":"Recommended","rule":"Run every check against the whole project with one command, and let the deploy go ahead only when all of them pass.","check":"Run the script on a clean build. It prints PASS for every check and exits with zero. Whenever you change how the script runs steps, plant a failure on purpose. The run must report it and exit with a code other than zero.","url":"https://agentwranglers.se/playbook/engineering/rules-as-code/run-one-check-before-every-deploy","related":["/playbook/ai-assisted-development/setting-up-the-project/instructions-file"],"sources":[]},{"chapter":"Rules as code","name":"Fail the build on broken rules","level":"Recommended","rule":"Make the build fail on rules that must always hold, so a broken build can never ship.","check":"Break one rule on purpose, and the build stops. Add a link to a missing page, written once as a path and once as a full address. The build stops for both.","url":"https://agentwranglers.se/playbook/engineering/rules-as-code/build-gates","related":["/playbook/ai-assisted-development/rules-the-agent-cannot-break/protect-the-checks","/playbook/website/performance/performance-budget","/playbook/engineering/rules-as-code/enforce-the-writing-style-in-code","/playbook/website/html-basics/valid-html","/playbook/html-css/structure-and-files/styles-only-in-stylesheets"],"sources":[]},{"chapter":"Rules as code","name":"Enforce the writing style in code","level":"Recommended","rule":"Check the writing of every page and document in the build, so the language stays plain and short as more people and AI tools write.","check":"Add a 30-word sentence or a semicolon to any page. The build stops and quotes the sentence.","url":"https://agentwranglers.se/playbook/engineering/rules-as-code/enforce-the-writing-style-in-code","related":["/playbook/engineering/rules-as-code/build-gates"],"sources":[]},{"chapter":"Build, test and deploy","name":"Unit test the tricky parts","level":"Recommended","rule":"Test logic that can break silently on its own, without a network, a database or a browser.","check":"The unit tests finish in under 60 seconds and run in the full check before every deploy. Break the logic on purpose, and a test fails.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/unit-tests-for-the-tricky-parts","related":["/playbook/testing/unit-tests/unit-behaviour"],"sources":[]},{"chapter":"Build, test and deploy","name":"Run the tests inside the container build","level":"Recommended","rule":"Make it impossible to produce a deployable image from untested code.","check":"Break a test. The image does not build.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/container-build-gated-by-tests","related":["/playbook/operations/containers/pinned-base-images","/playbook/operations/containers/multi-stage-builds"],"sources":[]},{"chapter":"Build, test and deploy","name":"Stamp every build with its version","level":"Recommended","rule":"Give every build a version and the commit it came from. Show both in the running app, and tag each release in version control.","check":"After a deploy, the version address returns the commit hash of the deployed commit. `git tag --points-at <that commit>` prints the release tag.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/version-every-release","related":["/playbook/engineering/build-test-and-deploy/health-check-and-rollback","/playbook/operations/metrics-and-traces/deploy-markers"],"sources":[{"label":"Semantic Versioning 2.0.0","url":"https://semver.org/spec/v2.0.0.html"}]},{"chapter":"Build, test and deploy","name":"Deploy in one step and roll back by itself","level":"Required","risk":"outage","rule":"Upload next to the live copy, swap in one step, health-check, and put the old copy back if the check fails.","check":"Deploy a build whose health check fails. The old version keeps serving, and the script exits with a code other than zero.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback","related":["/playbook/data/migrations/expand-and-contract","/playbook/engineering/build-test-and-deploy/health-check-and-rollback","/playbook/engineering/build-test-and-deploy/staged-rollouts","/playbook/engineering/running-in-production/stateless-processes","/playbook/testing/output-comparison/output-manifest","/playbook/testing/output-comparison/compare-live-before-and-after","/playbook/testing/output-comparison/keep-previous-manifest","/playbook/operations/incidents/mitigate-first","/playbook/operations/running-the-service/graceful-shutdown"],"sources":[]},{"chapter":"Build, test and deploy","name":"Give the server a health check","level":"Required","risk":"outage","rule":"Give the server a health check address that tests its dependencies, so deploys and monitors know when it is broken.","check":"Stop a dependency on a test server. The health check answers 503 within two seconds.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/health-check-and-rollback","related":["/playbook/engineering/build-test-and-deploy/version-every-release","/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback","/playbook/operations/running-the-service/liveness-and-readiness","/playbook/engineering/running-in-production/monitoring-uptime","/playbook/testing/end-to-end-and-browser-tests/smoke-test-every-deploy","/playbook/operations/containers/container-health"],"sources":[]},{"chapter":"Build, test and deploy","name":"Release to a small share first","level":"Recommended","rule":"Send a new release to a small share of traffic first, compare it with the old one, and roll back by itself when errors rise.","check":"Deploy a test release that returns errors on purpose. The rollout stops at the first step and returns to the old release without a person acting.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/staged-rollouts","related":["/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback","/playbook/engineering/build-test-and-deploy/staged-config-rollouts","/playbook/operations/running-the-service/launch-readiness","/playbook/infrastructure/environments/promote-infrastructure-changes"],"sources":[]},{"chapter":"Build, test and deploy","name":"Build releases only in CI and verify them before deploy","level":"Recommended","rule":"Build every release in the CI service from a reviewed commit, with signed provenance. Deploy or publish only a build whose provenance names your repository.","check":"Build a release on a laptop and try to deploy it. The deploy stops because verification fails, and the same release built in CI deploys.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/build-in-ci-and-verify","related":["/playbook/adversarial-testing/supply-chain-and-setup/trusted-publishing","/playbook/adversarial-testing/supply-chain-and-setup/sbom-and-provenance"],"sources":[{"label":"SLSA v1.1 security levels","url":"https://slsa.dev/spec/v1.1/levels"},{"label":"GitHub artifact attestations","url":"https://docs.github.com/en/actions/concepts/security/artifact-attestations"}]},{"chapter":"Build, test and deploy","name":"Roll out settings and data files like code","level":"Required","risk":"outage","rule":"Validate every change to settings, rules and generated data files before it ships, and roll it out in stages like code. A service that cannot load a new file keeps running on the last good one.","check":"Push a broken settings file to staging, such as one with twice the allowed entries. The service keeps serving with the old file, logs the rejection and sends an alert. The release history shows every settings change in production passed the same stages as code.","url":"https://agentwranglers.se/playbook/engineering/build-test-and-deploy/staged-config-rollouts","related":["/playbook/engineering/build-test-and-deploy/staged-rollouts","/playbook/engineering/running-in-production/deploy-is-not-release"],"sources":[{"label":"Google SRE Workbook on canarying releases","url":"https://sre.google/workbook/canarying-releases/"},{"label":"Google SRE Workbook on configuration design","url":"https://sre.google/workbook/configuration-design/"}]},{"chapter":"Version control and review","name":"Keep every change in version control","level":"Recommended","rule":"Keep code, settings, build scripts, infrastructure and database changes in version control. Only secrets stay out.","check":"A fresh clone, plus the secrets, builds and deploys the product with no manual steps. A secret scanner over the whole history, such as `gitleaks git`, finds no keys.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/everything-in-version-control","related":["/playbook/ai-assisted-development/apps-built-with-ai-builders/own-the-code","/playbook/engineering/running-in-production/secrets-store","/playbook/infrastructure/infrastructure-as-code/define-infrastructure-in-code","/playbook/data/migrations/versioned-migrations","/playbook/architecture/comments/no-journal-comments","/playbook/ai-features/prompts-as-code/prompts-in-files"],"sources":[]},{"chapter":"Version control and review","name":"Make small changes on short-lived branches","level":"Recommended","rule":"Merge small changes often. A branch lives for at most 5 working days, and a change does one thing.","check":"A pull request job counts the changed lines and fails above the limit unless the change carries a label that explains why. A report of open branches fails when one is older than 5 working days.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/small-changes","related":["/playbook/ai-assisted-development/working-in-small-steps/small-diffs","/playbook/ai-assisted-development/working-in-small-steps/branch-and-commit","/playbook/engineering/running-in-production/deploy-is-not-release"],"sources":[]},{"chapter":"Version control and review","name":"Protect the main branch","level":"Required","risk":"takeover","rule":"Nobody pushes straight to the main branch. Every change arrives through a pull request with passing checks and an approved review.","check":"A direct push to the main branch is refused. A pull request with a failing check or no approval cannot be merged.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/protect-the-main-branch","related":["/playbook/ai-assisted-development/reviewing-agent-output/independent-approval","/playbook/architecture/code-review/review-against-the-base","/playbook/engineering/version-control-and-review/code-owners","/playbook/infrastructure/infrastructure-as-code/plan-in-review","/playbook/infrastructure/identity-and-access/separate-plan-and-apply-roles","/playbook/compliance/controls-and-evidence/change-evidence","/playbook/stack/delivery-and-infrastructure/git-on-github"],"sources":[]},{"chapter":"Version control and review","name":"Run the checks on every change","level":"Recommended","rule":"Run the full check on a clean machine for every push and pull request, not only on a developer's computer.","check":"Push a commit that breaks one test. The pull request shows a failed check before the job's time limit, such as 20 minutes.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/continuous-integration","related":["/playbook/adversarial-testing/supply-chain-and-setup/ci-secrets","/playbook/architecture/structure/one-formatter","/playbook/stack/delivery-and-infrastructure/github-actions-ci","/playbook/infrastructure/policy-as-code/scan-infrastructure-code","/playbook/compliance/controls-and-evidence/automated-evidence"],"sources":[]},{"chapter":"Version control and review","name":"Fix a broken main branch first","level":"Recommended","rule":"When the check fails on the main branch, fixing it comes before any other work. Revert the change that broke it if a fix takes longer than an hour.","check":"The deploy script stops when the latest check on the main branch is not green. The CI history shows no red stretch on main longer than one working day.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/keep-main-green","related":["/playbook/testing/flaky-and-slow-tests/quarantine-flaky-tests"],"sources":[]},{"chapter":"Version control and review","name":"Update dependencies in small automatic steps","level":"Recommended","rule":"Let a bot open a pull request for each dependency update, and merge it when the checks pass.","check":"No bot pull request stays open longer than 14 days. No dependency is more than one major version behind without a written reason.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/automated-dependency-updates","related":["/playbook/adversarial-testing/supply-chain-and-setup/release-cooldown","/playbook/adversarial-testing/supply-chain-and-setup/audit-dependencies","/playbook/payments/payment-events-and-reconciliation/provider-api-version","/playbook/infrastructure/infrastructure-as-code/pinned-provider-versions","/playbook/infrastructure/infrastructure-as-code/versioned-modules","/playbook/stack/languages-and-runtimes/end-of-life-runtimes","/playbook/stack/testing-and-code-quality/dependency-bot"],"sources":[]},{"chapter":"Version control and review","name":"Require an owner's review for sensitive code","level":"Recommended","rule":"Name the owners of payment, login, permission, deploy and CI files. Require one of them to approve every change to those files.","check":"Open a pull request that changes a payment file, approved only by someone outside its owners. It cannot merge. The code host reports no errors in the code owners file, such as an empty list from `gh api repos/example/shop/codeowners/errors`.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/code-owners","related":["/playbook/engineering/version-control-and-review/protect-the-main-branch"],"sources":[{"label":"GitHub: About code owners","url":"https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners"}]},{"chapter":"Version control and review","name":"Protect the accounts that can change the code","level":"Required","risk":"takeover","rule":"Require two-factor login for everyone with write access to the code host. Remove a person's access when they leave, on the same day as their other keys.","check":"The organisation's member list, filtered for missing or insecure two-factor login, is empty. Every member and outside collaborator matches a name on the current staff or contractor list.","url":"https://agentwranglers.se/playbook/engineering/version-control-and-review/code-host-accounts","related":["/playbook/adversarial-testing/access-and-accounts/two-factor-login","/playbook/compliance/audit-logs-and-access/offboarding-within-a-day"],"sources":[{"label":"GitHub: Requiring two-factor authentication in your organization","url":"https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization"}]},{"chapter":"Running in production","name":"Make builds repeatable","level":"Recommended","rule":"The same commit always gives the same build. Pin the language version, the tools and every dependency.","check":"Build the same commit twice on different machines. The checksums of the output files match. The install fails when the lock file and the manifest disagree, as `npm ci` and `uv sync --locked` do.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/reproducible-builds","related":["/playbook/operations/containers/pinned-base-images","/playbook/infrastructure/infrastructure-as-code/pinned-provider-versions","/playbook/testing/output-comparison/same-input-same-bytes","/playbook/infrastructure/servers/immutable-servers","/playbook/stack/languages-and-runtimes/pip-and-venv"],"sources":[]},{"chapter":"Running in production","name":"Keep settings outside the code","level":"Recommended","rule":"Read everything that differs between test and production from the environment. Never edit code to deploy somewhere else.","check":"Start the app with one required setting missing. It stops at once and names the setting.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/settings-outside-the-code","related":["/playbook/adversarial-testing/data-and-secrets/secrets-out-of-code","/playbook/operations/containers/one-process-per-container"],"sources":[]},{"chapter":"Running in production","name":"Log, track errors and alert","level":"Required","risk":"outage","rule":"Write structured logs, collect every unhandled error in one place, and alert a person when errors or response times jump.","check":"Throw a test error in staging. It appears in the error tracker with its request reference. Send failing requests past the written threshold, and the alert fires.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/logs-and-alerts","related":["/playbook/adversarial-testing/data-and-secrets/private-data-out-of-logs","/playbook/operations/logs/structured-logs","/playbook/operations/alerts-and-on-call/alert-on-symptoms","/playbook/operations/logs/log-levels"],"sources":[{"label":"OWASP Logging Cheat Sheet","url":"https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html"}]},{"chapter":"Running in production","name":"Watch the service from outside","level":"Required","risk":"outage","rule":"Watch the service from outside your own network, and alert a person when it stops answering.","check":"Stop the database on staging. The health check answers 503, and the monitor sends an alert within its interval.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/monitoring-uptime","related":["/playbook/engineering/build-test-and-deploy/health-check-and-rollback","/playbook/operations/alerts-and-on-call/alert-on-symptoms","/playbook/operations/alerts-and-on-call/alert-pipeline-heartbeat"],"sources":[]},{"chapter":"Running in production","name":"Separate deploying from releasing","level":"Recommended","rule":"Ship unfinished or risky features switched off, and turn them on with a flag when they are ready.","check":"Deploy with the flag off. The old behaviour stays the same for users. Turning the flag on needs no deploy. Every flag in the code has an owner and a removal date in the flag list.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/deploy-is-not-release","related":["/playbook/engineering/build-test-and-deploy/staged-config-rollouts","/playbook/engineering/version-control-and-review/small-changes","/playbook/architecture/dead-code/remove-stale-flags","/playbook/app-ui/permissions-flags-and-failures/feature-flags-in-ui","/playbook/data/product-analytics/experiment-assignment","/playbook/adversarial-testing/ai-agents-and-models/agent-kill-switch"],"sources":[]},{"chapter":"Running in production","name":"Keep secrets in a secrets store","level":"Required","risk":"takeover","rule":"Keep passwords, keys and tokens in a secrets manager or the platform's encrypted store. Give them to the app when it starts, and rotate them on a schedule.","check":"A secret scanner finds no secret in the repository or the build output. Every secret in the store shows an owner and a rotation date that has not passed.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store","related":["/playbook/engineering/version-control-and-review/everything-in-version-control","/playbook/adversarial-testing/data-and-secrets/least-privilege-keys","/playbook/infrastructure/configuration-and-secrets/automatic-secret-rotation","/playbook/adversarial-testing/data-and-secrets/secrets-out-of-code","/playbook/infrastructure/configuration-and-secrets/oidc-for-ci","/playbook/infrastructure/configuration-and-secrets/secrets-out-of-state","/playbook/email/sending-domain-and-authentication/dkim","/playbook/email/email-security/submission-tls","/playbook/operations/containers/build-secrets","/playbook/adversarial-testing/ai-agents-and-models/no-secrets-in-prompt","/playbook/payments/checkout-and-card-data/test-and-live-keys","/playbook/infrastructure/configuration-and-secrets/secret-containers-in-code","/playbook/notifications/push-notifications/web-push-vapid","/playbook/stack/delivery-and-infrastructure/secrets-manager-or-sops"],"sources":[{"label":"OWASP Secrets Management Cheat Sheet","url":"https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html"}]},{"chapter":"Running in production","name":"Keep no state inside the app process","level":"Recommended","rule":"Keep sessions, uploads and pending jobs outside the app process and its local disk. Any copy of the app can then stop or start without losing them.","check":"Sign in, upload a file and start a background job on a test server. Deploy a fresh copy of the app on a new machine and stop the old one. The session, the file and the job are all still there.","url":"https://agentwranglers.se/playbook/engineering/running-in-production/stateless-processes","related":["/playbook/api-design/files-and-uploads/presigned-uploads","/playbook/engineering/build-test-and-deploy/atomic-deploys-with-rollback","/playbook/operations/running-the-service/graceful-shutdown"],"sources":[{"label":"The Twelve-Factor App, VI Processes","url":"https://12factor.net/processes"}]},{"chapter":"Documentation","name":"Get a new person running with one command","level":"Recommended","rule":"Start the README with what the project does in one sentence, then one command that installs and runs it from a clean checkout.","check":"CI copies the commands from the README's quick start block into a fresh container and runs them. The app answers on the named address within 5 minutes.","url":"https://agentwranglers.se/playbook/engineering/documentation/readme-quick-start","related":["/playbook/ai-assisted-development/setting-up-the-project/instructions-file","/playbook/ai-assisted-development/setting-up-the-project/runnable-from-clean-checkout","/playbook/operations/containers/compose-for-local","/playbook/stack/how-to-choose/easy-to-learn"],"sources":[]},{"chapter":"Documentation","name":"Change the docs in the same pull request","level":"Recommended","rule":"Keep docs in the repository next to the code they describe, and update them in the pull request that changes the behaviour.","check":"CI fails a pull request that changes a mapped code folder without changing its doc, unless the pull request carries the `no-docs` label.","url":"https://agentwranglers.se/playbook/engineering/documentation/docs-with-the-change","related":["/playbook/ai-assisted-development/context-and-memory/lessons-in-repo","/playbook/api-design/changes-over-time/api-changelog","/playbook/engineering/documentation/diagrams-as-code"],"sources":[]},{"chapter":"Documentation","name":"Keep decision records with a status","level":"Recommended","rule":"Number each decision record, give it a status, and replace it with a new record instead of editing it once accepted.","check":"A script reads every record. Each has a status from the list and a date. Every superseded record links to a record that exists.","url":"https://agentwranglers.se/playbook/engineering/documentation/decision-records","related":["/playbook/ai-assisted-development/setting-up-the-project/record-decisions","/playbook/architecture/comments/comments-say-why","/playbook/stack/how-to-choose/proven-for-five-years","/playbook/stack/how-to-choose/widely-used","/playbook/stack/how-to-choose/prefer-open-source"],"sources":[]},{"chapter":"Documentation","name":"Keep runbooks next to the code they run","level":"Recommended","rule":"Write a runbook in the repository for every task a person does by hand in production. Turn each step into a script when you can.","check":"A script lists `docs/runbooks/`. Every runbook has numbered steps and a \"last run\" date under 6 months old.","url":"https://agentwranglers.se/playbook/engineering/documentation/runbooks-in-repo","related":["/playbook/operations/alerts-and-on-call/actionable-alerts","/playbook/operations/disaster-recovery/restore-runbook"],"sources":[]},{"chapter":"Documentation","name":"Generate reference docs from the code","level":"Recommended","rule":"Build reference docs for every public interface from the code or contract, never by hand.","check":"The build regenerates the reference docs and fails when the result differs from the committed or published copy. The generator runs with warnings as errors, such as `typedoc --treatValidationWarningsAsErrors` with `validation.notDocumented` on. For Python, add a docstring linter such as Ruff's `D1` rules. A public function without a doc comment then fails.","url":"https://agentwranglers.se/playbook/engineering/documentation/generated-reference","related":["/playbook/api-design/contracts-and-docs/generated-docs"],"sources":[]},{"chapter":"Documentation","name":"Keep a changelog written for users","level":"Recommended","rule":"Keep a dated changelog that tells users what changed for them in each release, written in their words.","check":"CI fails a pull request that changes code without changing `CHANGELOG.md`, unless it carries the `no-changelog` label. Every released version in the changelog has a date and matches a version tag.","url":"https://agentwranglers.se/playbook/engineering/documentation/user-changelog","related":["/playbook/api-design/changes-over-time/api-changelog"],"sources":[]},{"chapter":"Documentation","name":"Test the docs in the build","level":"Recommended","rule":"Check every link in the docs and run every code sample as a test in CI.","check":"Add a broken internal link and a sample whose output is wrong on a branch. CI fails on both.","url":"https://agentwranglers.se/playbook/engineering/documentation/tested-docs","related":["/playbook/api-design/contracts-and-docs/examples"],"sources":[]},{"chapter":"Documentation","name":"Draw diagrams as code","level":"Recommended","rule":"Write diagrams as text in the repository, with a diagram language such as Mermaid, PlantUML or D2, never only as an exported image.","check":"The build renders every diagram source with its tool, such as `mmdc` for Mermaid, and fails on a syntax error. A search finds no `.png` or `.svg` diagram without a source file next to it.","url":"https://agentwranglers.se/playbook/engineering/documentation/diagrams-as-code","related":["/playbook/engineering/documentation/docs-with-the-change"],"sources":[]},{"chapter":"Documentation","name":"State each value in one document and link to it","level":"Recommended","rule":"Write each limit, time or threshold, such as a session length or a retry count, in one document only. Every other document links there.","check":"For each value in a list of key limits, a search of the docs finds one stated number. Every other mention is a link to that document.","measured":"On a reference site, a review of 17 guides written in parallel found 28 values or practices stated differently in two or more places.","url":"https://agentwranglers.se/playbook/engineering/documentation/one-home-per-value","related":["/playbook/architecture/solid-and-dry/dry","/playbook/website/site-architecture/one-source-many-formats","/playbook/data/product-analytics/metric-definitions"],"sources":[]},{"chapter":"Documentation","name":"Give every doc an owner and a review date","level":"Recommended","rule":"Give every guide and runbook an owner and a last-reviewed date, and flag any doc not reviewed in 6 months.","check":"A script reads the front matter of every doc. Each has an owner and a reviewed date under 6 months old, or an open ticket for it.","url":"https://agentwranglers.se/playbook/engineering/documentation/doc-ownership","related":["/playbook/operations/disaster-recovery/restore-runbook","/playbook/compliance/controls-and-evidence/policies-owned","/playbook/compliance/scope-and-ownership/named-owners"],"sources":[]},{"chapter":"Documentation","name":"Cite the primary source for every rule","level":"Recommended","rule":"Link every rule that follows a specification, standard or law to that text. Fail the build on a citation from a host outside an allow list of authorities.","check":"Add a source from a blog host to any rule. The build stops and names the host. A rule whose text names an RFC number with no source also stops it.","url":"https://agentwranglers.se/playbook/engineering/documentation/cite-primary-sources","related":["/playbook/engineering/documentation/watch-cited-sources","/playbook/website/seo/glossary-page"],"sources":[]},{"chapter":"Documentation","name":"Watch cited sources in code","level":"Recommended","rule":"Once a week, have a job find every cited source that stopped answering, moved or was replaced by a newer version. Alert with the rules that cite it.","check":"Cite RFC 7231 in one rule. The next run alerts that RFC 9110 replaced it and names that rule. A cited address that redirects to another host is reported as moved.","measured":"On a reference site, a check that followed redirects passed 13 of 530 sources that had moved to a new host or a home page.","url":"https://agentwranglers.se/playbook/engineering/documentation/watch-cited-sources","related":["/playbook/engineering/documentation/cite-primary-sources","/playbook/website/redirects-and-canonicals/check-outbound-links","/playbook/engineering/documentation/recheck-sources-with-an-agent"],"sources":[{"label":"RFC 9110 HTTP Semantics, which obsoletes RFC 7231","url":"https://www.rfc-editor.org/rfc/rfc9110"}]},{"chapter":"Documentation","name":"Let an agent reread rules whose sources changed","level":"Optional","rule":"When the source watch flags a rule, have an AI agent reread it against the current source. It proposes any fix as a pull request.","check":"Flag one rule whose source contradicts it. The next run opens a pull request that edits that rule and quotes the source.","url":"https://agentwranglers.se/playbook/engineering/documentation/recheck-sources-with-an-agent","related":["/playbook/engineering/documentation/watch-cited-sources","/playbook/ai-assisted-development/measuring-and-improving/evaluate-agent-setup"],"sources":[]}]}