Skip to content

Release 2.5.1: post-launch audit fixes - #7

Merged
guangmian-circle merged 15 commits into
masterfrom
publish/yaas-v2-20260817-143710
Aug 18, 2026
Merged

guangmian-circle merged 15 commits into
masterfrom
publish/yaas-v2-20260817-143710

Conversation

@guangmian-circle

@guangmian-circle guangmian-circle commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Imports the YAAS v2 snapshot at 2.5.1 from the upstream mirror.

The project now carries a version: VERSION holds it as plain text, CHANGELOG.md records what
landed, and the README states it near the top. This branch spans the 2.5 release and the 2.5.1 patch
release on top of it.

What is in here

2.5 — the first versioned release: the dashboard v2 manual-review surface, a quick start, the
security hardening, a README rewrite, and watermarks stored at Slack's 6-decimal precision.

2.5.1 — nine defects found by auditing that snapshot, plus one reported from live use. The ones
worth a reviewer's attention:

  • Watermark claims are truncated, never rounded. checkers/result.py formatted advance_to with
    :.6f, which is round-half-even, so a claim could land ahead of the point actually proven covered
    and a message sitting exactly on the rounded microsecond was then read as already-seen forever.
    slack_dm and slack_mention were pre-rounding at the call site too, which made the emit-side fix
    a no-op for the two checkers that reach it.
  • classify() no longer erases a numeric 0 watermark claim through falsiness. An erased claim
    is not a hold: the commit layer falls back to now - lag and jumps the watermark to NOW.
  • The dashboard stopped rebuilding DOM it had not changed. Every 2s poll rewrote whole subtrees
    even when the payload was identical, which made the prompt box flicker and reset a long draft's
    scroll in the review interface.
  • Briefings came off the poll path (~114ms and 75KB of JSON per poll on a 150-file archive) and
    gained one canonical timestamp plus a checked filename contract.
  • The markdown renderer's link placeholder can no longer be forged from prose, and a $& in a
    URL or label is inserted literally rather than expanded as a substitution pattern.

One behaviour change to read before merging

A fractional value for a whole-number knob is now refused at startup instead of being floored to
0, which silently disabled the cap the operator meant to tighten. Knobs whose reader honours a
fraction (YAAS_STALE_REPLY_HOURS, YAAS_MAX_SPEND_*) still accept one. An integer configuration is
unaffected.

Tests

48 suites and 29 differential goldens pass; the mutation suite catches 12 of 12. New:
yaas-triage/tests/unit/dashboard-render.test.sh exercises the dashboard's renderer, date helpers
and write guards by behaviour, running the shipped implementations rather than asserting the file
contains certain strings. It skips where node is absent (an optional dependency) and names what it
did not cover. Every fix in 2.5.1 has an assertion verified to fail when the fix is reverted.

Published from mirror SHA 1d4d861 (tagged v2.5.1). All commits on this branch are
signature-verified by GitHub.

🤖 Generated with Claude Code

@guangmian-circle guangmian-circle changed the title v2.5 post-launch PR: minor fixes Release 2.5.1: post-launch audit fixes Aug 17, 2026
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails

Scanned Files

@nexx88

nexx88 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

@guangmian-circlePonytail (complexity) review. Separate from the security pass (which found nothing to block). This PR is overwhelmingly bug fixes + tests + docs, and most prod changes are tight — the htmlOnce/textOnce idempotent setters and the build_briefs() extraction are net simplifications, not flagged. Two optional trims to consider before merge; please take a look and address or wave off:

1. dashboard.htmlmeasureModeNavigation / ResizeObserver overflow machinery (yagni, ~-10 lines). ResizeObserver + requestAnimationFrame + document.fonts.ready + scrollWidth measurement to decide whether to collapse a 3-item mode nav (Control / Briefings / Audit) into a menu. For 3 fixed labels, overflow is a CSS media-query call; the JS measurement is speculative until the item count becomes dynamic. Suggest dropping it (keep the menu markup, drive compact-modes from a media query).

2. dashboard.html — duplicated menu toggle pair (shrink, ~-4 lines). closeModeMenu/toggleModeMenu and closeBriefPicker/toggleBriefPicker are two identical (menu, trigger) hidden+aria-expanded pairs. Collapse to one setMenu(menu, trigger, open) helper.

3. (soft note, not counting) truncate-to-6-decimals duplicated 3× in result.py:emit, add-watch.py:main, and tick.py:slack_ts (math.floor(v*1e6)/1e6:.6f). A shared truncate6() would dedupe, but the three copies differ (omit-key vs str(value) passthrough vs keep-_raw) and this repo deliberately duplicates small helpers across standalone CLI scripts to avoid depth-sensitive imports — so it's defensible as-is. Your call.

