Your Slack Script Just Shipped

The second team is the product threshold

Share

Three weeks after the 857-line honesty machine, managers were running reports weekly. Slack carried forked copies with incompatible flags. Excel exports became the source of truth in staff meetings - and breakage was visible.

On 2026-06-01 at 09:32, commit 9d47215 refactored github-analysis into a uv-managed CLI with analyze, export, and run commands. This note is about recognizing when a personal script becomes team infrastructure.

Here's what this piece covers: the product threshold, what changed in the refactor, version as contract, and three lead actions.

Part of Field Notes: agentic delivery.


1. The leadership problem

Ad-hoc scripts spread via Slack. Everyone runs different flags. When the spreadsheet breaks mid-staff-meeting, you learn you never had an owner.

Wrong: "We refactored for cleanliness."
Right: "Jun 1 9d47215: monolith to github-analysis CLI because three managers were running incompatible exports."

The anti-pattern is the eternal personal script - no owner, no contract, no --help.


2. What the git history shows

Date Commit State
2026-04-10 d52975b 857-line single file + README
2026-06-01 09:32 9d47215 Modular package, pyproject + uv, CLI entry point

9d47215 - Refactor into modular CLI with uv, team summaries, and Excel export - touched the whole repo layout:

github_analysis/cli/commands/analyze.py
github_analysis/cli/commands/export.py
github_analysis/cli/commands/run.py
github_analysis/analysis/   github_analysis/export/
github_analysis/pipeline/
flowchart LR subgraph before["Apr 10 - probe"] M[857-line monolith] end subgraph after["Jun 1 - product"] CLI[github-analysis CLI] CLI --> A[analyze] CLI --> E[export] CLI --> R[run] end M --> CLI

3. What changed in the refactor

Package layout - commands, analysis, export, pipeline separated. Tests could target modules instead of a god file.

Commands:

Command When to use Output
analyze PR timeline / person rollups for a window TSV under analysis-results/
export Regenerate Excel from cached run .xlsx via openpyxl optional group
run Full pipeline - fetch, analyze, export Run logs + artifacts

Entry point as contract:

import click

@click.group()
@click.version_option("2.0.0")
def cli():
    """Engineering metrics - analyze, export, run."""


@cli.command()
@click.option("--since", required=True, help="Half-open window start (ISO).")
@click.option("--until", required=True, help="Half-open window end (ISO).")
def analyze(since: str, until: str):
    """PR timeline + person rollups for [since, until)."""
    ...

Version pin (2.0.0) - signals contract to consumers. Legacy wrapper kept github_pr_timeline_report.py forwarding to analyze for one release cycle.

README as contract - foreshadow article 10. --help before new metrics.

The named pattern:

Script → product threshold - modular CLI, version pin, --help before new metrics when a second team depends on you.

4. What broke / lessons

Refactor day is expensive - batch breaking changes when dependents are few. I waited until three managers depended on the script; I should have named an owner at two.

The afternoon of 2026-06-01 also shipped wrong person-summary metrics - three correction commits by 10:52 (article 09). Productizing without definitional discipline just scales bad numbers faster.


5. What I'd do as a lead

  1. Name an owner when the second team asks for the report. Not when the fifth team complains.
  2. Invest in --help and README before new metrics. Columns need definitions before staff meeting.
  3. Keep a legacy entry point for one release cycle. Forks die slower than you hope.

Further reading