Skip to main content

Setting Up Claude

Workloom brings all your Claude Code configuration under one roof. Instead of managing .claude/settings.json, CLAUDE.md, skills, hooks, and agents across dozens of repos, Workloom renders them from canonical packages—keeping everything in sync, version-controlled, and auditable.

What Workloom Renders for Claude

When you run wl pull on a workspace targeting Claude, Workloom generates these files:

FilePurposeOwnership
.claude/settings.jsonProject-level settings (model, temperature, context windows, provider overrides)Workloom-managed
CLAUDE.mdUser-facing context and instructionsWorkloom-managed
.claude/skills/**/SKILL.mdReusable skill definitionsWorkloom-managed
.claude/agents/*.mdAgent behavior definitionsWorkloom-managed
.claude/hooks/**Lifecycle hooks (pre-apply, post-apply)Workloom-managed (requires approval)
.claude/settings.local.jsonUser-local overrides (never committed)User-owned

All generated files carry Workloom ownership metadata and SHA-256 content hashes. Developer modifications are detected via drift checking—wl status shows you what's changed.

Claude's Layered Settings Hierarchy

Claude Code applies settings in this order (first match wins):

1. Enterprise policy (org-level, immutable)
2. CLI flags (--model gpt-4, --temperature 0.5)
3. Project settings (.claude/settings.json)
4. Global settings (~/.claude/settings.json)

Workloom targets step 3 only—the project-level settings. It never touches enterprise policy or global settings. Local overrides go in .claude/settings.local.json and are always user_owned.

Asset-to-File Mapping

When you author a Workloom package, you define assets with provider-specific projections. Here's how Claude assets map to files:

Instructions Asset → CLAUDE.md

{
"name": "engineering-guidance",
"type": "instruction",
"provider": "claude",
"trustClass": "passive_text",
"content": "# Your Team's AI Workflow Guidelines\n\n..."
}

Projects into .claude/CLAUDE.md (or CLAUDE.md at root, depending on your projection policy).

Settings Asset → .claude/settings.json

{
"name": "project-settings",
"type": "settings",
"provider": "claude",
"trustClass": "configuration",
"config": {
"model": "claude-3-5-sonnet-20241022",
"maxTokens": 8192,
"temperature": 0.7
}
}

Projects into .claude/settings.json with full schema validation.

Skill Asset → .claude/skills/*/SKILL.md

{
"name": "code-review",
"type": "skill",
"provider": "claude",
"trustClass": "passive_text",
"content": "# Code Review Skill\n\nUsed to analyze pull requests..."
}

Projects into .claude/skills/code-review/SKILL.md (skill name becomes directory name).

