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 AGENTS discovery
- Codex skill discovery
- Cursor rules
- Cursor skill directories
- Claude native AGENTS and configuration
- Claude skill directories
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.