Keep ego-browser loaded in every project - #123
Conversation
core declared browser/ego-browser, but the per-project loadout deferred it everywhere no project signal matched — which is most projects, since the signal set comes from package.json deps and framework detection and nothing there says "browser". The declaration was real and the skill still never loaded. Deferring it does not save a browser session; it sends the agent to MCP round-trips or web fetch instead, which costs more than this skill's frontmatter. So it joins the operational primitives in ALWAYS_KEEP, and the matching slug set in profile-merge so a budgeted composite can't drop it either. Verified on a neutral cwd with zero project signals: browser/ego-browser now classifies full, where it previously landed in deferred. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
core declares browser/ego-browser, but the pinned skills commit predates the skill, so `cue validate` failed the resolver dry-run with SKILL_NOT_FOUND on every profile that inherits core. Points at the branch tip that now carries both the skill and the smart-loader work the previous pin was tracking. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
NagyVikt
left a comment
There was a problem hiding this comment.
Automated review — verdict: no blocking findings. 0 CRITICAL, 0 HIGH, 0 MEDIUM, 1 LOW.
(Comment rather than approval: GitHub refuses self-approval.)
Four files, ten insertions: the core declaration, both keep-sets, and a
submodule bump.
The submodule bump is load-bearing, not incidental. Without it this PR is
broken on its own: core names a skill the pinned skills commit does not
contain, and cue validate fails the resolver dry-run with SKILL_NOT_FOUND on
every core-inheriting profile — which is all 87. The first CI run on this branch
did exactly that. The bump targets a commit carrying both the new skill and the
smart-loader work the previous pin was already tracking, so nothing regresses on
the way through.
ALWAYS_KEEP vs ALWAYS_KEEP_SLUGS — both needed, different matchers. The
first is full-id (browser/ego-browser) and gates the per-project loadout; the
second is slug-suffix (ego-browser) and gates composite-merge budgeting. Adding
only one leaves the other path able to drop the skill. Slug-suffix matching is
inherently collision-prone, but there is no other */ego-browser in the tree.
LOW — this buys always-on context with a permanent token cost
The skill's frontmatter is ~745 chars, so roughly 190 tokens on every session,
in every project, forever. That is the deliberate trade (one deferred browser
task costs far more in MCP round trips), and it is small against core's budget —
but it is the kind of cost that only ever accumulates. Worth remembering that
ALWAYS_KEEP is a list where every future addition is charged the same way.
Verification
| Check | Result |
|---|---|
bun test — skill-subset, project-loadout, profile-merge |
Pass — 47/47 |
Behavioural — applyProjectLoadout, neutral cwd, zero signals |
browser/ego-browser classifies full; before the change the same call returned deferred |
CI — lint, configured, Profiles e2e (ubuntu + macos) |
Pass |
CI — test |
Fail, pre-existing: the failing set is byte-identical to main's latest CI run (1 failure each, zero new) |
CI — validate |
Fail, pre-existing: same E3 (missing reference): MCP "openaiDeveloperDocs" that #121 failed on and merged with. This job never runs on main (pull_request-only), so it has no green baseline to regress from. The ego-browser SKILL_NOT_FOUND this branch originally added is gone |
Gate satisfied: zero new failing checks relative to base.
coredeclaredbrowser/ego-browser, but the per-project loadout deferred it inevery project where no signal matched — and signals come from package.json deps
and framework detection, none of which say "browser". The declaration was real
and the skill still never loaded; it only appeared to work where a project
happened to carry its own
.claude/skillssymlink.Deferring it does not save a browser session. It sends the agent to MCP
round-trips or web fetch instead, which costs more than this skill's frontmatter.
So it joins the operational primitives in
ALWAYS_KEEP, and the matching slug setin
profile-mergeso a budgeted composite can't drop it either.Three files, nine lines: the
coredeclaration plus the two keep-sets.Verification
applyProjectLoadouton a neutral cwd with zero project signals, profilecoolify(inherits core):browser/ego-browserclassifies full. Same callbefore the change put it in deferred — which is what
~/.config/cue/loadouts.jsonrecorded for every project on this machine.bun testonskill-subset,project-loadout,profile-merge: 47 pass,0 fail.
Branched off current
main, no conflicts.