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
15 changes: 13 additions & 2 deletions .github/workflows/pin-verb-scope.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# repo's own pin advance from coming back (opencharly/charly#1079).
#
# WHAT IT ASKS. `scripts/check-pin-verb-scope.py` reads this repo's own tracked
# tree and asks three things:
# tree and asks these things:
# SCOPE every claim-maker surface — the `sync` task's description and step
# name, the `pins` task's description and its MODE parameter, and the
# two AGENTS.md bullets — states that the advance touches EVERY pin
Expand All @@ -12,10 +12,19 @@
# declared pin, rolls the checkouts that exist and stages their
# gitlinks;
# COVERAGE every file that NAMES the verb is classified, so a new claim-maker
# surface cannot slip in unclassified.
# surface cannot slip in unclassified;
# ONE HOME the shared rule (`scripts/tracked-files.txt`) states its GRAMMAR and
# its exempt-mode LIST in its OWN header and nowhere else, and every
# reader that file NAMES still reads it. A copy of either into a
# reader is a second rule, and two rules drift (R2).
# The surfaces are located by STRUCTURAL anchors, so a surface that MOVES is a
# finding rather than a silent pass.
#
# WHY THE RULE FILE AND ITS READERS ARE IN THE TRIGGER: the ONE HOME arm reads
# `scripts/tracked-files.txt` and both of the readers that file names. A change to
# the rule file — a new exempt mode, a grammar that moved — and a change to a
# reader are exactly the changes that arm judges, so the gate has to run for them.
#
# WHY IT IS ITS OWN WORKFLOW, and not a step of pin-currency.yml: the currency
# control and this control answer different questions — one watches the PINS, the
# other watches the WORDS about the advance — and this one needs neither a Go
Expand Down Expand Up @@ -47,6 +56,8 @@ on:
- 'charly.yml'
- 'AGENTS.md'
- 'scripts/check-pin-verb-scope.py'
- 'scripts/tracked-files.txt'
- 'charly/retired_build_selector_test.go'
- '.github/workflows/pin-verb-scope.yml'
workflow_dispatch:

Expand Down
23 changes: 15 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,13 @@ own gate for the same rule says, in its own header, that it speaks for the umbre
prose only.

