@thebattlearena/corner 0.9.1-beta.70 → 0.10.1-beta.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -26
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/ring/agents/cornerman.md +32 -6
- package/ring/agents/rudo.md +2 -1
- package/ring/agents/wrestler.md +19 -4
- package/ring/hooks/hooks.json +42 -0
- package/ring/scripts/bout-stats-render.mjs +366 -0
- package/ring/scripts/bout-stats.mjs +360 -0
- package/ring/scripts/brief-build.mjs +130 -0
- package/ring/scripts/brief-guard.mjs +154 -0
- package/ring/scripts/brief.mjs +272 -0
- package/ring/scripts/compact-hook.mjs +110 -0
- package/ring/scripts/config.mjs +25 -1
- package/ring/scripts/contract-endpoints.mjs +163 -0
- package/ring/scripts/contract-preview.mjs +34 -14
- package/ring/scripts/fight.mjs +27 -0
- package/ring/scripts/findings.mjs +82 -3
- package/ring/scripts/format-gate.mjs +723 -0
- package/ring/scripts/format-worker.mjs +120 -0
- package/ring/scripts/front-routes.mjs +345 -0
- package/ring/scripts/judges-card.mjs +324 -3
- package/ring/scripts/lookout.mjs +22 -4
- package/ring/scripts/mask-guard.mjs +34 -1
- package/ring/scripts/page-embed.mjs +112 -0
- package/ring/scripts/play-by-play.mjs +155 -7
- package/ring/scripts/preparation-collect.mjs +177 -0
- package/ring/scripts/preparation.mjs +547 -0
- package/ring/scripts/round-bell.mjs +9 -2
- package/ring/scripts/rule-ids.mjs +124 -0
- package/ring/scripts/tech-plan-log.mjs +81 -0
- package/ring/scripts/tech-plan.mjs +191 -0
- package/ring/scripts/verdicts-log.mjs +75 -0
- package/ring/scripts/verdicts.mjs +205 -0
- package/ring/skills/play-by-play/SKILL.md +235 -33
- package/ring/skills/play-by-play/templates/blocks.css +196 -0
- package/ring/skills/play-by-play/templates/chronicle.html +358 -55
- package/ring/skills/play-by-play/templates/endpoints-view.js +1153 -0
- package/ring/skills/play-by-play/templates/interview-form.js +516 -0
- package/ring/skills/play-by-play/templates/now-panel.js +719 -0
- package/ring/skills/referee/SKILL.md +181 -56
- package/ring/skills/referee/references/api-diagram.md +56 -0
- package/ring/skills/referee/references/precedents.md +11 -0
- package/ring/skills/referee/references/rulebook.md +97 -6
- package/ring/skills/referee/templates/api-diagram.html +115 -0
- package/ring/skills/referee/templates/cornerman-batch.md +17 -11
- package/ring/skills/referee/templates/cornerman-concept.md +28 -30
- package/ring/skills/referee/templates/cornerman-range.md +16 -11
- package/ring/skills/referee/templates/escalation.md +7 -1
- package/ring/skills/referee/templates/round-bell-body.md +4 -0
- package/ring/skills/referee/templates/wrestler-brief.md +28 -41
- package/ring/skills/referee/templates/wrestler-cutoff.md +4 -0
- package/ring/skills/referee/templates/wrestler-resume.md +4 -0
- package/ring/skills/sparring/SKILL.md +13 -4
- package/ring/skills/sparring/templates/contrato.md +29 -0
- package/ring/skills/sparring/templates/rudo-brief.md +7 -0
- package/ring/skills/title-defense/SKILL.md +2 -2
- package/ring/skills/weigh-in/SKILL.md +6 -0
|
@@ -22,7 +22,7 @@ expression.
|
|
|
22
22
|
`if (existing) { …; return } create(...)`. Lookups that may legitimately find nothing return a
|
|
23
23
|
list or a null object, not a hidden null from a finder that should have failed.
|
|
24
24
|
|
|
25
|
-
**R4. Very few comments.** Only a non-obvious
|
|
25
|
+
**R4. Very few comments.** Only a non-obvious _why_, in one line. Remove comments that narrate
|
|
26
26
|
what or how, repeat the name, tell the history of the refactor, or describe another layer. Keep the
|
|
27
27
|
comment that guards a measured incident ("a 400 from the provider does not burn the key, measured
|
|
28
28
|
on <date>"): deleting it invites the bug back.
|
|
@@ -57,7 +57,8 @@ a large block becomes a helper or its own function.
|
|
|
57
57
|
identical methods (merge them unless the difference means something to the caller). Dependencies
|
|
58
58
|
point inward: the domain imports nothing from application or infrastructure; adapters implement
|
|
59
59
|
the ports the consumer owns, translate foreign errors and types at the border, and live by
|
|
60
|
-
technology.
|
|
60
|
+
technology. The same condition repeated across files is a finding even when every piece works on
|
|
61
|
+
its own: it lives in one place (a value object, a rule, a specification) and the rest call it.
|
|
61
62
|
|
|
62
63
|
**R12. Every value object is a class**, with a private constructor, named static factories and
|
|
63
64
|
methods with its behavior; never an interface plus a frozen object plus loose functions. A plain
|
|
@@ -71,6 +72,70 @@ existing value object when there is one. Constructors used for dependency inject
|
|
|
71
72
|
methods, a named option, a value object or polymorphism. The same for optional callbacks whose mere
|
|
72
73
|
presence changes the semantics: use a discriminated result.
|
|
73
74
|
|
|
75
|
+
**R15. Every new file earns its place with one business sentence**: in the language of the
|
|
76
|
+
domain, which fact of the customer it serves and what it will be used for next. A file without
|
|
77
|
+
that sentence does not enter.
|
|
78
|
+
|
|
79
|
+
**R16. The backend follows the business narrative, not the screen.** A field, filter or query that
|
|
80
|
+
exists only to paint a view, or only to validate before another action (a "preview"), is a
|
|
81
|
+
finding: the view composes what the business already exposes.
|
|
82
|
+
|
|
83
|
+
**R17. Every optional carries its reason.** Each new `?`, nullable or optional field in a DTO,
|
|
84
|
+
command, event or entity is justified in one sentence; otherwise it is required or has a default.
|
|
85
|
+
A union like `X | null` where null means "a different operation" becomes two commands.
|
|
86
|
+
|
|
87
|
+
**R18. An aggregate is born valid.** What gives it meaning exists from its factory; no aggregate
|
|
88
|
+
is created empty and completed later by setters or a second call.
|
|
89
|
+
|
|
90
|
+
**R19. Primitives do not cross boundaries.** Commands, events and ports carry value objects
|
|
91
|
+
(R12), not `string | null` or loose ids; the primitive is parsed once at the edge.
|
|
92
|
+
|
|
93
|
+
**R20. Before a new endpoint or command, list the existing ones that could do it** and why they do
|
|
94
|
+
not serve. A new route that duplicates an existing one under another verb (a PATCH where
|
|
95
|
+
`POST`/`DELETE` on the same resource already exists) is a finding.
|
|
96
|
+
|
|
97
|
+
**R21. Names come from the ubiquitous language and do not collide with another context.** Before
|
|
98
|
+
naming a module, aggregate or resource, search the repo: a name another bounded context already
|
|
99
|
+
owns (a `catalog` next to an existing `catalogs`) is renamed.
|
|
100
|
+
|
|
101
|
+
**R22. Design patterns where they fit, and only where they fit.** Conditionals repeated by type,
|
|
102
|
+
state or provider are replaced by the pattern that removes them (a chain of rules or a composed
|
|
103
|
+
specification, Strategy, polymorphism in the value object, Observer for effects between modules,
|
|
104
|
+
Factory Method for creation invariants, polymorphic errors instead of a map of codes; catalog:
|
|
105
|
+
https://refactoring.guru/design-patterns), citing the measured `file:line`. A pattern enters only
|
|
106
|
+
when it is simpler than the conditional it removes; a discarded pattern is written down with its
|
|
107
|
+
reason so it is not proposed again. Example: five chained `if`s assigning a number, with the
|
|
108
|
+
exclusivity rule repeated in three files, become one `AssignmentRule` per rule, reused by the
|
|
109
|
+
backfill. The same for code that names each channel, provider or flavor it serves (`if chat … if
|
|
110
|
+
voice … if whatsapp`): the core does not know which ones exist; each one is a strategy it delegates
|
|
111
|
+
to, and effects between them travel as events (publish and subscribe).
|
|
112
|
+
|
|
113
|
+
**R23. A ternary that fills a gap means the gap should not exist.** `x ? x : []`, `x ?? []` repeated
|
|
114
|
+
downstream or a `map` guarded against `undefined` say the value was born optional when it has a
|
|
115
|
+
default: the default lives where the value is born (an empty list, not an optional list), and the
|
|
116
|
+
code downstream stops asking. Every ternary that stays names its two business cases; one that
|
|
117
|
+
cannot is replaced by a named function or a strategy (R22).
|
|
118
|
+
|
|
119
|
+
**R24. Types come from their source.** A shape the SDK, the API spec or a validation schema already
|
|
120
|
+
defines is imported or derived from it (generated types, the schema's inferred type, the SDK's own
|
|
121
|
+
enums), never rewritten by hand, so it follows the source when the source changes. Closed sets of
|
|
122
|
+
strings (statuses, operations, channels) are those constants or value objects (R6), never loose
|
|
123
|
+
literals compared in an `if`.
|
|
124
|
+
|
|
125
|
+
**R25. What a provider returns crosses an anti-corruption layer.** A provider's response is
|
|
126
|
+
validated and transformed at the edge, by a schema, into our own model; neither the domain nor the
|
|
127
|
+
client ever receives the raw response. An optional field of the provider is optional only with the
|
|
128
|
+
evidence of when it does not arrive (the provider's docs, a captured response), never by
|
|
129
|
+
assumption.
|
|
130
|
+
|
|
131
|
+
**R26. Business metrics are not monitoring.** Product analytics records business events, each one
|
|
132
|
+
naming the business question it answers; errors go to the monitoring tool (error tracking,
|
|
133
|
+
alarms, F4). A failed operation is not a business event, and an error is never tracked as one.
|
|
134
|
+
|
|
135
|
+
**R27. A cross-cutting precondition is checked once, where it is born.** The selected workspace,
|
|
136
|
+
the session, the tenant: validated at one global point (a guard, a provider, a resolver), not in
|
|
137
|
+
every component, hook or handler that uses it (R8).
|
|
138
|
+
|
|
74
139
|
## T · Tests as a contract
|
|
75
140
|
|
|
76
141
|
**T1. In a refactor, no assertion of a test that exists in the base changes.** Moving or renaming a
|
|
@@ -142,6 +207,12 @@ purpose, short and clear, and are listed in the PR.
|
|
|
142
207
|
**F12. A quiet linter is not an approval.** No orphan entries in baselines or allowlists, and the
|
|
143
208
|
gates run clean against the stack base and against the default branch.
|
|
144
209
|
|
|
210
|
+
**F13. A provider's hard limits count against the base, not the diff.** On a new infrastructure
|
|
211
|
+
resource (metric filters, rules, indexes, queues, alarms), count how many the base already has
|
|
212
|
+
against the provider's quota before approving. _Example: AWS allows 100 metric filters per log
|
|
213
|
+
group; main already had 100 and the PR added 2, so the alarms would not have been created in
|
|
214
|
+
production._
|
|
215
|
+
|
|
145
216
|
## P · Review process
|
|
146
217
|
|
|
147
218
|
**P1. One PR per category.** Business logic and its tests apart from harness, mocks, tooling,
|
|
@@ -151,7 +222,7 @@ skills and docs. The deliverable PR carries only code and tests.
|
|
|
151
222
|
practice is stopped in time, with the approved pattern already applied.
|
|
152
223
|
|
|
153
224
|
**P3. If the human dislikes the class design, a structural pause.** First ask whether the
|
|
154
|
-
objection is to the
|
|
225
|
+
objection is to the _solution_ (the behavior) or to the _class design_; a validated solution is not
|
|
155
226
|
redesigned. On a design objection, finish what is mechanical, agree a target architecture with the
|
|
156
227
|
human and resume with a single sample concept.
|
|
157
228
|
|
|
@@ -160,7 +231,10 @@ per concept by a read-only reviewer on a fixed range of commits.
|
|
|
160
231
|
|
|
161
232
|
**P5. File-by-file design review in batches** of at most 20 files through 8 lenses: layer and
|
|
162
233
|
dependencies, coupling, duplication, SOLID, domain model, errors (fail open or closed),
|
|
163
|
-
expressiveness, production risk.
|
|
234
|
+
expressiveness, production risk. Each new file brings its business sentence (R15) and repeated
|
|
235
|
+
conditionals bring their pattern proposal or the reason none fits (R22). **It is mandatory before
|
|
236
|
+
the first commit when the PR creates a module or an aggregate**, not only when the change is
|
|
237
|
+
large or the human asks: a design review that arrives after the cleanup started arrives late.
|
|
164
238
|
|
|
165
239
|
**P6. One rebound package per review**: `file:line — rule — what is wrong — how it must be`,
|
|
166
240
|
blockers first (base assertion changed, event renamed, behavior changed). What is not applied is
|
|
@@ -175,8 +249,10 @@ decides it and records why, or, for the hard list or under `delegation: "human"`
|
|
|
175
249
|
human with two options, their cost and a recommendation. Meanwhile the author does not touch that
|
|
176
250
|
part and works on something else.
|
|
177
251
|
|
|
178
|
-
**P10.
|
|
179
|
-
|
|
252
|
+
**P10. Model and effort by role**: whoever writes runs on the cheaper model at high effort (the
|
|
253
|
+
wrestler and the rudo on Sonnet); whoever orchestrates, reviews or gives feedback runs on the
|
|
254
|
+
strongest model at high effort. The host can change either per role (`agents` in
|
|
255
|
+
`.claude/ring.json`). Set both explicitly on every launch; never let them be inherited.
|
|
180
256
|
|
|
181
257
|
**P11. When the host forbids them (`forbidAiTrailers`, the default), commits carry no AI
|
|
182
258
|
attribution trailers**; human co-authors are always fine. Stage by explicit paths.
|
|
@@ -189,6 +265,20 @@ battery runs once when everything converged.** The targeted reproduction (a dire
|
|
|
189
265
|
one e2e spec, minutes) must be green on the exact tip that ships before the finding's thread is
|
|
190
266
|
replied to as fixed or resolved; the full validation (hours) runs once, on the final tip.
|
|
191
267
|
|
|
268
|
+
**P14. The host's rules are not the referee's decisions.** When the host fixes a pattern (a
|
|
269
|
+
repository only through specifications, a layer that may not import another), a deviation is a
|
|
270
|
+
cornerman BLOCKER or goes to the hard list; under `delegation: "referee"` the referee may not
|
|
271
|
+
approve it as a design doubt.
|
|
272
|
+
|
|
273
|
+
**P15. A PR that changes how a flow works today explains it in plain words before the code**:
|
|
274
|
+
what happens today, what will happen, and who notices. It goes in the wrestler's brief ("Flow
|
|
275
|
+
change" line of `templates/wrestler-brief.md`) and in the round-bell body (`round-bell.mjs open …
|
|
276
|
+
--flow-change "<today …; after …; who notices …>"`, rendered under "What changes for whom").
|
|
277
|
+
|
|
278
|
+
**P16. Read the execution path before claiming "today it goes through X".** Where a value is
|
|
279
|
+
stored does not say which path uses it; a claim about current behavior cites the call chain that
|
|
280
|
+
runs, not the column or the config that exists.
|
|
281
|
+
|
|
192
282
|
## Who decides
|
|
193
283
|
|
|
194
284
|
The host's `delegation` (`.claude/ring.json`) sets who decides design doubts. With `"referee"`
|
|
@@ -208,6 +298,7 @@ bout moving; with `"human"` the referee escalates both lists, as before.
|
|
|
208
298
|
writes, data deletion).
|
|
209
299
|
- Anything `mask-guard` blocks.
|
|
210
300
|
- A direct contradiction between two instructions of the host repo: it is written down and waits.
|
|
301
|
+
- A deviation from a pattern the host's own rules fix (P14).
|
|
211
302
|
|
|
212
303
|
### The referee's under `delegation: "referee"`
|
|
213
304
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<!-- The endpoints of the contract for the judge (references/api-diagram.md). Copy to
|
|
3
|
+
<bout dir>/api-diagram.html and replace every <…>. Adapted from the architecture type of
|
|
4
|
+
diagram-design by Cathryn Lavery, MIT: references/diagram-design-LICENSE.md. No scripts: the
|
|
5
|
+
preview frames it without them. -->
|
|
6
|
+
<html lang="<judge's language, e.g. es>">
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="utf-8">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
10
|
+
<title><contract title></title>
|
|
11
|
+
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
12
|
+
<style>
|
|
13
|
+
:root { --paper:#f5f5f5; --ink:#2d3142; --muted:#4f5d75; --soft:#7a8399; --rule:rgba(45,49,66,0.12); --accent:#eb6c36; }
|
|
14
|
+
* { box-sizing:border-box; }
|
|
15
|
+
body { margin:0; background:var(--paper); color:var(--ink); font-family:'Geist',sans-serif; }
|
|
16
|
+
main { max-width:1080px; margin:0 auto; padding:32px 24px 40px; }
|
|
17
|
+
.eyebrow { font-family:'Geist Mono',monospace; font-size:12px; letter-spacing:0.14em; color:var(--muted); text-transform:uppercase; margin:0 0 8px; }
|
|
18
|
+
h1 { font-family:'Instrument Serif',serif; font-weight:400; font-size:1.75rem; margin:0 0 8px; }
|
|
19
|
+
.sub { color:var(--muted); font-size:14px; margin:0 0 24px; max-width:760px; line-height:1.5; }
|
|
20
|
+
svg { width:100%; height:auto; display:block; }
|
|
21
|
+
.card { background:#fff; border:1px solid var(--rule); border-radius:6px; padding:20px; margin-top:24px; overflow-x:auto; }
|
|
22
|
+
.card h3 { font-size:14px; margin:0 0 12px; }
|
|
23
|
+
table { border-collapse:collapse; width:100%; font-size:13px; }
|
|
24
|
+
th { text-align:left; font-family:'Geist Mono',monospace; font-size:11px; letter-spacing:0.08em; text-transform:uppercase; color:var(--soft); font-weight:500; padding:0 12px 8px 0; }
|
|
25
|
+
td { padding:8px 12px 8px 0; border-top:1px solid var(--rule); vertical-align:top; line-height:1.5; }
|
|
26
|
+
code { font-family:'Geist Mono',monospace; font-size:12px; }
|
|
27
|
+
.m { color:var(--accent); font-weight:600; }
|
|
28
|
+
ul { margin:0; padding-left:18px; font-size:13px; line-height:1.6; }
|
|
29
|
+
li { margin-bottom:6px; }
|
|
30
|
+
footer { margin-top:32px; padding-top:12px; border-top:1px solid var(--rule); font-family:'Geist Mono',monospace; font-size:12px; color:var(--soft); }
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
<body>
|
|
34
|
+
<main>
|
|
35
|
+
<p class="eyebrow">PR #<n> · <API contract></p>
|
|
36
|
+
<h1><contract title></h1>
|
|
37
|
+
<p class="sub"><one or two sentences: which endpoints change and for what, in plain words></p>
|
|
38
|
+
|
|
39
|
+
<!-- Size the viewBox to the boxes. Columns: callers (x 40), endpoints (x 300), tables (x 760).
|
|
40
|
+
Draw connectors first, then the boxes on top. -->
|
|
41
|
+
<svg viewBox="0 0 960 300" role="img" aria-labelledby="api-title api-desc">
|
|
42
|
+
<title id="api-title"><contract title></title>
|
|
43
|
+
<desc id="api-desc"><who calls what and which tables it touches, in one sentence></desc>
|
|
44
|
+
<defs>
|
|
45
|
+
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
|
46
|
+
<polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/>
|
|
47
|
+
</marker>
|
|
48
|
+
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
|
49
|
+
<polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/>
|
|
50
|
+
</marker>
|
|
51
|
+
</defs>
|
|
52
|
+
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
|
53
|
+
|
|
54
|
+
<!-- Caller → endpoint: a straight line when they share y, otherwise a rounded elbow
|
|
55
|
+
(M x1,y1 H mid-8 Q mid,y1 mid,y1+8 V y2-8 Q mid,y2 mid+8,y2 H x2). -->
|
|
56
|
+
<line x1="220" y1="96" x2="298" y2="96" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
|
57
|
+
<!-- Endpoint → table: solid = writes, dashed = reads; the label on a paper patch 6 px above. -->
|
|
58
|
+
<path d="M 660,96 H 702 Q 710,96 710,104 V 172 Q 710,180 718,180 H 758" fill="none" stroke="#eb6c36" stroke-width="1.2" marker-end="url(#arrow-accent)"/>
|
|
59
|
+
<rect x="672" y="78" width="40" height="12" rx="2" fill="#f5f5f5"/>
|
|
60
|
+
<text x="692" y="87" fill="#7a8399" font-size="8" font-family="'Geist Mono',monospace" text-anchor="middle" letter-spacing="0.06em">writes</text>
|
|
61
|
+
<line x1="660" y1="232" x2="758" y2="232" stroke="#4f5d75" stroke-width="1" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
|
62
|
+
<rect x="690" y="214" width="36" height="12" rx="2" fill="#f5f5f5"/>
|
|
63
|
+
<text x="708" y="223" fill="#7a8399" font-size="8" font-family="'Geist Mono',monospace" text-anchor="middle" letter-spacing="0.06em">reads</text>
|
|
64
|
+
|
|
65
|
+
<!-- Caller: grey, tag CALLER. -->
|
|
66
|
+
<rect x="40" y="64" width="180" height="64" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
|
67
|
+
<rect x="52" y="76" width="52" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
|
68
|
+
<text x="78" y="85" fill="#4f5d75" font-size="8" font-family="'Geist Mono',monospace" text-anchor="middle" letter-spacing="0.08em">CALLER</text>
|
|
69
|
+
<text x="52" y="112" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist',sans-serif"><screen or action></text>
|
|
70
|
+
|
|
71
|
+
<!-- New (or changed) endpoint: accent stroke and tint; method tag, path, then in / out / err. -->
|
|
72
|
+
<rect x="300" y="64" width="360" height="132" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
|
73
|
+
<rect x="312" y="76" width="40" height="12" rx="2" fill="none" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
|
74
|
+
<text x="332" y="85" fill="#eb6c36" font-size="8" font-family="'Geist Mono',monospace" text-anchor="middle" letter-spacing="0.08em">NEW</text>
|
|
75
|
+
<text x="312" y="108" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist Mono',monospace">POST</text>
|
|
76
|
+
<text x="352" y="108" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist Mono',monospace"><path></text>
|
|
77
|
+
<line x1="300" y1="118" x2="660" y2="118" stroke="rgba(235,108,54,0.30)" stroke-width="0.8"/>
|
|
78
|
+
<text x="312" y="138" fill="#2d3142" font-size="12" font-family="'Geist Mono',monospace">in · <param>: <type>, <body field>: <type></text>
|
|
79
|
+
<text x="312" y="158" fill="#2d3142" font-size="12" font-family="'Geist Mono',monospace">out · 201 { <field>: <type>, … }</text>
|
|
80
|
+
<text x="312" y="178" fill="#4f5d75" font-size="12" font-family="'Geist Mono',monospace">err · 404 <code> · 409 <code></text>
|
|
81
|
+
|
|
82
|
+
<!-- Existing endpoint the change reuses: grey, tag EXISTING, path only plus a note. -->
|
|
83
|
+
<rect x="300" y="212" width="360" height="56" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
|
84
|
+
<rect x="312" y="222" width="64" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
|
85
|
+
<text x="344" y="231" fill="#4f5d75" font-size="8" font-family="'Geist Mono',monospace" text-anchor="middle" letter-spacing="0.08em">EXISTING</text>
|
|
86
|
+
<text x="312" y="254" fill="#4f5d75" font-size="12" font-family="'Geist Mono',monospace">GET <path></text>
|
|
87
|
+
<text x="520" y="254" fill="#7a8399" font-size="12" font-family="'Instrument Serif',serif" font-style="italic">unchanged</text>
|
|
88
|
+
|
|
89
|
+
<!-- Tables: name only; accent when the model diagram shows them new or changed. -->
|
|
90
|
+
<rect x="760" y="164" width="160" height="32" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
|
91
|
+
<text x="772" y="185" fill="#2d3142" font-size="12" font-family="'Geist Mono',monospace"><new_table></text>
|
|
92
|
+
<rect x="760" y="216" width="160" height="32" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
|
93
|
+
<text x="772" y="237" fill="#2d3142" font-size="12" font-family="'Geist Mono',monospace"><existing_table></text>
|
|
94
|
+
</svg>
|
|
95
|
+
|
|
96
|
+
<div class="card">
|
|
97
|
+
<h3><The contract per endpoint></h3>
|
|
98
|
+
<table>
|
|
99
|
+
<thead><tr><th>Endpoint</th><th>Request</th><th>Response</th><th>Errors</th><th>Scoping</th></tr></thead>
|
|
100
|
+
<tbody>
|
|
101
|
+
<tr><td><code><span class="m">POST</span> <path></code></td><td><params and body></td><td><status and shape></td><td><status · code · when></td><td><tenant / workspace / user></td></tr>
|
|
102
|
+
</tbody>
|
|
103
|
+
</table>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="card">
|
|
106
|
+
<h3><What to validate></h3>
|
|
107
|
+
<ul>
|
|
108
|
+
<li><b><decision>:</b> <what it means and what to check></li>
|
|
109
|
+
<li><b><shortcut of the sparring>:</b> <keep, fix in this bout, or ticket></li>
|
|
110
|
+
</ul>
|
|
111
|
+
</div>
|
|
112
|
+
<footer><Sources: the spec paths on branch …, and the sparring's contrato-<repo>.md files></footer>
|
|
113
|
+
</main>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
you read: cite the lines of the moment. Rulebook `<absolute rulebook path>`.
|
|
1
|
+
Mode: **batch**. Read only. Worktree `{{worktree}}` at its live HEAD; the tree may change while
|
|
2
|
+
you read: cite the lines of the moment. The decisions taken are near the end of this brief and the
|
|
3
|
+
rules after them, at its end (the architecture checklist first). Ring scripts `{{ring}}/scripts`
|
|
4
|
+
(the format gate is `format-gate.mjs` there).
|
|
6
5
|
|
|
7
6
|
Files (≤20):
|
|
8
|
-
|
|
7
|
+
{{files}}
|
|
8
|
+
|
|
9
|
+
Review in two passes and report both together.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
1. **Sweep.** Read each file whole, then go through it lens by lens, every lens of this venue:
|
|
12
|
+
{{lenses}}. Report everything wrong you find, production risk and behavior as much as design.
|
|
13
|
+
There is no cap on findings, and a problem no rule fits is still a finding.
|
|
14
|
+
2. **Checklist.** Go over the architecture checklist at the end of this brief against each file
|
|
15
|
+
and add what the sweep missed.
|
|
12
16
|
|
|
13
|
-
Return per file the findings
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
Return per file the findings, one per line, as `<file:line> — <rule id> — <what is wrong> — <how
|
|
18
|
+
it must be>`. The rule id is one from the rules at the end of this brief, or `X0` when none covers
|
|
19
|
+
it: never drop a finding because no rule fits (the referee registers each line with
|
|
20
|
+
`findings.mjs add --source batch --file`, which refuses a line without a valid id). Then the
|
|
21
|
+
**open design questions**, numbered, each with two options, their cost and your recommendation.
|
|
@@ -1,44 +1,42 @@
|
|
|
1
|
-
<!-- Agent{subagent_type: "ring:cornerman", effort: "high"}. When a concept closes. -->
|
|
2
|
-
|
|
3
1
|
Mode: **concept**. You are the high-effort reviewer. Read only: no edits, no commits, no index or
|
|
4
2
|
tree writes in the wrestler's worktree.
|
|
5
3
|
|
|
6
|
-
Worktree
|
|
7
|
-
|
|
4
|
+
Worktree `{{worktree}}`, base `{{base}}`, range `{{range}}`. The decisions taken are near the end of
|
|
5
|
+
this brief and the rules after them, at its end. Ring scripts `{{ring}}/scripts`.
|
|
8
6
|
|
|
9
|
-
Commits
|
|
10
|
-
|
|
7
|
+
Commits of the concept:
|
|
8
|
+
{{commits}}
|
|
11
9
|
|
|
12
|
-
Author claims to verify against the base:
|
|
10
|
+
Author claims to verify against the base: {{claims}}
|
|
13
11
|
|
|
14
12
|
**Behavior: what matters most; any change is a BLOCKER.** Invariants, numbered:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
and the path of an export of that node made after its last change. Compare the screenshots of the venue's matrix against them:
|
|
31
|
-
<design file · node id · measurements · export path · screenshots>. A difference not listed by the
|
|
32
|
-
author is a finding; text is judged by the node's content, never by a layer name.
|
|
13
|
+
{{invariants}}
|
|
14
|
+
Base test assertions: none may change (`git show {{base}}:<path>` before calling it a blocker).
|
|
15
|
+
|
|
16
|
+
How to test: `git -C {{worktree}} archive <tip> | tar -x -C <new temp dir>`; install there if
|
|
17
|
+
needed; only the tests of the area, each through `node {{ring}}/scripts/one-at-a-time.mjs run --
|
|
18
|
+
<command>`; never a test run and a typecheck at the same time. For a pure-calculation refactor, a
|
|
19
|
+
differential check old vs new that fails if you remove the key piece.
|
|
20
|
+
|
|
21
|
+
**Design, the whole concept at once** (what a range-by-range review cannot see): read the concept
|
|
22
|
+
as one piece through the lenses of this venue, {{lenses}}. An anemic aggregate built across several
|
|
23
|
+
commits, a dependency that points outward once the pieces are together, a condition repeated
|
|
24
|
+
across the files of the concept: each is a finding with its rule id.
|
|
25
|
+
|
|
26
|
+
**Design of a screen (UI venues):** {{designReference}}. A difference from the reference not
|
|
27
|
+
listed by the author is a finding; text is judged by the node's content, never by a layer name.
|
|
33
28
|
|
|
34
29
|
**Leftovers (every concept close):**
|
|
30
|
+
|
|
35
31
|
- Symbols left without production callers: grep, on your copy, every exported or public symbol the
|
|
36
32
|
range touched and every symbol whose caller the range deleted; one used only by its own spec, or
|
|
37
33
|
by nobody, is dead code.
|
|
38
|
-
- Narrating, stale or now-wrong comments in the files the assignment covers:
|
|
39
|
-
ones this range did not edit.
|
|
40
|
-
- Commit messages of the range (`git -C
|
|
34
|
+
- Narrating, stale or now-wrong comments in the files the assignment covers: {{leftoverPaths}},
|
|
35
|
+
including the ones this range did not edit.
|
|
36
|
+
- Commit messages of the range (`git -C {{worktree}} log --format=%B {{range}}`) carrying bout ids
|
|
41
37
|
(D12, P7, HP3, PR5…).
|
|
42
38
|
|
|
43
|
-
Return: a table per file
|
|
44
|
-
totals, and a one-line verdict:
|
|
39
|
+
Return: a table per file (one finding per row, `| <file:line> | <rule id> | <what> | <how> |`), a
|
|
40
|
+
table per invariant (holds / broken + evidence), the leftovers, totals, and a one-line verdict:
|
|
41
|
+
`APPROVED` or `REBOUND: <n> blockers, <m> fixes`. Every finding cites one of the rules at the end of this brief, or
|
|
42
|
+
`X0` when none covers it.
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
<!-- Agent{subagent_type: "ring:cornerman", effort: "high"} -->
|
|
2
|
-
|
|
3
1
|
Mode: **range**. Read only: no edits, no commits, no index or tree writes in any worktree.
|
|
4
2
|
|
|
5
|
-
Worktree
|
|
6
|
-
`git -C
|
|
7
|
-
the decisions
|
|
3
|
+
Worktree `{{worktree}}`, base `{{base}}`, range `{{range}}`. Review each commit with
|
|
4
|
+
`git -C {{worktree}} show <sha>` against the rules at the end of this brief (the architecture
|
|
5
|
+
checklist first) and the decisions at its end. Only the lines these commits add or change. Ring
|
|
6
|
+
scripts `{{ring}}/scripts`.
|
|
7
|
+
|
|
8
|
+
Commits of the range:
|
|
9
|
+
{{commits}}
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
Author claims to verify against the base (if a single counter, event or payload changes, it is a
|
|
12
|
+
BLOCKER): {{claims}}
|
|
11
13
|
|
|
12
|
-
Return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Return one finding per line, exactly `<file:line> — <rule id> — <what is wrong> — <how it must be>`.
|
|
15
|
+
The rule id is the second field and must be one of the rules at the end of this brief (several as `R11/R22`); a
|
|
16
|
+
finding no rule covers carries `X0`, and the referee proposes the rule it lacks. A changed base
|
|
17
|
+
test assertion or a renamed telemetry event goes first, marked BLOCKER. "<sha>: no findings" when a
|
|
18
|
+
commit complies. No taste, no pre-existing debt. **At most 15 lines.** The referee registers each
|
|
19
|
+
line as a finding (`findings.mjs add --file`), which refuses a line without a valid rule id, so
|
|
20
|
+
never wrap one across lines.
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
host sets delegation to "human". Under the default "referee" delegation, design doubts are
|
|
3
3
|
decided and recorded, never sent here. Numbered text, answerable as "1. b", by default;
|
|
4
4
|
AskUserQuestion only when the host repo's instructions require it. The wrestler keeps working
|
|
5
|
-
on something else meanwhile: never leave it idle waiting for an answer.
|
|
5
|
+
on something else meanwhile: never leave it idle waiting for an answer.
|
|
6
|
+
Keep each question on one numbered line with its options «(a) … · (b) …» and «I recommend
|
|
7
|
+
(x)» (or «Te recomiendo (x)»): `judges-card.mjs log <pr> escalation <file>` reads them from
|
|
8
|
+
there for the chronicle's interview, and `log <pr> answer` stamps the judge's reply.
|
|
9
|
+
Write its context too, in a file of its own, one `## Contexto <n> · <question>` section per
|
|
10
|
+
question: what each option includes, leaves out and costs. Log it with `--context <file>`;
|
|
11
|
+
the chronicle shows it under «Ver más información». -->
|
|
6
12
|
|
|
7
13
|
**Done up to `<sha>`** (<concept>, round-bell #<n>).
|
|
8
14
|
|
|
@@ -1,58 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
Agent{subagent_type: "ring:wrestler", effort: "medium", run_in_background: true}.
|
|
3
|
-
Never `isolation: "worktree"`: that creates a new tree on another branch. -->
|
|
1
|
+
Assignment: {{assignment}}. PR #{{pr}}, branch `{{branch}}`, stack base `{{base}}`.
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
Flow change (P15): {{flowChange}}
|
|
6
4
|
|
|
7
|
-
Worktree:
|
|
8
|
-
Start with: `git -C
|
|
9
|
-
Ring scripts:
|
|
10
|
-
Bout dir:
|
|
5
|
+
Worktree: `{{worktree}}`. Your cwd resets: every git command is `git -C {{worktree}} …`.
|
|
6
|
+
Start with: `git -C {{worktree}} fetch -q origin && git -C {{worktree}} checkout -B {{branch}} origin/{{branch}}`.
|
|
7
|
+
Ring scripts: `{{ring}}/scripts` (one-at-a-time.mjs lives there).
|
|
8
|
+
Bout dir: `{{boutDir}}`. A helper script you need goes in `{{boutDir}}/tools/`, never in the repo.
|
|
11
9
|
Write only inside your worktree; never in the main checkout or any other tree.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Decisions already taken (do not reopen them):
|
|
11
|
+
Rules: the rulebook and the precedents of this venue ({{venue}}) are at the end of this brief, in
|
|
12
|
+
full. They are the ones in force: apply them while you write, not only when a rebound cites them,
|
|
13
|
+
and check the architecture checklist before every commit.
|
|
14
|
+
Decisions already taken (do not reopen them): the excerpt before the rules; the whole
|
|
15
|
+
ledger is `{{boutDir}}/decisions.md`.
|
|
17
16
|
|
|
18
|
-
Comments to address:
|
|
19
|
-
Reference pattern:
|
|
17
|
+
Comments to address: {{comments}}
|
|
18
|
+
Reference pattern: {{referencePattern}}
|
|
20
19
|
|
|
21
|
-
Order of concepts:
|
|
20
|
+
Order of concepts: {{concepts}}
|
|
21
|
+
One commit per theme, never one commit for a whole concept: a removal goes with the tests it
|
|
22
|
+
updates; a behavior change (what the flow-change line names, or an error that now surfaces
|
|
23
|
+
differently) goes in its own commit with the test that pins it (T6); renames and formatting go
|
|
24
|
+
apart from logic.
|
|
22
25
|
Commit locally and never push: when you close 2–3 commits (or ~200 lines), report the range and
|
|
23
26
|
keep going only if I have not stopped you. The PR branch receives what the cornerman approved, and I
|
|
24
|
-
push it; every commit you close is backed up for you to `
|
|
25
|
-
reached, report the range and wait for me.
|
|
27
|
+
push it; every commit you close is backed up for you to `{{backupBranch}}`, approved or not. If
|
|
28
|
+
mask-guard says the review cap is reached, report the range and wait for me.
|
|
26
29
|
|
|
27
|
-
Frozen zones (do not touch):
|
|
28
|
-
WAITING ON THE HUMAN (hard list; do not touch):
|
|
30
|
+
Frozen zones (do not touch): {{frozen}}.
|
|
31
|
+
WAITING ON THE HUMAN (hard list; do not touch): {{waitingOnHuman}}.
|
|
29
32
|
Design doubts go to me, never to the human: I decide them (or escalate them) and tell you.
|
|
30
33
|
|
|
31
34
|
Gates (from `.claude/ring.json`, each through one-at-a-time; a long run such as a battery adds
|
|
32
35
|
`--monitor <id>` when its command does not match a declared monitor, so it shows on the Scorecard):
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
+
|
|
37
|
+
- typecheck: `{{gateTypecheck}}`
|
|
38
|
+
- tests of what you touched: `{{gateTest}}`
|
|
39
|
+
- lint: `{{gateLint}}`
|
|
36
40
|
|
|
37
41
|
Standing conditions: behavior identical; no base test assertion changes (if one has to, stop and
|
|
38
42
|
tell me first); no new flags or env vars; one heavy command at a time; stage by paths;
|
|
39
|
-
forbidAiTrailers is
|
|
40
|
-
fine); disk floor
|
|
43
|
+
forbidAiTrailers is {{forbidAiTrailers}} (when true, no AI attribution trailers; human co-authors
|
|
44
|
+
are fine); disk floor {{diskFloor}} GB.
|
|
41
45
|
Do NOT run reviewers, review loops or Copilot. Do NOT open ready PRs. Do NOT merge or change bases.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Resume variant (a new session relaunches the wrestler)
|
|
46
|
-
|
|
47
|
-
Same brief, plus at the top:
|
|
48
|
-
|
|
49
|
-
You are resuming bout #<pr>; the previous wrestler stopped at `<sha>` while working on
|
|
50
|
-
"<last subject>". First `git -C <worktree> status` and `git -C <worktree> diff`: finish and commit
|
|
51
|
-
what was left uncommitted. Then read the open rebounds (`<bout dir>/rebounds.md`) and report the
|
|
52
|
-
commit you are on before continuing with <concept>.
|
|
53
|
-
|
|
54
|
-
## Cut-off variant (the same wrestler lost its connection)
|
|
55
|
-
|
|
56
|
-
The API cut you off mid-edit (you were on "<last subject>"). `git status` and `git diff`, finish
|
|
57
|
-
what was left uncommitted, commit it, read the last rebound (`<bout dir>/rebounds.md`) and report
|
|
58
|
-
the commit you are on.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
The API cut you off mid-edit (you were on "{{lastSubject}}", at `{{headSha}}`). `git -C {{worktree}} status`
|
|
2
|
+
and `git -C {{worktree}} diff`, finish what was left uncommitted, commit it, read the last rebound
|
|
3
|
+
(`{{boutDir}}/rebounds.md`) and report the commit you are on. The rules you work by are the ones
|
|
4
|
+
your first brief embedded; nothing about them changed.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
You are a new wrestler on bout #{{pr}}. The previous one stopped at `{{headSha}}` ("{{lastSubject}}").
|
|
2
|
+
First `git -C {{worktree}} status` and `git -C {{worktree}} diff`: finish and commit what was left
|
|
3
|
+
uncommitted. Then read the open rebounds (`{{boutDir}}/rebounds.md`) and report the commit you are
|
|
4
|
+
on before continuing with {{nextConcept}}.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sparring
|
|
3
|
-
description: Opens a sparring, a quick and deliberately low-quality draft (one PR per repo it touches, back and front included) that only proves whether a feature is worth building, before anyone pays for building it well. A rudo per repo (effort
|
|
3
|
+
description: Opens a sparring, a quick and deliberately low-quality draft (one PR per repo it touches, back and front included) that only proves whether a feature is worth building, before anyone pays for building it well. A rudo per repo (Sonnet at effort high by default) writes it inside a timebox in its own worktree; the draft PR (labels sparring + do-not-merge) is the event the host project's CI catches to deploy a preview; credentials travel by name only. The judge calls KO, rematch or discard, in two out of three falls: a KO passes the host gates (vestidor), faces the team's Tapes until a bell (unless «sin equipo»), keeps or loses the mask, and then hands each branch to a ring bout. Invoke with `/ring:sparring <idea | Linear ticket>`, `/ring:sparring preview <slug>`, `/ring:sparring verdict <slug>`, `/ring:sparring list`, "make a quick draft of this to try it", "spar this feature first".
|
|
4
4
|
argument-hint: '<idea | ticket> | preview <slug> | verdict <slug> | vestidor <slug> | list'
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -29,8 +29,16 @@ rest of the timebox goes to the controls that are still dead. Where time goes, a
|
|
|
29
29
|
correction. Everything that does not change the hypothesis, the proof, the scope or a hard stop,
|
|
30
30
|
you decide without asking, then and while the rudos work.
|
|
31
31
|
- **Contract first, in the first 15 minutes.** With several repos, the producer writes the contract
|
|
32
|
-
(routes, shapes, error codes) to `<sparring dir>/contrato
|
|
33
|
-
starts at once against it. The consumer never waits for the producer's code.
|
|
32
|
+
(routes, shapes, error codes) to its own `<sparring dir>/contrato-<repo>.md` before implementing,
|
|
33
|
+
and every rudo starts at once against it. The consumer never waits for the producer's code.
|
|
34
|
+
- **Every contract is written down the moment it is proposed**, with one repo too: each endpoint
|
|
35
|
+
and each data model a rudo adds or changes goes to `<sparring dir>/contrato-<repo>.md`
|
|
36
|
+
(`templates/contrato.md`) before it is implemented, with its shortcuts, and stays current when
|
|
37
|
+
the rudo changes it. **One file per repo, written only by that repo's rudo**: rudos run at the
|
|
38
|
+
same time, and two editing one file overwrite each other's entries. A rudo reads another repo's
|
|
39
|
+
file, never writes it. The sparring approves none of it: the referee bout that refactors a KO
|
|
40
|
+
opens with these bases and takes them to the judge first, because most of the code to build
|
|
41
|
+
depends on them.
|
|
34
42
|
- **Ceremony the rudo skips:** migrations in the repo (tables come from a SQL in `tools/`), OpenAPI
|
|
35
43
|
and generated types until the last push, typecheck after every edit (only before each push),
|
|
36
44
|
tests, wiki, DTOs, CQRS, ports, feature flags. Each one goes on the shortcuts list.
|
|
@@ -114,7 +122,8 @@ defense|bell|mask-kept|mask-lost|no-team` the rest).
|
|
|
114
122
|
for its repo (scope, designs, the other repos and what they exchange):
|
|
115
123
|
|
|
116
124
|
```
|
|
117
|
-
Agent{subagent_type: "ring:rudo",
|
|
125
|
+
Agent{subagent_type: "ring:rudo", model: "<config.agents.rudo.model>",
|
|
126
|
+
effort: "<config.agents.rudo.effort>", run_in_background: true,
|
|
118
127
|
description: "Rudo: <slug> <repo>", prompt: <the brief>}
|
|
119
128
|
```
|
|
120
129
|
|