Agents Builders

Mascot marker no-downgrade fallback

Archived
mascot-marker-no-downgrade-fallback

Created

Jun 24, 05:26

Started

Jun 24, 06:52

Completed

Jun 24, 13:45

DevOps handoff

Type

Bug

Shape

backend

Worktree Slug

mascot-marker-no-downgrade-fallback

Repositories

mcritchie-studio

Release Train

Branch

feat/mascot-marker-no-downgrade-fallback

Local URL

QA URL

Production URL

low tooling status-line

Acceptance Criteria

  • write_feature_marker keeps mascot when API response lacks it
  • Mascot resolves response then on-disk then board
  • Status line never flip-flops off the mascot handle

Expected Test Plan

  • [unit] FeatureMarker.mascot picks first present source
  • [integration] bin/task marker keeps mascot when response blank

Checks Run

  • [unit] FeatureMarker.mascot first-present pick + short-circuit ordering — test/lib/feature_marker_test.rb (6 runs / 9 assertions)
  • [integration] bin/task marker: keeps mascot when response blank, honors CLAUDE_PROJECTS_DIR, board read failure never aborts — test/lib/task_cli_test.rb (32 runs / 115 assertions)

Agent Context

Bug: bin/task's write_feature_marker copies the mascot straight from dv['mascot'] in a single API response. The board assigns the per-session mascot lazily (Task#sync_session_mascot runs on create AND re-derives on every build-phase transition), so a given create/move response can momentarily lack the mascot. When it does, the per-session marker (.agents/sessions/<id>.json) is written WITHOUT a mascot, and bin/statusline drops from the preferred '⊙ <Mascot> · app · feature' form to its no-mascot fallback ('app · feature · <task URL> [stage]') — the flip-flop the operator observed for a projects-root (non-worktree) session. bin/agent-worktree.resolve_mascot already has a no-downgrade fallback chain (TASK_MASCOT -> last-good on-disk -> board via 'task field'), added in d0a976c to fix the WORKTREE path; write_feature_marker never got the equivalent. Fix: give write_feature_marker the same guarantee — resolve mascot via response.devops.mascot -> existing on-disk marker value -> board GET, never overwriting a known mascot with blank. Extract the pure first-present pick into lib/feature_marker.rb (mirrors lib/claim_lease.rb) for a unit test; integration-test the end-to-end marker write via the TaskCliTest stub-server harness. Also make PROJECTS_DIR honor CLAUDE_PROJECTS_DIR (bin/statusline already does) so the integration test writes its marker to an isolated dir; no prod behavior change when the env is unset.

Stage Timeline

Who handled each stage, the time it took (measured), and the model / tokens / cost reported (best-effort) — plus who's on it right now. means the agent didn't report that metric.

  1. Created Designed
    D Drowzee
    Drowzee
    Model
    Duration
    Tokens
    Cost
    Completed Jun 24, 05:26 · 3 days ago
    api
  2. Designed Building
    D Drowzee
    Drowzee
    Model
    claude-opus-4-8
    Duration
    under a minute
    Tokens
    Cost
    Started Jun 24, 05:26
    Completed Jun 24, 05:27 · 3 days ago
    cli
  3. Building Submitted
    D Drowzee
    Drowzee
    Model
    claude-opus-4-8
    Duration
    11 minutes
    Tokens
    Cost
    Started Jun 24, 05:27
    Completed Jun 24, 05:38 · 3 days ago
    cli
  4. Submitted Blocked
    Model
    Duration
    about 1 hour
    Tokens
    Cost
    Started Jun 24, 05:38
    Completed Jun 24, 06:52 · 3 days ago
    api
  5. Blocked Building
    D Drowzee
    Drowzee
    Model
    claude-opus-4-8
    Duration
    under a minute
    Tokens
    Cost
    Started Jun 24, 06:52
    Completed Jun 24, 06:52 · 3 days ago
    cli
  6. Building Submitted
    D Drowzee
    Drowzee
    Model
    claude-opus-4-8
    Duration
    8 minutes
    Tokens
    Cost
    Started Jun 24, 06:52
    Completed Jun 24, 07:00 · 3 days ago
    cli
  7. Submitted Reviewed
    C Carl
    Carl primary
    S Shannon
    Shannon light
    Model
    claude-opus-4-8
    Duration
    1 minute
    Tokens
    13,176,324
    Cost
    ~$8.99
    Started Jun 24, 07:00
    Completed Jun 24, 07:02 · 3 days ago
    cli
  8. Reviewed Assembled
    S Steffon
    Steffon
    Model
    Duration
    2 minutes
    Tokens
    Cost
    Started Jun 24, 07:02
    Completed Jun 24, 07:04 · 3 days ago
  9. Assembled Shipped
    A Avi
    Avi
    Model
    Duration
    about 7 hours
    Tokens
    Cost
    Started Jun 24, 07:04
    Completed Jun 24, 13:45 · 3 days ago
  10. Shipped Archived
    1
    159aaa24-5db3-4c44-aa05-25c79d2902cd
    Model
    claude-opus-4-8
    Duration
    about 4 hours
    Tokens
    62,713,447
    Cost
    ~$53.44
    Started Jun 24, 13:45
    Completed Jun 24, 17:37 · 3 days ago
    cli

Conversation

QA review feedback, agent handoffs, and follow-up notes for this task.

Comment avi 3 days ago

Review cascade: shannon[light] APPROVE; carl[heavy] BLOCK.

QA Feedback avi 3 days ago

carl[heavy]: board_mascot calls api(:get) in-process; on a non-2xx board read api->die!->exit 1 raises SystemExit, which is NOT StandardError, so it escapes board_mascot's rescue AND write_feature_marker's rescue — aborting the whole bin/task move/create with exit 1 AFTER the server op succeeded (false failure; churn under the rate-limit epic). REQUIRED: make board_mascot incapable of terminating the process — mirror bin/agent-worktree resolve_mascot (shell out: `bin/task field <slug> mascot 2>/dev/null` in a subprocess) OR rescue SystemExit/Exception->nil around the api call. ADD an integration test: board-fallback path returns non-2xx -> command still exits 0 AND writes the marker. (Also: checks_run says unit(7); actual 6 tests/9 assertions.)

Comment avi 3 days ago

Rework verified (7c270b03): board_mascot rewritten to read via subprocess (`task field <slug> mascot 2>/dev/null`, shellescaped) mirroring resolve_mascot — SystemExit from a non-2xx board read is now contained in the child, can never abort bin/task. + board-fallback regression test (fail_get knob → non-2xx → asserts exit 0 + marker written + no mascot). RED->GREEN (1 fail → 32/115 + 6/9). dor-check ✓. carl[heavy] block resolved; shannon[light] had approved. Merge-gated on CI test green.

Sealed-bid sizing

Edit →

Alex (PM)

Avi (PO)

Dev

Actual