Skip to main content

Packages & Assets

A canonical package is the source of truth for your AI configuration. Let's understand how they work.

What Is a Canonical Package?

A canonical package is a versioned, immutable, org-scoped bundle of AI workflow assets. Once published, it never changes. If you need to make a change, you publish a new version.

Think of it like npm: you define it once, version it, publish it, and teams reference specific versions in their workspace manifests.

Package Identity

Every package has three parts:

@mycompany/baseline@1.0.0
↑ ↑ ↑
scope name version
  • Scope — Your organization identifier (e.g., @mycompany, @acme)
  • Name — The package name (e.g., baseline, security-review, react-agent)
  • Version — Semantic versioning (e.g., 1.0.0, 2.3.1)

Version constraints work like npm:

{
"packageId": "@mycompany/baseline@1.0.0",
"versionConstraint": "^1.0.0" // Accept 1.x.x, not 2.0.0
}

Asset Types

A package contains one or more assets. Each asset is a piece of AI configuration:

Asset TypePurposeExample
instructionLong-form system prompts and guidelinesClaude session instructions
skillReusable task definitions for agentsCode analysis, refactoring
agentAgent configurationsAgentic loop setup, tool bindings
workflowMulti-step orchestrationsCode review → approval flow
promptShort-form promptsQuestion templates, generation prompts
hookLifecycle triggersPre-commit, post-deploy
mcp_serverMCP server configurationsTool integrations, model context
provider_configProvider-specific settingsClaude settings, Cursor rules
templateBoilerplate for generated filesWorkflow templates, CI configs
policyGovernance rulesApproval requirements, trust gates
telemetry_schemaTelemetry event definitionsUsage tracking, metrics

Trust Classification

Every asset has a trust class that determines what gates must pass before it can be rendered to disk.

Trust ClassRisk LevelWhat HappensExample
passive_textLowestRendered automaticallyInstructions, prompts, README
configurationLowManual review recommendedProvider settings, editor config
tool_permissionMediumExplicit approval requiredSandbox settings, tool grants
executable_hookHighExplicit approval + audit logShell commands, pre-commit hooks
networked_mcpHighExplicit approval + network reviewMCP servers with URLs/auth
telemetry_emittingHighestExplicit approval + privacy reviewTelemetry collectors, analytics

Trust escalation is monotonic — trust can only go up, never down. If a package is marked executable_hook, you cannot weaken its protection by assigning it a passive_text policy.

Content Hashing

Every asset has a contentHash — a SHA-256 hash of its exact content:

{
"name": "baseline-instructions",
"type": "instruction",
"trustClass": "passive_text",
"path": "CLAUDE.md",
"contentHash": "7d3f4e6a2b1c5a8f3e9d2c4b5a6f7e8d"
}

Workloom uses content hashes to:

  • Detect when you've locally modified a generated file
  • Compare desired state against current state
  • Detect drift and conflicts

Visibility Levels

Control who can use your packages:

VisibilityWho Can UseBest For
privateYour org onlyInternal packages, company-specific guidance
orgYour organizationShared baseline across teams
publicEveryoneCommunity standards, open-source guidance

Signature States

Packages can be signed to verify authenticity:

StateMeaning
hash_onlyContent is hashed but not signed
signedSigned by publisher, not yet verified
verifiedSignature verified against publisher identity
revokedSignature revoked (compromised key)
rejectedExplicitly rejected by policy

Example Package Manifest

Here's a real package with multiple assets:

{
"scope": "@mycompany",
"name": "baseline",
"version": "1.0.0",
"description": "Baseline AI instructions and skills for all engineers",
"visibility": "org",
"trustClass": "passive_text",
"assets": [
{
"name": "claude-instructions",
"type": "instruction",
"trustClass": "passive_text",
"path": "claude-baseline.md",
"contentHash": "7d3f4e6a2b1c5a8f3e9d2c4b5a6f7e8d",
"projectionScopes": ["generated_local", "committed_projection"]
},
{
"name": "codex-agents",
"type": "agent",
"trustClass": "configuration",
"path": "AGENTS.md",
"contentHash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"providerOverrides": {
"codex": {
"mergeStrategy": "nested",
"commentStyle": "markdown"
}
}
},
{
"name": "baseline-hooks",
"type": "hook",
"trustClass": "executable_hook",
"path": "hooks.sh",
"contentHash": "m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8"
}
],
"publisherIdentity": {
"orgId": "org_mycompany",
"authMethod": "service_account"
},
"signatureState": "verified",
"contentHash": "z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4"
}

Provider Overrides

Assets can have provider-specific configurations:

{
"name": "agents-config",
"type": "agent",
"trustClass": "configuration",
"path": "AGENTS.md",
"providerOverrides": {
"codex": {
"mergeStrategy": "nested",
"rootPath": "docs/"
},
"cursor": {
"fileLocation": ".cursorrules",
"maxLength": 2000
}
}
}

Each provider has different capabilities. Provider overrides let a single asset adapt to those differences.

Immutability

Once a package is published, it is immutable. You cannot change @mycompany/baseline@1.0.0 — if you need to make changes, you publish 1.0.1 or 2.0.0.

This guarantees:

  • Reproducibility — the same workspace manifest always produces the same files
  • Auditability — you can trace exactly which version of a package was deployed
  • Safety — developers can't accidentally break production by modifying a package mid-deployment

Dependencies

Packages can depend on other packages:

{
"scope": "@mycompany",
"name": "react-agent",
"version": "2.1.0",
"dependencies": [
{
"scope": "@mycompany",
"name": "baseline",
"versionConstraint": "^1.0.0"
}
]
}

Workloom resolves dependencies transitively, similar to npm. If react-agent depends on baseline, any workspace that uses react-agent automatically includes baseline too.

What's Next

Now that you understand packages and assets, let's explore workspaces and targets — how you assign packages to repositories.

Publishing Packages

In Phase 2, Workloom will have a package registry. For now, packages are distributed however you like — git, HTTP, or local filesystem. Phase 1 is local validation and rendering.