Contents

Native project instructions and skill discovery

Shared project instructions live in one AGENTS.md. Skills live once in .agents/skills/yoke/. These are separate native loading mechanisms: an instruction file is always-loaded project guidance; a SKILL.md supplies metadata at discovery and its body when invoked.

Harness family and supported surfaces Instructions Skills
Codex CLI, desktop, editor (engine >=0.161.0) Root and nested AGENTS.md Native .agents/skills; no .codex/skills copy
Cursor Agent CLI (>=2026.10.01), IDE (>=3.14) Root and nested AGENTS.md Native .agents/skills; no .cursor/skills copy
Claude Code CLI, desktop Code, editor Native AGENTS.md on embedded engine >=2.1.281, with the built-in plugin enabled Required .claude/skills/yoke symlink to ../../.agents/skills/yoke

The supported surface versions remain declared in each product harness manifest's session_control.surfaces. The manifest's cli.project_discovery declares the additional embedded-engine floor and native layout. Claude's desktop app version is not its embedded Code engine version. Cowork is not a project-Code surface and is not an installed project skill consumer.

Claude configuration

Claude's default claude-md-or-agents-md loads AGENTS only when no CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md exists in the working directory or any ancestor. Personal ~/.claude/CLAUDE.md and managed organization instructions do not suppress it. Refresh preserves project-specific Claude content, including ancestor files; it refuses a configuration that would silently suppress the shared rules.

When keeping such files, use /config to set Project instructions to claude-md-and-agents-md. This preserves their instructions and loads AGENTS once. Enable the built-in AGENTS plugin in /plugin, remove any claudeMdExcludes matching AGENTS, run claude update if the engine is below 2.1.281, and start a new session. Verify the canonical path in /memory. The first session after upgrading an older engine may still need a restart.

For file configuration, instructionFiles belongs in user settings, managed settings, or an explicit --settings file. Claude ignores that plugin option in project/local settings. Current engines use pluginConfigs.cc-plugin-agents-md@builtin.options.instructionFiles; the earlier plugin id agents-md@builtin is accepted by newer engines too. Refresh reads user and managed files; an explicit launch settings file must permit the same native loading. Bare/safe mode or strict plugin-only policy that disables project skills is outside this supported configuration.

Yoke does not install a CLAUDE import or duplicate doctrine as a fallback. An existing user-owned link/import is accepted; Claude deduplicates an AGENTS file it has already loaded. Ordinary prose saying “See AGENTS.md” is not an import and does not guarantee loading. A parent CLAUDE.md link to the main checkout’s AGENTS.md is accepted from that checkout’s Git worktree, wherever the worktree lives. An explicit @AGENTS.md import resolves relative to its instruction file; code examples do not count as imports.

Refresh and ownership

Bundle schema 3 requires a matching CLI. An older CLI refuses and names the public-installer upgrade. An older serving bundle refuses as installed_manifest_bundle_unavailable; ask the control-plane operator to serve a matching release, then retry refresh. Source previews, local/self-hosted servers and hosted servers render the same canonical tree and discovery contract; wheels carry the same authored inputs.

Refresh uses one canonical skill tree and Claude discovery link. An unexpected entry at .claude/skills/yoke refuses as skill_discovery_entry_conflict; preserve its contents outside that path and rerun refresh. Codex and Cursor discover the canonical tree directly.

Install and refresh report install_drift.missing, changed, and interrupted. Missing recorded files are restored. Changed files require the recorded digest, resolved or archived release bytes, interrupted-apply digest, or installer-history proof; real edits refuse as install_drift_local_edits before mutation. The local .yoke/install-pending.json record identifies an unfinished apply. Rerun yoke project refresh to complete it; preserve that record until recovery. Git metadata locally excludes the recovery record even with an older bundle. The record also stores exact planned intermediate settings and instruction bytes, so a dirty interrupted checkout can resume without admitting new edits. Bundle files and the final manifest use atomic replacement. Completion verifies every recorded whole-file digest and retains the recovery record through the installer-owned local commit. Publication proves current installer-owned paths.

Yoke source repo only: regenerate packaged release hashes from fetched annotated tags with yoke dev run -- python3 -m runtime.api.tools.released_install_hashes --source-checkout /absolute/claimed/checkout and commit the catalogue.

Native symlink support is required for the Claude skill entry. On Windows, enable Developer Mode or administrator symlink permission and ensure Git checks links out as links (core.symlinks=true). A filesystem without native links receives skill_discovery_link_unavailable with recovery; Yoke does not copy a second discoverable tree. Hooks, subagent adapters, and intra-skill references retain their separate owners and canonical relative paths.

Read installed capabilities

