Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ Play stays predictable by making each layer own one job:
| **`SKILL.md`** | Teaches an agent how to enter the runtime and handle its next boundary. |
| **`play-machine`** | Owns search, inspection, approval, execution control, verification, saving, and fail-closed behavior. |
| **Structural hooks and journals** | Suggest Worker-confirmed matches, enforce direct routes, read bounded semantic Journey snapshots, and record typed recall events. |
| **Rote skills** | Own setup, tools, browsers, adapters, workspaces, authoring, and publication. |
| **Rote guidance** | `rote guidance <id>` owns setup, tools, browsers, adapters, workspaces, authoring, and publication. |
| **Rote CLI and registry** | Run exact Plays locally and distribute authorized Plays. |

The following sections are primarily for maintainers and integrators.
Expand All @@ -234,7 +234,7 @@ The following sections are primarily for maintainers and integrators.
Play is driven by one declarative machine,
[`references/controller/machine.yaml`](references/controller/machine.yaml) (`play.machine/v1`).
The typed runtime loads and validates the bundle once per invocation, executes eligible
deterministic actions until a model, human, specialist, or terminal boundary, and accepts only
deterministic actions until a model, human, guidance, or terminal boundary, and accepts only
events declared by [`actions.yaml`](references/controller/actions.yaml) and
[`prompts.yaml`](references/controller/prompts.yaml). It never jumps states from conversational
intuition. Initial state: `invoke`. Terminals: `receipt`, `completed`, `exited`, `blocked`.
Expand Down Expand Up @@ -307,7 +307,7 @@ stateDiagram-v2
exploration_one_off_present --> exited : visible completion

%% ── Save lifecycle (delegated to rote specialists) ──
crystallize --> save_prepare : rote-flow-crystallization candidate
crystallize --> save_prepare : play/crystallization candidate
crystallize --> completed : not reusable
save_prepare --> save_offer : namespaces resolved
save_offer --> author_release : Team / Community
Expand Down Expand Up @@ -457,10 +457,10 @@ There is deliberately **no Play-owned Explore execution lane**. Earlier versions
modality routing, adapter discovery, and effect approvals inside Play, re-implementing what the
Rote skills already own. Today, normal work exits quietly after an inadequate search. An explicit
`$play explore <outcome>` or `/play explore <outcome>` searches first. When no Play fits, it starts
a dedicated captured Rote workspace and yields a typed specialist instruction to the `rote`
orchestrator. Rote invokes `rote-task-routing`, then
`rote-adapter-create` for API adaptation, `rote-shell` for validated CLI/`rote proc` work, and
`rote-workspace` for adapter execution and cached evidence. Play resumes only with a verified
a dedicated captured Rote workspace and yields a typed guidance instruction to the `rote`
orchestrator. Rote runs `rote guidance gate/route`, then follows
`adapters/create` for API adaptation, `shell/essential` for validated CLI/`rote proc` work, and
`workspace/essential` for adapter execution and cached evidence. Play resumes only with a verified
result and capture-bound trajectory, then owns the save-worthiness and crystallization path.

The runtime enforces this boundary rather than relying on caller prose: continuation state is
Expand Down Expand Up @@ -492,7 +492,7 @@ The runtime provides typed cursors and events, context-schema validation, bundle
derived guards, mutation semantics, checkpointed `play.context/v1`, terminal enforcement, and
per-step timing. [`runtime_actions.py`](scripts/lib/play/runtime_actions.py) executes safe
deterministic commands without shell interpolation and loops until the next evaluator, prompt,
specialist, or terminal boundary.
guidance, or terminal boundary.

The automatic runner owns every deterministic action state. The harness sees only model judgments,
human prompts, exact Rote specialist handoffs, and terminal results. The complete context is
Expand Down Expand Up @@ -810,17 +810,18 @@ controller references, Python runtime, harness activation tools, and `justfile`
configure and verify explicit Play use. `scripts/bin/package-plugin --check` prevents those
installed files from drifting from this repository's source of truth.

