{"skill":"---\nname: orient\ndescription: Use when planning, tracking, or documenting work in Orient — creating or scheduling tasks, assigning people, writing documents, drawing architecture diagrams, filing work, or reporting progress. Also when the user mentions Orient, their plan, areas, maps, or nodes.\n---\n\n# Working in Orient\n\nOrient is a mind-map project management workspace: work lives as nodes on shared maps, every node carries state, and progress rolls up the tree. Your credential is the `ORIENT_API_KEY` environment variable — never print it; off production also set `ORIENT_API_URL`.\n\n## How to plan here\n\nOrient encodes a planning method — follow it, and explain the plan in these terms when your operator asks:\n\n- Titles are labels of 1–4 words, never sentences, and never numbered — no `1 - ` or `2 · ` prefixes; sibling order IS the sequence, and a dependency edge says what must finish first. Everything longer belongs in notes. The server answers a title of five or more words with a warning, and refuses an agent's title past 8 words or 60 characters: keep the label short and put the sentence in the notes (`orient node add \"\u003clabel\u003e\" --area \u003careaId\u003e --notes \"\u003ctext\u003e\"`).\n- A task is one concrete, doable action whose completion can be explicitly declared done and verified. A bucket of work is not work: if a node reads like a workstream, define the actual tasks beneath it — you cannot do a branch, you can only do tasks, and a plan left as high-level branches cannot be tracked.\n- Effort is `durationMinutes`: the working time of whoever does the task, at their speed. Grade each task by its assignee — an agent's task at agent speed, a person's task at a person's speed — and never grade an agent's task by how long a person would take, nor a person's by how fast an agent would do it. A task a person and an agent share is two tasks: split it, one for each. Set it with `orient task schedule \u003ctaskId\u003e --area \u003careaId\u003e --duration \u003cminutes\u003e`.\n- Effort must be gradeable, and the band follows the doer. A person's task is gradeable from 15 minutes up to a few hours; 12 hours is the rare ceiling. An agent's task is gradeable from a minute or two up to about an hour; two hours is the rare ceiling. If you cannot grade a task inside its doer's band, it is too big — split it into child tasks until every leaf is gradeable. A task shorter than its band is graded at what it takes, but the floor is not a target: a leaf is never smaller than something that can be declared done and verified on its own. The band is the method, not a refusal: the server accepts any whole number of minutes up to a year.\n- Effort counts working time only. Waiting is not effort: when the plan tracks a review, it is the reviewer's task, graded at the reviewer's speed, and anything else the work waits for is a dependency edge, or a block with its reason when the work cannot proceed now, not minutes on the task; a date known ahead belongs in the milestone's window. When a task changes hands between a person and an agent, grade it again. Until you have measured, start an agent's grades here: a page of text or a small change is minutes, a change with its checks is tens of minutes. Then grade from what you have measured: when a task of yours is done, compare the time it took with its grade and correct the open tasks like it.\n- Tasks on an area carry no dates. When work must land by a date, the date lives on a project's ladder — the project, each of its phases and each milestone carry a start→due window (the delivery chapter below). Never write a date from your host clock: resolve it first — `orient task resolve today` (or `POST /api/schedule/resolve`) answers the account's day in their time zone.\n- Every task carries at least one assignee. Unowned work is not planned work.\n- Effort and doing live only on terminal tasks — the leaves. A branch is not worked by anyone: it encompasses its children, and its progress and effort are computed from them. There is no separate subtask concept — structure is nesting, and a task under a task is just the plan getting more precise.\n- Not knowing how to approach something IS the signal to split it further.\n- Group one coherent piece of work as a branch, then split it into child tasks until every leaf is gradeable and its done state is verifiable. Attach the documents that carry its intent — the why, the constraints, what done looks like — to the branch and the leaves they cover (`orient doc create \u003cnodeId\u003e --title \"\u003ctitle\u003e\"` / `POST /api/nodes/{id}/documents {title}`), so the intent travels with the work.\n- Notes carry the context: one on-point paragraph in the plan's own terms — terse and complete, no filler.\n\n## When the work is a delivery — projects, phases, milestones, components\n\nRead this chapter when your operator runs a delivery here: a product, a release, a programme with dated milestones. On a personal or everyday area the method above is the whole of it — do not mint projects or components your operator did not ask for.\n\n- Delivery lives in standalone projects, each its own map: mint one from an area you hold with `orient project create \u003careaId\u003e \"\u003cname\u003e\"` (`POST /api/maps/{areaId}/projects` `{name}`) — your operator owns it and your key gets admin — and it rides `orient project list` / `GET /api/maps` with kind `project`. On a project map the root holds phases (a new root child births as a phase) and a phase groups milestones; milestones do not nest, and a phase is the only grouping above them. Never add children to a milestone on the project map: attach area work to it instead — a bare child there births a project-side component that no work can ever ride, and components are marked on the area map. The project root, each phase and each MILESTONE carries the window (a start and a due date) — the due is the commitment — and a milestone's progress is computed from the attached work, never written. `orient project show \u003cprojectId\u003e` renders the whole ladder; `orient project milestones \u003cprojectId\u003e` lists the windows. When the plan changes and a project you minted is no longer wanted, detach its work and park it with `orient project archive \u003cprojectId\u003e` (`PATCH /api/maps/{projectId}` `{\"archived\": true}`): it leaves the shelf and turns read-only — it refuses attach, moves and edits, while detach still lets work leave — and `orient project unarchive \u003cprojectId\u003e` brings it back. You may archive only a project you minted and still administer, and only while no work is attached to its milestones — the refusal says so; your operator can archive any project.\n- The work itself stays on the area maps and ATTACHES to milestones: `orient project attach \u003cnodeId\u003e --project \u003cprojectId\u003e --milestone \u003cmilestoneId\u003e --area \u003careaId\u003e` (`POST /api/nodes/{id}/milestone-binding` `{projectMapId, milestoneId}`) attaches an area node AND the branch beneath it — descendants ride along and new area-side children keep riding, though a nested area inside the branch does not ride, while a descendant's own binding outranks the inherited ride (one milestone per project — re-window with `orient project move \u003cnodeId\u003e --project \u003cprojectId\u003e --to \u003cmilestoneId\u003e`, not a second attach, which is refused until you detach; a node may attach to several projects); `orient project detach \u003cnodeId\u003e --project \u003cprojectId\u003e --area \u003careaId\u003e` (`DELETE` with `{projectMapId}`) releases the branch. The project view composes attached work read-time — attached rows carry their `areaMapId` and group under the nearest COMPONENT ancestor from their area; work with no component ancestor rides under a synthetic `No component` holder: it counts toward the milestone's progress like a component (its tasks count as work and it lists as unrun until done), and the web app offers no edits on it while the API and CLI still accept them — give it a component in its area (`orient node move \u003cnodeId\u003e --parent \u003ccomponentId\u003e --area \u003careaId\u003e`, or `orient project move \u003cnodeId\u003e --project \u003cprojectId\u003e --to \u003ccomponentId\u003e`). Attaching a reference node turns it into a task (its notes stay), so attach work, or the branch above a note. A component drawn under a second milestone appears there as an echo row (`echoOf`) — act on the real component id. Attach refuses a component (mark the work inside it), the area root, a node of a project map, a linked area, work in another workspace and a milestone of another project, each in its own words. When the project view must display a branch's hierarchy, bind the branches as well as the leaves — a descendant's own milestone binding stays explicit and outranks the inherited ride.\n- Size a window from the work attached to it and from who does it: add up the efforts, each at its doer's speed, then add the waits that are real — the time until a person can take their turn, a date someone outside fixed. Work an agent runs that adds up to a few hours fits one day, so the start and the due may be the same day, and a delivery that is all an agent's can be due the day it starts; a person's work takes the days that person has for it: use what your operator told you, and where they have not said, allow one day for each hand-off to a person and say in the milestone's notes that the day is assumed. Unless your operator gave the date, a window starts the day its first task can start and is due the day its last task can be done, so windows may overlap, and a milestone is never due before the milestones its attached work depends on. Never pad a window to the length a team of people would need. A date your operator gave is the commitment: keep it, and say so when the work will be ready sooner.\n- A component is a deployable or delivery boundary — an app, a service, the infrastructure, an environment, or an enduring product module that ships as one unit under one owner — and nothing else.\n- A feature, a capability or an experience that runs across several components is not a component, however large or lasting. The classic mistake is Voice beside Desktop app and Mobile app: the apps are components; Voice is a capability both of them ship. Its work goes inside each app — a Voice branch under Desktop app and another under Mobile app — and when Voice needs a plan of its own, it gets a milestone on the project (`Voice beta`, say) that both branches attach to. Never mark it `kind: component`.\n- A component is independently deployable or ships as one unit, and it is a stable, named part of the product or system that the delivery returns to across many releases. A component is not a phase, a sprint, a milestone, a temporary work bucket, an individual task, or a one-off feature request. Two deployable apps are two components; a command-line tool and the MCP server built from it are one component, not two. If a capability has a part that deploys on its own — a speech service behind Voice — that service is a component under its own name; the capability still is not. Keep a capability's branches inside components: a branch outside every component rides under `No component` on the project and counts toward its milestone's progress.\n- Keep a component's identity and history on the area map across projects: finishing or archiving a project does not delete or recreate its components — inspect the area first and reuse the existing component before minting another. The general examples your operator may recognise: a marketing website, an authentication service, the infrastructure, a mobile application.\n- Components are area nodes: `PATCH /api/nodes/{id}` `{\"kind\": \"component\"}` marks a branch (or the area root itself) as one; the same title may exist in several areas as distinct components; each carries owners — `orient project own \u003ccomponentId\u003e \u003caccountId\u003e --area \u003careaId\u003e` writes the list (name every owner, one id after another), `orient project components \u003cmapId\u003e` reads it. On the project view, move attached work between milestones or onto a same-area component with `orient project move \u003cnodeId\u003e --project \u003cprojectId\u003e --to \u003ctargetId\u003e` (`POST /api/nodes/{id}/plan-move` `{projectMapId, targetId}`, where the target is a milestone or a component) — moving a component re-attaches every task riding it, and dropping a task on a component also reparents it inside its area. Reference nodes and routines are refused on a project map, and planning kinds other than `component` are refused on the area map — the area map stays the description. Kinds change only within their level: the project root keeps its kind (an area root may become a component), and branches never move between an area and a project.\n\nStructure a delivery in this order, and the map stays honest:\n\n1. Describe the work on the AREA map first: mark the lasting parts as components (`kind: component`) and give each an owner (`orient project own \u003ccomponentId\u003e \u003caccountId\u003e --area \u003careaId\u003e` — your operator's account id, or your own agent id when you run it; `orient profile show` gives your own id and `orient workspace people \u003cworkspaceId\u003e` your operator's), then define gradeable tasks beneath them.\n2. Mint the project (`orient project create \u003careaId\u003e \"\u003cname\u003e\"`) and lay its ladder — phases for the delivery's chapters (`orient node add \"\u003ctitle\u003e\" --area \u003cprojectId\u003e --kind phase`), milestones inside each phase with real start→due windows sized from the attached work's efforts (`orient node add \"\u003ctitle\u003e\" --area \u003cprojectId\u003e --parent \u003cphaseId\u003e --kind milestone`, then `orient task schedule \u003cmilestoneId\u003e --area \u003cprojectId\u003e --start \u003cYYYY-MM-DD\u003e --due \u003cYYYY-MM-DD\u003e`).\n3. Attach the area work to milestones (`orient project attach \u003cnodeId\u003e --project \u003cprojectId\u003e --milestone \u003cmilestoneId\u003e --area \u003careaId\u003e`) — attach the branch root and the branches whose hierarchy the project view must display, not every leaf; the branch rides as one.\n4. Track by reading, never by writing roll-ups: `orient project show \u003cprojectId\u003e` answers where the delivery is because task completions roll up through milestones — a branch's progress is the floor of the mean of its contributing children, and a leaf contributes its own completion when it is a task — so replan by moving work (`orient project move \u003cnodeId\u003e --project \u003cprojectId\u003e --to \u003cmilestoneId\u003e`) or re-windowing milestones, not by editing progress. Roll-ups are computed for the reader: a branch you cannot see is not in your numbers, so you and your operator can read different progress on one node. A `completion` written on a task that has child tasks is accepted, but the rolled percentage ignores it (done counts still include it) — read `rolledCompletion` on anything with children.\n5. Deliver in bounded increments: when a piece passes review, release it the way your operator's release policy says, check that the release actually landed, and update the map at once — do not wait for unrelated roadmap work.\n\n## The orientation loop\n\nThe map is your memory between turns — work the loop and you never start amnesiac, and your operator never has to re-explain the context:\n\n- ORIENT: run `orient orient` (`POST /api/orient`) before your first write of a turn, after you finish a task, when you switch area, and whenever your operator says orient. It answers where you are (your working marks with the ancestor chain and its notes — ancestors' notes carry the intent and constraints your task inherits), what is yours (open assignments and what they wait on), what moved on your branch since you last oriented, and who else is working nearby. On a project you hold with read and write, its `project` block names the milestones overdue and due within a week against your operator's today (`today`, `timeZone`) and the open tasks no registered run is on (`unrun`, first ten, `unrunTotal`); a person's working mark is not a run, so read the task's `working` list before taking one. Reading it stamps your cursor, so the next answer is a delta. On Claude Code, `orient skill hook` installs a prompt hook that runs it for you every turn.\n- READ A LINK: people hand you work as an Orient node link — `\u003cappHost\u003e/#/map/\u003careaId\u003e/node/\u003cnodeId\u003e`. Pass it as it is to any command that takes a node id: `orient node show '\u003clink\u003e'` prints the node's title, notes and state, the path from the root and the children, with read access alone, and an area link works wherever an area is taken. Over MCP, call node_show with the link as its id. Fetching the link over HTTP gets only instructions, never the node.\n- PLAN IN THE OPEN: before executing, externalize your plan as child tasks of your assignment — the plan on the map is your working memory, and your operator steers by editing it.\n- REGISTER YOUR RUN: one enrollment can run many concurrent executions — a pane, a session, a worker on another machine — and without registration they collapse into one indistinguishable worker. Start a turn with `orient execution start --label \"\u003ca label a collaborator can read\u003e\" --executor \u003cmodel\u003e` (`POST /api/executions`), which answers your own execution id and session epoch and keeps its proof privately on this machine; never print that proof, never put it on the map, and never put a hostname, a local path or a secret in the label. Keep the run visible with `orient execution beat --node \u003cleafId\u003e --area \u003careaId\u003e` (`POST /api/executions/beat`) while you work: server time rules the lease, and once it lapses you read as stale rather than working. After a crash or a long pause use `orient execution beat --reconnect`, which takes a fresh session epoch; a resumed process carrying the old epoch is refused so it cannot overwrite the session that replaced it. Close explicitly with `orient execution stop` at the end of the run, and read `orient execution list` to see every execution under the enrollment. Capabilities and labels describe a worker; they never widen what it may read or write, and a proof alone can do nothing without the enrollment credential.\n- CLAIM: plainly mark the actual leaf before starting work — `orient task start \u003cleafId\u003e --area \u003careaId\u003e` (`POST /api/nodes/{id}/working`); release it with `orient task stop \u003cleafId\u003e --area \u003careaId\u003e` at hand-off (`DELETE /api/nodes/{id}/working`). Read the nearby marks first and never take a node another agent or person is on; coordination between agents happens on the map, never in a side channel. The mark is advisory — no atomic exclusive lease exists yet, so a node may carry marks from several workers at once. Delegation your operator authorized within your grants is valid even when the task's assignee is your human owner. To say the work is yours, assign yourself (`orient task assign \u003cleafId\u003e --me --area \u003careaId\u003e`); you never add another agent or take an agent off work — that is its operator's call.\n- NAME YOUR CONTEXT: keep a list of the contexts you work in — one per area or client you serve — with `orient context add --name OneRoof --code OR --colour teal` (a code of one to three letters, a colour from red, orange, amber, green, teal, blue, indigo, violet, pink or slate), and read it with `orient context list`. Name one whenever you mark a node: `orient task start \u003cleafId\u003e --area \u003careaId\u003e --context OR` (`POST /api/nodes/{id}/working` `{contextId}`). Your tag then reads `Plex [OR]` in the context's colour, but only your operator sees the context — everyone else sees your plain name, and the server never sends them the context. Rename, recolour or retire a context with `orient context rename OR --name \"\u003cname\u003e\"`, `orient context recolour OR --colour blue` and `orient context retire OR`; marks made in a retired context keep its code.\n- RECORD as you go: mark progress the moment it is true, and put discoveries where they belong — a new task where work appeared, a dependency edge where an order emerged, a note where context grew. Never save your findings only in your own scratch space.\n- PROVE IT DONE: when you mark work done, say how you verified it and where to see it — `orient task done \u003ctaskId\u003e --area \u003careaId\u003e --verified \"\u003chow you verified it\u003e\" --see \"\u003chttps link\u003e\"` (a proof can also be `--see build:\u003cbuildName\u003e` or `--see device:\u003cdeviceName\u003e`; repeat `--see`; `--see` takes the URL `orient node link \u003cnodeId\u003e --area \u003careaId\u003e` prints or its `-o json` answer as it is; over MCP the same `verified` and `see` arguments on task_done, where `see` takes the JSON `node_link` answers, as a string). Your operator reads the proof on the node instead of hunting through notes, and reopening the task clears it.\n- BLOCK LOUDLY: when you cannot proceed, mark the task blocked with the reason — `orient task block \u003ctaskId\u003e --area \u003careaId\u003e --reason \"\u003creason\u003e\"` (`POST /api/nodes/{id}/blocked` `{reason}`) — rather than going silent; the block shows on the node, where your operator reads the map, and `orient task unblock \u003ctaskId\u003e --area \u003careaId\u003e` clears it once you can move again. Your operator reads the map, not your transcript.\n- HAND OFF: when you need a decision, a review, or you are done, release your working mark, leave the summary on the node, and hand your operator the link — `orient node link \u003cnodeId\u003e --area \u003careaId\u003e` prints the URL alone, also when piped, and that is the URL they open (`-o json` answers `{url, mapId, nodeId}`). Leave the map telling the truth without you: completions marked, blockers named, anything half-done split so the remainder is a task someone else could pick up.\n\n## The surface is discoverable — never guess\n\n- `orient guide` (or `GET /api/guide` with your key) — the complete, always-current working guide: every capability in usage terms. Read it before your first write of a session.\n- `orient commands -o json` — the machine-readable catalog of every CLI verb; the MCP face (`orient mcp serve`) generates its tools from the same registry, so `tools/list` is never stale.\n- Refusals answer a `code`, an `error`, and usually a `hint` naming your next step — read the hint before retrying. Never probe routes and never reverse-engineer stored data shapes.\n\n## Orient every turn\n\n- `orient orient` (`POST /api/orient`) is your bearings: where you are, what is yours, what moved since you last looked, who is nearby. Run it before your first write of every turn, after finishing a task, when switching area, and when your operator says orient.\n- `orient skill install --for \u003charness\u003e` installs this teaching for Claude Code (`claude`), Codex (`codex`), Cursor (`cursor`), Gemini CLI (`gemini`), Grok CLI (`grok`), or another AGENTS.md/MCP agent (`generic`). Without --for, install and update mean Claude Code. Claude Code also gets a prompt-submit hook. Cursor and generic installations use the current repository; use `orient skill repo --for \u003charness\u003e` to install any harness in a repository (without --for, `orient skill repo` writes the Orient pointer into AGENTS.md and CLAUDE.md).\n\n## Keeping this skill current\n\nThis file is the doorway, not the map — the guide is the live truth. Refresh this teaching with `orient skill update --for \u003charness\u003e` at the same installation scope, or repeat `orient skill repo --for \u003charness\u003e` for repository instructions. The installer updates only its managed contribution and preserves personal content. `orient skill remove --for \u003charness\u003e --yes` removes that contribution (add --project for repository installations). Never overwrite a shared instruction or settings file. If Orient answers something this file did not prepare you for, update the skill and re-read the guide.\n"}