Hook Asset → .claude/hooks/**

{
"name": "pre-apply-validation",
"type": "hook",
"provider": "claude",
"trustClass": "executable_hook",
"event": "pre-apply",
"command": "bash scripts/validate-settings.sh"
}

Projects into .claude/hooks/pre-apply/pre-apply-validation.sh. Requires explicit approval.

Trust Considerations

Hooks Require Approval

Hooks can execute arbitrary shell commands. Workloom blocks hook projection by default:

wl pull --dry-run
# Output: Trust gate blocked: executable_hook assets in package "@acme/hooks@1.0.0"
# Approval required. Run: wl approve hook pre-apply-validation

After reviewing the hook command:

wl approve hook pre-apply-validation
wl pull # Now succeeds

MCP in Settings Requires Approval

If your settings reference an MCP server with a remote URL:

{
"mcp": {
"servers": {
"my-remote-server": {
"url": "https://api.example.com/mcp"
}
}
}
}

This requires approval before projection. Local MCP servers (localhost, 127.0.0.1) require review only.

Settings Files Need Review

Even without hooks or MCP, settings files default to manual_review—Workloom shows you the diff before writing:

wl pull --dry-run
# Displays the projected .claude/settings.json
# Requires acknowledgement before writing to disk

.claude/settings.local.json is Always User-Owned

Local settings are never overwritten by Workloom. Any file named settings.local.json is treated as user-owned regardless of the projection policy. Use it for:

  • Personal model preferences (e.g., Claude 3.5 Opus for longer tasks)
  • Local debug settings
  • Custom context windows
  • Feature flags for experiments
{
"model": "claude-3-opus-20250219",
"debugMode": true
}

Workloom merges local settings on top of projected settings at runtime—no conflicts, just layering.

Example: A Claude-Only Package

Create a canonical package targeting Claude:

{
"scope": "@acme",
"name": "claude-baseline",
"version": "2.1.0",
"trustClass": "passive_text",
"assets": [
{
"name": "engineering-guidelines",
"type": "instruction",
"trustClass": "passive_text",
"provider": "claude",
"content": "# Engineering Best Practices\n\n## Code Review\n...\n## Testing\n..."
},
{
"name": "project-settings",
"type": "settings",
"trustClass": "configuration",
"provider": "claude",
"config": {
"model": "claude-3-5-sonnet-20241022",
"maxTokens": 16000,
"temperature": 0.7
}
},
{
"name": "testing-skill",
"type": "skill",
"trustClass": "passive_text",
"provider": "claude",
"content": "# Testing Skill\n\nHelps design test cases..."
}
],
"providerCompatibility": [
{ "provider": "claude", "supported": true }
]
}

Example: Workspace Targeting Claude

Create a workspace manifest:

{
"workspaceId": "wksp_myteam_claude_01",
"orgId": "org_acme",
"name": "My Team's Claude Setup",
"binding": {
"type": "git-repository",
"gitRemote": "git@github.com:acme/myapp.git"
},
"targets": [
{
"id": "root",
"path": ".",
"providers": ["claude"],
"packages": [
{
"packageId": "@acme/claude-baseline@2.1.0",
"channel": "stable"
}
]
}
],
"revision": 1,
"projectionPolicy": {
"claude": "generated_local"
}
}

What the Rendered Output Looks Like

After wl pull, your repo looks like:

.claude/
├── settings.json # From project-settings asset (Workloom-owned)
├── settings.local.json # Your personal overrides (user-owned)
├── CLAUDE.md # From engineering-guidelines asset (Workloom-owned)
├── skills/
│ └── testing/
│ └── SKILL.md # From testing-skill asset (Workloom-owned)
├── hooks/
│ ├── pre-apply/
│ │ └── validate.sh # If approved (Workloom-owned)
├── agents/ # Additional agent files if defined
└── .workloom # Ownership metadata & hashes (Workloom internal)

Check the generated files:

cat .claude/settings.json
# {
# "model": "claude-3-5-sonnet-20241022",
# "maxTokens": 16000,
# "temperature": 0.7,
# "_workloom": {
# "packageId": "@acme/claude-baseline@2.1.0",
# "hash": "sha256:...",
# "state": "owned_clean"
# }
# }

cat CLAUDE.md
# # Engineering Best Practices
#
# ## Code Review
# ...

Drift Detection

If you or a teammate accidentally edit a Workloom-owned file:

wl status
# Workloom Status Report
# Workspace: My Team's Claude Setup
# Drift detected in 1 file:
# .claude/settings.json (state: owned_locally_modified)
# Run: wl diff --target root

See what changed:

wl diff --target root
# .claude/settings.json
# Current state does not match desired state
# (diff output showing changes)

Restore to desired state:

wl restore .claude/settings.json
# Restored .claude/settings.json to desired state

CI/CD Integration

In your CI pipeline, check for drift:

wl sync --check
# Exit code 0: All Claude files in sync
# Exit code 4: Drift detected (see wl status for details)

Fail the build if drift is detected:

# GitHub Actions example
- name: Check Claude configuration drift
run: wl sync --check --locked

Next Steps