The Rote skill provider is a prerequisite so Play can hand missing local installation to the
guided `rote-setup` specialist:
Play requires Rote 0.89.0 or newer. The Rote skill provider (`rote@rote-skills`) is a prerequisite;
Rote serves every instruction through `rote guidance <id>`, and missing local setup goes to
`rote guidance setup/essential`:

```bash
# Codex
codex plugin marketplace add modiqo/rote-skills
codex plugin add rote-onboard@rote-skills
codex plugin add rote@rote-skills

# Claude Code
claude plugin marketplace add modiqo/rote-skills
claude plugin install rote-onboard@rote-skills
claude plugin install rote@rote-skills
```

After Play is installed, the `play-machine` launcher is on `PATH`; harnesses invoke it directly
Expand All @@ -833,8 +834,10 @@ already active pinned environment, including the package index uv will download
authentication, and `rote play` capability; it also reports cross-harness coverage and
multi-select restoration targets. An empty `$play` or `/play` probes
the local binary and identity. If either
is missing, Play handles the exact gap. A missing binary invokes `rote-setup`, which asks before
downloaded installer code or optional onboarding. An installed but signed-out Rote shows only the
is missing, Play handles the exact gap. Without a `rote` binary the setup guidance cannot run, so
Play reports `setup_specialist_unavailable` and points the user at https://getrote.dev to install
Rote; it never improvises an installer. With Rote installed, `rote guidance setup/essential` owns
probes, the install choice, remote-code approval, and login. An installed but signed-out Rote shows only the
Google, GitHub, email, and **Not now** choices. Play runs the selected browser sign-in and verifies
`rote whoami`; it does not enter Rote's adapter setup menu.

Expand Down Expand Up @@ -899,8 +902,8 @@ just install
including `~/.agents/skills` — links this Play skill into each, and applies the activation metadata in
[`agents/openai.yaml`](agents/openai.yaml) (`allow_implicit_invocation: false`). Play and Rote stay
explicit-only until the user invokes Play. On Claude Code the profile never writes
`disable-model-invocation` into a Rote skill: that flag blocks every model-initiated call, including
the specialist hand-off an explicitly invoked Play makes through the Skill tool. Play's standby rule
`disable-model-invocation` into a Rote skill. Play's hand-offs do not go through the Skill tool:
an explicitly invoked Play runs `rote guidance <id>` in the shell and follows it. Play's standby rule
keeps Rote quiet outside a Play interaction instead. Play's
structured prompts map to Kimi's `askquestion` control
(`scripts/bin/play-question <prompt> --harness kimi`), and `just harness kimi` /
Expand Down Expand Up @@ -1094,7 +1097,7 @@ Explicit Explore always searches before creating. If an adequate Play exists it
**Inspect existing**. If none exists locally or in the authorized registry, the explicit command
starts a capture, binds a Rote workspace, and hands the unchanged outcome to Rote. For an API,
Rote searches installed adapters and the adapter catalog, then lets the user adapt a candidate;
for a user-supplied CLI, `rote-shell` verifies the executable with `rote deps check` and records
for a user-supplied CLI, `shell/essential` verifies the executable with `rote deps check` and records
discovery/use with `rote proc`. A later explicit
`$play settle <capture-handle> <summary>` can
re-enter the save path, and the save-worthiness judge examines the **bound trace, not the
Expand All @@ -1103,15 +1106,15 @@ and a stable output shape.
A worth-saving verdict leads to one offer:

- **Team** — release and publish to an authorized private organization, then offer colleague
invites through `rote-org`;
invites through `registry/org`;
- **Community** — release and publish under a selected public owner, verify associated adapter
credential contracts, then run the exact public URI once from an isolated directory;
- **Skip** — keep the result without publishing or indexing a Play.

Execution ownership stays with the rote skill suite end to end: crystallization with
`rote-flow-crystallization`, release with `rote-flow-authoring`, publication with `rote-registry`.
Play never re-implements those flows; it validates each specialist's typed receipt and blocks on
mismatch — a specialist cannot claim success in prose.
Execution ownership stays with Rote's guidance end to end: crystallization with
`play/crystallization`, release with `play/authoring`, publication with `registry/essential`.
Play never re-implements those flows; it validates each typed receipt and blocks on
mismatch — a guidance step cannot claim success in prose.

One save-time caveat Play discloses honestly: browser-derived (DRIVE) work has a crystallization
limit. Typed browser steps carry navigation, waits, clicks, typing, and canonical extract slices
Expand All @@ -1129,16 +1132,16 @@ and a redacted trace-learning summary showing explicit successes, errors, and un
closes with a personalized thank-you to the human domain expert. Organization membership,
invitations, and sharing use the organization/list surface rather than hidden local state.

Release and publication are deliberately separate specialist handoffs. `rote-flow-authoring` must
Release and publication are deliberately separate specialist handoffs. `play/authoring` must
stop after an explicitly unpublished local release. Play then captures the immutable birth object,
and only a fresh `rote-registry` handoff may publish that exact artifact while echoing the captured
and only a fresh `registry/essential` handoff may publish that exact artifact while echoing the captured
birth SHA. If a broad registry publication request publishes early, the machine emits
`publication_boundary_violated` and blocks instead of treating a registry summary as completion or
offering a retrospective certificate.

The same lifecycle accepts an explicit request to publish an already released local Play.
Qualification emits `play_publication_request` with the local reference, visibility, and optional
owner, bypassing saved-Play search and creator discovery. A read-only `rote-flow-authoring`
owner, bypassing saved-Play search and creator discovery. A read-only `play/authoring`
inspection must prove the exact release is unpublished and recover the original verified Rote
workspace; only then can Play capture birth and honor the explicit publication authorization. If
that provenance cannot be recovered, Play blocks instead of inventing a workspace or suggesting
Expand Down Expand Up @@ -1176,7 +1179,7 @@ it does not prove every consumer already has the required credentials.
A mismatch, missing credential, provenance failure, or unsuccessful run blocks Play-page links,
social copy, and congratulations. The gate does not silently pull or republish an adapter, change
`token_env`, authenticate, delete transaction backups, or retry. Remediation stays with the
appropriate Rote skill, after which the canonical gates run again. See the
appropriate Rote guidance, after which the canonical gates run again. See the
[GitHub token-env incident RCA](docs/rca/2026-08-06-github-token-env-var-confusion.md).

Open or verify how one of your Plays was born:
Expand Down
31 changes: 18 additions & 13 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ runtime runs its own `rote ls` and `rote trace --deps` checks; manually repeatin
not bind evidence to Play.

