grok-bot onboarding: a docs pointer on every CLI path + the grok-bot-operate skill - #982
Merged
Merged
Conversation
added 4 commits
September 8, 2026 08:25
…r first-run Measured on ec95eb2: the whole binary carried exactly one route to the docs, the MCP initialize.instructions text in mcp.rs (mcp.rs:31, tests at :701/:714). A buyer that registers `maxplayer mcp` was told where the guides are; nobody else ever was — not `maxplayer --help`, not `maxplayer doctor`, not a seller configuring a new seat — and mcp.rs:47 records that a client may discard `instructions`. A seller-only box never touches MCP, so it had no route at all. - New `crates/maxplayer/src/skill.rs`: `SKILL_URL`, `SKILL_INDEX_URL`, the shared `docs_pointer_line()`, and `maxplayer skill`, which prints the orientation URL and the machine-readable index to stdout. Pure: no home, key, wallet or network. - The same one-line pointer on the three paths that carried none: the top-level usage (stdout on --help, stderr on a wrong invocation), the doctor report preamble and `doctor --help`, and the seller first-run path after `wrote [seller]` (new seat only; relaunches stay quiet) plus `seller --help`. - mcp.rs INSTRUCTION_GUIDES now formats from the shared constant instead of carrying a second copy of the URL. Handshake text unchanged; the exact-text tests still pass. - Tests assert against the shared constant, never a hand-copied URL: skill::tests (4), cli::tests::help_and_skill_carry_the_docs_pointer, doctor::tests::doctor_usage_and_report_preamble_carry_the_docs_pointer, sell::tests::first_run_writes_seller_and_points_at_the_docs_once, and `skill --help` joins the MakePrisms#570 every-subcommand help roll-call.
Addendum 1, Part A3. Field evidence from a real Grok Bot box (2026-09-08): the handshake `instructions` WERE delivered — the agent could quote the guides line back later — and were still skimmed past. It summarised registration as "connected + 4 tools", went straight to hiring, and reached skill.md only under debugging pressure after it had started spending. A one-shot preamble is read like a banner; a tool description is read like an instruction, in the turn the agent decides to call that tool. - `with_guides()` appends the ONE shared guides sentence (built from `crate::skill::SKILL_URL`, the same text the handshake prints) as the final sentence of exactly two descriptions: `post_job`, the first tool a new buyer calls and the one that spends money, and `collect`, the tool reached for when something has gone wrong. Existing text is neither rewritten nor reflowed. - `get_job` and `award_claim` are deliberately left alone — two carriers are a pointer, four are noise — and the test asserts them clean. - Test `post_job_and_collect_descriptions_end_with_the_guides_pointer`: both carriers END with the shared sentence verbatim, carry the URL exactly once, and keep their original closing sentence intact; the other two tools do not carry the URL. No hand-copied URL anywhere.
Part B of the grok-bot onboarding brief. A Grok Bot box is an OPERATOR of the
marketplace, not a seller harness — the presets are exactly claude, cursor and
codex — and the page says so in its first paragraph. It opens on the mistake a
real box made on 2026-09-08: the MCP handshake DID deliver the guides pointer,
once, at connect; the agent read "connected · 4 tools" as setup being finished
and went straight to hiring. Step 1 is therefore "read this page before your
first post_job", stated as a step with that reason. The page does not claim the
client drops `instructions` — it does not.
Registered in all four surfaces, or it ships unreachable:
- the artifact, web/app/.well-known/skills/grok-bot-operate/skill.md;
- web/app/.well-known/skills/index.json ({name, description, path}) — the
build derives the RFC v0.2.0 discovery index and every sha256 digest from it;
- web/app/.well-known/skills/default/skill.md (which IS /skill.md, the URL the
handshake points at) now links [grok-bot-operate](…) — the top-down route;
- web/app/public/llms.txt under "Agent skills".
Content: what the box is (one persistent Linux VM per account, shared by every
bot, no Docker, no systemd) and why that changes the instructions; the buyer
path (tarball install verified against SHA256SUMS because the approval gate
blocks `curl | sh`, wallet setup AND mint-complete, `maxplayer mcp` with an
absolute binary path and explicit MAXPLAYER_HOME, tools on the next turn,
post_job → get_job → collect, posting is the spend decision); the seller path
(cursor-agent pinned to a grok model as the `cursor` preset, `[sandbox]
mode = "launcher"` over bubblewrap, Nix started by hand); the four footguns
with the fix that worked; one operator-written ~/AGENTS.md carrying the two
URLs. Every command, flag, path and config key was checked against ec95eb2;
field-note claims that could not be confirmed against the repo were dropped
(listed in the PR body). No secrets, tokens, auth-file contents, invoice or
quote ids.
Verified in this turn (web/app): `npm run build` OK, `npm test` 92 pass /
0 fail, including "the homepage skill links every companion skill the index
publishes" — the roll-call test that is the reachability proof.
|
Someone is attempting to deploy a commit to the MakePrisms Team on Vercel. A member of the Team first needs to authorize it. |
…octor's probe can run Addendum 2 Fix 2 (advisor round 1 F2). The bubblewrap sample bound /usr, /lib, /lib64, /bin, two /etc paths, the cursor-agent tree, .config/cursor and seller-jobs, but not ~/.local/bin/maxplayer, where step 1 installs the binary. run_under_launcher in sandbox_probe.rs executes current_exe() inside the launcher, so under the sample `maxplayer doctor` fails containment with ENOENT while the page tells the reader it must PASS. One read-only bind of the binary at its own absolute path, next to the cursor-agent binds, plus a paragraph naming why. $MAXPLAYER_HOME stays unbound, the seller-jobs bind stays narrow, no whole-home bind, no --unsafe-no-sandbox. Docs only; no Rust touched.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Base:
ec95eb2e995d357b5382e46d0efb3025f7d803a0(upstream/main, 2026-09-08 11:49 +0200). Branchfeat/grok-bot-onboarding, 5 commits, 0 merges. Governing brief + Addendum 1 + erratum + item-4 ruling + Addendum 2: forgebriefs/grok-bot-onboarding-*-20260908T1{515,521,525,752,813}Z.md.Why
A Grok Bot box is an operator, not a harness (
BUILTIN_PRESETS = ["claude", "cursor", "codex"]). On the base commit the whole binary carried exactly one pointer to the docs, and it sat in the MCPinitialize.instructionspreamble. Measured on a real box (2026-09-08): the string was delivered, the bot could quote it back, and it still treated "connected + 4 tools" as setup being finished and went straight topost_job. A seller never touches MCP, so it had no route to the docs at all.What changed
Code (Part A + Addendum 1 Part A3)
crates/maxplayer/src/skill.rs(new):SKILL_URLandSKILL_INDEX_URLconstants,docs_pointer_line(), andrender()/run()for a newmaxplayer skillsubcommand that prints the orientation URL and the machine-readable index to stdout. No wallet, no key, no network. Unit-tested against the constants, not a hand-copied string.cli.rs:maxplayer skillregistered;maxplayer --help(and the usage text on stderr for an unknown command) carriesdocs_pointer_line().doctor.rs:doctor --helpand the doctor run output carry the pointer.sell.rs: seller first-run (the turn that writes[seller]) prints the pointer once; a steady-state relaunch does not repeat it;seller --helpcarries it.mcp.rs:INSTRUCTION_GUIDESis now composed fromSKILL_URL(instruction_guides()), andwith_guides()appends the same sentence to the tool descriptions ofpost_jobandcollectonly.get_jobandawardare deliberately left alone per Addendum 1 item 3; I do not think a third carrier is needed.main.rs:mod skill;.Docs (Part B) — the skill in all four registries
web/app/.well-known/skills/grok-bot-operate/skill.md— the artifact. Opens on "Grok Bot is an operator, not a harness" with the preset list. Step 1 is read this page before your firstpost_job, with the observed reason: the MCP handshake does deliver the link, once, at connect, and it is easy to skim past. The page does not claim the client dropsinstructions. Covers: what a Grok Bot box is (one persistent shared Linux VM, no Docker, no systemd), buyer path (wallet setupandmint-complete,maxplayer mcpwith an absolute binary path and explicitMAXPLAYER_HOME,post_job → get_job → collect, posting is the spend decision and the daemon auto-awards), seller path (cursor-agentpinned to a grok model,[sandbox] mode = "launcher"over bubblewrap, Nix started by hand), the four footguns with the fix that worked, and the~/AGENTS.mdoperator step. No secrets, no invoice/quote ids.web/app/.well-known/skills/index.json—{name, description, path}entrymaxplayer-grok-bot-operate(drives the discovery index + sha256 digests).web/app/.well-known/skills/default/skill.md— the homepage skill (which is/skill.md, the handshake URL) now links[grok-bot-operate](/.well-known/skills/grok-bot-operate/skill.md); "five companion skills" → "six".web/app/public/llms.txt— entry under "Agent skills".Acceptance gates (run on head
6c1c5ab; re-run unchanged on889f149, which touches no file undercrates/)Part A gate — brief:
git grep -n 'maxplayer.ai/skill.md' -- crates/returns hits in the help, doctor and seller paths, not onlymcp.rsRead honestly: the literal URL has exactly one non-test hit,
skill.rs:27. The other five are insidemod tests(cli.rs tests start at 523, doctor.rs at 2551, sell.rs at 801, mcp.rs at 557). That is the brief's item 3 working as intended: one shared constant, so the literal cannot drift. The help, doctor and seller paths therefore show up under the symbol grep, not the literal one:Addendum 1 Part A3 gate, verbatim
Status against it: the constant's definition ✔ and the tests ✔ appear in the literal grep above. The
post_job/collectcomposing site (with_guides→instruction_guides→SKILL_URL, mcp.rs:134–154) and the CLI surfaces appear in the symbol grep, because they reference the constant rather than repeat the literal. The "strictly greater than one non-test literal hit" clause is not met and cannot be met without adding a second copy of the URL, which the brief's item 3 forbids and the web build already refuses for the same reason. Baseec95eb2had one non-test literal hit (mcp.rs:31,INSTRUCTION_GUIDES); this head has one (skill.rs:27,SKILL_URL). Flagging this for the ordering seat rather than resolving it by duplicating the string.Ruled: the ordering seat struck the count clause on 2026-09-08 17:52Z (
briefs/grok-bot-onboarding-addendum1-RULING-item4-20260908T1752Z.md); item 4 now requires exactly one non-test literal hit (the constant) plus the symbol grep showing thepost_job/collectsites and each Part A CLI surface, both verbatim. This head meets the gate as ruled; no code change was ordered.Part B proof — run this turn in
web/appincluding
test/build.test.mjs"the homepage skill links every companion skill the index publishes" — the roll-call that derives its expectation fromindex.jsonand fails until the homepage links the new skill.Rust:
cargo test -p maxplayer --bin maxplayer -- skill:: cli::tests doctor::tests sell::tests mcp::tests→ 146 passed, 0 failed (this turn).Addendum 2 — advisor round 1 DENY fixes, head
889f149(append-only on6c1c5ab; no rebase, no force-push)Fix 1 (F1, body only): the symbol grep above is now the unabridged 28-line output, both long
with_guides(description lines (mcp.rs:228 and :316) complete to their closing"),; the truncation note is gone; the item-4 status cites the 17:52Z ruling.Fix 1 gate, run on the live body 2026-09-08 ~18:55Z, before this block was added (the two commands quoted here contain the pattern themselves, so a re-count after this edit includes them):
Fix 2 (F2, docs only,
889f149): the[sandbox]launcher sample ingrok-bot-operate/skill.mdbound the agent's paths but not~/.local/bin/maxplayer, where step 1 installs the binary.run_under_launcher(crates/maxplayer/src/sandbox_probe.rs) executescurrent_exe()inside the launcher, so under that samplemaxplayer doctorfails containment with ENOENT while the page says it must PASS. One--ro-bindof the binary at its own absolute path now sits next to the cursor-agent binds, with a paragraph after the sample naming why.$MAXPLAYER_HOMEstays unbound, theseller-jobsbind stays narrow, no whole-home bind, no--unsafe-no-sandbox. The page has one launcher sample (8--ro-bindlines, all in that block).Fix 2 gates, run on
889f149:Rust is untouched by
889f149, so no cargo run was required for it.CI on
889f149: run34262534726failed one job, "Test the full shipped feature combo (acp + wallet)", on one test,seller_node::run::tests::a_losing_open_pool_claimant_releases_its_slot_when_it_sees_the_award, panic atcrates/maxplayer-core/src/seller_node/run.rs:11878. This PR touches no file undercrates/maxplayer-core/, and889f149changed onlyweb/app/.well-known/skills/grok-bot-operate/skill.md(+8/−0); the identical Rust tree at6c1c5abpassed that same job in run34259482953. The failure is not attributable to this PR. The other six code checks are green; the Vercel "Authorization required" check is the fork-branch deploy gate and clears at merge. Not re-run and the test not touched: a human decides whether to re-run or merge over it.Field-note claims dropped for lack of confirmation against
ec95eb2Not in the page because I could not verify them in the code or from a source I could check: the Determinate nix-installer flags (
--init none,determinate-nixd daemon &);NO_OPEN_BROWSER=1;cursor-agent status; the model idcursor-grok-4.6-high; thecontribution_enabled/slots = 3/[profile]config sample; writable.cursor/.cachebinds and themkdir .cursor/projectssymptom; the exact--modelpin oncursor-agent(kept as a<grok model id>placeholder); theharness: "codex"Wally anecdote; the~/.local/bin/agentsymlink.Out of scope — named, not touched
INSTRUCTION_NIX_MISSING(mcp.rs) still tells the operator tocurl … | sh, which a Grok Bot box's approval gate blocks. Needs a second, non-piped route. Separate change.npm/, and PR feat(plugin): ship the buyer playbook as a Claude Code plugin #938 (feat/buyer-plugin-skill).Formatting note
cargo fmt --checkis dirty onec95eb2in 93 files, including cli.rs, doctor.rs, sell.rs and mcp.rs before this branch touched them. This PR does not reformat them. The only fmt change here is6c1c5ab, which reflows theassert!lines this branch itself added so the branch introduces no new drift (per-file rustfmt hunk count at head equals the count at base for every touched file;skill.rsis clean).