fix: 10 validated bug fixes across serve, skills, render, and perf tools - #147
Merged
Conversation
Each fix is paired with a regression test that failed (RED) on main
before the fix and passes (GREEN) after; full per-bug rationale in the
test comments.
1. serve: eventsRing.snapshot served the OLDEST limit-matching events
once the ring held more than the limit; /api/events now returns the
most-recent window, oldest-first as documented.
2. skills: frontmatter scalars with numeric/bool forms (version: 1.2,
author: 7, trigger topic: 2) were silently dropped by bare string
assertions after parseYAMLValue type inference; string-typed fields
now coerce scalar forms canonically.
3. perf: head_tail description claimed a streaming early-stop the
implementation does not do (exact totals are pinned by test and kept);
description now matches behavior.
4. perf: math_eval % with fractional operands panicked (1 % 0.5 →
integer divide by zero) or silently truncated (0.5 % 2 → 0);
non-integer operands now get a clean error.
5. perf: sort order is now a validated case-insensitive enum ("DESC"
previously sorted ascending silently) and reverse flips the effective
direction (desc+reverse = ascending, per the schema contract).
6. render: extractJSONField required a space after the colon, so compact
JSON args ({"path":"main.go"}) silently lost their tool previews;
rewritten to locate keys properly and json-decode values (escapes
resolved).
7. render: tool-preview truncation sliced bytes, splitting multi-byte
runes into invalid UTF-8; truncation is now rune-safe.
8. perf: head_tail and word_count on directories surfaced raw scanner
errors (word_count also reported the dir stat size next to the error);
both now give count_lines' clear is-a-directory message.
9. perf: tree on a symlinked directory root reported a non-directory
"file" sized by the link-target string and walked nothing; the
explicitly-requested root is now resolved, descendants keep Lstat
semantics (symlinks shown, never followed).
10. serve: eventsRing.snapshot no longer aliases the ring's backing
slice in its result (copy before return).
Verified: go build, go vet ./..., golangci-lint (0 issues), full
internal/... suite, -race on changed internal packages, and the
cmd/odek stateless subset for every touched tool family. Known
environmental exclusion: TestBatchPatch_TrustedClasses blocks on an
interactive TTY approval prompt in headless runs (pre-existing, code
untouched by this branch).
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
odek | 75fc1fd | Commit Preview URL Branch Preview URL |
Aug 28 2026, 05:56 AM |
CI caught a data race in TestAudit_WriteWSJSONStalledClientBounded: the test retunes the package-global wsWriteTimeout while live WS write paths (including in-flight goroutines surviving earlier tests) read it inside writeWSJSON's select — an unsynchronized read/write of a plain time.Duration. Convert wsWriteTimeout to atomic.Int64 (Store at init, Load in the write watchdog) and update the test to Load/Store. Behavior unchanged; the memory-model violation is gone regardless of detector scheduling.
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.
Summary
Ten bugs found, each validated with a failing (RED) test on
mainbefore its fix, all GREEN after. Every fix pairs with a regression test pinning the corrected behavior; per-bug rationale lives in the test comments.eventsRing.snapshotserved the oldest N matching events once the ring exceeded the limit —/api/eventsstale exactly under loadversion: 1.2,author: 7,trigger.topic: 2) silently dropped by bare.(string)assertionshead_taildescription promised a streaming early-stop the implementation never does (exact totals are test-pinned)math_eval1 % 0.5→ integer divide-by-zero panic;0.5 % 2→ silently wrong0%requires integer operands, clean errororder:"desc"+reverse:trueignoredreversereverseflips the effective directionorder:"DESC"silently sorted ascending (schema enum violated){"path":"main.go"}→"file")extractJSONFieldrewritten: key-boundary aware, JSON-decodes valuestruncateRuneshead_tail/word_counton directories: raw scanner errors; word_count reported the dir stat size beside the errorcount_linestreeon a symlinked directory root → non-directory "file" sized by the target-path string, nothing walkedStat; descendants keep Lstat semantics (symlinks shown, never followed)Investigation notes
ParseRefs@@behavior looked like a broken escape, butTestParseRefs_DoubleAtpins it as intended. Reverted rather than weakening the pinned contract; replaced with bug feat(memory): path-aware episode/skill provenance + human-gated promote #10.TestBatchPatch_TrustedClassesblocks on an interactive TTY approval prompt in headless runs (pre-existing;batch_patchcode untouched by this branch).Test plan
main→ GREEN on this branchgo build ./...,go vet ./...golangci-lint run— 0 issues./internal/...suite;-raceon changed internal packagescmd/odekstateless subset for every touched tool family