feat(cli): serve guidance from the CLI, and stop dumping the whole surface - #1382
Draft
cristifalcas wants to merge 1 commit into
Draft
feat(cli): serve guidance from the CLI, and stop dumping the whole surface#1382cristifalcas wants to merge 1 commit into
cristifalcas wants to merge 1 commit into
Conversation
…rface #1377 made the surface answerable at runtime because Aspect's surface is per-repo: `aspect <task>` means whatever that repo's `.aspect/*.axl` defines, so it can never be in a training set. Opinions have the same property — a monorepo with a go.work and vendored protos needs different guidance from a single-module library — so they belong on the same mechanism. `aspect describe` was answerable but not affordable: 186,669 bytes, all or nothing. `--include=tasks,features,guidance` and `--task=<name>` narrow it, and a single task now costs 6,997 bytes. Omitted sections are absent rather than empty, because an empty array claims the repo has none, which is a different and wrong answer. `--task` implies its own section unless `--include` is explicit. `guidance(...)` declares a topic: id, title, summary, a markdown `body_file`, `applies_to` hints and a stability. Bodies are files, not inline strings — a few hundred lines of prose in a Starlark literal is neither reviewable nor diffable — resolved and existence-checked at load, then read only when a caller names the topic. `describe` carries a cheap index with a byte count; `--guidance=<id>` returns one topic with its body. Discovery mirrors tasks: auto-discovered from repo-local .axl, or declared with `use_guidance` in MODULE.aspect. A `config.axl` contributes topics with `ctx.guidance.add(guidance(...))`, and reusing an id replaces what a module shipped — which is the property no static skill file can offer. `defined_in` reports which declaration won, so a collision is visible rather than silent. `Guidance` is plain Rust rather than a heap-mapped Starlark value: it owns only Strings and PathBufs and nothing mutates it, so it needs none of Feature's live/frozen split, tracing or thawing. Only the collection lives on the heap, because Phase 2 configs append to it. Also strips ANSI escapes from describe's prose. `aspect delivery`'s description carries \x1b[3m…\x1b[23m, and terminal formatting has no business in machine-readable output. No `guidance_replace`: the collection resolves duplicate ids last-wins and `Guidance` is immutable, so it would be `add` under a second name. The tips precedent needs both only because a tip is mutable. Design doc, including why not MCP and why an Agent Skill is the real alternative: ~/development/docs/2026-08-08-aspect-agent-guidance-surface-design.md axl-runtime + aspect-cli: 459 passed, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
aspect describecan answer what this repo's surface is. It could not answeraffordably, and it could not answer the question an agent actually has, which is
not "what tasks exist" but "how do I do this here".
The whole surface, every time. 186,669 bytes, all or nothing.
--includeand
--tasknarrow it; one task now costs 6,997. Omitted sections are absentrather than empty —
[]claims the repo has none, which is a different andwrong answer.
--taskimplies its own section unless--includeis explicit.Guidance is prose the CLI serves, resolved per repo.
guidance(...)declares a topic with a markdown
body_file.describecarries a cheap indexwith a byte count;
--guidance=<id>returns one topic with its body. Bodies areread only when a caller names the topic — reading every one to answer an index
request is the cost the split exists to avoid.
A repo can replace what a module shipped.
ctx.guidance.add(guidance(...))in
config.axl, reusing an id to override. This is the property no static skillfile has: guidance that reflects this repo and versions with the binary
instead of rotting in a copied file.
defined_inreports which declaration won.Bodies are files rather than inline strings because a few hundred lines of prose
in a Starlark literal is neither reviewable nor diffable.
Also strips ANSI escapes from
describe—aspect delivery's descriptioncarries
\x1b[3m…\x1b[23m, and terminal formatting has no business inmachine-readable output.
Draft, because the form factor is a real question. MCP is not it: nobody
ships one inside their product CLI (GitHub, Azure, Netlify, Heroku, Stripe and
Sentry all ship siblings), and the industry serves guidance as Agent Skills and
reserves MCP for tools. The honest competitor is just shipping a skill, which
costs nothing to build and reaches every agent — but cannot resolve per-repo,
cannot be overridden by a customer's
config.axl, and goes stale on its ownschedule. Those three are the entire argument for this. Design doc, including
the industry check and the case for stopping at a skill:
~/development/docs/2026-08-08-aspect-agent-guidance-surface-design.md.The
--include/--taskfiltering stands on its own merits and could landseparately if the guidance half doesn't survive review.
Changes are visible to end-users: yes
New
aspect describeflags (--include,--task,--guidance), a newguidance(...)AXL global,use_guidanceinMODULE.aspect, andctx.guidanceon config contexts. Existingaspect describeoutput isunchanged when no flag is passed, apart from ANSI escapes no longer appearing.
Test plan
split, and
--guidancenarrowing are covered by new unit tests.config.axloverride serving the repo's body with
defined_inprovenance, unknown idsexiting 2 with the valid list, and a wrong value type rejected by name.
chmod 000'd, the indexstill succeeds (
bytescomes from metadata) and only the fetch reportsPermission denied.cargo test -p axl-runtime -p aspect-cli— 459 passed, 0 failed, no warnings.🤖 Generated with Claude Code