The command executes every eligible deterministic action and stops only at a model, human,
specialist, or terminal boundary, returning a short `continuation_id`. Keep that value opaque in
guidance, or terminal boundary, returning a short `continuation_id`. Keep that value opaque in
harness state — never inspect, print, or persist it yourself. The runtime stores context
owner-privately under `~/.rote-play/continuations` and expires it after 24 hours. Resume with the
same one-shot heredoc form:
Expand Down Expand Up @@ -290,10 +290,15 @@ run.
their behalf. Resume only with the event bound to the choice the user selected. The runtime
rejects any other event and names the declared ones; when that happens, show the projected
prompt again unchanged.
- `specialist`: invoke only `instruction.specialist` with `instruction.input` through the
harness's skill mechanism; resume with the one accepted typed receipt event. Interactive
specialists own their own user questions — ask those directly and continue inside the
specialist flow; return to the runtime only with a declared receipt event.
- `guidance`: run `rote guidance <instruction.guidance>` in the shell, follow it with
`instruction.input` within `command_policy`, then return the declared receipt event. Where a
receipt carries an executor, it is `{kind: guidance, id: <instruction.guidance>, digest: <the
data.result.digest field of rote guidance <id> --json>}`. Play owns the step boundary: Rote
documents end with `## Next` gates and gate branches that may lead on or answer the user; inside
a Play step these are informational. When the step's work is done, return a declared event to
Play; never follow a Rote gate past `command_policy`, and never answer the user from inside the
step. Interactive guidance (setup, authentication) asks its own user questions — ask those
directly and continue; return to the runtime only with a declared event.
- `terminal`: present the terminal outcome and stop. A `blocked` outcome arrives as a
presentation that names the step that stopped, the cause, and the next step. Relay that
Markdown verbatim. Never replace it with a generic phrase such as “couldn't continue due to
Expand Down Expand Up @@ -330,7 +335,7 @@ Authentication declared by a saved Play stays inside its approved `rote play run
shows `adapter.auth.ensure`, complete secure browser-capable provider sign-in inside that step and
continue the same run; never run `rote oauth` separately or synthesize an authentication receipt for
it. A missing static credential is the exception because the step can detect but cannot mint a
vendor secret: follow the projected `rote-adapter-config` boundary, resolve only the adapter
vendor secret: follow the projected `adapters/config` boundary, resolve only the adapter
catalog's first-party HTTPS token page, and tell the user to create the token there and run
`rote token set <ENV> --stdin` in their own terminal. Never request or receive the token in chat.
Only after the user confirms the out-of-band command and the named token is verified may Play retry
Expand All @@ -345,13 +350,13 @@ check. After verified sign-in, offer company setup once per identity on this dev
option uses the same Supabase email-code flow as the website. Enter email and codes only in the
local browser window; never collect them in chat.

Company setup is optional. Ask for the company name and handle, then use `rote-org` to create or
Company setup is optional. Ask for the company name and handle, then follow `rote guidance registry/org` to create or
verify the organization. Once ready, offer a developer invitation for shared Play creation and
publication, an explicit admin invitation for organization and member management, or Continue.
Never create an organization, invite anyone, or publish a Play from sign-in alone. Preserve the
original reference and parameters, then inspect the pending Play again before execution.

Do not invoke the general `rote-setup` wizard. Do not discuss adapters, ask the user to retry the
Do not run the general `rote guidance setup/essential` wizard. Do not discuss adapters, ask the user to retry the
Play, or start a new request. A failed login shows the same provider choice without running the
Play.

Expand Down Expand Up @@ -441,12 +446,12 @@ per sub-outcome, is a no-match. Never treat a result carrying `match_classificat
with a non-empty `uncovered_terms` as "nothing exists", and never treat an empty AND-of-terms
result for a query with surplus terms as proof of absence. Only a clean no-match lets the next
deterministic transition create the capture and Rote workspace before any work begins and yield
directly to the `rote` specialist without a second exploration prompt. Choosing to explore from a
directly to the `gate/route` guidance step without a second exploration prompt. Choosing to explore from a
partial offer scopes the capture to the uncovered sub-outcomes; covered sub-outcomes are handed to
the specialist as `creator.baselines` to run through `rote-flow-run`, never rebuilt by hand. That specialist must invoke
`rote-task-routing`; API adaptation belongs to `rote-adapter-create`, existing CLI discovery and
validation belong to `rote-shell` using `rote deps` and `rote proc`, and adapter execution belongs
to `rote-workspace`. Present the discovered routes, always allow another tool, wait for the user's
that step as `creator.baselines` to run through `rote guidance play/run`, never rebuilt by hand. That step must run
`rote guidance gate/route`; API adaptation follows `adapters/create`, existing CLI discovery and
validation follow `shell/essential` using `rote deps` and `rote proc`, and adapter execution follows
`workspace/essential`. Present the discovered routes, always allow another tool, wait for the user's
selection, verify that selection, and announce the first outcome-bearing step before execution.
Continue the original outcome through that returned workspace. Never invent a second search picker
or ask for the outcome again. Before novel outcome work starts, the runtime classifies it as
Expand Down
2 changes: 1 addition & 1 deletion docs/design/async-exploration-journey-graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ The detailed conversational inspection commands are not part of the first implem

### Phase 4 — crystallization input

- Pass the verified semantic snapshot to `rote-flow-crystallization` alongside authoritative raw
- Pass the verified semantic snapshot to `play/crystallization` alongside authoritative raw
evidence.
- Use phase membership as an authoring proposal, never as a dependency override.
- Verify that setup probes and abandoned routes are excluded from main candidate steps.
Expand Down
Loading