agentleFS
relvo-labsrelvo-labs/agent-runtime/.agents/skills/workspace-lifecycle/SKILL.md

workspace-lifecycle

Skill0 starsChanged 47 days agoApache-2.0View on GitHub

Acquire, lease and release agent workspaces so that borrowed directories are never destructively mutated and managed cleanup stays ownership-bound and idempotent.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when a change touches any of:

    line 13
  2. Distinctive:

    Do not use this skill when:

    line 22
  3. Very specific:

    Never write a destructive call that is not guarded: Every removal must pass assertRemovable(), which requires _all_ of:

    line 64
  4. Very specific:

    If you are tempted to add a force flag that bypasses this, stop.

    line 72
  5. Very specific:

    Only then reject, with an aggregate that stays truthful about the whole sweep: workspace_unavailable carrying attempted, released and the …

    line 84
  6. Very specific:

    Never compare argv by serialization.

    line 99

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Workspace lifecycle

Trigger

Use this skill when a change touches any of:

  • packages/workspace/src/ or packages/workspace-git/src/
  • anything that acquires, releases, cleans or deletes a directory
  • the WorkspaceSpec, WorkspaceLease or release-report shapes
  • git clone / worktree provisioning

Counter-trigger

Do not use this skill when:

  • the change is only the Zod shape of a workspace DTO — coordinate with runtime-contract-evolution, which owns schema classification
  • the change is credential handling for a git remote — out of scope; this repository does not own credentials
  • the change is which package may import the workspace SPI — use package-architecture

Owns

  • packages/workspace/src — workspace SPI, lease and ownership model
  • packages/workspace-git/src — git-backed workspace provider
  • docs/adr/ADR-0008-workspace-lease-ownership.md — the ownership decision record

Does not own

  • packages/protocol/src — owned by runtime-contract-evolution
  • packages/provider/src — owned by provider-adapter-development
  • packages/runtime/src — owned by runtime-lifecycle-coordination

Relationships

  • depends-on → runtime-contract-evolution — workspace DTOs are protocol types.
  • boundary-with → provider-adapter-development — a provider consumes a lease root; it never acquires or releases the lease itself.
  • boundary-with → runtime-lifecycle-coordination — this skill owns lease safety; runtime coordination owns acquisition and cleanup timing.

Procedure

  1. Ownership is decided at acquisition and is immutable.

    Spec kindOwnershipRuntime may createRuntime may delete
    existingborrowednonever
    managedmanagedyesonly the root it created

    There is no promotion from borrowed to managed. A caller cannot opt a borrowed directory into cleanup.

    Concrete leases keep canonical ownership and root in private immutable state. TypeScript readonly fields are not authority: freeze public accessors/views, and make destructive checks read only values captured privately at acquisition.

  2. Never write a destructive call that is not guarded. Every removal must pass assertRemovable(), which requires all of:

    • the lease exists and its ownership === 'managed'
    • the target is exactly the lease's own root
    • root resolves (after realpath) inside the provider's configured base directory
    • root is not the base directory itself, not /, and has depth > 1
    • the lease has not already been released

    If you are tempted to add a force flag that bypasses this, stop.

  3. Release is concurrency-idempotent, retryable on failure, and reports what it did. Concurrent release() callers await one in-flight operation. If it rejects, clear only that attempt so a later caller can retry. After success, every later call returns { alreadyReleased: true } and performs nothing. WorkspaceReleaseReport contains destructiveOperations: string[]; for a borrowed lease this array must be empty — that is a tested invariant, not a convention. Never fabricate a success report after failure.

    A provider-wide releaseAll() sweep is attempt-all, never fail-fast. Snapshot the tracked leases, attempt every entry even after one rejects, forget the entries that succeeded, and leave the entries that failed tracked and retryable by a later sweep. Only then reject, with an aggregate that stays truthful about the whole sweep: workspace_unavailable carrying attempted, released and the failed lease ids, and an AggregateError cause holding every individual failure. One lease that cannot be released must never starve the cleanup of every later lease.

  4. Do not follow symlinks out of the base directory. Resolve with fs.realpath before comparing paths, and compare on path segments (a/b is not inside a/bc).
  5. git workspaces: managed git workspaces are provisioned into a fresh directory under the configured base. existing git workspaces are inspected only — no checkout, clean, reset, stash or branch mutation. Shell out through the injected runGit seam so tests can assert the exact argv that would run; never call git directly from library code. Exact borrowed-workspace templates used for enforcement stay private and deeply immutable. Any exported command catalog is a deeply frozen, detached documentation snapshot; JavaScript mutation of it must never widen the policy. Never compare argv by serialization. Require an ordinary array of own primitive string entries, compare length and elements against private templates, and execute a detached validated copy so toJSON, prototypes, accessors, or mutation cannot swap the command.
  6. Leases outlive runs, not sessions. A lease is acquired when a session opens and released when the session closes or fails. Interrupting a run must not touch the workspace.

Verification

pnpm --filter @relvo-labs/agent-workspace test
pnpm --filter @relvo-labs/agent-workspace-git test
pnpm gate

The workspace suites include negative tests that assert a borrowed release performs zero destructive operations and that an escape attempt (root symlinked outside the base) is refused. A change that makes those tests pass by weakening the assertion is rejected.

Provenance

  • Source: independent — authored for this repository against the Node fs/fs.promises documentation (realpath, rm) and git-worktree(1).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.