ratchet report - xopherdeep/do-it-for-the-xp GitHub Wiki

Ratchet cleanup report (@sonnet-ratchet)

Status: DONE_WITH_CONCERNS. Every regression in the brief is gone; the whole-project gate still fails on two regressions that come from the parallel Task 11 builder's in-progress files (not touched, see Concerns).

Gate lines

Before (chemx audit at the worktree root, my first run):

gate: fail (ratchet)
  regression: AI_SLOP_REDUNDANT_PASSTHROUGH 0 -> 5
  regression: CONTROL_FLOW_DISPATCH_SWITCH 36 -> 38
  regression: CONTROL_FLOW_INLINE_BOOLEAN 8 -> 22
  regression: LINE_BUDGET_FILE 39 -> 40

After (last run, 19:30, with Task 11's files in the tree as they stood then):

gate: fail (ratchet)
  regression: COMPLEXITY_CYCLOMATIC_HIGH 27 -> 28
  regression: CONTROL_FLOW_INLINE_BOOLEAN 8 -> 9

Counts from the full JSON audit for the four brief rules: AI_SLOP_REDUNDANT_PASSTHROUGH 0, CONTROL_FLOW_DISPATCH_SWITCH 36, LINE_BUDGET_FILE 39 (all back at baseline), CONTROL_FLOW_INLINE_BOOLEAN 9 = the 8 old ones + src/lib/services/copy/credits.ts:106 (Task 11, new untracked file). None of the 14 INLINE_BOOLEAN sites of this task remain. The COMPLEXITY_CYCLOMATIC_HIGH regression is src/app/Admin/XpApprovals/XpApprovals.vue:336 (13 > 12), also Task 11's work in progress (the file is modified by the other builder; I never touched it).

The per-file lines came from chemx audit --json --full (the violations array: filePath, line, rule); chemx q --hazards in this chemx build ignores the flag and chemx audit <dir> only prints counts.

Items

  1. AI_SLOP_REDUNDANT_PASSTHROUGH (5): returned the expression directly.

    • src/lib/databases/ProjectDb.ts isRecord: return typeof id === "string" && typeof status === "string";
    • src/lib/engine/dungeons/generator/templeSolver.ts waitsOnFloor: expression-bodied arrow, no isItsStairs.
    • src/lib/services/projects/projectChores.ts rangeHolds: return size >= low && size <= high;
    • src/lib/services/projects/projectQuests.ts needsApproval: return hasChild && !hasGrownUp;
    • src/lib/services/projects/projectTower.ts phaseDrafts: the filter callback is an expression (chore.roomId === room.id && chore !== boss).
  2. CONTROL_FLOW_DISPATCH_SWITCH (2 new switches). The brief named the travel.ts switch as switch (lock) at ~L71, but the L71 switch is switch (kind) in doorActions and it predates the feature (the Task 5 review diff does not touch it). The switch the branch added is switch (lock) in canOpenClimb (~L153), so that is the one I replaced. The count came back to exactly 36, which confirms the L71 switch was part of the baseline and is left alone.

    • templeSolver.ts passable: PASSES: Record<LockKind, Passes> (none, small, master, bomb, floorCleared) and passable is PASSES[door.lock](door, opened, carried). A Record<LockKind, ...> makes TypeScript demand every kind, as the exhaustive switch did. Unused handler arguments are _-prefixed (eslint argsIgnorePattern: "^_").
    • travel.ts canOpenClimb: HOLDS_WHAT_LOCK_WANTS: Record<ClimbLock, (templeId) => boolean> (small key count, Boss Key, floorCleared always false) and canOpenClimb indexes it. temples() is still read inside each handler at call time.
  3. CONTROL_FLOW_INLINE_BOOLEAN (14): named each condition in a const before its if.

    • floorBonus.ts:45 hasNoWorkers
    • projectChores.ts isPoolEmpty (144), isTeamChore (186), hasNoHeroes (195)
    • projectSchedule.ts isLastPhase (30), isTooShort (60), hasNoPhases (68), isBeforeToday (92)
    • projectTower.ts hasStray (90), hasNoFinale (92), hasManyFinales (93), holdsNothing (110)
    • travel.ts isKeyLock (132, lockLine) and isFloorLock (143, lockToOpen). Both guard a never-reassigned const or parameter, so TypeScript 5.9 still narrows through the alias (the repo's climb already relies on this with isFloorShut). Not typechecked by me (not allowed): the lead's typecheck should confirm CLIMB_LOCK_LINES[lock] in lockLine still narrows.
  4. LINE_BUDGET_FILE: src/lib/engine/quests/QuestSchedule.ts 519 -> 500 lines. New sibling src/lib/engine/quests/projectQuestSchedule.ts (pure, no Vue, no storage) holds:

    • isProjectQuest (moved as is; QuestSchedule.ts imports it and re-exports it with export { isProjectQuest } from "./projectQuestSchedule";, so every importer is unchanged);
    • isProjectQuestAwake(quest) = Boolean(quest.project.wokenAt) (was inline in isQuestActiveOn);
    • oneOffDueDayOf(quest, starts, day) (was the private helper in QuestSchedule.ts; the caller now passes parseDate(quest.startsOn) because parseDate stays private to QuestSchedule.ts, which avoids a circular import). In QuestSchedule.ts: the parseLocalDate and ProjectQuestLink imports are gone, the deadlineDayOf doc's project sentence is folded into the "once" bullet (3 lines to 2), and the doc comment Task 1 added on isQuestActiveOn is dropped (the original had none; its sentence now lives on isProjectQuestAwake). That doc was the last line needed to reach 500. The file sits at exactly 500, so it has no headroom: the next line added to it trips the rule again. No behaviour change.

Specs (12 files, NODE_PATH=$PWD/node_modules/.pnpm/node_modules chemx test ...)

Before my edits: All tests passed (619 passed in 84673ms). After my edits: All tests passed (619 passed in 73904ms). Files: ProjectDb, FloorClearedClimb, TowerFloorLock, projectChores, projectQuests, projectTower, floorBonus, projectSchedule, QuestScheduleProjectQuests, plus QuestSchedule, TempleSolver and TempleSystemDoors (the brief's "specs that exist" for QuestSchedule, templeSolver and the door code; there is no spec named after roomInteractions/travel, FloorClearedClimb covers it). No typecheck or lint run (the brief reserves them for the lead).

Files changed

  • src/lib/databases/ProjectDb.ts
  • src/lib/engine/dungeons/generator/templeSolver.ts
  • src/lib/engine/quests/QuestSchedule.ts
  • src/lib/engine/quests/projectQuestSchedule.ts (new, untracked: the lead must add it)
  • src/lib/services/projects/floorBonus.ts
  • src/lib/services/projects/projectChores.ts
  • src/lib/services/projects/projectQuests.ts
  • src/lib/services/projects/projectSchedule.ts
  • src/lib/services/projects/projectTower.ts
  • src/lib/services/temples/roomInteractions/travel.ts

Concerns

  • The gate is not pass yet, only because of Task 11's files: src/lib/services/copy/credits.ts:106 (if (mine.length === 0) return []; in heroCredits: needs const hasNoWork = mine.length === 0;) and src/app/Admin/XpApprovals/XpApprovals.vue:336 (cyclomatic complexity 13, limit 12). Both belong to the parallel builder (@sonnet-pt11 holds the locks on its neighbours); I did not touch them. After they are fixed, chemx audit should print gate: pass.
  • chemx-ratchet.json shows as modified in git status (ruleset 6 -> 11, new SECURITY_WP_* entries, a languages list). Its mtime is 19:06:38, before my first audit run at about 19:16, so I did not write it; I ran chemx audit without --rebaseline. The lead should decide whether to keep or revert it before committing by path (do not commit it with these files).
  • Local chemx is the starter-kit working copy and CI uses the published pin (memory note): the rule set can differ, so the lead may want to confirm the final gate with the pinned version.
  • I edited with the Edit/Write tools, not chemx patch; I only ran git status and chemx d for reading. A hook flagged one out-of-band edit of src/lib/services/widgets/widgetDataExtractor.ts during my last call: that is not my file, it is a peer's write.
  • Locks: acquired and released on all ten files (the new file needed --new).
⚠️ **GitHub.com Fallback** ⚠️