net: ~-14 lines possible. Both #1 and #2 are polish, not blockers.

(Also, minor robustness aside from the security pass: a briefing filename with digits that pass the _BRIEF_NAME regex but aren't a valid calendar date — e.g. month 99 — makes datetime(...) in build_briefs raise → 500 on /api/briefs. A try/except ValueError: continue tidies it.)

- Fix malformed brief handling and unify menu state
- Allow free-form briefing filenames
- Make the approval review buttons prompt-driven
- Add slack-profile surface to client.py
- Collapse the mode nav on width, and scope the Initialising group

Source-SHA: ea48bf5f12fdf14a688383bf2ddcefab909c58b9
@guangmian-circle
guangmian-circle force-pushed the publish/yaas-v2-20260817-143710 branch from 8bcfab8 to b3469f4 Compare August 18, 2026 13:51
@guangmian-circle

Copy link
Copy Markdown
Collaborator Author

Thanks for the pass. Both trims are in, plus the aside. It all arrived as one squashed snapshot commit (b3469f4), so the individual pieces are not separate commits here. Its message lists the five source commits it covers, which is the only place they are described now that they are squashed. Breaking it down:

1. measureModeNavigation / ResizeObserver: removed. The nav collapses on width alone now. @media(max-width:840px) hides .navs and shows the menu, and the pre-existing @media(max-width:620px) block re-shows it as the wrapped full-width three-column row. Rule order is load-bearing there, so there is an assertion that the 620px rule still comes last, since a reordering that let the menu rule win would hide the nav on phones.

On the breakpoint, I did not want to guess a number, so I disabled the menu rule and measured where the nav actually clips: clean at 820px, clipped at 812px. 840px leaves about 25px of margin, which is the job document.fonts.ready was doing, since the label widths shift slightly before the webfont lands.

Removing the observer did cost one behaviour, which a cross-check caught and I reproduced before fixing. measureModeNavigation also closed the menu whenever the nav un-collapsed. Without it, opening the menu at 780px and then widening past 840px left aria-expanded="true" on a now-hidden trigger, and the menu came back already open on the way down. One line covers it: matchMedia('(max-width:840px)').addEventListener('change',closeModeMenu).

2. Duplicated toggle pair: collapsed. Both pairs go through one setMenu(menu, trigger, open = menu.hidden).

3. truncate-to-6-decimals: leaving it, taking your read. The three copies genuinely differ, and the standalone CLI scripts avoid depth-sensitive imports on purpose, so a shared helper would buy less than it costs.

The /api/briefs aside: fixed, then made unreachable. First the exact try/except ValueError: continue you suggested, which also turned up a related bug: the loop sliced to limit before skipping anything, so one malformed filename silently ate a slot in the response. The count check moved inside the loop. After that, build_briefs stopped parsing filenames altogether. at and ts come from filesystem metadata and the cadence words in a name are optional display hints, so there is no datetime() over filename digits left to raise.

On the other changes in this snapshot. Every publish replaces the whole tracked tree from the mirror, so a snapshot carries everything that has landed there since the last one, not only the review fixes. Four other things came along:

  • Approval review buttons are prompt-driven, so Approve and Request change both run the typed instruction, and a bare Approve sends the draft as-is. That is the approval_state.py, approval-helper.py and transitions-test churn.
  • Briefing filenames are free-form (the change described above).
  • A slack-profile get|set subcommand on client.py for the caller's own Slack status. The writable payload is restricted to the status fields, and missing_scope errors now print the full needed and provided lists instead of a truncated slice. The matching scopes went into the app config.
  • The dashboard's Initialising group is scoped to quests that actually have a first worker run pending, via a requires_initial_run flag set by the creation surface. Before this, any quest that had never dispatched read as still setting up and sat greyed out indefinitely, which is wrong for an ordinary monitoring quest that can be fully active before its first event. The same change adds a count pill to quest rows with more than one message awaiting review.

Full suite is green, 48 suites plus the 29 differential goldens. The UI changes were checked in a browser at 1440px, 780px and 600px rather than by assertion alone.

- Add YAAS_SLACK_CHECKERS_ENABLED switch to disable local Slack adapter
- Revert default Claude model to Opus 4.8; drop stale contract test

Source-SHA: 16b9654aec77d2e10d77a71843f62f89cafe61c2
Source-SHA: b54e04936f1a06438c51645d98a7e8efbadb339c
Source-SHA: e09a6494d03ce2cc8280345599901a75a87ea748
@guangmian-circle
guangmian-circle merged commit 1c74488 into master Aug 18, 2026
3 checks passed
@guangmian-circle
guangmian-circle deleted the publish/yaas-v2-20260817-143710 branch August 18, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants