100 lines
4.8 KiB
Markdown
100 lines
4.8 KiB
Markdown
|
|
# Spec: determinism-promotion
|
||
|
|
|
||
|
|
## ADDED Requirements
|
||
|
|
|
||
|
|
### Requirement: Conventions Catalog Is Global-Only and Machine-Readable
|
||
|
|
|
||
|
|
The plugin SHALL ship a global-only, machine-readable completion-conventions
|
||
|
|
catalog at `plugins/os-doc-hygiene/conventions.json`. There SHALL be no
|
||
|
|
per-project override of this catalog — it only recommends; adoption of a
|
||
|
|
convention lands in the project's own rulebook, not in a project-specific
|
||
|
|
copy of the catalog.
|
||
|
|
|
||
|
|
#### Scenario: The catalog is read from a single global location
|
||
|
|
|
||
|
|
- **WHEN** the deterministic pipeline consults the conventions catalog
|
||
|
|
- **THEN** it reads `plugins/os-doc-hygiene/conventions.json` and no project-level override file for it exists or is consulted
|
||
|
|
|
||
|
|
#### Scenario: Adoption is a rulebook write, not a catalog write
|
||
|
|
|
||
|
|
- **WHEN** a project adopts a convention
|
||
|
|
- **THEN** the adoption is expressed as a graduated rule in the project's `.dochygiene-rules.json`, and the global catalog itself is unchanged
|
||
|
|
|
||
|
|
### Requirement: Convention Entry Shape
|
||
|
|
|
||
|
|
Each entry in the conventions catalog SHALL record: a name, a description of
|
||
|
|
what the convention proves (i.e., what filesystem-observable condition
|
||
|
|
counts as "done"), the `served_when_path` pattern or frontmatter template a
|
||
|
|
rule graduates to when the convention is adopted, and a one-line human pitch
|
||
|
|
for why adopting it is worthwhile.
|
||
|
|
|
||
|
|
#### Scenario: An entry carries all required fields
|
||
|
|
|
||
|
|
- **WHEN** a convention entry is read from the catalog
|
||
|
|
- **THEN** it includes a name, a "what it proves" description, the graduation target (`served_when_path` pattern or frontmatter template), and a one-line pitch
|
||
|
|
|
||
|
|
### Requirement: v1 Catalog Contains Exactly Two Conventions
|
||
|
|
|
||
|
|
The v1 conventions catalog SHALL contain exactly two entries: `archive-bucket`
|
||
|
|
(done = the file moved into a sibling `archive/` directory, graduating a rule
|
||
|
|
to `served_when_path: <dir>/archive/{name}`) and `status-frontmatter` (done =
|
||
|
|
a `status: shipped|done` frontmatter key is present, with the file staying in
|
||
|
|
place and the scanner reading the frontmatter). No other conventions SHALL be
|
||
|
|
present in v1.
|
||
|
|
|
||
|
|
#### Scenario: Exactly two conventions ship in v1
|
||
|
|
|
||
|
|
- **WHEN** the v1 conventions catalog is loaded
|
||
|
|
- **THEN** it contains exactly the `archive-bucket` and `status-frontmatter` entries and no others
|
||
|
|
|
||
|
|
#### Scenario: archive-bucket graduates to a served_when_path
|
||
|
|
|
||
|
|
- **WHEN** a project adopts `archive-bucket` for a rule
|
||
|
|
- **THEN** the rule graduates from a classifier-judged `served_when` to a scanner-provable `served_when_path` pointing at the sibling `archive/` directory
|
||
|
|
|
||
|
|
#### Scenario: status-frontmatter graduates via a frontmatter key
|
||
|
|
|
||
|
|
- **WHEN** a project adopts `status-frontmatter` for a rule
|
||
|
|
- **THEN** the rule graduates to a condition the scanner can check deterministically by reading a `status: shipped|done` frontmatter key, with the file remaining at its original path
|
||
|
|
|
||
|
|
### Requirement: Check Names Promotion Candidates Deterministically in Every Report
|
||
|
|
|
||
|
|
The `:check` skill's deterministic finalize pass SHALL, for every entry whose
|
||
|
|
lifecycle signal is classifier-judged (`served_when` present, no
|
||
|
|
`served_when_path`), check the conventions catalog for an applicable
|
||
|
|
not-yet-adopted convention and, when one applies, emit an entry in the
|
||
|
|
report's `promotion_candidates` section naming the convention and its
|
||
|
|
one-line pitch. This check SHALL run without any model call.
|
||
|
|
|
||
|
|
#### Scenario: A classifier-judged entry with an applicable convention is named
|
||
|
|
|
||
|
|
- **WHEN** an entry uses `served_when` and the `archive-bucket` convention is not yet adopted for that rule
|
||
|
|
- **THEN** the report's `promotion_candidates` section names `archive-bucket` for that entry with its one-line pitch
|
||
|
|
|
||
|
|
#### Scenario: Promotion-candidate naming requires no model call
|
||
|
|
|
||
|
|
- **WHEN** `report_builder.py` computes `promotion_candidates`
|
||
|
|
- **THEN** it does so by reading `conventions.json` and the project's rulebook state directly, with no subagent dispatch
|
||
|
|
|
||
|
|
#### Scenario: An already-adopted convention is not re-named
|
||
|
|
|
||
|
|
- **WHEN** a rule has already graduated to a `served_when_path` matching a catalog convention
|
||
|
|
- **THEN** that rule does not reappear in `promotion_candidates`
|
||
|
|
|
||
|
|
### Requirement: Calibrate May Draft Adoption but Never Applies Unasked
|
||
|
|
|
||
|
|
The `:calibrate` skill MAY draft the adoption of a catalog convention — the
|
||
|
|
graduated rule plus the file moves or frontmatter additions the convention
|
||
|
|
implies — and present it to the human for approval. It SHALL NEVER apply an
|
||
|
|
adoption without explicit human confirmation.
|
||
|
|
|
||
|
|
#### Scenario: Calibrate drafts a convention adoption for review
|
||
|
|
|
||
|
|
- **WHEN** `:calibrate` identifies an unmatched pattern that would benefit from `archive-bucket`
|
||
|
|
- **THEN** it drafts the graduated rule and the implied file moves and presents them to the human before any change is made
|
||
|
|
|
||
|
|
#### Scenario: No adoption is applied without confirmation
|
||
|
|
|
||
|
|
- **WHEN** a human has not yet confirmed a drafted adoption
|
||
|
|
- **THEN** no rulebook write and no file move occurs
|