040-scripts/ is the accumulation substrate for ad hoc tooling

Type: ../types/adr.md · Status: accepted

Status: accepted Date: 2026-07-07

Context

AGENTS.md's Development section named two tiers of code: python3 for stdlib-only throwaway tooling, and the installed commonplace package for shipped commonplace-* commands. A third tier already existed in practice and had existed since the repository's first commit — the git-tracked scripts/ directory, holding ad hoc tooling that is committed (not thrown away) but hasn't earned a commonplace-* entry point. ADR-014 documents the one precedent for a promotion out of scripts/, at subsystem scale, but nothing named the tier itself, its lifecycle, or when an individual script should graduate.

The gap showed up concretely: scripts/move-reviews-to-subdir.py, self-described as "one-off" and last touched in April, sat unused and undeleted for months — the only genuine evidence of drift, but real.

Decision

Name scripts/ explicitly as the destination for ad hoc tooling expected to be reused (by the same agent later in a session, or by a future one), distinct from both heredoc-and-discard and the installed package. Adopt two lightweight norms alongside it:

  • Cleanup norm. A script whose docstring says "one-off" or "temporary" is deleted by whoever finishes using it, in the same session or commit series, rather than left for someone else to notice later.
  • Promotion signal. A script graduates to a commonplace-* command when it has been invoked, unmodified in its core logic, across multiple unrelated sessions or triage passes — repetition with a stable interface, the same signal spec mining uses generally (spec mining is codification's operational mechanism) and consistent with committing only after patterns stabilize (progressive constraining commits only after patterns stabilize). A script whose interface is still changing hasn't stabilized enough to promote, no matter how many times it's been touched. This is a judgment call exercised periodically (e.g., at monthly triage), not a mechanical trigger.

The rule lives in two places: a one-line pointer in AGENTS.md (visible to every agent immediately) and the fuller norm/signal detail in scripts/README.md (visible to an agent that opens the directory). No scheduled sweep or expiry-timestamp machinery is adopted — one stale file in six, over 15 months, is thin evidence for anything heavier than an informal norm.

Consequences

Easier:

  • An agent deciding between a heredoc and a saved file has a documented decision point instead of guessing.
  • Stale one-off scripts have a stated exit path, so scripts/ stays a substrate rather than a junk drawer.
  • A future triage pass reviewing scripts/ contents has a named promotion signal instead of re-deriving one from ADR-014.

Harder / accepted costs:

  • The cleanup norm is informal and relies on the finishing agent remembering; if drift turns out to be worse than the one observed instance, a scheduled sweep is the escalation path, not adopted now.
  • The promotion signal is a judgment call, not a mechanical trigger, so it depends on someone noticing recurrence rather than firing automatically.

Relevant Notes: