Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ When continuing cannot satisfy the contract safely, detect the condition at the
- Would continuing preserve a truthful and safe contract?
- Does the error include enough evidence for recovery?

## Follow Published Standards
A part whose behavior a published standard specifies should conform to that standard, cite it by number and version, and be tested against its examples or conformance suite, so that peers, tools, and reviewers can check it against a text other than the code.

**Applies when**
- The part reads or writes a format, speaks a protocol, or implements an algorithm that a published standard specifies: timestamps, URIs, JSON, email addresses, TLS, password hashing, version strings.
- What it emits will be consumed by tools or peers the author does not control.
- A security property depends on the part, so the standard's review history is evidence a private design lacks.
- The standard publishes test vectors or a conformance suite a test can run.

**Ask**
- Which standard specifies what this part reads, writes, or computes, is it cited by number and version where the code is, and has it been obsoleted or amended since?
- Which subset or profile of the standard is implemented, and what happens on input that uses the rest?
- Is conformance tested against the standard's own examples, test vectors, or conformance suite?
- Where this departs from the standard, is the departure written down, and which peers will it break?

## Goodhart's Law
When a measure becomes a target, it ceases to be a good measure, because those it measures move the number by means that decouple it from what it was chosen to indicate.

Expand Down Expand Up @@ -352,6 +367,21 @@ Protection mechanisms must be easy enough to apply correctly and routinely that
- Is there a scoped way in for a tree that does not yet comply, such as a baseline or a ratchet?
- Six months from now, what evidence would show this is still enabled everywhere it was installed?

## Reuse Maintained Components
Do not hand-roll a function that a maintained component already provides at adequate fit, because the component carries the edge cases, platform coverage, and fixes of every user it has, while a private copy carries only the cases its author met.

**Applies when**
- A change implements something a widely used library, standard-library module, or tool already provides: parsing a standard format, quoting for a shell, splitting arguments, installing a toolchain, cryptography.
- The hand-rolled form is short enough to look obviously correct, so its untested edge cases are not visible in review.
- The same helper exists, or is about to, in more than one repository.
- A candidate component exists whose maintenance can be judged from evidence: release history, open advisories, and how many projects depend on it.

**Ask**
- Which maintained library, standard-library module, or tool already does what this code does, and why was it not used?
- If one was rejected, is the reason written beside the code: poor fit, size against the need, licence, or maintenance?
- Which inputs and platforms has the hand-rolled form been run on, and which has the maintained component met that this one has not?
- Is the chosen component maintained, judged by its release history, open advisories, and dependents, and who updates it here?

## Optimize for Reversible Decisions
For uncertain, noncritical choices, favor designs and commitments whose consequences can be observed and reversed at acceptable cost before scaling them.

Expand Down
24 changes: 16 additions & 8 deletions QUICK_REFERENCE.md

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions REVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ When continuing cannot satisfy the contract safely, detect the condition at the
- Would continuing preserve a truthful and safe contract?
- Does the error include enough evidence for recovery?

## Follow Published Standards
A part whose behavior a published standard specifies should conform to that standard, cite it by number and version, and be tested against its examples or conformance suite, so that peers, tools, and reviewers can check it against a text other than the code.

**Applies when**
- The part reads or writes a format, speaks a protocol, or implements an algorithm that a published standard specifies: timestamps, URIs, JSON, email addresses, TLS, password hashing, version strings.
- What it emits will be consumed by tools or peers the author does not control.
- A security property depends on the part, so the standard's review history is evidence a private design lacks.
- The standard publishes test vectors or a conformance suite a test can run.

**Ask**
- Which standard specifies what this part reads, writes, or computes, is it cited by number and version where the code is, and has it been obsoleted or amended since?
- Which subset or profile of the standard is implemented, and what happens on input that uses the rest?
- Is conformance tested against the standard's own examples, test vectors, or conformance suite?
- Where this departs from the standard, is the departure written down, and which peers will it break?

## Goodhart's Law
When a measure becomes a target, it ceases to be a good measure, because those it measures move the number by means that decouple it from what it was chosen to indicate.

