Skip to content

Fix Python setup issues from scalebridge and move from Graft to Trail - #14

Merged
antomanc merged 7 commits into
mainfrom
fix/scalebridge-findings
Oct 20, 2026
Merged

antomanc merged 7 commits into
mainfrom
fix/scalebridge-findings

Conversation

@antomanc

Copy link
Copy Markdown
Owner

Summary

Fixes the four problems found when running aginit 0.5.1 on an existing Python repo (uv, pytest, ruff, tests/), and moves the codebase graph from Graft to Trail, its upstream successor.

 aginit init  (Python repo)
   tool-ignores
     prettier, eslint, biome
+    ruff            # extend-exclude .agents/.claude in ruff.toml or [tool.ruff]
   projectCommands(python)
-    test: uv run pytest
+    lint: uv run ruff check . && uv run ruff format --check .
+    test: uv run pytest
   testing guide
-    "Keep tests next to the module"
+    "Put tests in `tests/`, mirroring the module"   # when tests/ or test/ exists
   AGENTS.md
+  <!-- aginit:start -->
     ## Bootstrap & First Session     # was appended after aginit:end
     Task Routing
-      PRODUCT.md row (always)
+      PRODUCT.md row only if the file exists or a design capability writes it
   <!-- aginit:end -->
-  <!-- graft:start -->              # @nanonets/graft, bin graft
+  <!-- trail:start -->              # @trailhq/trail-code, bin trail

Trail rename: capability id trail, --no-trail, codebase.trail. Saved configs that say graft load as trail. trail init migrates repos graft wired before, and aginit removes graft's leftover .ignore hint when it hasn't been edited. The wizard summary and README disclose that Trail sends anonymous telemetry and how to turn it off.

This repo's own tooling also moves to Trail (.trail/, .claude/settings.json), and HANDOFF notes are now gitignored.

Evidence

Python fixture (pyproject.toml with [tool.ruff], uv.lock, tests/, hand-written AGENTS.md), packed CLI, real skills and real trail, same flags as the scalebridge run:

  • Before (0.5.1): ruff check . fails on .agents/skills/humanizer/scripts/validate-package.py; testing.md has no static-check line and says to put tests beside the module; bootstrap section sits outside the block; PRODUCT.md is routed but doesn't exist.
  • After: uv run ruff check . reports All checks passed! and ruff format --check . reports 8 files already formatted, with the humanizer script present. testing.md lists the ruff command and tests/. aginit doctor passes all 16 checks. A second init leaves git status clean.
  • Migration: a repo set up by published 0.5.1 with graft, re-run with this build: graft helpers, .mcp.json, graft/ and .ignore are gone, bootstrap moves inside the block, the PRODUCT.md row is dropped, and the config says trail. A second run is a no-op.
  • pnpm check (195 tests, including new ones for each finding) and pnpm smoke pass.

trail check flags 3 overlaps with an earlier learning about "changing the Graft hooks in .claude/settings.json from aginit". They're keyword matches: this PR never writes those hooks. Upstream trail init still owns them.

Merge Danger

Door: two-way

The code can be reverted. Projects re-run with this version keep trail in their config, and older aginit versions won't read that.

Blast Radius: wide

  • Every project with the default codebase graph now needs trail on PATH (npm install -g @trailhq/trail-code) instead of graft. Without it, aginit init warns and exits nonzero, as it did before for a missing Graft.
  • --no-graft and --without graft are gone (pre-1.0 breaking change).
  • AGENTS.md changes on the next run for every existing project: bootstrap moves into the block, and the PRODUCT.md row disappears where there's no PRODUCT.md and no design capability.
  • Ruff users get a one-line edit to pyproject.toml or ruff.toml.

trail (@trailhq/trail-code) replaces graft upstream. trail init migrated
the Claude Code hooks, AGENTS.md block and opencode.json; the graph cache
now lives in the git-ignored .trail/cache. Handoff notes stay local.
A ruff config (.ruff.toml, ruff.toml or [tool.ruff] in pyproject.toml)
now sets the Python lint command (ruff check + format --check, through
uv when locked), and aginit adds .agents/.claude to its extend-exclude
so vendored skill scripts no longer fail the project's ruff CI. An
existing extend-exclude gets advice instead of an edit.
The native guide told agents to keep tests next to the module, which
contradicts the separate tests/ directory most Python and Rust projects
use. It now names an existing tests/ or test/ directory, and otherwise
defers to the toolchain convention.
The Bootstrap & First Session section was appended after aginit:end, so
aginit could never update it and re-added it whenever the heading was
missing. It now opens the managed block; an unedited copy left outside
by older releases is removed, an edited one is kept. doctor checks for
the block instead of the heading.

The Task Routing row for PRODUCT.md now appears only when the file
exists or a design capability writes it, so non-UI projects no longer
get a dangling reference.
Graft became Trail upstream (@trailhq/trail-code, bin trail). The
capability, flag (--no-trail), config switch (codebase.trail) and setup
now use it; trail init migrates repos graft wired before, and aginit
drops graft's leftover .ignore hint when it is unedited. The graph cache
lives in .trail/cache, ignored by trail itself, so aginit's gitignore no
longer lists /graft/ or .ignore.

Configs saved with codebase.graft or a graft capability id keep loading
as trail. The wizard summary and README disclose Trail's anonymous
telemetry and how to opt out.

BREAKING CHANGE: --no-graft is now --no-trail and --without graft is
--without trail.
@antomanc
antomanc merged commit e3d9530 into main Oct 20, 2026
6 checks passed
@antomanc
antomanc deleted the fix/scalebridge-findings branch October 20, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant