|
1 | | -# [PROJECT_NAME] Constitution |
2 | | -<!-- Example: Spec Constitution, TaskFlow Constitution, etc. --> |
| 1 | +<!-- |
| 2 | +Sync Impact Report |
| 3 | +================== |
| 4 | +Version change: TEMPLATE → 1.0.0 (initial ratification) |
| 5 | +
|
| 6 | +Templates requiring updates: |
| 7 | + ✅ .specify/templates/plan-template.md — "Constitution Check" gate |
| 8 | + references this file generically; gate items are determined per- |
| 9 | + feature by /speckit.plan from the principles below. No edit required. |
| 10 | + ✅ .specify/templates/{spec,tasks,checklist}-template.md — no edits. |
| 11 | +Top-level AI-agent guidance: |
| 12 | + ✅ AGENTS.md created at repository root as canonical guidance file. |
| 13 | + ✅ CLAUDE.md (locally excluded) symlinked → AGENTS.md. |
| 14 | +Deferred TODOs: declare `black`/`pyflakes` as dev extras + wire into CI; |
| 15 | + the Quality Gates "Style" item promotes from operator-installed to a |
| 16 | + MUST gate at that point (next PATCH bump). |
| 17 | +--> |
| 18 | + |
| 19 | +# Tributors Constitution |
| 20 | + |
| 21 | +Tributors pays tribute to every contributor by automating bookkeeping |
| 22 | +across `all-contributors`, `Zenodo`, `CodeMeta`, `mailmap`, and |
| 23 | +ORCID-backed identity. This constitution sets the non-negotiable rules |
| 24 | +every change MUST follow. |
3 | 25 |
|
4 | 26 | ## Core Principles |
5 | 27 |
|
6 | | -### [PRINCIPLE_1_NAME] |
7 | | -<!-- Example: I. Library-First --> |
8 | | -[PRINCIPLE_1_DESCRIPTION] |
9 | | -<!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries --> |
| 28 | +### I. Comprehensive Contributor Acknowledgement |
| 29 | + |
| 30 | +Every person who has made a verifiable contribution to a downstream project |
| 31 | +that exceeds the user-configured threshold MUST be representable in the |
| 32 | +output formats Tributors supports. The default behaviour is *inclusive*: an |
| 33 | +operator opts contributors *out* (via skip lists or a higher threshold), not |
| 34 | +*in*. Bots are excluded by default because they are not people, not because |
| 35 | +their work doesn't count. |
| 36 | + |
| 37 | +**Rationale**: The whole purpose of the project is to make sure no |
| 38 | +contributor falls through the cracks. A silent omission is a worse failure |
| 39 | +than a noisy one. |
| 40 | + |
| 41 | +### II. Named Contributor Fields Are Sacred (NON-NEGOTIABLE) |
| 42 | + |
| 43 | +Once truthy, the named contributor fields — `name`, `email`, `affiliation`, |
| 44 | +`orcid`, `blog`/`profile`, `bio` — in `.tributors`, `.zenodo.json`, |
| 45 | +`.all-contributorsrc`, `codemeta.json`, and any future contributor file |
| 46 | +MUST NOT be overwritten by an automated run. New information may be added; |
| 47 | +existing values may not be silently replaced. |
| 48 | + |
| 49 | +**Rationale**: operators hand-curate this exact set of fields; destroying |
| 50 | +that work breaks trust. New parsers and update paths route through the |
| 51 | +shared merge logic; unconditional assignment to a populated named field is |
| 52 | +a violation that MUST be justified in Complexity Tracking or rejected. |
| 53 | + |
| 54 | +**Known scope limit**: the codebase rebuilds container structures (e.g., |
| 55 | +`.all-contributorsrc` `contributors`, `.zenodo.json` `creators`) on each |
| 56 | +run, so list *order* is not preserved. Order preservation is a SHOULD, not |
| 57 | +a MUST, until a parser explicitly opts in. |
| 58 | + |
| 59 | +### III. Pluggable Parsers & Shared Cache |
| 60 | + |
| 61 | +Each input source and each output format MUST be implemented as a parser |
| 62 | +deriving from `ParserBase` (`tributors/main/parsers/base.py`). Cross-parser |
| 63 | +state MUST flow through the single shared cache file `.tributors`, indexed |
| 64 | +by the canonical identity (the GitHub login when available; otherwise the |
| 65 | +most stable identifier the parser exposes). Parsers MUST NOT reach across |
| 66 | +into each other's file formats directly. |
10 | 67 |
|
11 | | -### [PRINCIPLE_2_NAME] |
12 | | -<!-- Example: II. CLI Interface --> |
13 | | -[PRINCIPLE_2_DESCRIPTION] |
14 | | -<!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats --> |
| 68 | +**Rationale**: The shared cache is what makes "update Zenodo from data the |
| 69 | +all-contributors run discovered" cheap and consistent. Bypassing it |
| 70 | +re-introduces the manual-bookkeeping problem the project was built to solve. |
15 | 71 |
|
16 | | -### [PRINCIPLE_3_NAME] |
17 | | -<!-- Example: III. Test-First (NON-NEGOTIABLE) --> |
18 | | -[PRINCIPLE_3_DESCRIPTION] |
19 | | -<!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced --> |
| 72 | +**How to apply**: A new format (e.g., a new author file standard) is added |
| 73 | +by writing a parser, not by patching an existing one. A new identity source |
| 74 | +updates `.tributors` via `update-lookup`; it does not write directly into a |
| 75 | +contributor file. |
20 | 76 |
|
21 | | -### [PRINCIPLE_4_NAME] |
22 | | -<!-- Example: IV. Integration Testing --> |
23 | | -[PRINCIPLE_4_DESCRIPTION] |
24 | | -<!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas --> |
| 77 | +### IV. Automation Across Equivalent Surfaces |
25 | 78 |
|
26 | | -### [PRINCIPLE_5_NAME] |
27 | | -<!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity --> |
28 | | -[PRINCIPLE_5_DESCRIPTION] |
29 | | -<!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles --> |
| 79 | +Every contributor-management capability MUST be reachable from the Python |
| 80 | +library API, the `tributors` CLI, the published container image, and the |
| 81 | +GitHub Action (`action.yml`), with matching options (CLI dashes ↔ Action |
| 82 | +underscores) and equivalent results. A feature is not "done" until the CLI |
| 83 | +and (where applicable) the Action expose it, and its output is a |
| 84 | +deterministic, diff-friendly file reviewable in a pull request. |
30 | 85 |
|
31 | | -## [SECTION_2_NAME] |
32 | | -<!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. --> |
| 86 | +### V. Identity Resolution with Human-in-the-Loop |
33 | 87 |
|
34 | | -[SECTION_2_CONTENT] |
35 | | -<!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. --> |
| 88 | +When automatic identity resolution is ambiguous (e.g., multiple ORCID |
| 89 | +records match a name), Tributors MUST NOT silently pick one. The default |
| 90 | +behaviour is to skip the ambiguous entry; under `--interactive` mode, the |
| 91 | +operator is prompted with each candidate's distinguishing fields and |
| 92 | +selects (or skips). External authoritative sources (ORCID, mailmap, the |
| 93 | +shared cache) take precedence over heuristic guesses. |
36 | 94 |
|
37 | | -## [SECTION_3_NAME] |
38 | | -<!-- Example: Development Workflow, Review Process, Quality Gates, etc. --> |
| 95 | +**Rationale**: A wrong attribution is worse than a missing one — it |
| 96 | +misrepresents a real person. Ambiguity is a signal that human judgement is |
| 97 | +required, not that the tool should pick the first match. |
39 | 98 |
|
40 | | -[SECTION_3_CONTENT] |
41 | | -<!-- Example: Code review requirements, testing gates, deployment approval process, etc. --> |
| 99 | +## Metadata & Standards Compliance |
| 100 | + |
| 101 | +Output files MUST conform to the upstream schemas they target: |
| 102 | + |
| 103 | +- `.all-contributorsrc` follows the all-contributors specification, including |
| 104 | + the documented contribution-type emoji keys. |
| 105 | +- `.zenodo.json` follows Zenodo's metadata schema; ORCID IDs are stored in |
| 106 | + their canonical format. |
| 107 | +- `codemeta.json` follows the CodeMeta specification. |
| 108 | +- `.mailmap` follows git's mailmap syntax. |
| 109 | + |
| 110 | +Tributors MUST NOT invent new fields inside these files, MUST NOT reorder |
| 111 | +or rewrite content beyond what is necessary to apply an update, and MUST |
| 112 | +preserve any keys it does not understand so that hand-edits and |
| 113 | +out-of-band tooling continue to work. |
| 114 | + |
| 115 | +## Development Workflow & Quality Gates |
| 116 | + |
| 117 | +The following gates apply to every change (human-authored or AI-assisted) |
| 118 | +and MUST be checked by `/speckit.plan` for any new feature: |
| 119 | + |
| 120 | +1. **Principle compliance**: every Functional Requirement in the spec is |
| 121 | + mapped to one or more principles above; any deviation appears in |
| 122 | + Complexity Tracking with explicit justification. |
| 123 | +2. **Parser discipline**: new behaviour for an existing format goes into |
| 124 | + that format's parser; cross-format flow goes through `.tributors`. |
| 125 | +3. **Surface parity**: behaviour added to the library is reflected in the |
| 126 | + CLI and (where applicable) the GitHub Action with matching options. |
| 127 | +4. **Tests**: unit tests for parser logic (`tests/test_parsers.py` and |
| 128 | + peers) and CLI tests (`tests/test_client.sh`) MUST cover the new path; |
| 129 | + the merge-without-overwriting invariant MUST be exercised whenever a |
| 130 | + parser's write path is touched. |
| 131 | +5. **Style**: Python source is formatted with `black` and passes |
| 132 | + `pyflakes`; both are operator-installed today and not yet wired into |
| 133 | + CI (the gate promotes to MUST when they are). New files MUST carry the |
| 134 | + MPL-2.0 license header in the form used across the codebase. |
| 135 | +6. **No silent network calls in tests**: parser tests MUST be runnable |
| 136 | + offline; live API interaction goes behind an explicit fixture/flag. |
42 | 137 |
|
43 | 138 | ## Governance |
44 | | -<!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan --> |
45 | 139 |
|
46 | | -[GOVERNANCE_RULES] |
47 | | -<!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance --> |
| 140 | +This constitution supersedes ad-hoc conventions in the codebase and other |
| 141 | +guidance documents (including `AGENTS.md` / `CLAUDE.md`, README, and per- |
| 142 | +parser docs). Where any of those conflict with this file, this file wins |
| 143 | +and the conflicting document MUST be reconciled. |
| 144 | + |
| 145 | +**Amendment procedure**: amendments are proposed in a pull request that |
| 146 | +edits this file and, when applicable, the affected templates under |
| 147 | +`.specify/templates/`. The PR description MUST include the version bump |
| 148 | +(see below) and a Sync Impact Report at the top of this file describing |
| 149 | +what changed and which downstream artifacts (templates, AGENTS.md, |
| 150 | +parsers, docs) require follow-up. The PR MUST be reviewed by a project |
| 151 | +maintainer before merge. |
| 152 | + |
| 153 | +**Versioning policy**: the constitution itself uses semantic versioning. |
| 154 | + |
| 155 | +- MAJOR: a principle is removed or redefined in a backward-incompatible way |
| 156 | + (e.g., relaxing the "manual edits are sacred" invariant). |
| 157 | +- MINOR: a new principle or normative section is added, or existing |
| 158 | + guidance is materially expanded. |
| 159 | +- PATCH: clarifications, wording fixes, typo repairs, non-semantic |
| 160 | + refinements. |
| 161 | + |
| 162 | +**Compliance review**: every pull request that adds or modifies behaviour |
| 163 | +MUST verify against the Quality Gates above. AI agents (Claude Code, |
| 164 | +Codex, Cursor, Aider, and any future assistant) MUST read this |
| 165 | +constitution and `AGENTS.md` before proposing changes, and MUST surface |
| 166 | +principle violations rather than silently work around them. |
| 167 | +`AGENTS.md` (and its `CLAUDE.md` symlink) is this constitution's delegate |
| 168 | +for day-to-day conventions — build/test commands, code style specifics, |
| 169 | +pointers back here. Principles are added here, not there. |
48 | 170 |
|
49 | | -**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] |
50 | | -<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 --> |
| 171 | +**Version**: 1.0.0 | **Ratified**: 2026-05-18 | **Last Amended**: 2026-05-18 |
0 commit comments