Expand Down Expand Up @@ -352,6 +367,21 @@ Protection mechanisms must be easy enough to apply correctly and routinely that
- Is there a scoped way in for a tree that does not yet comply, such as a baseline or a ratchet?
- Six months from now, what evidence would show this is still enabled everywhere it was installed?

## Reuse Maintained Components
Do not hand-roll a function that a maintained component already provides at adequate fit, because the component carries the edge cases, platform coverage, and fixes of every user it has, while a private copy carries only the cases its author met.

**Applies when**
- A change implements something a widely used library, standard-library module, or tool already provides: parsing a standard format, quoting for a shell, splitting arguments, installing a toolchain, cryptography.
- The hand-rolled form is short enough to look obviously correct, so its untested edge cases are not visible in review.
- The same helper exists, or is about to, in more than one repository.
- A candidate component exists whose maintenance can be judged from evidence: release history, open advisories, and how many projects depend on it.

**Ask**
- Which maintained library, standard-library module, or tool already does what this code does, and why was it not used?
- If one was rejected, is the reason written beside the code: poor fit, size against the need, licence, or maintenance?
- Which inputs and platforms has the hand-rolled form been run on, and which has the maintained component met that this one has not?
- Is the chosen component maintained, judged by its release history, open advisories, and dependents, and who updates it here?

## Optimize for Reversible Decisions
For uncertain, noncritical choices, favor designs and commitments whose consequences can be observed and reversed at acceptable cost before scaling them.

