From 36af2b34bd94483bc66bf1fca0cb7418def361a3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 12 Nov 2026 00:43:15 +0000 Subject: [PATCH] Standardize shared documentation and maintenance policies --- doc/LICENSE.md | 7 ++ doc/POLICY.md | 220 +++++++++++++++++++++++++++++++++++++------------ doc/VERSIONS | 37 ++++++--- script/build | 2 +- 4 files changed, 200 insertions(+), 66 deletions(-) diff --git a/doc/LICENSE.md b/doc/LICENSE.md index bb14258..21e7f2a 100644 --- a/doc/LICENSE.md +++ b/doc/LICENSE.md @@ -8,6 +8,13 @@ For the full legal text, please refer to the included files: - [`COPYING`](COPYING) (GPLv3) - [`COPYING.LESSER`](COPYING.LESSER) (LGPLv3) +The licenses above govern permissions granted to recipients. They do not +restrict a copyright holder from separately reusing, relicensing, or +incorporating material for which that copyright holder owns all necessary +rights into another work under different terms. This clarification does not +grant any right to relicense third-party material or contributions for which +the necessary rights are not held. + --- Copyright (c) 2012-2026 Automatic Ruby Developers. diff --git a/doc/POLICY.md b/doc/POLICY.md index eaf2eec..da0306f 100644 --- a/doc/POLICY.md +++ b/doc/POLICY.md @@ -5,9 +5,10 @@ responsibilities of the parts and the direction of dependency between them, the handling of settings and credentials, the approach to tests and documentation, the versioning scheme, and the criteria a change is judged by. -It stands on its own. No rule here is completed by a document kept in another -repository, and a subject it does not cover is a gap in this document, to be -filled here rather than looked up elsewhere. +This document stands on its own. It is the whole implementation policy of this +repository, and no rule here is completed by a document kept somewhere else. A +subject it does not cover is a gap in this document, to be filled here rather +than looked up elsewhere. What the system is for belongs to [`REQUIREMENTS.md`](REQUIREMENTS.md). How it is composed belongs to [`BASIC_DESIGN.md`](BASIC_DESIGN.md). The Recipe format @@ -22,9 +23,25 @@ The Invariants below decide over the rest of it. **Simplicity is robustness.** -This principle governs the following implementation and maintenance rules. It -does not permit dropping required behavior, security, compatibility, or -validation. Satisfy those obligations without unnecessary complexity. +This is the governing principle for every rule below. It does not authorize +dropping required behavior, compatibility, security, safety, documentation, or +validation. It requires satisfying those requirements with no more complexity +than the actual problem justifies. + +Complexity is itself a source of failure, compatibility risk, operational risk, +security risk, and maintenance cost. Do not add a branch, state variable, +helper, abstraction, dependency, network boundary, retry, fallback, validation, +configuration state, or framework unless the specification requires it or it +addresses a realistic failure mode with meaningful consequence. + +Do not re-check a condition already guaranteed by a preceding successful +operation or an established invariant. Do not create a layer merely to resemble +a possible future architecture. + +When two designs satisfy the same requirements, choose the one with less +control flow, less state, fewer dependencies, fewer side effects, fewer moving +parts, and fewer operational assumptions. Simplicity is judged by the number of +necessary concepts and behaviors, not by line count alone. ## 1. General Policy @@ -124,18 +141,22 @@ degree of conservatism. - Understand why something exists before replacing it. A constant that looks arbitrary usually encodes an operational fact. - A capability that can live in a plugin lives in a plugin. -- Where a decision looks odd, a comment gives the reason, so that a later change - does not quietly undo it. +- A comment preserves a reason, constraint, non-obvious intent, or decision that + a later change could otherwise undo. Do not use comments merely to restate code + whose operation is already evident. - Old is not a defect. Neither is unfashionable. A defect is something that does not work, is not understood, or cannot be tested. -- Use `must`, `always`, and `never` only for invariants that admit no - reasonable exception. Express preferences and situational decisions with - `prefer`, `should`, or other qualified wording. Do not apply a rule literally - where doing so would defeat the repository's stated purpose, intended - behavior, compatibility, safety, or approved change scope. Where the - applicable specifications and policy leave a legitimate choice open, an - explicit maintainer decision governs that choice, and general conventions do - not override it. +- Use `must`, `always`, and `never` only for invariants that admit no reasonable + exception. Express preferences and situational decisions with `prefer`, + `should`, or other qualified wording. + + Do not apply a rule literally where doing so would defeat the repository's + stated purpose, intended behavior, compatibility, safety, or approved change + scope. + + Where the applicable specifications and policy leave a legitimate choice + open, an explicit maintainer decision governs that choice. General + conventions do not override it. ### 1.4 Change discipline and maintenance boundary @@ -144,10 +165,28 @@ for long-lived host infrastructure. Its core contracts deserve comparable caution because external Recipes and plugins depend on them, but the whole repository is not treated as immutable infrastructure. -Finding a possible safety, portability, maintainability, cleanup, -modernization or refactoring improvement does not by itself authorize an -implementation change. A change is made when that change is part of the stated -work, not merely because an opportunity was noticed while editing nearby code. +Documentation work, policy work, review, diagnostics, cleanup, or another +task whose stated scope does not include an implementation change must not +expand into one merely because an improvement opportunity is discovered. + +Before changing established behavior, weigh the probability and impact of the +failure being prevented against the added complexity, new failure modes, +compatibility risk, operational cost, maintenance cost, and rollback cost. + +A safety-motivated change is not automatically justified by Safety having +priority over Efficiency. Added complexity can itself create new failure +modes, compatibility risk, operational risk, and maintenance cost. Evaluate +the proposed change as a whole. + +Behavior that has operated reliably over time is evidence and has value of +its own. Do not refactor established infrastructure merely because another +design appears cleaner, more modern, or more defensive. + +An implementation change is made only when that change has been explicitly +chosen as part of the work being performed. Before deployment, validate it in +the supported and representative environments affected by the change. A +successful check in one convenient environment is not sufficient evidence for +a change whose compatibility risk extends to other supported environments. Established behaviour is evaluated by layer. A Recipe or plugin contract that has been used for years has strong compatibility value. A framework internal @@ -348,12 +387,16 @@ Dependency points one way and there is no edge back up: ### 1.13 Judging a change +Before accepting a change, ask whether it is the smallest coherent change that +serves its purpose, whether it alters behavior outside that purpose, whether it +adds an unnecessary dependency or side effect, whether it exposes private +information, and whether directly affected documentation remains correct. + - Does it keep the Recipe format and the plugin contract, and if not, is that deliberate and recorded? - Does it respect the direction of dependency? - Does it leave the framework the small part? - Does it keep a plugin's dependency out of everyone else's installation? -- Is it the smallest change that does the job? - Does a test say it works, and does the default suite still need no network? - Do the documents still match the code, in the same commit? - Which layer is changing: a core contract, framework implementation or a @@ -369,19 +412,35 @@ Dependency points one way and there is no edge back up: ### 1.14 Pull Request Scope and History A pull request carries one coherent higher-level purpose, which may require -coordinated changes across several files or responsibilities. Do not split one -approved purpose mechanically by individual finding, file, or review comment, -and do not include unrelated cleanup, formatting, or feature work. Represent -one coherent change as one commit and amend review corrections instead of -accumulating follow-up commits. Use `--force-with-lease` only on the branch -under review when a safe history rewrite is required. Check the final branch -against its base to remove abandoned intermediate wording and work. Merge only -with explicit maintainer approval. - -An automated agent must not commit or push directly to `master`. -It must commit authorized changes to a work branch and submit them through -a pull request targeting the approved base branch. This paragraph does not -change a human maintainer's authority or the existing merge approval rule. +coordinated changes across several files or responsibilities. + +Do not split one approved purpose mechanically by individual finding, file, +or review comment, and do not include unrelated cleanup, formatting, or +feature work. + +Represent one coherent change as one commit and amend review corrections +instead of accumulating follow-up commits. + +Rewriting the history of a branch under review requires an explicit +instruction from the maintainer. When such a rewrite is authorized, use +`--force-with-lease` and limit the operation to the branch under review. + +Check the final branch against its base to remove abandoned intermediate +wording and work. Merge only with explicit maintainer approval. + +Unless explicitly instructed otherwise by the maintainer, an automated agent +must commit authorized changes to a work branch and submit them through a +pull request targeting the approved base branch. + +An automated agent must not commit or push directly to `master` without +explicit instructions from the maintainer authorizing that operation. + +Creating or updating a pull request does not authorize the agent to merge it +or enable auto-merge. Either action requires an explicit instruction from +the maintainer. + +Authorization for one operation does not imply authorization for another. +These rules do not change a human maintainer's authority. --- @@ -406,13 +465,28 @@ makes a diff harder to read than the style saves. - Prefer a guard clause to a wrapping `unless`, in new code. - Write English explanatory prose in clear, natural sentences. Do not replace a sentence with a label and a colon, a status prefix such as `Implement:` or - `Incompatible:`, a symbol, or an unexplained abbreviation. Apply this to - English prose in comments, docstrings, documentation, version histories, - release notes, commit messages, and pull request descriptions. This rule does - not alter the established forms of headings, list labels, tables, code, - configuration syntax, machine-readable fields, literal interface strings, or - non-English content required by the repository's purpose. Do not rewrite - historical entries or unrelated text merely to align their style. + `Incompatible:`, a symbol, or an unexplained abbreviation. + + Apply this to English prose in comments, docstrings, documentation, version + histories, release notes, commit messages, and pull request descriptions. + + This rule does not alter the established forms of headings, list labels, + tables, code, configuration syntax, machine-readable fields, literal + interface strings, or non-English content required by the repository's + purpose. + + Wrap ordinary prose at approximately 80 columns where practical. Preserve + the logical structure of paragraphs, lists, and other document elements. + Do not break URLs, code, tables, identifiers, or other elements whose + structure requires a longer line. + + Shared boilerplate must retain its common wording, line breaks, blank lines, + and formatting. Do not reformat it independently in individual repositories. + Its established common form takes precedence over the ordinary line-wrapping + guideline. + + Do not rewrite historical entries or unrelated text merely to align their + style. ### 2.2 Scope of a change @@ -468,8 +542,8 @@ appear in the order shown below. An executable uses this canonical form: place in existing files, because removing it across existing files is a diff with no benefit, and it is not required in a new file. -Files do not carry a per-file version history. This repository versions at the -repository level only. See section 10. +Ruby files do not carry a per-file version history. Ruby source is versioned +at the repository level. See Section 10. ### 2.4 Ruby version compatibility @@ -701,7 +775,11 @@ behaviour breaks nothing. - **Documentation is updated in the same change as the behaviour it describes.** A behaviour change with no documentation change has not been finished. -- The documents divide as follows, and one fact has one home: +- A concrete specification has exactly one authoritative home appropriate to the + responsibility that owns it. Other documents may link to or summarize that + specification for navigation, but they do not create a competing normative + copy. +- The documents divide as follows: | Document | Holds | | --- | --- | @@ -715,6 +793,17 @@ behaviour breaks nothing. | `doc/LICENSE.md`, `doc/COPYING`, `doc/COPYING.LESSER` | The licence | | `doc/AUTHORS` | Contributors | +- The implementation is the primary evidence of what currently happens. It is + not, by itself, proof that the current behavior is the intended specification. + + When implementation and documentation disagree, compare the implementation, + documented interface, component header, history, existing design, and + maintenance intent. If the implementation contains a regression, do not adopt + that regression as the specification merely because it is present in the + current code. +- Content adapted from an external article, answer, documentation example, source + file, dataset, or other third-party material credits its source and respects + the license or redistribution terms that apply to it. - **No cross-repository reference.** These documents never say "see the policy of another repository", or "as in *X*". Everything needed to understand, build, run and change this repository is here. Another repository may be a @@ -925,16 +1014,16 @@ the version history records what it amounts to. - Each entry opens with `vX.YY (YYYY-MM-DD)`, or `vX.YY (Release Date: TBD)` while unreleased, underlined with `-`, followed by one `-` bullet per change. Newest first. UTF-8. -- **One coherent change is one bullet, at most two physical lines.** A single - line at or under 80 columns is preferred whenever practical. This is an - explicit limit, not a prompt to reread: a bullet that runs past two lines, - or a single line that runs past 80 columns without necessity, must be - shortened. The entry is a list meant to be scanned, and a bullet that grows - past this limit costs it that: the eye no longer finds the changes by - counting lines, and a diff no longer shows a small, bounded edit. -- A bullet carrying file names, module names, setting names or plugin names - may pass 80 columns on its one or two lines when those names cannot be - shortened without losing meaning. The two-line ceiling still applies. +- Write one coherent change per bullet, at most two physical lines. +- A single line at or under 80 columns is preferred whenever practical. + Names and identifiers necessary to describe the change may pass 80 columns + on the bullet's one or two lines when they cannot be shortened without + losing meaning. +- When a version history already exists, balance a new entry against the + length of the existing lines, so that the whole file stays consistent. + Holding to the form this file has settled on comes before the two-line, + 80-column limit above, and leaves that limit standing wherever no such + form exists. - **When a bullet runs long, abstract it first.** Drop the implementation detail, the example, the reason and the secondary effect, and state what the change is. Wrap onto the second line only when the abstracted bullet @@ -969,6 +1058,29 @@ the version history records what it amounts to. - Where the record is incomplete — releases with no tag, or a version bumped with no entry — `VERSIONS` says so rather than inventing an entry. +### 10.6 Source File Version Numbering + +The Ruby file-header convention in Section 2.3 remains unchanged. The +following rules apply to the existing versioned shell build script, not to +Ruby files that carry no individual version history. + +These rules apply to individual source files that carry their own version +history. Repository release versions are governed separately. + +- Source file versions use a two-level `major.minor` scheme. +- When incrementing `minor` would reach `10`, roll over instead: increment + `major` by 1 and reset `minor` to `0` (for example `v0.9` -> `v1.0`, + `v1.9` -> `v2.0`, `v2.9` -> `v3.0`). +- Do not continue `minor` past `9` as in standard semantic versioning + (do not use `v1.10`, `v1.11`, ...). +- Raising `major` for a reason other than the rollover is a decision the + maintainer makes, not one this document derives from the change. +- Removing or renaming an option, changing what an existing argument means, + changing a default so that an unchanged invocation does something else, and + changing how a path or a configuration value is resolved are all incompatible + changes. Say so in the `Version History` entry, so that the number the change + is released under can be chosen knowing that. + --- ## 11. Continuous integration diff --git a/doc/VERSIONS b/doc/VERSIONS index 3620115..ee1329b 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -237,19 +237,22 @@ Version History Guidelines - Record externally meaningful or architecturally significant outcomes, not a diary of implementation work. - Omit development-time corrections and intermediate states that were reverted - or superseded before release; Git history retains that detail. + or superseded before release. Git history retains that detail. - Summarize related low-level changes under their substantive outcome. - Write one coherent change per bullet, at most two physical lines. - A single line at or under 80 columns is preferred whenever practical. - Necessary file names, module names, plugin names, option names, and - configuration names may pass 80 columns on the bullet's one or two lines - when they cannot be shortened without losing meaning. -- When a version history already exists, balance a new entry against the length - of the existing lines, so that the whole file stays consistent. + Names and identifiers necessary to describe the change may pass 80 columns + on the bullet's one or two lines when they cannot be shortened without + losing meaning. +- When a version history already exists, balance a new entry against the + length of the existing lines, so that the whole file stays consistent. + Holding to the form this file has settled on comes before the two-line, + 80-column limit above, and leaves that limit standing wherever no such + form exists. - When an entry becomes substantially longer, omit or abstract implementation details, examples, reasons, and secondary effects where possible. -- Preserve the changed target, externally observable behavior, compatibility - or security impact, and important option or configuration names. +- Preserve the changed target, externally observable behavior, compatibility, + privacy and security impact, and important names and identifiers. - Combine related changes within the same version, especially changes to the same file or feature. - Place closely related entries near each other. @@ -258,9 +261,21 @@ Version History Guidelines - Independent changes may use separate bullets, but they stay in that day's single version entry. - Past entries and their dates are a record. Do not rewrite, renumber or merge - them. Past releases that share a date stay recorded as they were made; they + them. Past releases that share a date stay recorded as they were made. They do not conform to the rule above and are not precedent for new releases. -- This file records the history of the repository. A change that is not - observable from outside does not need an entry here. - The first entry, at the lowest version this file reaches, reads only "Initial release." and nothing else. +- An unreleased entry carries (Release Date: TBD). Replacing TBD with the + actual date is the release itself, and is not a change to record here. +- This file records the history of the repository. A change that is not + observable from outside does not need an entry here, and a documentation + only change takes none unless its scale makes it worth one line saying so. +- Where individual source files carry their own Version History, that history + records changes to the file independently of the repository release history. + A repository release entry does not raise a source-file version, and a + source-file version change does not by itself require a repository release + entry. Record it here only when the change meets the repository-level + criteria above. +- Recording a repository version here does not create or require a Git tag or + GitHub Release. Either is created only when the maintainer explicitly asks + for it. diff --git a/script/build b/script/build index df32580..4ea19b9 100755 --- a/script/build +++ b/script/build @@ -13,7 +13,7 @@ # script/build all Also run the integration recipes by hand. # # Author: id774 (More info: https://id774.net) -# Source Code:: https://github.com/id774/automaticruby +# Source Code: https://github.com/id774/automaticruby # License: The GPL version 3, or LGPL version 3 (Dual License). # Contact: idnanashi@gmail.com #