cat .yoke/harness/codex/manifest.json

Read .yoke/harness/<harness-dir>/manifest.json for the installed release. Directories are claude, codex, and cursor; claude-code uses claude. agent_wake names wake support and its evidence, session_control names message/launch routes, and supports names hook affordances. unverified means the capability has no proof; it does not authorize guessing. Implement shared behavior once behind its harness-neutral owner. Keep capability-specific branches thin, named and co-located; record an explicit designed deferral for a missing primitive, and teach each harness only the primitives it supports. The existing install bundle publishes renderer-owned release bytes and refresh manages their digests, restores missing files and resumes interrupted application. Do not edit managed manifests to change capabilities. If a manifest is missing, run yoke project refresh from this project. If its serving bundle predates schema 3, follow the operator recovery above. Local edits use the refresh refusal's recovery.

Hook diagnostics

Hook infrastructure failures never hold Stop, SessionStart or SessionEnd. They return allow with one short warning naming the failure and its recovery. Repair machine configuration or connectivity before resuming work. Tool and prompt hooks still refuse when scope or authority cannot be resolved; identical failures show their full diagnosis once per five minutes, then a short reference. Policy denials remain enforced.

The shared client boundary protects every supported harness and surface, including resident and in-process evaluation. stop_hook_active on Claude and Codex, or a positive Cursor loop_count, prevents another Stop hold. Without that native signal, at most three consecutive identical Stop blocks are allowed in five minutes; the next attempt allows Stop with hook_stop_block_limit. A changed reason or expired window starts a new count. Counters live in private machine-local hook-safety/counters.json, independent of machine config and server telemetry. Unavailable counters allow Stop with hook_stop_safety_unavailable; they never relax tool guards. Cursor's declared Stop contract still returns {} without a follow-up; its SessionEnd cannot continue the turn.

Human diagnostics inside Git and harness tools begin with “yoke (<hook>): ”, for example “yoke (pre-commit): ERROR: file-line-limit gate blocked this commit.” Follow the repair in that diagnostic. Successful checks and the identity-only lane-head recordings after commits, merges, rebases and checkouts stay quiet. Required orientation, instructions, continuations, handoffs and recovery still arrive through their normal owner. JSON replies, delivery markers and machine identifiers retain their wire form; the shared context composer budgets the combined delivery for each harness. Inspect hook configuration with yoke hook --help.

Verify native discovery

Startup orientation uses one client composer, harness JSON envelope and combined context budget. Codex delivers early on SessionStart when its startup payload names a transcript (every start source without a path is suppressed before relay and registration); Claude delivers on UserPromptSubmit, and Cursor on SessionStart. A later Codex or Claude prompt, or Cursor tool result, retries missing or unconfirmed orientation. A session's project scope is fixed by its first registration. Claude Code reads hooks installed mid-conversation and registers on the next prompt in the new project. Codex and Cursor do not load hooks installed mid-conversation, so a session open during the install never registers in the project. yoke doctor run --session in the project folder fails session-hook-registration: with SESSION_HOOK_UNOBSERVED when the session started without Yoke hooks, or with SESSION_HOOK_PROJECT_MISMATCH when machine hooks had already registered it with no project. Open a new session in the project folder; it registers on its first prompt. Only actual emitted valid context arms the existing delivered marker; registration success and composition do not. A denied or interrupted emission remains eligible for recovery. Successful emission stops repeat orientation while registration/backfill, model facts, first-prompt telemetry and independently owned resume notices still run.

Install advice and command pointers stay in the shared orientation; Codex no longer emits a separate command catalog on its first prompt. Registration failures retain their named reason and recovery in the same budgeted envelope. The delivered marker records the emitted UTF-8 body byte count and SHA-256; it proves hook emission, not that an agent read it. If marker writes fail, restore write access to the hook-markers directory or set YOKE_SCRATCH_ROOT to a writable path, then retry a context-bearing hook. HTTPS skips server lifecycle rendering; local lifecycle handlers share the client output path.

After fresh install and repeated refresh, inspect the native skills menu: each native Yoke entry should appear once. Select the installed yoke skill, which routes to onboarding; there is no separate Yoke Onboard picker entry. In Codex, search the skill picker for yoke and invoke $yoke onboard. In Cursor, invoke /yoke onboard. Claude Code discovers one /yoke router through its native link; invoke /yoke onboard. Inspect /config for Project instructions and /memory in a fresh supported session. Directory counts alone do not prove native discovery or instruction loading.

Official sources checked 2026-10-08:

