Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bca43cbfd | |||
| 47fff7d289 | |||
| 2b621843a2 | |||
| 9ca3f48def |
@@ -108,3 +108,59 @@ to remove one, that is the escalation path, not the workaround.
|
|||||||
`.agents/scripts/visual-regression.mjs` runs. It used to throw for everyone,
|
`.agents/scripts/visual-regression.mjs` runs. It used to throw for everyone,
|
||||||
which is why no task in this plan ever produced the captures its brief asked
|
which is why no task in this plan ever produced the captures its brief asked
|
||||||
for.
|
for.
|
||||||
|
|
||||||
|
## Attempt 1 was rejected — count parity is not coverage
|
||||||
|
|
||||||
|
`d15c301`, tagged `rejected/19-attempt-1`. It did good work: `verify.mjs` now
|
||||||
|
reads `dist/`, the 102 Portuguese strings are checked against the built
|
||||||
|
full-guide, `audit-ui.mjs` gained per-page CSS-variable resolution and a
|
||||||
|
built-CSS baseline (`.agents/snapshots/built-css-values.json`). Keep all of
|
||||||
|
that.
|
||||||
|
|
||||||
|
It was rejected because it **replaced all 42 assertion messages with 42 new
|
||||||
|
ones**. Not one of the originals survives. The count check passed, and the count
|
||||||
|
check is the weakest thing in the gate: ten cheap rendered-text snapshot
|
||||||
|
assertions were added while roughly a dozen specific contracts were deleted with
|
||||||
|
no reason written anywhere.
|
||||||
|
|
||||||
|
Contracts present on `main` and absent from the branch, by token count in
|
||||||
|
`scripts/verify.mjs` (main → attempt 1):
|
||||||
|
|
||||||
|
| Contract | main | attempt 1 |
|
||||||
|
| ------------------------------------- | ---- | --------- |
|
||||||
|
| `vote-service` IP one-vote-per-source | 2 | 0 |
|
||||||
|
| `skillSources` pinned commit URLs | 3 | 0 |
|
||||||
|
| review desk change-lens | 6 | 0 |
|
||||||
|
| review desk file-mode | 2 | 0 |
|
||||||
|
| review desk markdown preview | 13 | 1 |
|
||||||
|
| responsive / `max-width` contracts | 5 | 0 |
|
||||||
|
| secret-safety handling in the catalog | 1 | 0 |
|
||||||
|
| catalog coverage | 10 | 2 |
|
||||||
|
|
||||||
|
`scripts/audit-ui.mjs` also went from 6 assertions to 5.
|
||||||
|
|
||||||
|
A rendered-text snapshot does not replace these. "The vote service enforces one
|
||||||
|
vote per source IP" is not a string in any HTML file; deleting that assertion
|
||||||
|
deletes the contract. Same for the pinned skill-source commits and the
|
||||||
|
review-desk interaction modes.
|
||||||
|
|
||||||
|
### What attempt 2 must produce
|
||||||
|
|
||||||
|
1. **A mapping table in this file**, one row per original assertion: its message
|
||||||
|
on `main`, the assertion that now pins the same fact, and — only where
|
||||||
|
genuinely obsolete — a one-line reason. Build it from
|
||||||
|
`git show rejected/19-attempt-1^:scripts/verify.mjs | grep -oP 'throw new Error\(\s*\K.*'`
|
||||||
|
so no row is missed. 42 rows, no gaps.
|
||||||
|
2. **Every fact still pinned.** Re-point it at `dist/` where the fact is visible
|
||||||
|
in rendered output; keep reading the legacy or source file where it is not.
|
||||||
|
`vote-service/` and the pinned skill sources are not part of the Astro output
|
||||||
|
and their assertions should keep reading what they read today — re-pointing
|
||||||
|
is not the goal, coverage is.
|
||||||
|
3. **Raise the baseline.** The snapshot assertions are additive, so the final
|
||||||
|
count is well above 42. Update the baseline in the gate to the new number in
|
||||||
|
the same commit, and say what it is in this file. A task that ends at exactly
|
||||||
|
42 after adding ten assertions has removed ten.
|
||||||
|
4. Keep `audit-ui.mjs` at 6 or more.
|
||||||
|
|
||||||
|
Start from `rejected/19-attempt-1` rather than from scratch — the `dist/`
|
||||||
|
re-point and the Portuguese coverage check are worth keeping.
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ const isDiff = mode === 'diff';
|
|||||||
.skill-diff {
|
.skill-diff {
|
||||||
border: 1px solid var(--ink);
|
border: 1px solid var(--ink);
|
||||||
color: var(--paper);
|
color: var(--paper);
|
||||||
animation: lens-enter 0.28s ease both;
|
/* purpose: change lens reveal (state change) */
|
||||||
|
animation: lens-enter 200ms cubic-bezier(0.2, 0, 0, 1) both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.change-lens {
|
.change-lens {
|
||||||
|
|||||||
@@ -139,4 +139,27 @@ const share = (count: number) => (total ? Math.round((count / total) * 100) : 0)
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vote-buttons button b {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
:global(.is-updating) {
|
||||||
|
/* purpose: vote widget tally update (feedback) */
|
||||||
|
animation: tally-pop 200ms cubic-bezier(0.2, 0, 0, 1) both;
|
||||||
|
}
|
||||||
|
@keyframes tally-pop {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
:global(.is-updating) {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -99,7 +99,11 @@ const { rootSelector, data } = Astro.props;
|
|||||||
|
|
||||||
function replace(target, markup) {
|
function replace(target, markup) {
|
||||||
const panel = root.querySelector(target);
|
const panel = root.querySelector(target);
|
||||||
if (panel) panel.innerHTML = markup;
|
if (!panel) return;
|
||||||
|
panel.innerHTML = markup;
|
||||||
|
panel.classList.remove('is-swapping');
|
||||||
|
void panel.offsetWidth;
|
||||||
|
panel.classList.add('is-swapping');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Names deliberately match legacy functions until task 19 updates its checks.
|
// Names deliberately match legacy functions until task 19 updates its checks.
|
||||||
@@ -291,4 +295,24 @@ const { rootSelector, data } = Astro.props;
|
|||||||
outline: 3px solid var(--gold);
|
outline: 3px solid var(--gold);
|
||||||
outline-offset: -3px;
|
outline-offset: -3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.is-swapping > *) {
|
||||||
|
/* purpose: tab panel change in the guide (state change) */
|
||||||
|
animation: guide-swap 200ms cubic-bezier(0.2, 0, 0, 1) both;
|
||||||
|
}
|
||||||
|
@keyframes guide-swap {
|
||||||
|
from {
|
||||||
|
opacity: 0.15;
|
||||||
|
transform: translateY(5px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
:global(.is-swapping > *) {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const { target = '.reading-progress span' } = Astro.props;
|
|||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
const height = document.documentElement.scrollHeight - window.innerHeight;
|
const height = document.documentElement.scrollHeight - window.innerHeight;
|
||||||
span.style.width = (height > 0 ? (window.scrollY / height) * 100 : 0) + '%';
|
span.style.transform = `scaleX(${height > 0 ? window.scrollY / height : 0})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// `{ passive: true }` is non-negotiable. The legacy app.js binds
|
// `{ passive: true }` is non-negotiable. The legacy app.js binds
|
||||||
|
|||||||
@@ -235,7 +235,8 @@ const packageFiles: PackageFile[] = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
.package-preview.is-swapping {
|
.package-preview.is-swapping {
|
||||||
animation: package-preview-in 0.34s ease both;
|
/* purpose: review-desk detail swap on selection (state change) */
|
||||||
|
animation: package-preview-in 200ms cubic-bezier(0.2, 0, 0, 1) both;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes package-preview-in {
|
@keyframes package-preview-in {
|
||||||
|
|||||||
Reference in New Issue
Block a user