Expand Down
105 changes: 105 additions & 0 deletions name-index.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@
"title": "Defense in Depth",
"path": "principles/defense-in-depth.toml"
},
{
"name": "Build versus buy",
"key": "build versus buy",
"tokens": [
"build",
"versus",
"buy"
],
"field": "alias",
"id": "reuse-maintained-components",
"title": "Reuse Maintained Components",
"path": "principles/reuse-maintained-components.toml"
},
{
"name": "Calculator with one_plus_one()",
"key": "calculator with one plus one",
Expand Down Expand Up @@ -366,6 +379,20 @@
"title": "Informed Consent for Consequential Actions",
"path": "principles/informed-consent.toml"
},
{
"name": "Conform to the specification",
"key": "conform to the specification",
"tokens": [
"conform",
"to",
"the",
"specification"
],
"field": "alias",
"id": "follow-published-standards",
"title": "Follow Published Standards",
"path": "principles/follow-published-standards.toml"
},
{
"name": "Confused Deputy",
"key": "confused deputy",
Expand Down Expand Up @@ -466,6 +493,18 @@
"title": "Graceful Degradation",
"path": "principles/graceful-degradation.toml"
},
{
"name": "Dependency currency",
"key": "dependency currency",
"tokens": [
"dependency",
"currency"
],
"field": "alias",
"id": "deprecation-discipline",
"title": "Deprecation Discipline",
"path": "principles/deprecation-discipline.toml"
},
{
"name": "Deprecation Discipline",
"key": "deprecation discipline",
Expand Down Expand Up @@ -530,6 +569,21 @@
"title": "Explicit Unknown",
"path": "principles/explicit-unknown.toml"
},
{
"name": "Do not reinvent the wheel",
"key": "do not reinvent the wheel",
"tokens": [
"do",
"not",
"reinvent",
"the",
"wheel"
],
"field": "alias",
"id": "reuse-maintained-components",
"title": "Reuse Maintained Components",
"path": "principles/reuse-maintained-components.toml"
},
{
"name": "Do one thing well",
"key": "do one thing well",
Expand Down Expand Up @@ -837,6 +891,19 @@
"title": "Backpressure",
"path": "principles/backpressure.toml"
},
{
"name": "Follow Published Standards",
"key": "follow published standards",
"tokens": [
"follow",
"published",
"standards"
],
"field": "title",
"id": "follow-published-standards",
"title": "Follow Published Standards",
"path": "principles/follow-published-standards.toml"
},
{
"name": "Goodhart's Law",
"key": "goodhart s law",
Expand Down Expand Up @@ -1308,6 +1375,19 @@
"title": "Explicit Unknown",
"path": "principles/explicit-unknown.toml"
},
{
"name": "Not Invented Here",
"key": "not invented here",
"tokens": [
"not",
"invented",
"here"
],
"field": "alias",
"id": "reuse-maintained-components",
"title": "Reuse Maintained Components",
"path": "principles/reuse-maintained-components.toml"
},
{
"name": "Observability",
"key": "observability",
Expand Down Expand Up @@ -1730,6 +1810,19 @@
"title": "Reproducible Derived State",
"path": "principles/reproducible-derived-state.toml"
},
{
"name": "Reuse Maintained Components",
"key": "reuse maintained components",
"tokens": [
"reuse",
"maintained",
"components"
],
"field": "title",
"id": "reuse-maintained-components",
"title": "Reuse Maintained Components",
"path": "principles/reuse-maintained-components.toml"
},
{
"name": "Robustness Principle",
"key": "robustness principle",
Expand Down Expand Up @@ -1989,6 +2082,18 @@
"title": "High Cohesion, Low Coupling",
"path": "principles/high-cohesion-low-coupling.toml"
},
{
"name": "Standards conformance",
"key": "standards conformance",
"tokens": [
"standards",
"conformance"
],
"field": "alias",
"id": "follow-published-standards",
"title": "Follow Published Standards",
"path": "principles/follow-published-standards.toml"
},
{
"name": "System of Record",
"key": "system of record",
Expand Down
8 changes: 4 additions & 4 deletions policy/upheld.toml
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,10 @@ acyclic-dependencies = "No gate here decides a module graph. uphold is one crate
# whoever wrote the record is the only reader who knows what violating it looks
# like, and a fixture in a file is reviewable.
#
# One control, deliberately, and the run says so on every invocation: twenty-eight
# review-carried records have none. That line is the honest reading of what has
# been demonstrated here, and it is what the next control should be chosen
# against.
# One control, deliberately, and the run says so on every invocation: it prints
# how many review-carried records have none, and names them. That line, not a
# count copied here, is the honest reading of what has been demonstrated, and it
# is what the next control should be chosen against.
[[review.control]]
record = "single-authoritative-source"
catches = "Add a hand-written docs/PRINCIPLES.md that restates each record's claim and applies_when, alongside the generated REVIEW.md that already compiles them from principles/*.toml."
Expand Down
12 changes: 9 additions & 3 deletions principles/deprecation-discipline.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
id = "deprecation-discipline"
title = "Deprecation Discipline"
aliases = ["Compatibility budget", "Semantic versioning"]
aliases = ["Compatibility budget", "Semantic versioning", "Dependency currency"]
kind = "practice"
status = "seed"
domains = ["evolution", "interfaces"]
summary = "Change a published interface through announced, versioned, time-boxed steps, and finish them; a deprecated path that is never removed is compatibility debt that keeps accruing."
claim = "Every incompatible change to a published interface should be signaled by its version, announced with a migration path and a removal point, and completed by removal, so that the cost of compatibility is budgeted and paid rather than accumulated."
problem = "Interfaces change either abruptly, breaking consumers who had no warning, or never, because old paths are marked deprecated and then kept indefinitely. Both come from treating compatibility as free and deprecation as an announcement rather than a process with an end."
rationale = "A version number that encodes compatibility lets a consumer decide mechanically which updates are safe, and a deprecation with a date and a migration turns an open-ended obligation into a bounded one. Measuring how far each consumer's pin is behind the newest release makes unpaid compatibility debt visible before it becomes a forced jump across several versions."
applies_when = ["An interface, package, rule, or format is consumed by code its maintainer does not control or release with.", "An incompatible change is planned, or an old path is being kept alive beside a new one.", "Consumers pin versions of their dependencies and must decide when to move.", "A pin, lock, or reference can fall behind the newest release of what it names."]
applies_when = ["An interface, package, rule, or format is consumed by code its maintainer does not control or release with.", "An incompatible change is planned, or an old path is being kept alive beside a new one.", "Consumers pin versions of their dependencies and must decide when to move.", "A pin, lock, or reference can fall behind the newest release of what it names.", "A component in use has reached its end of life, or carries a published vulnerability that a newer release fixes, so the consumer is the one left on the deprecated path."]
does_not_mean = ["That a version number proves compatibility; a semantic version is the publisher's promise, and consumers depend on more than the promise covers.", "Deprecate without shipping the replacement; a deprecation with no migration path is a breaking change announced early.", "Move to the newest release of everything at once; the discipline is to know the gap and close it on a schedule.", "Keep compatibility shims indefinitely to avoid disappointing anyone; the unfinished deprecation is the failure this record names."]
benefits = ["Consumers can tell safe updates from breaking ones without reading every diff.", "Old paths are removed, so the cost of maintaining them stays bounded.", "Staleness is measured, so large version jumps are avoided."]
costs = ["Two paths are maintained through the deprecation window.", "Migration has to be communicated and tracked across consumers.", "Version numbers invite false confidence where the contract is underspecified."]
failure_when_overapplied = ["Every change is released as a major version out of caution, so the version stops distinguishing breaking changes from safe ones.", "Deprecation windows are so long that the old path gains users faster than migration removes them.", "Automated update pressure churns pins daily and consumers learn to merge updates unread.", "Removal dates are enforced against consumers who were given no migration path, turning the process into a scheduled outage."]
conflicts_with = ["robustness-principle"]
related = ["hyrums-law", "reversible-decisions", "single-authoritative-source", "chestertons-fence"]
review_questions = ["Is this change compatible under the interface's versioning promise, and does the version bump say so?", "If something is deprecated here, where is its replacement, and when is the old path removed?", "How far is each pin in this tree behind the newest release of what it names, and who closes that gap?", "Which consumers still use the old path, and how would the maintainer know?"]
review_questions = ["Is this change compatible under the interface's versioning promise, and does the version bump say so?", "If something is deprecated here, where is its replacement, and when is the old path removed?", "How far is each pin in this tree behind the newest release of what it names, and who closes that gap?", "Which consumers still use the old path, and how would the maintainer know?", "Which component in this stack is past its end of life, or behind a release that fixes a published advisory, and what is the plan to move off it?"]

[enforcement]
level = "lint"
Expand Down Expand Up @@ -47,3 +47,9 @@ title = "Software Engineering at Google, Chapter 21: Dependency Management"
url = "https://abseil.io/resources/swe-book/html/ch21.html"
type = "book"
notes = "Argues that a semantic version is a lossy estimate of compatibility, which is why the record keeps version signalling and completed removal together."

[[sources]]
title = "OWASP Top 10:2021 A06 Vulnerable and Outdated Components"
url = "https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components/"
type = "standard"
notes = "The consumer's side of deprecation: a component left unsupported, out of date, or carrying known vulnerabilities is a risk the consumer owns, and the remedy it gives is a continuous inventory and an update process."
2 changes: 1 addition & 1 deletion principles/economy-of-mechanism.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ does_not_mean = ["KISS as general code simplicity; the slogan is broader than th
benefits = ["Review and testing can cover the whole mechanism rather than a sample of it.", "The permitted set can be stated and compared with the implementation.", "Fewer interacting options leave fewer combinations for an attacker to search."]
costs = ["Convenience features are pushed to other layers, which callers then have to compose.", "Keeping a trusted core small takes continuing refusal of plausible additions.", "A small general mechanism can be slower than a larger specialized one."]
failure_when_overapplied = ["A needed check is left out to keep the mechanism small, and the omission becomes the vulnerability.", "Logic moves out of the core into callers that each reimplement it, so verified code shrinks while trusted code grows.", "Simplicity is judged by line count, and the complexity reappears in configuration the mechanism interprets."]
conflicts_with = ["defense-in-depth"]
conflicts_with = ["defense-in-depth", "reuse-maintained-components"]
related = ["least-common-mechanism", "complete-mediation", "fail-safe-defaults", "minimize-attack-surface", "least-power", "information-hiding"]
review_questions = ["Which part of this change is trusted to refuse, and how large is it after the change?", "Could every path through the mechanism be enumerated in review, and was it?", "Does a new option belong inside the protected mechanism, or can it live in untrusted code that calls it?", "Is the mechanism short because it is simple, or because it hands the hard case to configuration it interprets?"]

Expand Down
Loading
Loading