diff --git a/AGENTS.md b/AGENTS.md index 8b349e7..1282150 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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. @@ -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. diff --git a/QUICK_REFERENCE.md b/QUICK_REFERENCE.md index 00091ba..5ec3276 100644 --- a/QUICK_REFERENCE.md +++ b/QUICK_REFERENCE.md @@ -13,13 +13,14 @@ Generated from `principles/*.toml`. Do not edit this file directly. | [Conway's Law](principles/conways-law.toml) | Mirroring hypothesis; Organization-structure homomorphism | law | socio-technical, architecture | A system's real module boundaries settle where the designing organization's communication boundaries are, whatever the architecture diagram says. | review; partially | | [Data Minimization](principles/data-minimization.toml) | Purpose limitation; Collect only what is needed; Publish only what is needed | principle | security, ai-harness | Collect, keep, and publish only the data a stated purpose requires. | lint; yes; rung: text | | [Defense in Depth](principles/defense-in-depth.toml) | Layered defenses; Fault containment; Blast radius | principle | security, reliability, ai-harness | Use independent controls so one failed assumption does not become complete compromise. | governance; partially | -| [Deprecation Discipline](principles/deprecation-discipline.toml) | Compatibility budget; Semantic versioning | practice | evolution, interfaces | 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. | lint; yes; rung: text | +| [Deprecation Discipline](principles/deprecation-discipline.toml) | Compatibility budget; Semantic versioning; Dependency currency | practice | evolution, interfaces | 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. | lint; yes; rung: text | | [Economy of Mechanism](principles/economy-of-mechanism.toml) | KISS; Keep it simple; Keep security simple; Small enough to verify | principle | security, architecture | Keep a protection mechanism small and simple enough that every path through it can be inspected and tested. | review; partially | | [End-to-End Principle](principles/end-to-end-principle.toml) | End-to-end arguments in system design | principle | distributed-systems, security, reliability | Place correctness guarantees at the endpoint that has enough context to verify them; lower layers may only assist. | test; partially | | [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml) | No rule without a firing condition; Prose is not a check; Evidence-bound enforcement; Actionable signal | principle | reliability, socio-technical, ai-harness, security | A rule is enforcement only when it names what fires it and cites what it observed; otherwise it is documentation. | lint; partially | | [Explicit Unknown](principles/explicit-unknown.toml) | Distinguish not-violated from not-inspected; No silent pass; Report could-not-check | principle | reliability, security, data, ai-harness | A check that could not evaluate must say so, in a state distinct from pass. | test; yes | | [Fail Fast and Explicitly](principles/fail-fast.toml) | Fail fast; Fail loudly | principle | reliability, interfaces, testing | Detect invalid assumptions near their source and stop before corrupted state propagates. | test; partially | | [Fail-Safe Defaults](principles/fail-safe-defaults.toml) | Default deny; Fail closed; Secure by default | principle | security, reliability, architecture, ai-harness | Base access on explicit permission rather than explicit exclusion; the default answer is no. | lint; yes | +| [Follow Published Standards](principles/follow-published-standards.toml) | Standards conformance; Conform to the specification | principle | interfaces, security | Where an RFC, ISO, W3C, or industry standard specifies a format, protocol, or algorithm, implement that standard and cite it; a private variant interoperates only with itself and repeats mistakes the standard's review already fixed. | test; partially; rung: text, syntax | | [Goodhart's Law](principles/goodharts-law.toml) | Campbell's law; When a measure becomes a target | law | socio-technical | A number chosen to stand for a goal stops standing for it once people or agents are rewarded or gated by the number. | review; partially | | [Graceful Degradation](principles/graceful-degradation.toml) | Degraded mode; Partial availability; Design for failure | principle | reliability, distributed-systems | Preserve truthful, bounded, useful service when full functionality is unavailable. | runtime; partially | | [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml) | Cohesion and coupling; Law of Demeter; Principle of least knowledge; Interface segregation; Stable dependencies; Stable abstractions; Common closure; Common reuse | principle | architecture | Keep related responsibilities together and minimize unnecessary dependencies between independently changing parts. | review; partially | @@ -37,6 +38,7 @@ Generated from `principles/*.toml`. Do not edit this file directly. | [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml) | Combinatorial explosion; One entity per value; Calculator with one_plus_one(); Parameterize Function; Method-per-argument | principle | architecture, interfaces, ai-harness | When entities differ only in a value they carry, take the value as an argument; a name per value grows multiplicatively and each copy is a place the behavior can drift. | lint; partially | | [Psychological Acceptability](principles/psychological-acceptability.toml) | Usable security; A control people can keep; Human interface must not obstruct | principle | security, socio-technical, ai-harness | A control that people cannot routinely comply with is a control that gets bypassed. | review; partially | | [Reproducible Derived State](principles/reproducible-derived-state.toml) | Reproducible builds; Determinism; Deterministic generation | principle | data, reliability, evolution | Anything generated -- a build, a lockfile, a rendered document, an index -- can be regenerated from declared inputs and compared, so a copy that drifted from its source is caught rather than trusted. | lint; yes; rung: text | +| [Reuse Maintained Components](principles/reuse-maintained-components.toml) | Not Invented Here; Build versus buy; Do not reinvent the wheel | principle | architecture, evolution | Where a maintained library, tool, or service already does the job, use it rather than writing your own; a hand-rolled copy re-decides every edge case the maintained one has already met, and is tested only where its author happened to run it. | review; partially; rung: text, syntax | | [Robustness Principle](principles/robustness-principle.toml) | Postel's law; Be liberal in what you accept; Be conservative in what you send | principle | interfaces, distributed-systems | Send only what the specification allows and tolerate peers' deviations where their meaning is clear -- an interoperability rule whose long-run price is that the tolerated deviations become the protocol. | review; partially | | [Rule of Least Power](principles/least-power.toml) | Principle of least power; Least expressive language that suffices | principle | interfaces, architecture | Pick the weakest language, format, or interface that can express the need; what a weaker form cannot say, a reader or a tool can show it does not say. | review; partially | | [Rule of Three](principles/rule-of-three.toml) | Three strikes and you refactor; Wait for the third instance | heuristic | evolution, architecture | Tolerate the second copy and abstract at the third, when enough instances exist to show what actually varies between them. | review; partially | @@ -53,28 +55,28 @@ Generated from `principles/*.toml`. Do not edit this file directly. - **law**: [Conway's Law](principles/conways-law.toml), [Goodhart's Law](principles/goodharts-law.toml), [Hyrum's Law](principles/hyrums-law.toml) - **philosophy**: [Unix Composability](principles/unix-composability.toml) - **practice**: [Deprecation Discipline](principles/deprecation-discipline.toml) -- **principle**: [Acyclic Dependencies Principle](principles/acyclic-dependencies.toml), [Complete Mediation](principles/complete-mediation.toml), [Compromise Recording](principles/compromise-recording.toml), [Data Minimization](principles/data-minimization.toml), [Defense in Depth](principles/defense-in-depth.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Graceful Degradation](principles/graceful-degradation.toml), [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml), [Idempotency](principles/idempotency.toml), [Information Hiding](principles/information-hiding.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Least Privilege](principles/least-privilege.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Observability](principles/observability.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Robustness Principle](principles/robustness-principle.toml), [Rule of Least Power](principles/least-power.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml), [Separation of Concerns](principles/separation-of-concerns.toml), [Separation of Privilege](principles/separation-of-privilege.toml), [Single Authoritative Source](principles/single-authoritative-source.toml) +- **principle**: [Acyclic Dependencies Principle](principles/acyclic-dependencies.toml), [Complete Mediation](principles/complete-mediation.toml), [Compromise Recording](principles/compromise-recording.toml), [Data Minimization](principles/data-minimization.toml), [Defense in Depth](principles/defense-in-depth.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Follow Published Standards](principles/follow-published-standards.toml), [Graceful Degradation](principles/graceful-degradation.toml), [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml), [Idempotency](principles/idempotency.toml), [Information Hiding](principles/information-hiding.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Least Privilege](principles/least-privilege.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Observability](principles/observability.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Reuse Maintained Components](principles/reuse-maintained-components.toml), [Robustness Principle](principles/robustness-principle.toml), [Rule of Least Power](principles/least-power.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml), [Separation of Concerns](principles/separation-of-concerns.toml), [Separation of Privilege](principles/separation-of-privilege.toml), [Single Authoritative Source](principles/single-authoritative-source.toml) - **tactic**: [Backpressure](principles/backpressure.toml) ## By domain - **ai-harness**: [Complete Mediation](principles/complete-mediation.toml), [Confused Deputy](principles/confused-deputy.toml), [Data Minimization](principles/data-minimization.toml), [Defense in Depth](principles/defense-in-depth.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Idempotency](principles/idempotency.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Privilege](principles/least-privilege.toml), [Observability](principles/observability.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml) -- **architecture**: [Acyclic Dependencies Principle](principles/acyclic-dependencies.toml), [Complete Mediation](principles/complete-mediation.toml), [Conway's Law](principles/conways-law.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml), [Information Hiding](principles/information-hiding.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Rule of Least Power](principles/least-power.toml), [Rule of Three](principles/rule-of-three.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml), [Separation of Concerns](principles/separation-of-concerns.toml), [Single Authoritative Source](principles/single-authoritative-source.toml), [Unix Composability](principles/unix-composability.toml) +- **architecture**: [Acyclic Dependencies Principle](principles/acyclic-dependencies.toml), [Complete Mediation](principles/complete-mediation.toml), [Conway's Law](principles/conways-law.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml), [Information Hiding](principles/information-hiding.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Reuse Maintained Components](principles/reuse-maintained-components.toml), [Rule of Least Power](principles/least-power.toml), [Rule of Three](principles/rule-of-three.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml), [Separation of Concerns](principles/separation-of-concerns.toml), [Single Authoritative Source](principles/single-authoritative-source.toml), [Unix Composability](principles/unix-composability.toml) - **data**: [Explicit Unknown](principles/explicit-unknown.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Single Authoritative Source](principles/single-authoritative-source.toml) - **distributed-systems**: [Backpressure](principles/backpressure.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Graceful Degradation](principles/graceful-degradation.toml), [Idempotency](principles/idempotency.toml), [Robustness Principle](principles/robustness-principle.toml) -- **evolution**: [Chesterton's Fence](principles/chestertons-fence.toml), [Deprecation Discipline](principles/deprecation-discipline.toml), [Hyrum's Law](principles/hyrums-law.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Rule of Three](principles/rule-of-three.toml) -- **interfaces**: [Deprecation Discipline](principles/deprecation-discipline.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Hyrum's Law](principles/hyrums-law.toml), [Idempotency](principles/idempotency.toml), [Information Hiding](principles/information-hiding.toml), [Least Astonishment](principles/least-astonishment.toml), [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Robustness Principle](principles/robustness-principle.toml), [Rule of Least Power](principles/least-power.toml), [Unix Composability](principles/unix-composability.toml) +- **evolution**: [Chesterton's Fence](principles/chestertons-fence.toml), [Deprecation Discipline](principles/deprecation-discipline.toml), [Hyrum's Law](principles/hyrums-law.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Reuse Maintained Components](principles/reuse-maintained-components.toml), [Rule of Three](principles/rule-of-three.toml) +- **interfaces**: [Deprecation Discipline](principles/deprecation-discipline.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Follow Published Standards](principles/follow-published-standards.toml), [Hyrum's Law](principles/hyrums-law.toml), [Idempotency](principles/idempotency.toml), [Information Hiding](principles/information-hiding.toml), [Least Astonishment](principles/least-astonishment.toml), [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Robustness Principle](principles/robustness-principle.toml), [Rule of Least Power](principles/least-power.toml), [Unix Composability](principles/unix-composability.toml) - **performance**: [Backpressure](principles/backpressure.toml) - **reliability**: [Backpressure](principles/backpressure.toml), [Defense in Depth](principles/defense-in-depth.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Graceful Degradation](principles/graceful-degradation.toml), [Observability](principles/observability.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml) -- **security**: [Complete Mediation](principles/complete-mediation.toml), [Compromise Recording](principles/compromise-recording.toml), [Confused Deputy](principles/confused-deputy.toml), [Data Minimization](principles/data-minimization.toml), [Defense in Depth](principles/defense-in-depth.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Least Privilege](principles/least-privilege.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Separation of Privilege](principles/separation-of-privilege.toml) +- **security**: [Complete Mediation](principles/complete-mediation.toml), [Compromise Recording](principles/compromise-recording.toml), [Confused Deputy](principles/confused-deputy.toml), [Data Minimization](principles/data-minimization.toml), [Defense in Depth](principles/defense-in-depth.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Follow Published Standards](principles/follow-published-standards.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Least Privilege](principles/least-privilege.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Separation of Privilege](principles/separation-of-privilege.toml) - **socio-technical**: [Chesterton's Fence](principles/chestertons-fence.toml), [Compromise Recording](principles/compromise-recording.toml), [Conway's Law](principles/conways-law.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Goodhart's Law](principles/goodharts-law.toml), [Hyrum's Law](principles/hyrums-law.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Astonishment](principles/least-astonishment.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Separation of Privilege](principles/separation-of-privilege.toml), [Single Authoritative Source](principles/single-authoritative-source.toml) - **static-analysis**: [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml) - **testing**: [Fail Fast and Explicitly](principles/fail-fast.toml) ## By rung -- **text**: [Data Minimization](principles/data-minimization.toml), [Deprecation Discipline](principles/deprecation-discipline.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml) -- **syntax**: [Chesterton's Fence](principles/chestertons-fence.toml) +- **text**: [Data Minimization](principles/data-minimization.toml), [Deprecation Discipline](principles/deprecation-discipline.toml), [Follow Published Standards](principles/follow-published-standards.toml), [Minimize Attack Surface](principles/minimize-attack-surface.toml), [Reproducible Derived State](principles/reproducible-derived-state.toml), [Reuse Maintained Components](principles/reuse-maintained-components.toml) +- **syntax**: [Chesterton's Fence](principles/chestertons-fence.toml), [Follow Published Standards](principles/follow-published-standards.toml), [Reuse Maintained Components](principles/reuse-maintained-components.toml) - **semantic**: [Acyclic Dependencies Principle](principles/acyclic-dependencies.toml), [Make Illegal States Unrepresentable](principles/make-illegal-states-unrepresentable.toml) - **none stated**: [Backpressure](principles/backpressure.toml), [Complete Mediation](principles/complete-mediation.toml), [Compromise Recording](principles/compromise-recording.toml), [Confused Deputy](principles/confused-deputy.toml), [Conway's Law](principles/conways-law.toml), [Defense in Depth](principles/defense-in-depth.toml), [Economy of Mechanism](principles/economy-of-mechanism.toml), [End-to-End Principle](principles/end-to-end-principle.toml), [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml), [Explicit Unknown](principles/explicit-unknown.toml), [Fail Fast and Explicitly](principles/fail-fast.toml), [Fail-Safe Defaults](principles/fail-safe-defaults.toml), [Goodhart's Law](principles/goodharts-law.toml), [Graceful Degradation](principles/graceful-degradation.toml), [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml), [Hyrum's Law](principles/hyrums-law.toml), [Idempotency](principles/idempotency.toml), [Information Hiding](principles/information-hiding.toml), [Informed Consent for Consequential Actions](principles/informed-consent.toml), [Least Astonishment](principles/least-astonishment.toml), [Least Common Mechanism](principles/least-common-mechanism.toml), [Least Privilege](principles/least-privilege.toml), [Observability](principles/observability.toml), [Optimize for Reversible Decisions](principles/reversible-decisions.toml), [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml), [Psychological Acceptability](principles/psychological-acceptability.toml), [Robustness Principle](principles/robustness-principle.toml), [Rule of Least Power](principles/least-power.toml), [Rule of Three](principles/rule-of-three.toml), [Separate Mechanism from Policy](principles/mechanism-policy-separation.toml), [Separation of Concerns](principles/separation-of-concerns.toml), [Separation of Privilege](principles/separation-of-privilege.toml), [Single Authoritative Source](principles/single-authoritative-source.toml), [Unix Composability](principles/unix-composability.toml) @@ -95,6 +97,7 @@ Machine-readable, and without this table's escaping, in [`name-index.json`](name | Be conservative in what you send | [Robustness Principle](principles/robustness-principle.toml) | | Be liberal in what you accept | [Robustness Principle](principles/robustness-principle.toml) | | Blast radius | [Defense in Depth](principles/defense-in-depth.toml) | +| Build versus buy | [Reuse Maintained Components](principles/reuse-maintained-components.toml) | | Calculator with one_plus_one() | [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml) | | Campbell's law | [Goodhart's Law](principles/goodharts-law.toml) | | Canonical representation | [Single Authoritative Source](principles/single-authoritative-source.toml) | @@ -107,14 +110,17 @@ Machine-readable, and without this table's escaping, in [`name-index.json`](name | Common reuse | [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml) | | Compatibility budget | [Deprecation Discipline](principles/deprecation-discipline.toml) | | Confirm destructive actions | [Informed Consent for Consequential Actions](principles/informed-consent.toml) | +| Conform to the specification | [Follow Published Standards](principles/follow-published-standards.toml) | | Confused deputy attack | [Confused Deputy](principles/confused-deputy.toml) | | Confused deputy problem | [Confused Deputy](principles/confused-deputy.toml) | | Default deny | [Fail-Safe Defaults](principles/fail-safe-defaults.toml) | | Degraded mode | [Graceful Degradation](principles/graceful-degradation.toml) | +| Dependency currency | [Deprecation Discipline](principles/deprecation-discipline.toml) | | Design for failure | [Graceful Degradation](principles/graceful-degradation.toml) | | Determinism | [Reproducible Derived State](principles/reproducible-derived-state.toml) | | Deterministic generation | [Reproducible Derived State](principles/reproducible-derived-state.toml) | | Distinguish not-violated from not-inspected | [Explicit Unknown](principles/explicit-unknown.toml) | +| Do not reinvent the wheel | [Reuse Maintained Components](principles/reuse-maintained-components.toml) | | Do one thing well | [Unix Composability](principles/unix-composability.toml) | | Do what it says on the tin | [Least Astonishment](principles/least-astonishment.toml) | | Don't repeat yourself | [Single Authoritative Source](principles/single-authoritative-source.toml) | @@ -156,6 +162,7 @@ Machine-readable, and without this table's escaping, in [`name-index.json`](name | No rule without a firing condition | [Enforcement Needs a Trigger](principles/enforcement-needs-a-trigger.toml) | | No silent mutation | [Informed Consent for Consequential Actions](principles/informed-consent.toml) | | No silent pass | [Explicit Unknown](principles/explicit-unknown.toml) | +| Not Invented Here | [Reuse Maintained Components](principles/reuse-maintained-components.toml) | | One entity per value | [Parameterize, Do Not Enumerate](principles/parameterize-do-not-enumerate.toml) | | One-way door | [Optimize for Reversible Decisions](principles/reversible-decisions.toml) | | Operational observability | [Observability](principles/observability.toml) | @@ -196,6 +203,7 @@ Machine-readable, and without this table's escaping, in [`name-index.json`](name | SSOT | [Single Authoritative Source](principles/single-authoritative-source.toml) | | Stable abstractions | [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml) | | Stable dependencies | [High Cohesion, Low Coupling](principles/high-cohesion-low-coupling.toml) | +| Standards conformance | [Follow Published Standards](principles/follow-published-standards.toml) | | System of Record | [Single Authoritative Source](principles/single-authoritative-source.toml) | | Tamper-evident history | [Compromise Recording](principles/compromise-recording.toml) | | Three strikes and you refactor | [Rule of Three](principles/rule-of-three.toml) | diff --git a/REVIEW.md b/REVIEW.md index 8b349e7..1282150 100644 --- a/REVIEW.md +++ b/REVIEW.md @@ -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. @@ -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. diff --git a/name-index.json b/name-index.json index 0d38c21..4e29216 100644 --- a/name-index.json +++ b/name-index.json @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", @@ -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", diff --git a/policy/upheld.toml b/policy/upheld.toml index 493cb29..6e3fe77 100644 --- a/policy/upheld.toml +++ b/policy/upheld.toml @@ -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." diff --git a/principles/deprecation-discipline.toml b/principles/deprecation-discipline.toml index 3021fab..2a6138d 100644 --- a/principles/deprecation-discipline.toml +++ b/principles/deprecation-discipline.toml @@ -1,6 +1,6 @@ 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"] @@ -8,14 +8,14 @@ summary = "Change a published interface through announced, versioned, time-boxed 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" @@ -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." diff --git a/principles/economy-of-mechanism.toml b/principles/economy-of-mechanism.toml index c868a2c..3247799 100644 --- a/principles/economy-of-mechanism.toml +++ b/principles/economy-of-mechanism.toml @@ -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?"] diff --git a/principles/follow-published-standards.toml b/principles/follow-published-standards.toml new file mode 100644 index 0000000..6a86a74 --- /dev/null +++ b/principles/follow-published-standards.toml @@ -0,0 +1,44 @@ +id = "follow-published-standards" +title = "Follow Published Standards" +aliases = ["Standards conformance", "Conform to the specification"] +kind = "principle" +status = "seed" +domains = ["interfaces", "security"] +summary = "Where an RFC, ISO, W3C, or industry standard specifies a format, protocol, or algorithm, implement that standard and cite it; a private variant interoperates only with itself and repeats mistakes the standard's review already fixed." +claim = "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." +problem = "Timestamps in a local format, a home-made token scheme, a CSV dialect with its own quoting, a version string that looks like Semantic Versioning and is not. Each works between the author's own components, then breaks at the first peer that read the standard, and the security review the standard went through never covered the variant." +rationale = "A standard is a contract that many independent implementations already agree on, reviewed by more people than any one project can gather. Conforming to it buys interoperability with peers not yet written, and lets a reviewer check behavior against a specification instead of reverse-engineering intent from code. A citation by number turns 'what does this accept' into a lookup." +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."] +does_not_mean = ["Implement the standard by hand; a maintained library that already conforms is usually the better way to follow it.", "Implement every optional feature; name the profile or subset implemented and refuse the rest explicitly.", "Treat a standard as correct because it is published; errata, obsoleting RFCs, and deprecated algorithms are part of following it.", "Reject every nonconforming input; how liberal a reader should be is the robustness principle's question, and this record asks what the part itself emits and claims."] +benefits = ["Interoperability with implementations the author never tested against.", "Reviewers check behavior against a specification instead of inferring it from code.", "Security analysis done on the standard applies to a conforming implementation."] +costs = ["Standards are long, and the parts used must be read and tested.", "A standard can lag the need, or be heavier than a private format would be.", "A citation goes stale when the standard is superseded, so following one includes migrating off it."] +failure_when_overapplied = ["A heavyweight standard is adopted for an internal exchange a two-field record would serve.", "Conformance is claimed by citing an RFC the code does not implement, and nothing tests the claim.", "A project waits for a standard that does not exist yet instead of documenting its own format.", "Every optional extension is implemented, enlarging the attack surface for features no peer uses."] +conflicts_with = [] +related = ["robustness-principle", "reuse-maintained-components", "hyrums-law", "least-astonishment", "deprecation-discipline"] +review_questions = ["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?"] + +[enforcement] +level = "test" +automatable = "partially" +rung = ["text", "syntax"] +observable = ["Citations of standards in source comments and documentation, and the status the publisher's index gives each cited document.", "Output the part emits, which a validator for the claimed standard can parse.", "Test vectors and conformance suites the standard publishes."] +checks = ["Run the standard's test vectors or conformance suite against the implementation as part of its tests.", "Validate emitted documents against the standard's grammar or schema, such as its ABNF or a published JSON Schema.", "Flag a cited RFC that the RFC Editor's index marks obsoleted, naming the document that obsoletes it."] +limits = ["Which standard applies to a part is a judgment; a tool checks only the claims a part makes.", "A conformance suite covers what its authors wrote, so passing it does not prove conformance.", "A private format that should have been a standard carries no citation for a tool to find."] + +[[sources]] +title = "RFC 2026: The Internet Standards Process -- Revision 3" +url = "https://www.rfc-editor.org/rfc/rfc2026" +type = "standard" +notes = "Defines the IETF's maturity levels and the review a specification passes before it becomes a standard; the review history this record counts as evidence." + +[[sources]] +title = "RFC 7282: On Consensus and Humming in the IETF" +url = "https://www.rfc-editor.org/rfc/rfc7282" +type = "standard" +notes = "Describes rough consensus: that every objection raised was addressed, not that everyone agreed. That is why a standard carries more review than a private design." + +[[sources]] +title = "QA Framework: Specification Guidelines" +url = "https://www.w3.org/TR/qaframe-spec/" +type = "standard" +notes = "W3C guidance on conformance clauses, profiles, and optional features; the source of this record's advice to name the subset implemented." diff --git a/principles/minimize-attack-surface.toml b/principles/minimize-attack-surface.toml index fed7234..d916fca 100644 --- a/principles/minimize-attack-surface.toml +++ b/principles/minimize-attack-surface.toml @@ -13,7 +13,7 @@ does_not_mean = ["Rely on obscurity; an undocumented endpoint is still surface." benefits = ["Fewer places to defend, test, and monitor.", "Flaws in unused features cannot be reached.", "An explicit surface can be compared across versions, so growth is reviewable."] costs = ["Disabling features and declaring grants takes configuration work per component.", "Users who need a disabled feature have to enable it deliberately.", "Measuring the surface needs an inventory that has to be kept current."] failure_when_overapplied = ["Diagnostic and recovery interfaces are removed, so incidents take longer to resolve.", "Functions are folded into one large endpoint, which lowers the count while widening what each entry exposes.", "A declaration is demanded everywhere, and authors paste a broad grant to satisfy the check."] -conflicts_with = ["observability"] +conflicts_with = ["observability", "reuse-maintained-components"] related = ["least-privilege", "fail-safe-defaults", "economy-of-mechanism", "defense-in-depth", "least-power"] review_questions = ["What does this change add to what an outside party can reach or invoke?", "Is any capability granted by a default the artifact does not state?", "Is each new entry point needed in production, or only for development or debugging?", "Did the surface grow since the last release, and was that growth reviewed?"] diff --git a/principles/reuse-maintained-components.toml b/principles/reuse-maintained-components.toml new file mode 100644 index 0000000..fab06f0 --- /dev/null +++ b/principles/reuse-maintained-components.toml @@ -0,0 +1,49 @@ +id = "reuse-maintained-components" +title = "Reuse Maintained Components" +aliases = ["Not Invented Here", "Build versus buy", "Do not reinvent the wheel"] +kind = "principle" +status = "seed" +domains = ["architecture", "evolution"] +summary = "Where a maintained library, tool, or service already does the job, use it rather than writing your own; a hand-rolled copy re-decides every edge case the maintained one has already met, and is tested only where its author happened to run it." +claim = "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." +problem = "A parser, an installer, a quoting routine, or a date calculation is written in place because it looks like fifteen lines. The fifteen lines are right on the author's machine and wrong on the input or platform nobody tried, and each repository that writes them finds that out separately, in production, months apart." +rationale = "A maintained component spreads the cost of discovering failure cases over all of its users, and its maintainers ship each fix to every one of them through a version bump. A hand-rolled copy pays that discovery cost alone and receives no fixes. The comparison that matters is not code size but where the failures are found: in the component's issue tracker before you meet them, or in your own incident after." +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."] +does_not_mean = ["Take any dependency that exists; an abandoned or single-maintainer component is a hand-rolled copy somebody else wrote, plus a supply-chain edge.", "Never write what a library could have provided; when the fit is poor, the dependency is large against the need, or the function is the product's core, writing it is the decision, and the reason is written beside it.", "Wrap every dependency in an in-house abstraction; a thin wrapper re-hand-rolls the interface and hides the component's documentation from the reader.", "Adopt a framework to get one function; reusing a component's function does not oblige taking on its whole model."] +benefits = ["Edge cases and platform differences are met by the component's other users before they reach yours.", "Security fixes arrive through a version bump rather than a rewrite.", "Readers recognize a known component and can read its documentation, where a private one must be read in full."] +costs = ["Each dependency is a supply-chain edge whose compromise reaches every consumer at once.", "The component's release cadence, breaking changes, and licence become the consumer's constraints.", "Adapting to an interface designed for many users can cost more than a narrow private function."] +failure_when_overapplied = ["A trivial function is replaced by a dependency whose transitive tree dwarfs it, and one unpublished package breaks every build that pulled it.", "A component adopted for one function spreads its framework's assumptions through the codebase.", "Domain logic that is the product's reason to exist is bent to fit a generic library.", "Dependencies are added faster than anyone reviews or updates them, so reuse turns into a stack nobody keeps current."] +conflicts_with = ["economy-of-mechanism", "minimize-attack-surface"] +related = ["follow-published-standards", "deprecation-discipline", "rule-of-three", "least-common-mechanism"] +review_questions = ["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?"] + +[enforcement] +level = "review" +automatable = "partially" +rung = ["text", "syntax"] +observable = ["Shell that downloads a tool and unpacks it by hand, where a version manager would resolve it.", "New functions whose names or bodies match a known hand-rolled shape, such as shell quoting, argument splitting, or a Markdown fence scanner.", "Helpers that recur across repositories with near-identical bodies."] +checks = ["Refuse a fetch piped into an unpacker outside a version manager's own bootstrap, as uphold's hand-rolled-toolchain rule set does for tool installers.", "Flag a new function that matches a recorded hand-rolled shape, naming the component that provides it, and accept a waiver that states why it was not used.", "Report near-identical helpers across repositories, so one can be replaced by a shared component."] +limits = ["Whether a component fits the need, and whether it is maintained well enough to trust, is a judgment no pattern decides.", "A list of known shapes catches only shapes someone already wrote down; the next hand-rolled parser is new text.", "A tool cannot see that a component was considered and rejected unless the reason is written where it reads."] + +[[tools]] +name = "OpenSSF Scorecard" +url = "https://scorecard.dev/" +notes = "Scores an open-source project's maintenance and security practices, such as recent commits, code review, and pinned dependencies; one input to judging whether a component is maintained before reusing it." + +[[sources]] +title = "Investigating the Not Invented Here (NIH) syndrome: A look at the performance, tenure, and communication patterns of 50 R&D project groups" +url = "https://doi.org/10.1111/j.1467-9310.1982.tb00478.x" +type = "paper" +notes = "Katz and Allen, R&D Management 12(1), 1982. The empirical origin of the term: groups that stay together long reduce their communication with outside sources and their performance falls." + +[[sources]] +title = "In Defense of Not-Invented-Here Syndrome" +url = "https://www.joelonsoftware.com/2001/10/14/in-defense-of-not-invented-here-syndrome/" +type = "essay" +notes = "Spolsky, 2001. The counterweight this record's does_not_mean carries: when a function is the core of the business, build it yourself." + +[[sources]] +title = "Our Software Dependency Problem" +url = "https://research.swtch.com/deps" +type = "essay" +notes = "Cox, 2019. Argues for reuse while setting out how to inspect a dependency before adopting it, and how to keep it isolated and current afterwards; the costs side of this record." diff --git a/review-controls.json b/review-controls.json index 172f02e..fb1fa51 100644 --- a/review-controls.json +++ b/review-controls.json @@ -15,6 +15,7 @@ "end-to-end-principle", "enforcement-needs-a-trigger", "fail-fast", + "follow-published-standards", "goodharts-law", "graceful-degradation", "high-cohesion-low-coupling", @@ -29,6 +30,7 @@ "observability", "parameterize-do-not-enumerate", "psychological-acceptability", + "reuse-maintained-components", "reversible-decisions", "robustness-principle", "rule-of-three", diff --git a/src/catalog.rs b/src/catalog.rs index 95be745..22d1922 100644 --- a/src/catalog.rs +++ b/src/catalog.rs @@ -90,6 +90,10 @@ const RECORDS: &[(&str, &str)] = &[ "fail-safe-defaults", include_str!("../principles/fail-safe-defaults.toml"), ), + ( + "follow-published-standards", + include_str!("../principles/follow-published-standards.toml"), + ), ( "goodharts-law", include_str!("../principles/goodharts-law.toml"), @@ -159,6 +163,10 @@ const RECORDS: &[(&str, &str)] = &[ "reproducible-derived-state", include_str!("../principles/reproducible-derived-state.toml"), ), + ( + "reuse-maintained-components", + include_str!("../principles/reuse-maintained-components.toml"), + ), ( "reversible-decisions", include_str!("../principles/reversible-decisions.toml"),