Repository navigation
sdk: ship the instructions to the repo that installs us, not inside the package - #14
Merged
Merged
Conversation
…he package
A developer runs `pip install ubag`, their coding agent knows nothing about the
protocol, and it invents an API. Shipping an AGENTS.md inside the package does
not fix that: agents read AGENTS.md, CLAUDE.md and .agents/skills from the
project root, never out of site-packages or node_modules. The file has to be
copied out to where it will be found.
So both SDKs now carry skill templates and an init command that writes them into
the consuming repo:
ubag init [--agent|--both|--check]
npx ubag-web init [--agent|--both|--check]
Two audiences, because they need opposite things. The publisher skill covers
mounting the middleware, the two separate keys, and the rules that are
load-bearing: no model runs in the resolve path, misses are reported rather than
guessed, control parameters never reach the origin. The agent skill covers the
three calls, persisting the identity so agent_id stays stable, and reading
ubag:unresolved correctly, since "this resource says nothing about price" and
"the price is nothing" are different answers and blurring them is how a
retrieval layer starts returning confident wrong ones.
What it refuses to do is the part worth reviewing. An existing AGENTS.md is
never modified; it is somebody's file, probably long, and appending to it unasked
is how a tool gets uninstalled. The line to add is printed instead. Same for
CLAUDE.md. Re-running writes nothing when the content already matches.
No pointer is written under .claude/skills. A one-line CLAUDE.md containing
@AGENTS.md was confirmed to pull the whole file into context; the import
semantics of a file under .claude/skills were not, and a pointer that silently
resolves to nothing is worse than no pointer.
Packaging carries the templates deliberately: package-data for the wheel, since
packages.find takes modules and not .md files, and "bin" plus "src" in the npm
files list. Verified against a built wheel rather than assumed.
Also fixes __version__, which said 0.5.0 while pyproject said 0.6.0 through a
release. Harmless while nothing read it. Not harmless now that init stamps the
version into a file and compares it back to decide whether a repo's copy is
stale, because the check would quietly lie. It reads installed metadata instead
of restating a literal, with a test asserting the two agree.
Node keeps its own copy of the templates, because the packages publish
separately and neither can reach the other once installed. A test asserts the
copies are byte-identical whenever the sibling repo is present, so drift is
caught here and not by a user.
Python 102 passed, Node 110 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…his too tomllib is 3.11+, this package supports 3.10, and CI runs the matrix. The test that asserts __version__ agrees with pyproject imported tomllib and was the only red square on the board. Skipping it below 3.11 was the other option and is worse: 3.10 is the runtime most likely to be somebody's system default, and it is exactly where an installed package quietly diverging from the source tree would go unnoticed. A regex over the one line covers the whole matrix and drops a stdlib dependency the test never needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 28, 2026
Merged
mohameduk
added a commit
that referenced
this pull request
Sep 16, 2026
sdk: ship the instructions to the repo that installs us, not inside the package
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.
A developer runs
pip install ubag, their coding agent knows nothing about the protocol, and it invents an API.Shipping an
AGENTS.mdinside the package does not fix that. Agents readAGENTS.md,CLAUDE.mdand.agents/skillsfrom the project root, never out ofsite-packagesornode_modules. The file has to be copied out to where it will be found.What this adds
Two skill templates, because the two audiences need opposite things:
ubag-publisherubag-agentagent_idstays stable, readingubag:unresolvedcorrectlyThat last one is the one that prevents wrong answers downstream. "This resource says nothing about price" and "the price is nothing" are different answers, and a retrieval layer that blurs them starts returning confident wrong ones.
What it refuses to do
This is the part worth reviewing.
AGENTS.mdis never modified. It is somebody's file, probably long, and appending to it unasked is how a tool gets uninstalled. The line to add is printed instead. Same forCLAUDE.md..claude/skills. A one-lineCLAUDE.mdcontaining@AGENTS.mdwas confirmed to pull the whole file into context. The import semantics of a file under.claude/skillswere not, and a pointer that silently resolves to nothing is worse than no pointer.Packaging
Carried deliberately and verified against a built wheel rather than assumed:
package-datafor the wheel, sincepackages.findtakes modules and not.mdfiles, andbinplussrcin the npmfileslist.Drive-by fix
__version__said0.5.0whilepyproject.tomlsaid0.6.0, through a release. Harmless while nothing read it. Not harmless now thatinitstamps the version into a file and compares it back to decide whether a repo's copy is stale, because the check would quietly lie. It now reads installed metadata instead of restating a literal, with a test asserting the two agree.Template drift
Node keeps its own copy of the templates, because the packages publish separately and neither can reach the other once installed. A test asserts the copies are byte-identical whenever the sibling repo is present, so drift is caught here and not by a user.
Tests
Python 102 passed, Node 110 passed. 29 of those are new and mostly about the refusals above.
🤖 Generated with Claude Code