- **What it asks.** `scripts/check-pin-verb-scope.py` reads this repo's own tracked
tree over three arms: **SCOPE** (every claim-maker surface states that the advance
tree over these arms: **SCOPE** (every claim-maker surface states that the advance
touches EVERY pin this repo declares — the CLAIM, not the keyword, because "every"
alone also matches a question about currency), **NO RETIRED CLAIM** (no tracked file
calls the advance a non-mutating kind) and **COVERAGE** (every file that names the
verb is classified, so a new claim-maker surface cannot slip in unclassified). The
calls the advance a non-mutating kind), **COVERAGE** (every file that names the
verb is classified, so a new claim-maker surface cannot slip in unclassified) and
**ONE HOME** (the shared rule's GRAMMAR and its exempt-mode LIST live in the rule
file's OWN header, and every reader that file names still reads it). The
surfaces are located by structural anchors, so a surface that moves is a finding,
not a silent pass.
- **It is run two ways.** `charly task pin-verb-scope` runs the control and
Expand All @@ -162,15 +164,20 @@ prose only.
control (`charly/retired_build_selector_test.go`) read — so the exemptions have ONE
home and the two gates cannot drift on WHICH modes are exempt. Each reader parses
that file in its own language, so a copy of the LIST in a reader would be a second
list, and two lists drift (R2). That file's own header specifies its grammar; read
it there, never copy it here. Edit that file, never a reader's copy.
list, and two lists drift (R2). That file's own header specifies its grammar, and
the ONE HOME arm holds that: the grammar and the LIST live in that header and
nowhere else, and every reader the file names still reads it — read the grammar
there, never copy it here. Edit that file, never a reader's copy.
- **The control proves it can fail.** `python3 -I scripts/check-pin-verb-scope.py
--self-test` turns each of the arms RED on its own mutation — a surface that drops
the scope, a surface whose line is gone, a file that calls the advance a
non-mutating kind (including the exact wording this defect carried), a file that
names the verb without being classified, and a classification that has gone stale —
while the shipped tree stays GREEN in the same run. A gate that cannot fail is not
a gate.
names the verb without being classified, a classification that has gone stale, a
reader that restates the shared rule's grammar, a copy of that grammar inside the
rule file's own other paragraph, a rule file whose header stops stating the
grammar, a reader that copies the exempt-mode list, and a named reader whose code
stops naming the rule file — while the shipped tree stays GREEN in the same run. A
gate that cannot fail is not a gate.

## Core key rules

Expand Down
25 changes: 17 additions & 8 deletions charly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4197,21 +4197,26 @@ pin-currency-proof:
# UMBRELLA's prose only: "a submodule is a repo of its own, with its own
# rulebook and its own gates".
#
# THREE arms over this repo's own tracked tree:
# Arms over this repo's own tracked tree:
# SCOPE every claim-maker surface states that the advance touches
# EVERY pin this repo declares (the CLAIM, not the keyword:
# "every" alone also matches a question about currency);
# NO RETIRED no tracked file calls the advance a non-mutating kind;
# COVERAGE every file that NAMES the verb is classified, so a new
# claim-maker surface cannot slip in unclassified.
# claim-maker surface cannot slip in unclassified;
# ONE HOME the shared rule (scripts/tracked-files.txt) states its
# GRAMMAR and its exempt-mode LIST in its OWN header and
# nowhere else, and every reader that file NAMES still reads
# it — a copy of either into a reader is a second rule, and two
# rules drift (R2).
# The surfaces are located by STRUCTURAL anchors, so a surface that MOVES is a
# finding rather than a silent pass.
pin-verb-scope:
task:
description: Check this repo's own pin-advance claim — every claim-maker surface must state that the advance touches EVERY pin this repo declares, and no tracked file may call the advance a non-mutating kind
description: Check this repo's own pin-advance claim — every claim-maker surface must state that the advance touches EVERY pin this repo declares, no tracked file may call the advance a non-mutating kind, and the shared rule's grammar and exempt-mode list must live in the rule file's own header, with every reader it names still reading it
dir: .
plan:
- check: every pin-advance claim in this repo states its scope, and no tracked file calls the advance a non-mutating kind
- check: every pin-advance claim in this repo states its scope, no tracked file calls the advance a non-mutating kind, and the shared rule has one home
command: "python3 -I scripts/check-pin-verb-scope.py"
stdout:
- contains: PIN-VERB-SCOPE-OK
Expand All @@ -4223,9 +4228,13 @@ pin-verb-scope:
# turns each of the control's arms RED on its own mutation: a surface that
# drops the scope, a surface whose line is gone, a tracked file that calls the
# advance a non-mutating kind — including the EXACT wording this issue was
# filed about — a file that names the verb without being classified, and a
# classification that has gone stale. The shipped tree must be GREEN in the
# same run, so the arms are discriminating rather than merely loud.
# filed about — a file that names the verb without being classified, a
# classification that has gone stale, a reader that restates the shared rule's
# grammar, a copy of that grammar inside the rule file's own other paragraph, a
# rule file whose header stops stating the grammar, a reader that copies the
# exempt-mode list, and a named reader whose code stops naming the rule file.
# The shipped tree must be GREEN in the same run, so the arms are discriminating
# rather than merely loud.
pin-verb-scope-proof:
task:
description: Prove the pin-verb-scope control can fail — every arm must go red on its own mutation, including the retired wording this issue is about, while the shipped tree stays green
Expand Down Expand Up @@ -4366,7 +4375,7 @@ check-task:
task: pin-currency-proof
context:
- runtime
- check: the pin-verb-scope CONTROL itself runs green on the tree the bed just realized — every claim-maker surface in it states its scope, and no tracked file calls the advance a non-mutating kind
- check: the pin-verb-scope CONTROL itself runs green on the tree the bed just realized — every claim-maker surface in it states its scope, no tracked file calls the advance a non-mutating kind, and the shared rule's grammar and exempt-mode list live in the rule file's own header
id: task-pin-verb-scope-runs
task:
task: pin-verb-scope
Expand Down
Loading
Loading