At dawn, dusk and night the environment shows the moon in the top-left
corner of the scene, behind the plan: computed in the card from the home
coordinates and the browser clock (short Meeus series + topocentric
parallax, within 1.4° / 1.8 pp of JPL Horizons), one designer image under
a continuous phase mask with the lit side always on the left (owner
2026-09-29), a feathered terminator, 3°/3 % thresholds and the 2 s fade of
the window rays. Everything but a small gate lives in the lazy
moon-runtime chunk, with its own 30 s ticker. General settings: "Sun"
becomes "Sun and Moon" with one switch, on for new installations
(DEFAULT_CONFIG), off for existing ones.
The initial View graph sat 728 B under its budget: the gate is paid for by
moving fifteen dialog-only strings of General settings into the lazy
settings dictionary (#459) and by one build fingerprint literal instead of
three, so the graph ends 4 B above dev. Golden: two new moon scenes, and
the two General settings help frames show «Sun and Moon»; the WSL artifact
test fixture now models scenes whose first capture awaits acceptance.
Issue: #661
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Owner's decision in #694: icons must not change position with state.
Since #651 the rigid overlay layout sized a device by its value text and
badges, which change with HA state: a light toggling on changed its width
from 37.2 to 26.7 CSS px and re-laid out all 62 overlays of the dense
scene (~385 of 495 ms of stateUpdate; v1.77.0 had 208 ms).
- iso-scene-render.ts: the layout sees the state-free tile (icon at its
configured size, no value text, badge or supplemental metrics). An
HA-only change keeps the layout and refreshes only the visual extent
that scene bounds read, without a collision search.
- iso-overlays.ts: the rigid-group search skips candidates that already
lose to the fallback on room, then wall violations (lexicographic
bound). The result is unchanged — identical placement hash on the dense
scene — at about 35 % less work.
- docs/ISOMETRIC.md, changelogs; test #711; mutant
iso-device-layout-follows-state-again (written, not run — #709).
Local isometric-stage3-dense-v1, 3 samples: stateUpdate 522 → 89 ms
(v1.77.0: 208), modelReady 3665 → 3129, switchCycle 5544 → 4700.
Issue: #711
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The full workflow's 7-sample median of firstStableRenderMs for
large-house-interaction-v1 was about 2790 ms across the 1.77 line and
about 2920 ms at v1.78.0 (7d4d75bd: 2925.0; the neighbouring run of the
same SHA read 3144.8). The 3000 ms ceiling sat 2.7 % above the level and
failed on runner noise; #689's 3-sample smoke read 3002.4.
- hardMaxMs 3000 → 3400 in the full profile and its smoke twin (one
number, #473 AC4): +16 % over the 1.78 level, +8 % over the worst run.
The base-relative ratio and noise allowance are unchanged.
- README: the series and the reasoning; the test pins the number and the
series points.
Issue: #692
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
CODE-REVIEW-709-r1 M1: the "Локальный набор перед пушем" section still
showed `--no-mutants`/`--max-mutants` and listed diff mutants among what
the manual pre-push-gate runs, right after the paragraph saying it runs
none. The examples and the list now match the code; the flags are named
as accepted no-ops. The `--changed` tool description is marked as a
nightly-failure diagnostic, not a task gate.
Issue: #709
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Owner's decision 2026-09-29: mutants check the tests, not the product.
During development they are not run at all — not locally, not in CI,
not by the reviewer. The whole registry is the nightly run
(mutation-gate.yml, #513); a survivor files an issue (#472). The #693
post-mortem: 36 of 57 minutes of a one-line fix went to optional work.
- process-track.mjs: `mutants` is always false (no track, no label).
- classify-changes.mjs: Validate requests no diff mutants on any event;
the `mutants` input stays so old `-f mutants=…` calls do not fail.
- _process.yml: the default for the gate and the merge is false.
- pre-push-gate.mjs: the manual run no longer runs mutants.
- Canon: PROCESS §2.7 (a mutant is written, not run; `--check` keeps the
anchors), §5.1 (`ci:mutants` retired), §8 (ship/show: nothing beyond
gate:small and the spec — one proof per item, no `--smokes` on ship,
a stray flake is an issue, not an investigation), §10.4; AUTHOR,
REVIEWER, AGENTS, TESTING.
- Registry: four mutants of the old request rules replaced by
dev-mutants-requested-again and track-pays-for-mutants-again.
Issue: #709
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The Plan editor rule `.hp-stair.input-enabled .hp-stair-hit { cursor: move }`
also matched the View layer, which sets input-enabled only to receive
clicks. The hit area sits over the outline, so the link's pointer on the
group was never visible and every stair in View showed a drag it cannot do.
- src/stairs-view.ts: View stairs carry `hp-stair-view`.
- plan.styles.ts: `move` applies only without it; in View the hit area
keeps the group's cursor — pointer on a link, the stage's otherwise.
- demo/smoke_stairs.mjs: computed cursors in View (link, no target) and
in the Plan editor; the two View checks are red on the old code.
- test/stairs.test.mjs: the cascade without Chromium; mutant
view-stair-cursor-move-again.
- docs/STAIRS.md, changelogs.
Issue: #693
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The two remaining owner decisions of #690 and the legacy trivial text.
- scripts/smoke-select.mjs: VISUAL_MINIMUM, eight smokes of modes,
layers and rendering (under a minute locally). An executable diff
with no proven link now returns and prints it instead of only "the
reviewer decides"; #687 missed smoke_modes that way (item 1').
- scripts/gate-small.mjs: `--smokes` runs the minimum with the
selection.
- PROCESS §7.1 and AUTHOR.md: a raster, sharpness or compositing defect
needs a witness red on the old code for the owner's symptom and the
owner's confirmation in a real GPU browser (item 4).
- PROCESS §8, TESTING.md: the minimum in the smoke-select rule.
- scripts/task-packet.mjs: legacy `trivial` is product flow read as
track:show (§5.1), not a short track without a spec.
- Tests; mutants visual-minimum-silent-again,
visual-minimum-on-proven-link, gate-small-skips-visual-minimum;
task-packet-trivial-is-product-flow retargeted.
Issue: #690
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The label step after integration ran one gh call
`--add-label "$TO" --remove-label "$FROM"`. For the rereview outcome
TO == FROM == S7-code-review, and gh added and removed the same label:
#699 was left without a status and no new round started (run
36491087708).
- scripts/status-label.mjs: the same label is removed and set again
through relabel from process-reconcile (#555), so the labeled event
starts the next round and a failed restore fails the step; a
different label is still one call.
- _process.yml: the step calls the script.
- PROCESS.md: the exact-candidate rule names the relabel.
- test/status-label.test.mjs; mutants rereview-relabel-in-one-call and
process-label-step-combined-again.
Issue: #706
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
CODE-REVIEW-699-r1 M1: `node scripts/ratchets.mjs tighten` was named only
by the warning `release:prerelease` prints at publication, when the
candidate commit is already made. The candidate checklist in
docs/DEVELOPMENT.md now runs it after `npm run bundle:release`, so the
caps come from the fresh dist/ and land in the candidate commit.
- test/ratchets.test.mjs pins the step and its order.
- Mutant release-runbook-forgets-tighten.
Issue: #699
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Validate on 3dd032d7 (run 36480911145): the mutant
initial-view-ceiling-unplugged survived. With the band over the ceiling,
ceiling + band (303 000) lies above the absolute INITIAL_VIEW_GZIP_BUDGET
(301 066), so every value the CLI test could feed went red on the budget
first and the ceiling check became unobservable.
- bundle-budget.mjs CLI: the initial View ceiling is judged before
assertBundleBudget, so a growth over the band names the ratchet that
caught it; the budget still stops anything the band lets through.
- The CLI test feeds ceiling + band + 1 and expects the band message.
- The mutant's anchor follows the moved lines.
Issue: #699
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Two-sided ratchets with zero slack made parallel tasks conflict on shared
numbers, recompute them after every rebase and hit a ceiling because a
neighbour merged first (#689 after #691).
- Core lines (test/core-file-budget.test.mjs): a branch may grow up to
CORE_BAND = 50 lines over the beta ceiling; shrinking no longer fails it.
- Bundle graphs (bundle-budget.mjs): initial View and lazy graphs fail only
above ceiling + 2 000 B; below the ceiling is not a branch finding. The
absolute INITIAL_VIEW_GZIP_BUDGET stays the wall.
- Monolith numbers (monolith-metrics.mjs, unused-locals-gate.mjs):
METRIC_BANDS — 5 for delegates, port members and privates, 25 for host.
refs, 2 000 B for dist/; a lower number is reported, not failed.
- Browser mutation guards: 200 is a guideline — mutation-gate --check warns
above it instead of failing; every guard still needs its reason line.
- scripts/ratchets.mjs: `report [--warn]` and `tighten` — on the beta
candidate the release manager sets every ceiling to the fact in one
commit; release:prerelease prints loose ceilings as a warning.
Canon: PROCESS.md §3 (browser guards, monolith numbers) and §8 «Храповики»;
docs/TESTING.md.
Issue: #699
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
CODE-REVIEW-700-r1 Medium: `gh issue list … || true` turned a failed read
into an empty answer, and the step went on to gh issue create — a second
[workflow-sync] issue next to the open one on every network or rate-limit
failure. A failed read now warns and exits 0; creating stays reserved for
«read succeeded, nothing open».
Mutant workflow-sync-issue-duplicated-on-read-failure.
Issue: #700
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
11 of 85 returns in #600–#691 were the thin-workflow mirror check, and any
push could turn red because a foreign site behind a docs link was down.
- validate.yml preflight: on refs/heads/issue/* the workflow_sync mismatch
is a warning in the summary, not a failed verdict; push to dev, the beta
candidate and the release keep it red.
- On push to dev a mismatch opens one owner issue titled [workflow-sync]
(or comments on the open one), like the nightly mutation gate (#472);
preflight gets issues: write for that.
- check-docs --external=warn: external link failures become warnings; the
docs step passes it on task branches only.
Canon: PROCESS.md §10.4 («Workflow из ветки по умолчанию»).
Issue: #700
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Сверка PROCESS.md, ролевых выжимок, AGENTS.md, TESTING.md, CONTRIBUTING.md
и скриптов по 26 найденным расхождениям (D1–D26): трейлеры по классам
изменений, gate:small как единственный источник состава, пороги ревью,
путь реестра мутантов, golden по ci:golden, порядок чтения промпта ревью.
- scripts/change-classes.mjs: классы A/B/C/D — один модуль для
process-gate и проверки трейлеров.
- commit-msg: коммит только с файлами класса C (документация) трейлеров
не требует; указанные трейлеры по-прежнему проверяются.
- Маршрут автора без docs/STATUS.md: 5345 → 4703 слова.
- Промпт ревью читает SCOPE → AGENTS → REVIEWER, как ROUTES.reviewer.
Issue: #701
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
370 merged issue/* branches sat on origin; the branch list stopped meaning
anything and an agent looking a branch up by number could take a stale one.
- merge-candidate.mjs: after a successful push to dev the task branch is
deleted with --force-with-lease on the tip the merge saw last — the
candidate published into the branch, or the material on fast-forward
(the index commit lives only in dev). A commit that landed after the
merge keeps the branch, and the merge comment says so; a failed delete
never undoes the merge. Failed, stale and conflicting merges keep it.
- The one-time cleanup of the already merged branches is not in this
commit: the list goes to the owner first.
Canon: PROCESS.md §10.4 (exact-candidate merge).
Issue: #702
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
CODE-REVIEW-698-r1 Medium: the canon said the merged monolith numbers are
judged «by the band test (#699)», but #699 is not merged — today
compareWithBaseline judges five numbers exactly and only dist/ bytes with
a band. The paragraph now says so: dev's side of the baseline turns the
candidate's Validate red when the task itself changed those numbers — the
same return to the author as before, after Validate instead of before the
review; the band for all six numbers is #699. The comment on UPSTREAM_WINS
says the same.
Issue: #698
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
14 of 48 returns in #600–#691 were rebase or merge conflicts on shared
files where the two edits do not contradict each other.
- .gitattributes: docs/CHANGELOG.md and docs/CHANGELOG.ru.md use the
built-in merge=union driver — both tasks' lines in ## Unreleased survive
a rebase, a merge and git merge-tree (#696's clean-merge test) without a
stop.
- rebase-generated.mjs: UPSTREAM_WINS — on a conflict in
scripts/monolith-baseline.json the rebase takes dev's side; the band test
on the candidate's Validate judges the merged tree (#699). Any other
conflicting path aborts exactly as before, with the full list.
- merge-candidate.mjs: the candidate's patch-id excludes the changelogs and
the monolith baseline next to docs/reviews, so a neighbour's line next to
the task entry does not re-send a green task to review.
- screenshots.json needs nothing: after #697 task branches do not commit it.
Canon: PROCESS.md, the rebase paragraph of the review index (#643).
Issue: #698
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The screenshot fingerprint and golden baselines stop being a tax on every
task branch:
- Task branches no longer commit docs/images/** or golden baselines. On a
branch the screenshot freshness stays a preflight warning; the review
prompt, REVIEWER.md and AUTHOR.md drop check-docs as a per-task gate.
- beta-derived.yml refreshes them on dev in one bot commit before the beta
candidate: canonical docs capture + docs:accept --reviewed, golden from
the golden-images artifact of a completed Validate on dev +
golden:accept --reviewed. A changed frame or scene is accepted only when
named in the inputs; undeclared differences refuse. Baseline commits carry
Release: and Baseline-Reviewed:; the subject is not a candidate subject.
- classify-changes: the Release: trailer on an issue/* branch no longer
switches on the heavy set. ci:full / ci:golden do: process-track emits
full=true, the review gate dispatches Validate with full=true and does not
accept a light proof.
Canon: PROCESS.md §3 п.13, §5.1, §8, §11.4; CONTRIBUTING.md.
Issue: #697
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
show/ship stop paying for diff mutants and for every move of dev:
- scripts/process-track.mjs resolves the track from the current labels and
the diff (show for unlabelled infra, ask for unlabelled product work) and
checks the mechanical ship limits; outside them the pipeline comments and
relabels track:ship -> track:show in the same round.
- Validate on the review material is light on show/ship: a completed push
run on the exact SHA is proof, a dispatch asks mutants=false. ask and the
ci:mutants label keep the mutant dispatch.
- show/ship skip the pre-review rebase when git merge-tree with dev is
clean; the candidate is rebased once at merge and still passes Validate
before the push to dev. The light merge waits for the push run of the
candidate and dispatches only when none appears.
- ship inside the limits merges after the light Validate without a model
review; the issue gets a machine marker hp:ship-merge.
- ship-review.yml + scripts/ship-review.mjs read the code of all ship
tasks of a beta range in one model session and publish
docs/reviews/SHIP-REVIEW-<tag>.md; both beta publication paths refuse a
range with ship tasks the document does not cover or that carries a High.
- show reviews judge correctness and AC; the spec review installs neither
npm ci nor Chromium, the show review installs Chromium only when the issue
names a smoke.
Canon: PROCESS.md §5, §5.1, §10.4, new §11.7; REVIEWER.md, AUTHOR.md and
AGENTS.md digests.
Issue: #696
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd