Skip to content

[dog-intelligence] Follow-up improvements from arc0btc review #598

Description

@LimaDevBTC

Tracking the non-blocking carry-forward items from @arc0btc's review on PR #14 (comment). The PR is approved and merged-ready; this issue captures the polish items for a follow-up patch.

Items

1. fetchMultiple short-circuit on 429 (correctness)

Current behavior: when any single path in a parallel batch returns 429, the helper calls process.exit(0) and drops the entire batch — including paths that succeeded.

Proposed: return { ok: false, status: 429, retryAfter } per-path so partial results survive. Each action handler then decides whether to proceed with partial data or surface status: "blocked".

Scope: touches the helper + all 8 action handlers. Low risk per handler but wide blast radius. Best done as a focused PR with action-by-action verification.


2. Hardcoded 100_000_000_000 total supply in whales (documentation)

DOG is a Bitcoin rune with a fixed, etched supply of 100B. The constant is correct today and forever — there's no minting mechanism. Just needs a comment.

Fix:

// DOG total supply is fixed at etching (rune 840000:3). Cannot change.
const totalSupply = 100_000_000_000;

3. action field embeds prose rather than short verb (cosmetic)

Today: \"action\": \"DOG pulse snapshot. Use this data for market analysis and signal generation.\"

Proposed: short verb (\"action\": \"pulse\") and move the prose to a separate summary or description field. Easier for agents to switch on programmatically.

Scope: ~10 out() call sites. Cosmetic but breaks any consumer that grepped on action strings.


4. Rate-limit response lacks structured retry_after_seconds (ergonomics)

Today the retry-after value is encoded only in the error string: \"Rate limited on /endpoint. Retry after 60s.\"

Proposed: add a top-level numeric field so agents don't have to regex the error string.

Fix sketch:

out(\"blocked\", \"rate_limited\", { retry_after_seconds: retryAfter ?? 60 }, ...)

5. get() catch discards error class (debugging)

The catch block in get() swallows the underlying error:

} catch {
  clearTimeout(timer);
  return { ok: false, status: 0, data: null, retryAfter: undefined };
}

Proposed:

} catch (err) {
  clearTimeout(timer);
  return { ok: false, status: 0, data: err instanceof Error ? err.message : String(err) };
}

So timeout vs DNS vs TLS errors are distinguishable in the response payload.


Plan

Items #2, #4, #5 are one-line / few-line patches and could land together as a low-risk hygiene PR.

Item #1 deserves its own focused PR with smoke tests across all 8 actions.

Item #3 is cosmetic and breaking — should wait until there's a versioning story for skill output schemas.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions