Repository navigation
docs: write docs/loopwright/principles.md (#11) - #14
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…le (#11) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rding (#11) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ption (#11) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Quality gate passedcommit
|
| Check | Baseline | Now | Verdict | |
|---|---|---|---|---|
| TypeScript errors | — | n/a | collector not configured — see docs/loopwright/quality-gate.md | |
| High advisories | 0 | 2 | regressed 2 (tolerance 0) |
High advisories
brace-expansion— high: brace-expansion: Quadratic-time expansion of the{a},b}rewrite causes CPU denial of service · fix available — upgrade itjs-yaml— high: js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources · fix available — upgrade it
📊 All metrics
| Check | Baseline | Now | Verdict | |
|---|---|---|---|---|
| ✅ | Failing tests | 0 | 0 | holding |
| ✅ | Failing test suites | 0 | 0 | holding |
| TypeScript errors | — | n/a | collector not configured — see docs/loopwright/quality-gate.md | |
| ✅ | Lint errors | 0 | 0 | holding |
| ✅ | Lint warnings | 0 | 0 | holding |
| ✅ | Critical advisories | 0 | 0 | holding |
| High advisories | 0 | 2 | regressed 2 (tolerance 0) | |
| ✅ | Suppressed advisories | 0 | 0 | holding |
| 📈 | Line coverage | 84.67% | 85.01% | improved 0.34% |
| 📈 | Branch coverage | 78.93% | 79.44% | improved 0.51% |
| 📈 | Function coverage | 89.65% | 89.71% | improved 0.06% |
| 📈 | Statement coverage | 85.01% | 85.41% | improved 0.40% |
| 📈 | Duplicated code | 0.90% | 0.88% | improved 0.02% |
| ✅ | Highest function complexity | 14 | 14 | holding |
| 📈 | Average function complexity | 1.81 | 1.80 | improved 0.01 |
| ✅ | Oversized files | 0 | 0 | holding |
| ✅ | Skipped tests | 0 | 0 | holding |
| ✅ | Focused tests (.only) | 0 | 0 | holding |
| ✅ | Tests with no assertion | 0 | 0 | holding |
| ✅ | Coverage-ignore hints | 1 | 1 | holding |
| ✅ | Type suppressions (@ts-ignore etc.) | 2 | 2 | holding |
| ✅ | Inline lint suppressions | 2 | 2 | holding |
| ✅ | Empty catch blocks | 0 | 0 | holding |
📈 This PR improves 6 metric(s). Run
node .loopwright/scripts/quality-gate.mjs --update-baselineand commit.loopwright/baseline.jsonto lock the gain in.
Generated by .loopwright/scripts/quality-gate.mjs · reproduce locally with node .loopwright/scripts/run-report.mjs --all && node .loopwright/scripts/quality-gate.mjs · full reports are in the workflow artifacts.
Brings in the platform-dependent test fix from #15 so this PR's gate can run against a green base. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SamuelDenani
marked this pull request as ready for review
October 7, 2026 21:25
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
This was referenced Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Adds
docs/loopwright/principles.md— the descriptive statement of loopwright'score opinions and its detail territory, with the classification rule and the
amendment mechanism.
Loopwright's identity is currently written through its stack. The reason it
exists is not the stack, and three open RFCs already cite this boundary
textually: #7 ("a detail behind a contract, per the principles RFC", and
peer-to-peer "conflicts with the mediated principle"), #8 ("the section
boundaries mirror the principles RFC"), and #6, which carries the defaults rule
nearly verbatim. They do not need the document to enforce anything — they need
it to exist and to name things, so they can cite it.
The document is descriptive: no skill consults it, no gate checks it, no RFC
is required to carry a classification line.
Part of #11. Spec:
docs/specs/issue-11.md.Plan recap
cbf6eb8,2280f70rejects:and an enforcement pointer8348fc507547ec835971a,d601107,f38fa53Amendments5870e63b7b01be,7a4274d,2ece4838c45702Gate: green, exit 0 — "passed, 2 warning(s), 6 improvement(s)". Coverage
improved on all four metrics; duplication and average complexity fell. Both
warnings are pre-existing and not from this diff (see Known gaps).
No test, by design: markdown is outside every collector's scope
(
.loopwright/config.jsonscopessources.rootsto.mjsunder.loopwright/scriptsand.loopwright/tests), so each step substituted acheck first command that fails before the change and passes after.
Rulings I made
Each with what it costs if it is wrong.
On content
asserts changesets serves a Go host because the engine is already Node. That
is false —
@changesets/cliassumes apackage.json. The seam and thedefault travel; the justification does not. Cost if wrong: the doc is silent
on an RFC claim until RFC: Versioned releases with changesets, and automatic changesets in the loop #9 is grilled.
collectorRegressionsreturns
STATUS.BLOCK; RFC: One config file, YAML, sectioned by feature #8's open question 3 understates the engine. Cost ifwrong: RFC: One config file, YAML, sectioned by feature #8 corrects its own description when grilled.
path, and P2's two clauses have two enforcers — the gate for configured
checks,
babysit-prfor review findings. Cost if wrong: anyone ticking AC 2literally stops here; one sentence of explanation.
Cost if wrong: a territory is missing, and the
Amendmentssection the docdefines is the fix.
creates a tag with no opt-in. Changesets' usual shape is a release PR a human
merges, which satisfies P8 through the merge. Cost if wrong: RFC: Versioned releases with changesets, and automatic changesets in the loop #9 needs an
explicit opt-in for the tag.
decision, not a claim about what RFC: Stack connectors, decouple the quality gate from JS/TS #6 settled; RFC: Stack connectors, decouple the quality gate from JS/TS #6's open question 4 stays open.
Cost if wrong: a reader thinks RFC: Stack connectors, decouple the quality gate from JS/TS #6 agreed.
lands. The one-way rule forbids contradicting an RFC, not anticipating an
unlanded one — RFC: Isolated agent runtime with a mediated, async channel #7 proposing Docker does not make Docker a present default.
Cost if wrong: the doc trails RFC: Isolated agent runtime with a mediated, async channel #7 by one amendment.
defining what a default is. Three cells named decided-but-unbuilt defaults
(
misehas no toolchain layer at all,changesetshas no.changeset/,container does not exist), so the heading promised present-tense fact the
values could not deliver. Cost if wrong: a reader loses the
implementation-state signal — which would have gone stale on every landing.
Where I was wrong and corrected myself
Four of my own fix instructions were defective, each the same way: I took a
correct review finding and prescribed a more specific fix than I had grounds
for, without reading the code.
review's only blocker. I assumed "no seam" meant "no swap route". T4 has no
seam because its swap needs none — it is the only territory whose swap
route exists today (
config.jsonlimits.complexityplusquality-gate.md## Tuning). It also broke RFC: One config file, YAML, sectioned by feature #8's cited claim, whose configsketch puts
limitsundergate:— that section is T4. Reverted to theoriginal phrase with T6 as the sole exception.
that contradicted its own lead-in and RFC RFC: Core principles, opinionated about process, agnostic about stack #5's verbatim "an empty pointer is
itself a finding". The last sentence achieves the whole purpose alone.
detect-stack.mjsmain()doeswriteFileSync(CONFIG_PATH, ...), RFC: One config file, YAML, sectioned by feature #8 says"the installer and the future TUI write it", RFC (draft): Interactive installer for first-time setup #10 says "The TUI only writes
config.yml". Both files are engine-written. Reverted to P3's own axis:hand-editable vs never hand-edited.
softening became a known-divergence note, which Out of scope bars. Restored
to the RFC's declarative form.
rejects:line was weakened by replacing "unconfigured" with "out". Reviewtraced the mechanism: integrity metrics have no collector adapter — they come
from
collectStaticAnalysis, always called — so nointegrity.*metric canever report
unconfigured. The spec's seed word was factually wrong.On process
one extra fix round, since that step edits the file anyway. Cost if wrong:
five minors arrive as "look for something".
found two factual errors in the table, which is the loop's other trigger.
Cost if wrong: none — the step review saw the whole step diff.
verified point by point) and the second fix rounds of steps 4 and 6 (a column
rename and five textual corrections, each verified individually). All of that
text was reread by the final branch review. Cost if wrong: a defect reaches
the PR that a dedicated reviewer would have caught.
Known gaps, consciously shipped
requires host-scheduled re-invocation (
/loop, declared inbabysit-pr/SKILL.md:3, absent from this repo) and a native task list(
TaskCreate, mandated inexecute-issueandgrill-rfc). The failure modeis silent: a host implementing only the four reaches the draft PR, then cannot
start the babysit, the PR never leaves draft,
claude-code-review.ymlneverfires because of
if: !draft, and the loop stalls with no error. Not fixedhere: adding a capability is a core change by the doc's own rule, and AC 3
requires exactly four. The vehicle is an amendment to RFC: Core principles, opinionated about process, agnostic about stack #5 through the
Amendmentssection this PR adds. The session that produced this PR is liveevidence —
TaskCreatewas unavailable in it..claude/agents/reviewer.md:4grantsBash, which is write-capable, soP10's own enforcer can commit over the diff it reviews. The three sibling
reviewers carry
Read, Grep, Globonly. Out of scope for a docs-only task;worth its own issue. The spec's justification row was corrected in
8c45702so the record does not claim otherwise.
audit.highregressed 0 → 2 —brace-expansionandjs-yaml, bothwith a fix available upstream. Advisory-database movement, not this diff,
which touches no package file. High warns by design. Worth a chore PR; do not
add an
audit.ignoreentry, since fixes exist.collect-metrics.mjs, but nothing there rejects aninvented key.
quality-gate.mjswritesmetrics: currentwholesale intothe baseline and evaluation iterates the config, so a connector-invented key
would be persisted and never scored. The honest pointer today is empty. Left
as is because no third-party connector exists yet.
rejects:line is the literal negation of its assertion and refusesno change anybody would propose. Nine of the twelve do real work; this is the
one a reader can skip with no loss.
"Replace changesets with knope" alters neither what counts as done, nor how
work flows, nor how a fact is measured, nor where a step runs — the rule
returns no verdict and the reader falls back to the territory table.
a "Default today" column (ruling 8 renamed it) and an
enforced by:count of12 (it is 13, the 13th being prose). Noted so nobody reads a pass as a fail.
asserts the swap rule without T6's exception (ruling 9). Both need a close-out
pass on RFC: Core principles, opinionated about process, agnostic about stack #5 itself.
For #12
P1 admits no exception, but
docs/loopwright/loop-harness.md:70-74documentsone — "except the grill phase itself, whose task spine and drafts are
session-scoped, so a crashed grill restarts". #12 replaces that rule with a
reference to P1, so it must decide where the exception lives: mechanics that
stay, or a P1 violation.
🤖 Generated with Claude Code