Skip to content

Desired-State Resources

How CompozyOS stores extensible runtime resources, validates mutations, and reconciles projected runtime state.

For people running agent work1 page in this section

Resources are CompozyOS's desired-state layer for runtime objects that must be extensible and agent-manageable. Instead of letting every subsystem invent its own private storage shape, CompozyOS writes canonical resource records, validates their specs through registered codecs, and reconciles them into runtime state.

Use this page when you need to understand why a tool, MCP server, agent definition, package-owned agent sidecar, skill, automation job, trigger, window layout, or bridge instance can be managed through the same control plane.

Mental model

Rendering diagram…

Desired-state resources pass through validation, storage, and reconcile before they affect runtime subsystems.
TermMeaning
KindResource family, such as tool, agent, or automation.job.
IDStable resource identity inside the kind.
Scopeglobal or workspace; workspace scope requires a workspace id.
OwnerWho owns the record, such as daemon control or an extension.
SourceWhere the record came from, such as an extension, daemon, or session.
VersionOptimistic mutation version used to prevent blind overwrites.
SpecCanonical JSON payload for the resource kind.

Registered resource kinds

The daemon registers typed codecs for these resource families at boot:

KindProjects into
hook.bindingHook registry bindings.
toolTool Registry entries.
mcp_serverMCP server declarations.
agentAgent catalog definitions.
agent.soulPackage-owned SOUL.md defaults for resource-backed agents.
agent.heartbeatPackage-owned HEARTBEAT.md defaults for resource-backed agents.
skillSkill catalog entries.
automation.jobScheduled or claimable automation jobs.
automation.triggerAutomation trigger definitions.
window_layoutStrict declarative desktop and tiled-group layout templates.
bridge.instanceBridge runtime instances.

Write flow

PUT /api/resources/automation.job/nightly-resource-audit
Content-Type: application/json

{
  "scope": { "kind": "global" },
  "expected_version": 0,
  "spec": {
    "id": "nightly-resource-audit",
    "name": "Nightly resource audit",
    "target_kind": "agent",
    "agent_name": "general",
    "prompt": "Inspect desired-state resource health.",
    "schedule": { "mode": "every", "interval": "24h" },
    "enabled": false
  }
}

What happens:

  1. CompozyOS validates the path kind and id.
  2. CompozyOS validates the scope binding.
  3. If a codec is registered for that kind, CompozyOS canonicalizes the spec.
  4. The record is written with an owner, source, version, and timestamps.
  5. Reconcile is triggered for that kind.

Use expected_version = 0 when creating a new record. Use the returned version on update or delete so stale operators and agents do not overwrite each other silently.

Kinds with a dedicated lifecycle service reject direct mutations with 403. Use the owning API or CLI so its invariants remain coherent.

Read and filter

GET /api/resources
GET /api/resources/automation.job
GET /api/resources/automation.job/nightly-resource-audit
GET /api/resources/automation.job?scope_kind=workspace&scope_id=ws_project

Filters can narrow by kind, scope_kind, scope_id, owner_kind, owner_id, source_kind, source_id, and limit.

Delete

DELETE /api/resources/automation.job/nightly-resource-audit
Content-Type: application/json

{ "expected_version": 3 }

Deletes also trigger reconcile for the kind. Extension-owned records converge from the package's declared kit, so disable or update the owning extension instead of mutating those children directly.

Failure guide

SymptomLikely causeFirst check
400 on writeThe request body is malformed JSON or cannot be decoded.Response body and submitted payload.
403 on write/deleteThe resource kind has a dedicated lifecycle service.Use the kind-specific API or CLI.
422 on writeInvalid kind, scope binding, or registered-codec spec validation.Response body and kind-specific docs.
409 on update/deleteexpected_version is stale.GET /api/resources/:kind/:id for the current version.
Record exists but runtime did not changeReconcile failed or is degraded.Observe resource/reconcile health and daemon logs.
Projected record reappearsAn extension or another declarative source owns it.owner and source fields on the resource record.
Workspace write failsscope.id does not name a valid workspace.compozy workspace list -o json.

Next

  • Extensions explains how installed packages publish resource records.
  • API Reference lists the current resource route families.

On this page