Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ stateDiagram-v2

Figure 2. How a rule is admitted and retired. Every transition happens at a revision, with a person agreeing; the labels name the rows of `standards/dials.md`. A graduated rule is enforced by a lint, pre-commit or CI check, and its wording may stay as prose for what the check cannot judge, as R-012's does.

The driver runs `/lasp-dev:revise` before the monthly group meeting, or once ten pull requests have merged since the last report; nothing schedules it. Between meetings, the driver runs `/lasp-dev:revise capture` weekly: it harvests the window's merged pull requests into the standard's log and reads those new or changed since the last capture, so the monthly run reads them from there instead of starting dozens of agents at once. It rebuilds each merged pull request's record, and `thread-analyst` reads every thread, reviewer's summary and conversation comment; with `measures`, it also reads the tickets those pull requests name, the escaped defects and the build yield. The report proposes to keep, reword, retire or graduate each rule and to admit each candidate that meets the Dials, each to its destination: a rule, agent guidance, a data convention, a decision, a lint setting or a question for the group; and it says which numbers are counted and which are the analyst's reading. It also reports, from a sweep of the window's merged diffs, where the code follows or breaks the rules and the documented practice, and proposes a ticket for a problem still on `main` and a fix for a document the merged work has left behind. It opens with an overview of every proposal by priority and impact; the group takes them in that order, marks each accept, decline or escalate, a change to a data convention `accept, owner: <name>` and a question `answer: <the answer>`, and leaves the rest blank, deferred. `revise apply` drafts only what was accepted, as reviewed pull requests, the standard's repository first when the standard lives elsewhere, then this repository's `standards/` and documents, and hands each accepted ticket to `ticket-draft` one at a time. The tiers, graduation and the archive are in the README's "How the corpus grows".
The driver runs `/lasp-dev:revise` before the monthly group meeting, or once ten pull requests have merged since the last report; nothing schedules it. Between meetings, the driver runs `/lasp-dev:revise capture` weekly: it harvests the window's merged pull requests into the standard's log and reads those new or changed since the last capture, so the monthly run reads them from there instead of starting dozens of agents at once. It rebuilds each merged pull request's record, and `thread-analyst` reads every thread, reviewer's summary and conversation comment; with `measures`, it also reads the tickets those pull requests name, the escaped defects and the build yield. The report proposes to keep, reword, retire or graduate each rule and to admit each candidate that meets the Dials, each to its destination: a rule, agent guidance, a data convention, a decision, a lint setting or a question for the group; and it says which numbers are counted and which are the analyst's reading. It also reports, from a sweep of the window's merged diffs, where the code follows or breaks the rules and the documented practice, and proposes a ticket for a problem still on `main` and a fix for a document the merged work has left behind. It opens with an overview of every proposal by priority and impact; the group takes them in that order and discusses each in its own words, on the proposal's `Mark:` line, in review comments and replies on the draft pull request `prepare` can open when the standard lives in another repository, or in meeting notes the driver pastes into `.review/revision/meeting/`, and leaves the rest alone, deferred. Anyone can ask how a proposal came about, with `/lasp-dev:revise <the question>` or in a comment the driver has answered, and the answer cites the cases it rests on. `revise apply` first reads the discussion and settles each proposal's mark, accept, accept with the agreed wording, decline or escalate, a change to a data convention `accept, owner: <name>` and a question `answer: <the answer>`, which the driver confirms before it is written; then it drafts only what was accepted, as reviewed pull requests, the standard's repository first when the standard lives elsewhere, then this repository's `standards/` and documents, and hands each accepted ticket to `ticket-draft` one at a time. The tiers, graduation and the archive are in the README's "How the corpus grows".

A new or reworded rule is first held to `standards/rule-bar.md`, its example resolving in merged code.

