Skip to content

Commit cae8c99

Browse files
yarikopticclaude
andcommitted
ENH: ratify project constitution v1.0.0 + add AGENTS.md
Populate .specify/memory/constitution.md (previously template placeholders only) with five principles centred on the project's actual ideals: comprehensive contributor acknowledgement, named-contributor fields are sacred, pluggable parsers + shared .tributors cache, automation across equivalent surfaces (library/CLI/container/Action), and identity resolution with human-in-the-loop. Add AGENTS.md at the repository root as the canonical guidance file for AI agents (Claude Code, Codex, Cursor, Aider, …) and humans wanting a quick orientation — preserves the prior build/test/code-style content, adds a spec-kit command cheat-sheet, and points to the constitution as required reading. CLAUDE.md (locally excluded) is symlinked to AGENTS.md. Principle II is intentionally scoped to the *named* contributor fields (`name`, `email`, `affiliation`, `orcid`, `blog`/`profile`, `bio`) — the exact set the codebase currently protects in its merge logic. List ordering across runs is a SHOULD, not a MUST. The Quality Gates "Style" item notes that `black`/`pyflakes` are operator-installed today; promoting the gate to a MUST in CI is the only listed deferred TODO. Co-Authored-By: Claude Code 2.1.143 / Claude Opus 4.7 <noreply@anthropic.com>
1 parent ed9d07a commit cae8c99

2 files changed

Lines changed: 248 additions & 35 deletions

File tree

.specify/memory/constitution.md

Lines changed: 156 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,171 @@
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.
325

426
## Core Principles
527

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.
1067

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.
1571

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.
2076

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
2578

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.
3085

31-
## [SECTION_2_NAME]
32-
<!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. -->
86+
### V. Identity Resolution with Human-in-the-Loop
3387

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.
3694

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.
3998

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.
42137

43138
## Governance
44-
<!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan -->
45139

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.
48170

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

AGENTS.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# AGENTS.md
2+
3+
Canonical guidance for AI coding agents (Claude Code, Codex, Cursor, Aider,
4+
and any future assistant) and for humans who want a quick orientation.
5+
`CLAUDE.md` in this directory is a symlink to this file.
6+
7+
## Read these first — every session
8+
9+
1. **`.specify/memory/constitution.md`** — the project's constitution. It
10+
defines the non-negotiable principles (most importantly: named
11+
contributor fields, once set, MUST NOT be overwritten — see principle
12+
II). Any change you propose MUST be consistent with it; surface a
13+
conflict rather than working around one.
14+
2. **This file** — for build/test commands and code-style conventions.
15+
3. The plan for the current feature, if one is active under `specs/`.
16+
17+
## Spec-Kit Workflow
18+
19+
This project uses [spec-kit](https://github.com/github/spec-kit) for
20+
feature work. The relevant slash commands and the artifacts they
21+
produce/consume:
22+
23+
| Command | Reads | Writes |
24+
| ----------------------- | ------------------------- | ----------------------------------------------- |
25+
| `/speckit.constitution` | repo context | `.specify/memory/constitution.md` |
26+
| `/speckit.specify` | constitution | `specs/<###-name>/spec.md` |
27+
| `/speckit.clarify` | spec | spec (updated) |
28+
| `/speckit.plan` | spec, constitution | `plan.md`, Phase 0/1 artifacts, agent context |
29+
| `/speckit.tasks` | plan + Phase 1 artifacts | `tasks.md` |
30+
| `/speckit.implement` | tasks, plan, constitution | source / tests |
31+
32+
Each command is bounded — do not silently progress into the next one.
33+
34+
## Build and Test Commands
35+
36+
- Install: `pip install .[all]` (`pytest` is not pulled in by `[all]`; add
37+
it explicitly for the test suite, e.g. `pip install -e .[all] pytest`)
38+
- Run tests: `pytest -sv tests/*.py`
39+
- Run CLI tests: `/bin/bash tests/test_client.sh`
40+
- Run a single test: `pytest -sv tests/test_parsers.py::test_parser_zenodo`
41+
- Format code: `black tributors`
42+
- Check formatting: `black --check tributors`
43+
- Check imports: `pyflakes tributors`
44+
45+
Parser tests MUST be runnable offline; do not introduce live network
46+
calls without an explicit opt-in fixture/flag.
47+
48+
## Code Style Guidelines
49+
50+
### Python
51+
52+
- Format with Black; follow PEP 8 for everything Black does not enforce.
53+
- Public classes and functions get a docstring (`"""triple quotes"""`).
54+
- Import order: standard library, then third-party, then local — separated
55+
by blank lines. Use relative imports within the `tributors` package.
56+
- `snake_case` for variables and functions; `PascalCase` for classes.
57+
- Catch specific exceptions, not bare `except:`.
58+
- New `.py` files MUST start with the MPL-2.0 header used across the
59+
codebase (see `tributors/main/parsers/base.py` for the canonical form).
60+
61+
### Markdown
62+
63+
- Markdown tables MUST be column-aligned in source: every cell padded to
64+
the column's widest content, separator dashes matching, outer pipes
65+
vertical. The raw `.md` is read as often as the rendered view.
66+
67+
## Architecture in One Paragraph
68+
69+
`tributors` is a Python library + CLI + container + GitHub Action. Each
70+
input source or output format is a *parser* deriving from `ParserBase`
71+
(`tributors/main/parsers/base.py`). Parsers exchange information through a
72+
single shared cache file, `.tributors`, indexed by GitHub login when
73+
available. `update-lookup` populates the cache from sources (GitHub API,
74+
mailmap, ORCID, etc.); `update` writes from the cache into per-format
75+
files (`.all-contributorsrc`, `.zenodo.json`, `codemeta.json`, …) without
76+
overwriting populated fields. New formats are added by writing new
77+
parsers, not by patching existing ones — see the constitution, principle
78+
III, for the rationale.
79+
80+
## What Counts as "Done"
81+
82+
See `.specify/memory/constitution.md` § "Development Workflow & Quality
83+
Gates" for the authoritative checklist. Short form: parser/cache
84+
discipline (III), surface parity (IV), tests covering the no-overwrite
85+
invariant (II), `black` + `pyflakes` clean, deterministic diff-friendly
86+
output.
87+
88+
<!-- SPECKIT START -->
89+
For additional context about technologies to be used, project structure,
90+
shell commands, and other important information, read the current plan
91+
under `specs/<active-feature>/plan.md`.
92+
<!-- SPECKIT END -->

0 commit comments

Comments
 (0)