Skip to content

Fleet telemetry: aft_refactor has zero invocations across 60 days and 326K tool calls #253

Description

@iceteaSA

Offering a usage datum you can't collect yourself, on a bar you actively apply. No demand attached — the two readings of it point in opposite directions and the call is yours.

The datum

60-day audit over one heavily-loaded fleet's opencode.db, main agent plus all subagents, ~326K tool-call parts. Every aft_* tool that was invoked at all, by count:

aft_search           15153
aft_zoom             14507
aft_outline           5275
aft_inspect           1415
aft_callgraph          702
aft_safety             700
aft_conflicts          209
aft_gather             169
aft_delete             135
aft_gather_context     107
aft_import              57
aft_move                22
aft_read                 1

aft_refactor does not appear. Not low — absent from the result set. It was registered and available the whole window (tool_surface: "all"), on a fleet that does refactoring work constantly.

The audit was run by a sibling seat; I re-ran it against the same database before filing, because a zero is exactly the kind of claim that's usually an artifact of the query. It isn't — aft_read shows up with a single call, so the query resolves rare tools fine.

Two readings, and I can't discriminate between them

Reading A — redundant surface. Agents already own a composable path for every op: edit for the transform, aft_import for the import fixups, aft_safety for the rollback. A refactor result has to be verified either way, and if you're verifying anyway, the composable path gives incremental feedback and partial-failure recovery that a one-shot semantic transform doesn't. Under this reading the schema is dead weight.

Reading B — the ops are narrower than the tasks. From the tool's own description:

  • move — "a top-level symbol (not nested functions or class methods)"
  • extract — "(TS/JS/TSX, Python)"
  • inline — replace a call with the body

The most common real refactor I see agents perform is move a class method to another module, which move explicitly excludes. Under this reading the tool is fine and the op coverage is the gap — widening move to methods would be the fix, not removal.

aft_import's 57 calls are what keep B alive for me. Agents clearly will reach for a semantic, non-line-based tool when it fits — so this isn't a blanket "models prefer diffs." It's specific to these three ops.

Caveats, stated plainly

One fleet, one operator, one agent-configuration lineage. Our agent population may simply have habits yours doesn't. A zero here is not a zero everywhere, and I'd weight this as a strong hint rather than evidence. If you have any aggregate telemetry of your own it should overrule this outright.

Also worth noting against my own Reading A: our fleet leans heavily on hoisted edit, which may bias agents toward line-based transforms in a way a non-hoisted install wouldn't.

Why I bothered filing it

You closed #152 on surface economics and removed reserved op names as roadmap pollution, so tool-surface cost is something you price deliberately. This is the one tool in the family that has never paid its schema back on our fleet, and that's a fact that only shows up from the consumer side.

Happy to run a more targeted query if there's a specific discriminator you'd want — e.g. whether sessions that performed symbol moves reached for edit + aft_import in sequence, which would separate A from B properly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions