{
  "schema_version": 1,
  "site": "https://ccinternals.dev",
  "generated_at": "2026-08-05T13:36:12Z",
  "verified": {
    "date": "2026-08-05",
    "note": "Exact artifact versions and capture identity are on the current-state page.",
    "current_state_url": "https://ccinternals.dev/cowork/current-state/"
  },
  "disclaimer": "This documentation does not detect product changes. It records what was verified on a date against a build.",
  "staleness": {
    "verified": "2026-08-05",
    "compute": "age = today - verified; do not cache a precomputed band",
    "bands_days": {
      "fresh": 45,
      "aging": 90
    }
  },
  "tiers": {
    "measured": "Observed live, with controls where noted",
    "binary": "Read from a shipped artifact; behaviour not exercised",
    "inference": "Stated inference — see caveats"
  },
  "facts": [
    {
      "id": "paths.connected-folders-are-mounts",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Treat a folder the user connected as a separate mount with its own rules, not as part of the workspace.",
      "detail": "Connected folders appear as their own mounts alongside the outputs location. Permissions are tracked per mount, so a capability granted for one does not extend to another. A skill that assumes one uniform writable area will be surprised the first time it touches a connected folder.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.projects-differ-from-folders",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Do not assume a connected project gives you a folder mount. It does not.",
      "detail": "Connecting a project and connecting a folder are different actions producing different results. A session with a project attached and no folder attached has no folder mount at all, and a skill that looks for one will find nothing.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.relative-filenames",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Write files using bare or relative filenames, not absolute paths.",
      "detail": "Your skill's shell commands and its file-reading and file-writing tools operate on the same underlying scratch space, but each refers to it by a different absolute path. A relative filename is correct for both. An absolute path is correct for at most one of them, and which one changes between configurations.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.scratch-is-not-delivered",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Do not leave anything you want the user to see in the working directory alone.",
      "detail": "The directory your skill works in is a scratch space the user does not see. Files there are not presented, not listed, and on one lane not retained. Producing a file is a separate act from delivering it, and the working directory is on the wrong side of that line.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.session-paths-denied",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Never pass an absolute session path to the file tools. It is denied, not translated.",
      "detail": "When a skill discovers an absolute path from shell output and hands it to a file-reading or file-writing tool, the call is rejected. Nothing rewrites it into the form those tools expect. This is the most common way a skill that works in the CLI fails in Cowork, and the error does not point at the path form as the cause.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.skills-are-a-read-only-mount",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Treat your own skill's files as read-only at runtime.",
      "detail": "A skill's own directory is made available to the session as a mount you should not expect to write back to. Generate into the outputs location instead. A skill that rewrites its own files to keep state will not carry that state anywhere useful.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "paths.uploads-read-only",
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "rule": "Treat the uploads location as read-only and write everything to the outputs location.",
      "detail": "Uploaded files are mounted read-only. Attempting to write there fails. Deliverables belong in the outputs location, which is writable and is also what the delivery mechanisms operate on.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delivery.act-not-location",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Do not rely on writing a file to a directory as the act of delivering it.",
      "detail": "In one lane the workspace location is itself the delivery channel and writing there is enough. In the other it delivers nothing: the file exists only inside a session filesystem that is discarded when the session ends, and the user never sees it. A skill written against the first behaviour loses its deliverables silently in the second — no error, no warning, just nothing.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delivery.capability-conditional",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Write the deliverable to a stated path, then present it with whichever delivery tool the session offers; if none exists, state the path and stop.",
      "detail": "This is the pattern Anthropic's own bundled skill-authoring guidance uses, phrased as a capability check rather than a fixed tool name. Check what is available at the moment of use — the tool that presents files differs between lanes — and degrade to naming the path rather than failing. Do not hardcode one tool name and assume it exists.",
      "tier": "binary",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Which delivery tools exist in a session is served at spawn time and has changed across releases; the capability check is what makes this durable, not the tool names."
      ]
    },
    {
      "id": "delivery.name-the-path-anyway",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "State the path of what you produced even when a delivery tool worked.",
      "detail": "It costs one sentence and it is the only part of your output that survives every lane, every tool-surface change, and a user reading a transcript later. If delivery silently failed, the stated path is the difference between a recoverable result and a lost one.",
      "tier": "inference",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Reasoned from the lane split rather than measured; the cost is one sentence either way."
      ]
    },
    {
      "id": "delivery.never-commit-to-disk",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Never call a tool that writes to the user's own disk from inside a skill.",
      "detail": "Committing files onto the user's machine is infrastructure the agent and the user negotiate through folder-connection consent, not something a skill should reach for. No first-party skill names such a tool. Present the file and let the delivery path be decided outside your skill.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delivery.presenting-copies-for-you",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Do not hand-copy files into the outputs location before presenting them.",
      "detail": "The tool that presents files to the user copies what you give it out of the scratch space for you. Copying first and then presenting the copy produces duplicates and obscures which file is the deliverable.",
      "tier": "binary",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Behaviour of the presenting tool is served per session; check that it exists before relying on it."
      ]
    },
    {
      "id": "delivery.remote-filesystem-discarded",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Assume the session filesystem does not outlive the session.",
      "detail": "On the remote lane the filesystem is discarded at session end. On the local lane undelivered files are hidden from the user rather than destroyed, and can in principle be surfaced on a later turn — but a skill should not depend on that difference. Deliver within the turn that produces the file.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delivery.two-lanes",
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "rule": "Assume your skill may run in either of two lanes, and never assume which one.",
      "detail": "Cowork sessions run either on the user's own machine or on remote infrastructure. The lanes differ in where the filesystem lives, whether it survives the session, and how a file reaches the user. Which lane a session uses depends on how it was created and on account configuration, neither of which a skill can control.",
      "tier": "measured",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Lane availability is rolled out per account, so two users running the same skill can be in different lanes."
      ]
    },
    {
      "id": "delete.approval-interrupts-the-user",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Treat needing a delete as a design smell, because getting one interrupts the user.",
      "detail": "Enabling deletion requires a prompt the user must accept, and it is presented as irreversible for the remainder of the session. It also fires regardless of how permissive the session's permission mode is. A skill that routinely needs deletions will routinely interrupt its user, so prefer writing new files over rewriting in place.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delete.approval-is-per-mount",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Do not assume that approval to delete in one location applies anywhere else.",
      "detail": "Approval is granted per mount. Enabling deletion for the outputs location leaves a connected folder still denied, in the same shell and in later ones. A skill that gets one approval and then assumes free rein across the workspace will fail on the second mount it touches.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Established with a control: an unapproved connected folder stayed denied while the approved location succeeded."
      ]
    },
    {
      "id": "delete.cross-mount-moves-fail",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Do not move files between mounts with a rename. Copy, then verify.",
      "detail": "The outputs location is a genuinely separate device from the rest of the session filesystem, so renaming across that boundary fails with a cross-device error rather than falling back to a copy. Shell tools usually degrade to copy-then-delete on their own — and the delete half will then hit the permission denial.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delete.deny-set",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Expect removing a file or a directory to fail with a permission error on every Cowork mount.",
      "detail": "The denied set is exactly those two operations. This is not specific to the outputs location — a freshly connected folder behaves identically. The failure is a permission error, not a missing-file error, and it happens even though the same directory is writable.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Measured in the default configuration; see this page's open question about fully sandboxed organisations."
      ]
    },
    {
      "id": "delete.expect-self-escalation",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Expect the agent to ask for delete permission on its own the first time a removal fails.",
      "detail": "The permission tool's own description instructs the agent to request approval whenever a removal fails, rather than reporting it as impossible. So a skill that merely attempts a delete may cause a prompt it never asked for. If you do not want that, do not attempt removals.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "delete.truncate-and-rename-permitted",
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "rule": "Do not treat a file vanishing from its old path as evidence that it was deleted.",
      "detail": "Truncating a file to zero length, renaming it within the mount, and renaming it onto an existing file all succeed. The last of those destroys whatever was at the destination. So content can be emptied and paths can be reused without any delete having occurred, and a check based on 'the old path is gone' will report deletions that did not happen.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "shell.inline-execution-disabled",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not use the inline shell-execution syntax in skill instructions and expect it to run.",
      "detail": "The syntax that lets a skill embed a command in its own instructions and have the result substituted is disabled in Cowork. It fails quietly rather than erroring, so a skill that relies on it to gather context gets an empty result and carries on with wrong assumptions.",
      "tier": "binary",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Controlled by a setting rather than hardcoded, so the behaviour is configuration-dependent."
      ]
    },
    {
      "id": "shell.no-arbitrary-network",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not rely on arbitrary outbound network access from shell commands.",
      "detail": "Fetching over the network happens through a dedicated capability with its own routing and allow rules, not through unrestricted sockets from the shell. Write skills that use the fetch capability when it exists and state a clear limitation when it does not, rather than shelling out to a network client and assuming it works.",
      "tier": "binary",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Routing for fetching has changed across releases and is configuration-dependent."
      ]
    },
    {
      "id": "shell.no-package-installs",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not plan on installing packages at runtime.",
      "detail": "Outbound network access is constrained, so a skill whose first step is a package install will fail or hang in a way that looks like a bug in your skill. Use what is present, vendor what is small, and state the limitation when neither is possible.",
      "tier": "inference",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "Follows from the egress constraints rather than a direct install attempt; routing is configuration-dependent."
      ]
    },
    {
      "id": "shell.python-stack-is-preinstalled",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not assume the sandbox has no third-party libraries. It ships a large preinstalled stack.",
      "detail": "The environment your shell commands run in comes with a substantial set of Python packages already installed — data, document, and imaging libraries among them. Skills have shipped workarounds and portability warnings for a scarcity that is not there. Check for what you need before vendoring it or degrading.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Read from the shipped guest image; the exact package set is a property of that image and can change with it."
      ]
    },
    {
      "id": "shell.runs-as-its-own-user",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not expect to read or write anything outside your own session.",
      "detail": "Each session runs as its own operating-system user with its own identity, and other sessions' data is not readable even though the machine may be shared. Anything your skill needs must be inside the session or fetched into it.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Verified by attempting cross-session reads, which were refused."
      ]
    },
    {
      "id": "shell.sealed-environment",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not pass configuration to your skill's shell commands through the environment.",
      "detail": "The shell your skill's commands run in does not inherit the host environment. Variables set in user or managed settings do not appear, and neither do exports written by hooks. Configuration has to travel in the command itself, in a file the skill writes, or through a mechanism designed to cross that boundary.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Established by a live probe rather than from the binary; the symbol that once documented the boundary has since disappeared from the shipped application."
      ]
    },
    {
      "id": "shell.tool-is-not-the-cli-tool",
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "rule": "Do not assume the shell tool has the same name it has in the CLI.",
      "detail": "The tool your skill uses to run commands in Cowork is a different tool from the CLI's, with a different name. This matters if your skill's instructions name tools explicitly, and it is also useful: the tool surface is a more reliable indicator of where you are running than the environment is.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "detect.branch-on-tools",
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "rule": "For behaviour rather than reporting, branch on which tools exist instead of on the environment.",
      "detail": "The tool surface is the most durable runtime signal available to a skill: it is what actually determines what the skill can do, it is visible without a shell, and it stays correct when environment markers are added or removed. Use environment detection to report where you are; use capability detection to decide what to do.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "detect.markers-come-and-go",
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "rule": "Do not hard-fail when a runtime marker is missing. Fall through to the next check.",
      "detail": "Markers are set by the host at spawn time and have been added and removed across releases. A detection routine that treats one missing variable as proof of a runtime will be wrong the next time the spawn contract changes. Order the checks so each one only adds coverage.",
      "tier": "measured",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "detect.naive-env-check-false-negatives",
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "rule": "Do not detect Cowork with a bare environment-variable check.",
      "detail": "A skill spans two execution contexts. The part that runs shell commands runs in a sealed context with none of the usual markers set, so a bare environment check returns 'not Cowork' in precisely the production configuration you most needed to detect. The failure is silent and produces confidently wrong behaviour.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "detect.ordered-recipe",
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "rule": "Detect the runtime with an ordered sequence of checks, not a single environment test.",
      "detail": "Check the Cowork environment marker first; if it is set you are in Cowork. Otherwise check whether the working directory matches the session-path signature, which catches the case where your skill's shell commands run somewhere the marker is absent. Otherwise check the CLI's own marker. Each step only adds coverage — a later one never contradicts an earlier one.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "detect.two-contexts",
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "rule": "Remember your skill spans two execution contexts, and test the one you are actually in.",
      "detail": "Part of a skill runs where the agent runs; the shell commands it issues run somewhere else with a different environment and a different filesystem view. A check performed in one tells you little about the other, which is why a single probe gives confident wrong answers.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.hook-exports-do-not-cross",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Do not use a hook to export environment variables for your skill's shell commands.",
      "detail": "Hooks run, but the environment they modify is not the environment those commands see. This is a common way a plugin appears broken in Cowork while working in the CLI: the hook fires, the export succeeds, and the value is simply absent downstream.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.hooks-do-fire",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Expect plugin hooks to fire in Cowork.",
      "detail": "Hooks shipped by a plugin do run. An earlier belief that they were disabled was wrong; the real determinant is installation namespace, not hook support.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.install-through-the-app",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Install a plugin through the Cowork application if you want Cowork sessions to see it.",
      "detail": "Plugins installed through the CLI's own installation path land in a namespace that Cowork sessions never read, so the plugin appears installed and is simply invisible. This is the usual explanation for 'my plugin works in the CLI but not in Cowork'.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.mounts-are-read-only",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Do not write into your plugin's own directory at runtime.",
      "detail": "Plugin content is mounted for reading. Treat everything shipped with the plugin as immutable during a session and put generated state in the outputs location.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.plugin-files-are-mounted",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Expect plugin files to be present as a mounted directory, and find it rather than hardcoding it.",
      "detail": "Plugin content is made available to the session as its own mount. The exact location embeds identifiers that vary per plugin and per install source, and the shape has changed across releases, so discovery at runtime is the only stable approach.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "plugins.plugin-root-per-consumer",
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "rule": "Use the plugin-root token for file-tool reads, and discover the mounted path at runtime for anything you execute.",
      "detail": "The plugin-root token expands differently depending on which consumer expands it and which execution lane the session is in. Expanded for one consumer it names a location the other cannot reach. Reading plugin files through the file tools with the token is reliable; executing a script by that path is not. For execution, locate the plugin's mounted directory at runtime.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Resolution differs between the two execution lanes; this rule is written to be correct in both."
      ]
    },
    {
      "id": "subagents.name-the-type",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Always name the agent type when dispatching a sub-agent.",
      "detail": "Omitting the type yields a general-purpose agent holding the full tool surface, including the shell. If your intent was a constrained helper — a reader, a summariser — you have instead created something with more capability than the task needs, and the dispatch will look correct in every log.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Observed in a large sample of real dispatches, where the type-less form was a substantial fraction of the total."
      ]
    },
    {
      "id": "subagents.no-resume",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Do not plan to resume a finished sub-agent. Dispatch a fresh one with the context restated.",
      "detail": "In Cowork a completed or stopped sub-agent cannot be continued — the mechanism that does this elsewhere is not available. Recovery and follow-up work therefore mean a new dispatch carrying whatever context it needs, so design sub-agent prompts to be self-contained.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "subagents.same-containment",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Do not use a sub-agent to get around a path restriction or a permission prompt.",
      "detail": "Sub-agents run under the same containment as the main thread. The path rules apply identically inside them, and the permission machinery fires there too. Dispatching a sub-agent changes what work happens in parallel; it does not change what is allowed.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "subagents.self-contained-prompts",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Put everything a sub-agent needs in its prompt. It cannot ask you for more.",
      "detail": "Because a finished sub-agent cannot be resumed, a dispatch that omits context cannot be topped up — it can only be redone. Restating context is cheaper than a failed dispatch, and it is the only recovery mechanism available.",
      "tier": "inference",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Follows from the no-resume behaviour rather than being separately measured."
      ]
    },
    {
      "id": "subagents.tolerate-limits",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Write sub-agent fan-out so that a dispatch being queued or refused is handled, not fatal.",
      "detail": "Concurrency and per-session limits are enforced, and the numbers have changed between releases. A skill that dispatches a fixed wide fan-out and assumes every one starts immediately will behave differently across versions. Treat parallelism as an optimisation, not a requirement.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "subagents.working-directory",
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "rule": "Write sub-agent prompts with relative paths, exactly as you would the main thread.",
      "detail": "A sub-agent starts in the session's own working area, not in a private one. The same path rules apply, and absolute session paths handed to file tools are rejected there for the same reason.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "change.detect-at-use",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Detect capabilities at the moment you use them, and state a clear fallback when they are missing.",
      "detail": "This is the single defensive pattern that survives everything else on this page. A skill that checks for the tool it needs, uses it if present, and says plainly what it could not do otherwise will keep working across lane changes, served-configuration flips, and version bumps. A skill that assumes a surface breaks silently on all three.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "change.mid-session",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Do not assume configuration is fixed for the lifetime of a session.",
      "detail": "At least some served configuration is subscribed to rather than read once, so it can change while a session is running and the application reacts. A skill that reads a capability at the start of a long task and caches the answer can be wrong by the end of it.",
      "tier": "binary",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "change.never-assert-on-prompt-wording",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Never write a skill that depends on the exact wording of the system prompt.",
      "detail": "The instructions a Cowork session runs with can be patched from the operator's side, including a mode that replaces the computed instructions wholesale rather than adding to them. So a model of the session prompt as 'the standard preset plus my additions' can be wrong at any time, with no local artifact changing. Depend on behaviour you can observe, not on text you expect to be present.",
      "tier": "binary",
      "server_flag_dependent": true,
      "verified": "2026-08-05",
      "caveats": [
        "The replace mode is the one that matters: it discards the computed instructions rather than appending to them."
      ]
    },
    {
      "id": "change.no-version-bump",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Do not treat 'the version has not changed' as evidence that behaviour has not changed.",
      "detail": "Behaviour governed from the operator's side changes with no new version, no release note, and nothing observable locally. This has been directly observed: a capability that was off in one week's capture was on in the next, with no application update in between.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "change.served-not-shipped",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Assume tool availability and defaults are served to the session, not shipped in the application.",
      "detail": "A meaningful part of what a session offers is decided on the operator's side at spawn time. Two sessions on the same application version can therefore present different tools and different defaults. Nothing about the installed version tells you what a given session will look like.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    },
    {
      "id": "change.state-your-assumptions",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Write down which behaviours your skill depends on, in the skill itself.",
      "detail": "When something changes underneath you, the cost of diagnosis is dominated by not knowing what was assumed. A short stated list of dependencies — this needs a delivery tool, this needs shell access, this assumes files persist within the turn — turns a silent failure into an obvious one.",
      "tier": "inference",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": [
        "Editorial guidance drawn from the failure modes on this site rather than a measurement."
      ]
    },
    {
      "id": "change.tool-names-are-not-stable",
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "rule": "Do not hardcode a tool name your skill merely hopes is present.",
      "detail": "Tool surfaces have changed across releases: names differ between runtimes, tools have been added and withdrawn, and which ones a session gets is decided when it starts. Name a tool only after checking it exists, and say what you will do if it does not.",
      "tier": "measured",
      "server_flag_dependent": false,
      "verified": "2026-08-05",
      "caveats": []
    }
  ],
  "open_questions": [
    {
      "page": "https://ccinternals.dev/cowork/files-and-paths/",
      "question": "The exact path form the shell sees has changed shape across releases. Relative paths have been stable throughout; absolute forms have not. Prefer relative for that reason, not merely for tidiness."
    },
    {
      "page": "https://ccinternals.dev/cowork/delivering-outputs/",
      "question": "Which lane a given session runs in is decided by the surface it was created from and by account-level configuration. There is no reliable way for a skill to force a lane, and no documented way to read it directly — detect the available tools instead."
    },
    {
      "page": "https://ccinternals.dev/cowork/deleting-files/",
      "question": "This was measured in the default configuration. Organisations that require a fully sandboxed VM take a different internal code path for enabling deletion, and nobody has measured whether it behaves the same way. Treat the approval mechanics, but not the deny-set, as unverified there."
    },
    {
      "page": "https://ccinternals.dev/cowork/shell-commands/",
      "question": "Network egress is allowed through a fetch capability rather than arbitrary outbound sockets, and the routing has changed across releases. Assume fetch works and arbitrary sockets do not, and degrade gracefully rather than probing."
    },
    {
      "page": "https://ccinternals.dev/cowork/detecting-cowork/",
      "question": "Runtime markers are set by the host at spawn time and have been added and removed across releases. The ordering below degrades safely: a later check never contradicts an earlier one, it only adds coverage."
    },
    {
      "page": "https://ccinternals.dev/cowork/plugins-and-plugin-root/",
      "question": "Plugin-root resolution differs between the two execution lanes. The guidance below is written to be correct in both, at the cost of being less direct than hardcoding a path would be."
    },
    {
      "page": "https://ccinternals.dev/cowork/sub-agents/",
      "question": "Fan-out limits are enforced and have changed between releases. Write skills that tolerate a dispatch being queued or refused rather than assuming unlimited parallelism."
    },
    {
      "page": "https://ccinternals.dev/cowork/what-can-change-under-you/",
      "question": "This site does not detect product changes. It records what was verified on a date against a build. Anything on this page can be true today and false tomorrow with nothing observable in between."
    }
  ]
}
