Skip to content

Linear workspace contract

The rules every Linear-touching skill obeys. linear-steward, linear-feature-intake, and linear-release-audit all read this file first; it exists so the three of them cannot drift from one another, and so a fourth skill inherits the same invariants without a fourth copy of the prose.

Scope authority lives in mvp-scope.md. This document says how that authority is recorded in Linear. It never decides what is in scope.

1. Workspace shape

One team: Ogur (OGUR). Statuses, in workflow order:

Status Type Means
Backlog backlog Accepted, not in the active milestone
Todo unstarted In the active milestone, not started
In Progress started A branch or worktree exists
In Review started A PR is open
Done completed Evidence exists — see §3
Canceled canceled Decided against; reason recorded
Duplicate duplicate Superseded; the survivor is named in a relation

Projects are outcomes, not areas. An issue has exactly one project (§2). The two release projects (Road to MVP-1, Road to MVP-2) carry a project milestone that is the release gate; other projects do not.

Labels split into two axes, and this split is load-bearing:

  • OwnershipTech, Commercial, infra. Answers "who does this".
  • Capabilitydiscovery, eval, source-integration, MVP-1 stretch, plus the kind labels Bug / Feature / Improvement.

Capability labels are how an issue is found from a project it does not belong to. They are the mechanism §2 relies on.

2. One primary project per issue

An issue belongs to exactly one project: the outcome that is not delivered until this issue is done. Not "every outcome this issue touches."

When an issue is genuinely relevant to a second project:

  1. Add the capability label the other project is tracked by, or
  2. Add a Linear relation (related to / blocks) to a specific issue in it.

Never create a second issue to represent the same work in a second project. Two tickets for one piece of work is how a workspace stops being able to answer "is the release gate met" — both rows move independently and neither is the truth.

Worked case: "Serve the built React app and both frozen packs from one container" delivers the MVP-1 gate; hosting is the means. Primary project is Road to MVP-1, label infra, and it is found from hosting work through that label — not through a duplicate row in Deploy & Hosting.

3. Evidence rules for Done

A status is a claim about the world. These are the admissible proofs.

Work type Done requires Not sufficient
Engineering A merged PR (or a commit on main) that implements it, named in the issue An open PR, a green branch, "the code is written"
Release gate The gate's own acceptance evidence executed — the QA artifact, the smoke run, the recall number The implementation PR for the gate merged
Commercial / GTM Named, dated real-world evidence — the call happened, the tester replied, the list was sent Inference from activity, or from a doc being written
Decision The decision is written in an ADR, the decision log, or the scope contract The decision was discussed

The asymmetry is deliberate. A gate is not passed because its implementation merged. MVP-1 Gate C — Make every client-reachable surface auditable is met when every client-reachable surface has been walked and found auditable, not when the PR that added the audit code merged. Conflating the two is the single failure this contract exists to prevent.

Commercial work is never auto-completed. No skill may infer that a GTM issue is done. If the real-world state cannot be established from the workspace, the skill reports UNKNOWN — needs founder input and stops. Guessing here produces a workspace that reports outreach that never happened.

4. Historical work is preserved

Completed issues are the record of what happened. A skill may not:

  • Re-open, re-scope, re-title, or re-project a completed issue to tidy the board.
  • Delete or archive an issue to remove a duplicate — set status Duplicate and add a relation to the survivor.
  • Rewrite a milestone description that records a correction.

siRNA Closed-World Coverage carries two milestones whose descriptions correct their own headline numbers (Deal recall → 10/12, Asset recall → 16/32). Those descriptions are the most valuable text in the workspace. They are read-only.

5. Milestone progress is derived, not asserted

Linear computes project-milestone progress from the closure state of its issues. It is therefore not a measurement of the thing the milestone is named after.

Deal recall → 10/12 reports progress: 100% while the actual result is 10 of 12. It reads 100% because its issues are closed.

Consequences, binding on every skill:

  • Never report milestone progress as if it were the metric in the milestone name. Quote the milestone description instead, which carries the real number.
  • Never close issues into a milestone whose name states a target, unless the target was actually reached. Closing the work publishes a number you did not hit.
  • When naming a milestone, name the work, not the number, unless the number is already true.

6. Mutation safety

Default is read-only. Writes happen only when the invocation explicitly asks (apply / --apply), and only after a change ledger has been printed and approved.

The ledger is a table, one row per intended write, printed before the first write:

# Issue Field From To Evidence Reversible

Rules:

  • Resolve names to IDs before writing. The Linear MCP write path fails open on name resolution: save_issue returns HTTP 200 with the field silently unset when a name does not resolve. An ampersand in a project name (Evidence Graph & Extraction) never resolves. Always look the name up with list_projects / list_issue_labels / list_issue_statuses first and pass the returned id.
  • Read back after every write. A 200 is not confirmation. Re-get_issue and compare the field to the intended value; report any row that did not take.
  • One field per ledger row. A row that changes status and project is two rows.
  • Stop on the first mismatch. Do not continue a batch whose earlier rows did not land as intended.
  • Never delete. Never archive. Never bulk-edit issues outside the ledger.

7. Reporting

Every skill's output ends with the same three sections so the founder reads them the same way:

  1. Ledger — what changed, or what would change under --apply.
  2. Unknowns — what could not be established, and what would establish it.
  3. Next actions — at most three, each concrete and doable today.

Findings carry their evidence inline: the issue identifier, the PR number, the file and line, or the quoted milestone description. A claim with no pointer is labelled an assumption in the same sentence or it is cut.

8. Future consumers

This contract is written to be inherited. One consumer is already named and not yet built: dispatch-implementation, the seam between an approved Linear issue and an executor session. Its full description is in product-development-workflow.md; what it inherits from this document is fixed now, so the skills above are built against a known consumer rather than retro-fitted to one.

Linear is shared state, not one harness's scratchpad. The dispatcher routes work to either Claude or Codex, and both write their results back to the same issue. Every rule in §1–§7 therefore binds the executor session too, not merely the three skills in this repository. An implementation session that closes its own issue on its own say-so violates §3 exactly as a skill would.

Specifically, the dispatcher and anything it launches:

  • May not create a second ticket. It consumes an existing implementation-ready issue. Cross-project relevance stays a label or a relation (§2), and "the executor needed its own tracking row" is not an exception.
  • May not reconsider scope or rewrite acceptance criteria. product-manager owns scope; the dispatcher owns routing; the receiving executor owns the technical plan and nothing above it. Three owners, no overlap.
  • May not mark its own work Done. The §3 evidence rules apply unchanged: a merged PR for engineering, the gate's own acceptance artifact for a release gate, named dated user evidence for commercial work. The implementing session never certifies its own gate — an independent review or eval gate does.
  • Reads back through the ledger (§6). The completion report is a write to shared state like any other: names resolved to ids first, read back after, batch stopped on the first mismatch.
  • Never merges automatically. Neither harness may.

Both harnesses can reach this workspace today. Codex has the Linear MCP server through its linear plugin (.mcp.jsonhttps://mcp.linear.app/mcp, OAuth); Claude has it through its own MCP configuration. The tool surface every rule above is written against — list_issues, get_issue, save_issue, save_status_update — is the same on both sides, which is why the contract is worth writing once.

The open item is discovery, not access: it has not been demonstrated that a project-local .agents/skills/ directory is picked up from a repository checkout, and AGENTS.md currently points Codex at a .Codex/skills/ path that does not exist. Canonical placement is settled; invocation is not. Verify it by invoking one skill from a real Codex session before the dispatcher depends on it.