feat(studio): gzip run-log commits, behavior_v2 default, bridge log-level ack (PR 2 of 3) — Studio v0.72 - #186
Open
mbreiser wants to merge 1 commit into
Conversation
…bridge log-level ack (PR 2 of runlog-behavior-v2-plan) — Studio v0.72 Studio side of docs/development/runlog-behavior-v2-plan.md (Part 1 §5 + Part 2). Stacks on PR #183 (bridge). Readers (dashboard / replay viewer) are PR 3 — until it lands, .jsonl.gz files need gunzip or `bridge.py --convert`. - js/fictrac-bridge-client.js: LOG_LEVELS [behavior_v2, behavior_v1, full] (v2 default); handles hello_ack (bridgeInfo, bridgeSupportsLevel) and log_control_ack (ackedLogLevel, cleared on every setLogging and on close); new 'loglevel' event + an err log line when the bridge cannot write the requested level; waitForLogLevelAck(ms) → acked level or null (old bridge). - js/studio-github.js: gzipBytes (CompressionStream) + isGzip; Git Database builders (reqCreateBlob/reqGetCommit/reqCreateTree/reqCreateCommit/ reqUpdateRef, allowlisted, fast-forward only); directCommitLarge (7-call blob→tree→commit→ref sequence, per-step errors); commitFile routes by size (LARGE_FILE_BYTES = 30 MiB) and reports via + bytes. - arena_studio.html v0.72: File ▾ → Run logging offers behavior_v2 (default) / behavior_v1 (legacy) / full; Console mirror follows the bridge's ack (⚠ on mismatch); run start awaits the ack ≤ 800 ms, names the level in the banner + transcript and warns "bridge too old for behavior_v2 — logging behavior_v1" (or "did not confirm" for a pre-3.0 bridge); run_metadata gains log_format; commitRunLog gzips the export → runlogs/<bench>/<name>.jsonl.gz via GH.commitFile (raw .jsonl fallback without CompressionStream) and shows raw → gz size + the path used. - Tests: test-fictrac-bridge-client.js 42 → 71 checks (levels, hello_ack, log_control_ack, mismatch, waiters, close reset); test-studio-github.js 118 → 160 (gzip round trip via zlib, git-db builders + token containment, directCommitLarge sequence + failure step, commitFile routing, Studio wiring assertions on the HTML). - Docs: release notes v0.72, cshl-pipeline-test-plan size-limits, CLAUDE.md Studio rule, plan doc status + PR 2 notes (merge with/after PR 3). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Studio side (PR 2 of 3) of docs/development/runlog-behavior-v2-plan.md. Stacks on #183 (the bridge PR); the base is that branch and should be retargeted to
mainonce #183 merges.What changed
arena_studio.htmlv0.72commitRunLoggzips the bridge export in the browser (GH.gzipBytes, nativeCompressionStream) and commitsrunlogs/<bench>/<name>.jsonl.gzthroughGH.commitFile, which uses the Contents API up to 30 MiB and the Git Database API above it (the Contents API rejects ~35 MiB+ files, which is what killed the 51 MB rig03-sr run). The log line, the upload modal and the run-summary line show raw → gzipped size and, when used, the large-file path. A browser withoutCompressionStreamfalls back to raw.jsonl.behavior_v2 (compact — default),behavior_v1 (legacy)andfull. Nothing stored → v2; an explicitly stored v1 is honored (one release, per the plan).log_control_ack, and names the confirmed level in the banner and the recorded transcript. When the bridge cannot write it: "⚠ bridge too old for behavior_v2 — logging behavior_v1 (restartpixi run bridge…)"; when it never answers (pre-3.0 bridge): "did not confirm … assuming behavior_v1". The Console's read-only#cFtLogLevelmirror follows the ack with a ⚠ and an explanatory tooltip on mismatch.run_metadatagainslog_format= the acked level, or the inferred one for a non-acking bridge (behavior_v1when v2 was requested, else the request itself). Set from the ack, never injected by the bridge, so the v1↔v2 file round trip from feat(bridge): behavior_v2 run-log format, --convert CLI, log_control ack (PR 1 of 3) #183 stays exact.js/fictrac-bridge-client.jsLOG_LEVELS = ['behavior_v2','behavior_v1','full'], default v2 (setLogLevelwhitelist).hello_ack→bridgeInfo,bridgeSupportsLevel(level)(null when unknown = old bridge) andlog_control_ack→ackedLogLevel(cleared by everysetLogging()and on close).'loglevel'event{source, requested, level, ok, levels, enabled, file}plus an'err'log line on mismatch;waitForLogLevelAck(ms)resolves the acked level or null.js/studio-github.jsgzipBytes(input),isGzip(bytes).reqCreateBlob/reqGetCommit/reqCreateTree(path allowlisted) /reqCreateCommit/reqUpdateRef(fast-forward only),directCommitLarge(repo → ref → commit → blob → tree → commit → ref, per-step error reporting),commitFile(size router;LARGE_FILE_BYTES= 30 MiB;thresholdBytestest hook; result carriesvia+bytes).Docs: release notes v0.72,
cshl-pipeline-test-plan.mdsize-limits section, CLAUDE.md Studio rule (readers must inflate;log_formatonly from the ack), plan doc status + "PR 2 implementation notes".Tests
tests/test-fictrac-bridge-client.js: 42 → 71 checks — v2 default, v1/full selectable, unknown ignored;hello_ackrecorded +bridgeSupportsLevel;log_control_acksetsackedLogLevel, resolves waiters, emits'loglevel'; disabled ack; mismatch →ok:false+ err line naming both levels; hello from a bridge lacking the level warns up front; close resets everything and resolves pending waiters null; old-bridge timeout path.tests/test-studio-github.js: 118 → 160 checks — gzip round trip againstzlib.gunzipSync(UTF-8 preserved), gzip magic; builders' URLs/bodies/token containment, tree refuses a non-allowlisted path;directCommitLargeexact 7-call sequence with a mocked fetch (tree on the head root tree, commit parents = head, ref moved without force), blob-failure step reporting;commitFilesmall → Contents path, over threshold → git-db, UTF-8 byte counting; and assertions on the Studio HTML thatcommitRunLoggzips, names.jsonl.gz, routes throughcommitFile, keeps the raw fallback, offers the v2 option and stampslog_format.pixi run testpasses; the four touched JS files are Prettier-clean; all five inline Studio script blocks parse.CompressionStream(Chrome ≥ 80; same API works in Node 26, where the gzip test runs) and the Studio DOM wiring, which is asserted textually. Bench check: recorded 20 s run →.jsonl.gzcommitted with the size shown and the banner namingbehavior_v2; then run against an old bridge checkout and confirm the "too old" warning +log_format: behavior_v1in the file; force the Git Database path by temporarily loweringLARGE_FILE_BYTESand confirm the blob/tree/commit/ref sequence lands one file.🤖 Generated with Claude Code