Codex and Cursor Agent floors name the native releases verified for this layout; the installer probes detected CLIs before writing project guidance. An older engine or failed version probe appears in the install and preview report's harness_health section. Each supported CLI has its detected version, floor, status (ok, below_floor, probe_failed or absent), loading effect and next step. Operational warnings remain separate. Other supported harnesses can still use the installation. CLI versions never block installation; absent CLIs appear in health so installation can precede native harness setup. Install or upgrade a supported native CLI or embedded desktop engine, start a new session, and rerun project refresh. Desktop users verify their embedded engine separately; the outer app version proves no capability.

Harness setup and later installs

Run yoke doctor run --only harness-setup --fix to repair folder trust, Codex hook trust, unattended permissions, machine-wide hooks and the yoke-global skill together. Setup, project install/refresh, source launcher install and lane preparation call the same idempotent reconcile. The relay detects a newly present harness home and reconciles every registered checkout and its Git-registered lanes. It never creates an absent harness home; CLI presence alone is not installation. Lane hook trust is mirrored only from identical trusted checkout content. Malformed or unwritable files are preserved and named with recovery while other facets continue. Read without --fix to inspect without writing. The relay's harness-setup-reconcile.json records successful fingerprints and failed rows; failures retry after 15 minutes or immediately on another change. Doctor includes that durable failure only while its own inspection still finds a problem, so a relay pass that ran before an installer wrote project files cannot fail setup's install health. It also reports a Codex home without a CLI or desktop app, with instructions to remove an unintended home or open Codex.

Retired lane settings

Lane retirement removes path-owned state for that exact retired lane in Claude Code, Codex and Cursor, plus Codex hook trust for the lane's own hooks file. Shared machine hooks, approval posture, live lanes and settings outside managed roots stay in place. Each format uses the same ownership selection and publishes config changes atomically.

To clean settings already left behind by deleted lanes:

yoke harness lane-config sweep --dry-run
yoke harness lane-config sweep

The sweep uses registered checkout lane roots, including deploy worktrees. Use repeatable --managed-root PATH for additional verified lane roots, including installed checkouts no longer mapped on this machine, or for roots reserved for QA fixtures Yoke creates. Ownership follows the path, with no ledger or new record store. Before changing a config it writes an exact timestamped CONFIG.yoke-backup-TIMESTAMP beside it and reports before/after bytes. Paths outside those roots stay untouched even when deleted. A malformed config, failed backup or write refuses with harness_lane_config_cleanup_failed and the recovery command. Repair the named file or permissions and rerun; successful files need no repeat work. Project and machine uninstall keep their existing ownership boundaries.

Outside a project: yoke-global

Yoke must run before any project exists, so setup always configures every installed harness for unattended commands. It replaces prompting permission modes and preserves unrelated settings. HC-harness-unattended-posture requires those unattended modes; a command allow entry does not satisfy it. Repair with yoke doctor run --only harness-setup --fix.

Full Yoke skills stay per-project. The one user-level skill is yoke-global, for a session opened outside every Yoke project: it checks the machine, picks or adds the project and names the folder where a new session does the work. Its startup orientation names the skill as the next action. Setup places it once in ~/.agents/skills/yoke-global, which Codex and Cursor read natively, and links ~/.claude/skills/yoke-global to it for Claude Code; the harness setup reconcile above keeps it current. A harness whose home folder is absent is skipped. Each manifest's global_skill field states its placement. yoke uninstall removes both paths, and any parent folder setup created for them once it is empty. An existing path Yoke did not create refuses as global_skill_path_not_owned; move it aside, then run yoke doctor run --only harness-setup --fix, which works outside a project.

Guard scope

Register a managed checkout with yoke project register <checkout> --project-id <id>. Its subdirectories and Git worktrees share that project; an unrelated Git repository nested inside it does not. A machine connection or a folder named .yoke alone does not make a checkout managed.

Outside managed projects, hooks apply machine safety rules: privacy-database protection, literal search quoting and unmatched path globs. Setup writes these machine-wide hooks into each existing harness home's user config (the manifest's machine_hooks names the file and events); inside a managed project they step aside so the project's own hooks run once per event. Project rules (such as main-commit and destructive-Git checks) apply inside managed projects. Lane rules check the real lane and claim authority there, including on main. Unmapped HTTPS clients finish machine checks locally without project registration. All harnesses use the same applicability declarations.

yoke hook evaluate PreToolUse --dry-run shows the registered chain inventory; it does not execute guards or prove a workspace is registered. A hook_guard_scope_missing diagnostic names the undeclared guard; report it with yoke feedback --to yoke --category failed --evidence '<diagnostic>'. A hook_scope_unavailable diagnostic names the mapping or scope repair needed before retrying. Required project messages and lifecycle delivery retain their own handlers; guard scope does not redefine session lifecycle.

Native discovery · Yoke