Expand Down Expand Up @@ -209,7 +209,7 @@ Every finding is a proposal. Every count the revision reports is per rule, never
- **Corpus:** the shared files in this plugin's `standards/`: the review contract, terminology, cross-repository decisions, context links, the archive and the records.
- **Dial:** a named threshold in `standards/dials.md`, such as the Admission Dial; the revision applies no number that is not one.
- **Held candidate:** a proposed rule whose evidence does not yet meet the Dials; the revision keeps it and judges it again as evidence accumulates.
- **Rule bar:** `standards/rule-bar.md`, what a new or reworded rule passes before the group marks it, its example resolving in merged code.
- **Rule bar:** `standards/rule-bar.md`, what a new or reworded rule passes before the group decides on it, its example resolving in merged code.
- **Driver:** the person who runs the month's revision; the role rotates.
- **Tier:** where a rule is enforced: `prose`, the instruction file only, which the reviewer does not check; `reviewer`, a ledger entry the reviewer checks every diff against; `check`, a tool's configuration, with the ledger entry kept as a pointer (the README's "How the corpus grows").
- **Provisional, established, graduated:** a rule's status on its ledger entry. A rule is admitted provisional, becomes established when the Established Dial is met, and is graduated when the revision judges that a check enforces it; one that leaves is retired.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ session-start line or `work` says something unexpected, these files are what it
| `revision/drift.txt` | `revise` `prepare` step 2, through `scripts/drift_checks.py`: the scripted claims' `claim` and `break` lines | `prepare` steps 2 and 6, for "Practice" and `ticket/` and `doc/` proposals | Rewritten at each revision |
| `revision/state.json` | `revise` `prepare`, through `scripts/revise_state.py`: each stage done or skipped, with why | `prepare` step 10, which writes the report only once every stage is recorded | `revise_state.py start`, at the next `prepare` |
| `revision/notes/` | The driver, before `revise` `prepare`: meeting or chat notes, pasted | `revise`, read as asks at `prepare` step 5, and by `scripts/quote_check.py` for the report's pasted quotes | Not cleared by the tools |
| `revision/marks.md` | `revise` `apply`, when it settles the marks | The driver, before the yes that writes them into the report | Rewritten at each `apply` |
| `revision/meeting/` | The driver, before `revise` `apply`: the revision meeting's notes, or a pull request's threads, pasted | `revise` `apply`, when it settles each proposal's mark | Not cleared by the tools |
| `revision/spot-check.md` | `revise` `prepare` step 2: one line per guidance item `scripts/spot_check.py` sampled, right or wrong | `scripts/spot_check.py tally`, for the report's Head | Rewritten at each revision |
| `revision/tickets/` | `revise` `apply`: each accepted `ticket/` proposal as a prompt (`<n>-<slug>.md`) | `ticket-draft`, given a prompt's path, one at a time | Replaced at each `apply` |
| `revision/feedback/` | `revise`: a `skill-feedback` draft per procedure finding, from `prepare` step 2 and `correct` step 2 | `skill-feedback`, given a draft's path | Not cleared by the tools |
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ merged pull request is its record. Owners are roles. Status is `planned`, `defer
| --- | --- | --- | --- | --- |
| Evidence by citation, in place of the record store | Each rule cites the pull requests it fired on, and counts are derived from the distinct citations ([docs/standards.md](docs/standards.md), "Evidence for the revision"). Replaces the review records, which move to the standard's `log/<repo>/`, and most of `ratchet_counts.py` and `archive_records.py` | plugin maintainer | after the talk | planned |
| Other repositories' threads in the revision's analysts | `prepare` reads every covered repository's comments for guidance and clusters them together, but runs `thread-analyst` and the sweep only on this repository, since its `diff:` verdict and the bar's probes read this repository's code | plugin maintainer | a project wants one revision run to draft rules for several repositories | deferred |
| Revision marks read from the pull request | `prepare` can open the report's branch as a draft pull request for discussion, but a verdict counts only on the report's `Mark:` line, so the driver copies verdicts given in review. `apply` could read them from the review threads through the GitHub server, with a rule for whose reply counts as `pr-review`'s "Whose reply counts" has, and write them into the report before acting | plugin maintainer | a revision where copying verdicts from the pull request proves a burden | idea |
| A rule ages only by pull requests in its scope | The expiry Dials count checked pull requests, ones a review or a build ran the rules on. Once a family's revision harvests every member repository, a rule scoped to one repository's paths would also age by members' pull requests it could never fire on, so the count should take only the pull requests whose changed files its `scope:` matches; the records do not yet carry a pull request's files | plugin maintainer | with the family harvest | planned |
| A held candidate's form in the ledger | No writer says how a held candidate is written below `## Candidates below the criteria`, and a held admission is drafted with its `### R-NNN` heading; `parse_entries` in `ratchet_counts.py`, which `rule_lint.py` shares, reads such a heading anywhere in the file as a live rule. Either the writers state the held form, or `parse_entries` stops at the heading as `standard_file.sh` does. `guidance_clusters.py` reads a held candidate by its `###` heading or the bold title its bullet opens with, the two forms ledgers hold. Its `kind:` and `prs:` lines are now set (`docs/contracts.md`, "The ledger's held-candidates heading"); its heading and the rest of its form are not | plugin maintainer | before a revision holds a candidate it has drafted as a rule | planned |
| People's asks as evidence for a live rule | `prepare.md` step 6 turns a candidate a live rule covers into a reword proposal, with no outcome for asks that are only more evidence for the rule. Established counts agreed findings, not asks, so 12 asks for R-002, R-006 and R-015 in the dry run led nowhere; nor does it say whether Admission or Recurring ask governs a rewording | plugin maintainer, with the team | before the second revision | idea |
Expand Down Expand Up @@ -38,6 +37,7 @@ merged pull request is its record. Owners are roles. Status is `planned`, `defer
| The next round offered, from review to fix and back | After `pr-review` posts, or `pr-fix` pushes, one question offers the next round: make the fixes, commit, push and run `pr-review` again. Asked, never automatic, since one round is sometimes enough and the author may want to move fast. Today each skill ends by naming the next command | plugin maintainer | | idea |
| Every decision point says what each answer does and where it lands (#14) | An audit of nine skills found Stop options that do not say what is kept and push gates that do not name the repository and branch | plugin maintainer | one skill at a time, each with sandbox evidence | planned |
| Review without a typed command | The review contract run when a pull request opens, by a CI action, and `revise prepare` as a scheduled routine, so neither waits for someone to start it; posting stays behind a person's yes | plugin maintainer | the review's findings are trusted enough to run unattended | idea |
| The revision's draft pull request when the standard is this repository's own (#65) | With no clone, `prepare` leaves the report uncommitted in the working tree and offers no pull request, since `revise` never opens this repository's pull request; the group discusses on the report's `Mark:` lines or in pasted notes. A branch and draft pull request here would give it the review threads a clone's standard gets | plugin maintainer | a team with its standard in its own repository wants to discuss on GitHub | idea |

## Build and work

Expand Down
5 changes: 4 additions & 1 deletion docs/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,10 @@ otherwise than its lines, and reads each tally line's fields by place, the quote
a quote splits nothing.

Writers: the driver, in harvest.md's "Clusters". Readers: `scripts/guidance_clusters.py`; `revise`
`prepare` steps 5, 6 and 10, through its printout; `sandbox/harvest_recall.py` `--clusters`.
`prepare` steps 5, 6 and 10, through its printout; `sandbox/harvest_recall.py` `--clusters`. The
printout the report was written from is kept, as printed, in `<log>/ratchet-YYYY-MM.clusters.txt`
beside the report, and `revise`'s `discuss.md` reads it to trace a proposal, which names its
cluster `C<n>`, to its pull requests and quotes.

Pinned by: tests/test_guidance_clusters.py::test_prints_each_cluster_with_its_people_prs_and_quotes

Expand Down
4 changes: 3 additions & 1 deletion docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ Libera's standard.

**The ticket comes before the code.** The most useful review comments were often design questions asked after the code was written, so `ticket-draft` asks them first. It asks them against a draft: placement and a rough size come back first, so a duplicate or a split is decided before any question, then the draft with a recommended answer on each Open Question, since walking eight rounds of questions before any ticket text asked the person to hold the ticket in their head. Every question it raises is answered, marked open or dropped by a person; an open one goes to the ticket's Open Questions with why it stays open and what it affects, and every later step offers to settle it. A ticket may keep a question open, since an answer invented to pass a readiness gate is worse than an honest open question; the ticket writer judges readiness when moving it to To Do. The agent never invents a component, an epic key or a link target. No question crosses into the build unanswered, but an answer can be provisional: researched and chosen so the work can go on, and flagged to revisit, with why it is not final and what would make it final, since implementation often answers what planning could not. A provisional decision is shown again at the plan and diff gates, listed in the pull request's description and given to the reviewer as a focus point, since it is where the human review needs to look. Making a decision provisional costs a reason, so the flag keeps its meaning. (`ticket-draft` step 6; `using-jira`, "Never"; `GUIDE.md`, "Why".)

**A skill researches and recommends before it asks; the person decides.** Asking for an answer, a verdict or a mark before anything has read the code asks the person to do that research alone, or to guess. So the planner recommends an answer to each question with its evidence and drafts the plan on it, marking the steps that assume it, so another answer is a visible edit rather than a second plan; `pr-fix`'s assessment recommends a disposition for each thread; and the revision report gives each proposal a `Recommended:` line with the evidence that decides it. A recommendation is never an answer: the plan gate asks with it marked, and the revision's checkboxes stay blank until the group marks them. (`.claude/CLAUDE.md`, "How a skill behaves".)
**A skill researches and recommends before it asks; the person decides.** Asking for an answer, a verdict or a mark before anything has read the code asks the person to do that research alone, or to guess. So the planner recommends an answer to each question with its evidence and drafts the plan on it, marking the steps that assume it, so another answer is a visible edit rather than a second plan; `pr-fix`'s assessment recommends a disposition for each thread; and the revision report gives each proposal a `Recommended:` line with the evidence that decides it. A recommendation is never an answer: the plan gate asks with it marked, and the revision's checkboxes stay blank until `apply` writes the marks the group decided, on the driver's yes. (`.claude/CLAUDE.md`, "How a skill behaves".)

**The group decides in its own words; `apply` settles the marks.** A mark in a fixed form had to be typed on the report's line, so a meeting that agreed in a review thread, or agreed to different wording, had its outcome copied by hand or lost. No script parses a mark: `apply` reads the report already, so it reads the discussion too, the `Mark:` lines, the draft pull request's threads and the meeting notes the driver pastes, kept apart from the asks pasted for `prepare` so an ask is never taken for a decision, and settles each proposal to one mark, which the driver confirms before it is written on the report's line. The fixed marks stay, as what a proposal settles to, because `apply`'s rules on overrides, owners and held candidates hang on them and the report stays the record of what was decided. A question about how a proposal came about is answered from the report, the clusters printout kept beside it and each pull request's capture, read from the revision's branch until it merges, never from memory, so whoever asks, whenever, gets the cases it rests on. Settling is conservative: only people's words decide, and sources that disagree, or an accept missing the reason or owner a mark needs, settle to unclear for the driver rather than to a guess. (`skills/revise/apply.md`; `skills/revise/discuss.md`.)

**The person steers; the sequence is a default.** A skill that runs a fixed sequence leaves the person a passenger, approving each step in turn. So at a natural decision point a skill says where things stand and asks what the person wants to do, the usual next step marked recommended: after the brief, `implement-change` asks whether to plan the change or build it now, since a small change at standard depth does not need a planner run of a quarter of an hour. The gates that stay are the ones before something hard to undo. The shape of a decision point is written once, in a file every asking skill cites, because `.claude/CLAUDE.md` loads only in this repository, and a review of the skills found about twenty widgets, half offering "Let's discuss", four marking a recommendation and several offering no way to stop. The same file says how a skill writes a file, since a heredoc carrying a ticket's markup stops the person at a permission prompt no skill planned. (`.claude/CLAUDE.md`, "How a skill behaves"; `skills/work/decision-points.md`.) What a skill says when a server it needs is missing or failing is written once too, in `skills/work/servers.md`: a review found about twenty skills each wording it their own way, most naming no fix and some stopping with only the error, so a person who had never set a server up could not tell what was lost or what to do. A person whose server is missing meets that message at whichever skill they run first, so it gives the same four things everywhere: which server, what is lost, whether the run goes on, and how to fix it.

Expand Down
Loading
Loading