The four layers in this repository
The four layers in this repository
Section titled “The four layers in this repository”Each section states what the layer does, which tier owns it, and the enforcement switch that tier
would add to go live. The switches are shown commented out. JSON has no comment syntax, so a
commented-out block cannot live in the .json file itself — it lives here, and enabling it means
copying the block into the layer and deleting the leading // from each line.
10-enterprise.json — enterprise
Section titled “10-enterprise.json — enterprise”Owner: Patterson Companies, corporate IT.
What it does: registers the enterprise catalog patterson-corp from its GitHub repository, and
states autoUpdate explicitly so that a lower layer has something concrete to override.
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "extraKnownMarketplaces": { "patterson-corp": { "source": { "source": "github", "repo": "patterson-agents/patterson-corp" }, "autoUpdate": false } }}The github source type “uses repo” and is one of seven documented source types (CC-settings
§ extraKnownMarketplaces). The repo value “must name a single repository” — the owner-wildcard
form "acme-corp/*" is accepted only in strictKnownMarketplaces and blockedMarketplaces
(CC-settings § strictKnownMarketplaces, “Owner wildcards”). Each marketplace entry “also accepts an optional autoUpdate
Boolean … When omitted, official Anthropic marketplaces default to true and all other marketplaces
default to false” (CC-settings § extraKnownMarketplaces). Setting false here restates the
documented default for a non-official marketplace; it removes nothing.
extraKnownMarketplaces in managed settings is the documented way to register a catalog centrally:
“add the marketplace to extraKnownMarketplaces in the same managed-settings.json so Claude Code
registers it automatically” (CC-marketplaces § Managed marketplace restrictions).
Enforcement switch — strictKnownMarketplaces and disableSideloadFlags
// "strictKnownMarketplaces": [// { "source": "github", "repo": "patterson-agents/*" }// ],// "disableSideloadFlags": truestrictKnownMarketplaces is managed-settings-only and “cannot be overridden by user or project
settings”; undefined means no restrictions, an empty array [] is “complete lockdown that blocks
every marketplace source, including the official Anthropic marketplace”, and a list of sources is an
allowlist (CC-settings § strictKnownMarketplaces; CC-marketplaces § Managed marketplace
restrictions). The owner-wildcard "patterson-agents/*" matches every repository under that GitHub
owner and requires Claude Code v2.1.223 or later (CC-settings § strictKnownMarketplaces, “Owner wildcards”).
disableSideloadFlags rejects --plugin-dir, --plugin-url, --agents, and --mcp-config, “which
users could otherwise pass to bypass strictKnownMarketplaces for a single run”; it requires v2.1.193
or later (CC-settings § Available settings). The two belong together — the allowlist without the
flag rejection has a documented one-run bypass.
Login enforcement (forceLoginMethod, forceLoginOrgUUID) is the other enterprise-tier switch. It
restricts login to a specific method or Anthropic organization and is enforced across the terminal,
VS Code extension, Agent SDK, claude setup-token, and /install-github-app; when set, sessions
authenticated by ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or apiKeyHelper are blocked at
startup (CC-admin § Decide what to enforce; CC-settings § Available settings). It is deliberately not
drafted here — Patterson’s provider and licensing posture is not settled.
20-suborg.json — sub-organization
Section titled “20-suborg.json — sub-organization”Owner: the segment — Patterson Dental, Patterson Veterinary.
What it does: adds the two sub-org catalogs alongside the enterprise one. It does not touch
patterson-corp; deep-merge means both keys survive into the effective policy.
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "extraKnownMarketplaces": { "patterson-dental": { "source": { "source": "github", "repo": "patterson-agents/patterson-dental" } }, "patterson-vet": { "source": { "source": "github", "repo": "patterson-agents/patterson-vet" } } }}patterson-dental and patterson-vet are the sub-org catalogs named in this repository’s README
topology table. Their repositories are planned rather than published; the entries demonstrate the
shape and will not resolve until those repositories exist. Their plugin contents are
[TBD: no source] — see Open questions.
Enforcement switch — blockedMarketplaces
// "blockedMarketplaces": [// { "source": "github", "repo": "untrusted-fork/patterson-dental" }// ]blockedMarketplaces is a managed-settings-only blocklist, “enforced on marketplace add and on
plugin install, update, refresh, and auto-update, so a marketplace added before the policy was set
cannot be used to fetch plugins”. Blocked sources “are checked before downloading, so they never
touch the filesystem”, and a github entry may use the owner-wildcard "owner/*" form. Requires
Claude Code v2.1.223 or later (CC-settings § Available settings).
A blocklist is the right shape at this tier precisely because of constraint 2: the realistic sub-org threat is a fork registered under a name that collides with an official catalog.
30-department.json — department
Section titled “30-department.json — department”Owner: the department — Engineering, Marketing, Infra CloudOps.
What it does: turns on the two patterson-corp plugins for everyone in the department.
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "enabledPlugins": { "patterson-engineering@patterson-corp": true, "patterson-brand@patterson-corp": true }}enabledPlugins “controls which plugins are enabled”, in the format
"plugin-name@marketplace-name": true/false, and “a plugin with no entry at any scope falls back to
its defaultEnabled value” (CC-settings § enabledPlugins). Both plugin names and the marketplace
name are taken from this repository’s own .claude-plugin/marketplace.json.
Two second-order effects of force-enabling a plugin at the managed tier, both worth knowing before this ships for real:
- Hooks from plugins force-enabled in managed
enabledPluginsare loaded even underallowManagedHooksOnly, which lets administrators “distribute vetted hooks through an organization marketplace while blocking everything else” (CC-settings§ Hook configuration). Enablingpatterson-engineeringhere also blesses itsPreToolUsehook. - Managed settings are read-only to Claude Code, so if a plugin is renamed the rewrite that happens
automatically in user, project, and local scopes does not happen here: “the rename notice recurs
until an administrator updates
enabledPluginsin the managed settings file to use the new name” (CC-marketplaces§ Rename or remove a plugin).
Enforcement switch — permissions.deny
// "permissions": {// "deny": [// "Read(./.env)",// "Read(./.env.*)",// "Read(./secrets/**)"// ]// }The permissions object with allow and deny arrays is the documented settings shape
(CC-settings § Settings files, example settings.json). At the managed tier it “cannot be
overridden by any other level, including command line arguments” (CC-settings § Settings
precedence).
The department tier is the natural owner of tool denials because denials are workload-shaped rather
than identity-shaped. Note the array-merge caveat in constraint 1: deny entries from several
fragments concatenate and de-duplicate, which for a deny list strengthens the policy — but the
documentation states the merge rule generally rather than confirming this specific reading. See
Open questions.
40-team.json — team, and the extend-versus-override worked example
Section titled “40-team.json — team, and the extend-versus-override worked example”Owner: an individual team inside a department. What it does: demonstrates both halves of the merge in one file — extending an inherited object with a new key, and overriding an inherited scalar.
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "extraKnownMarketplaces": { "patterson-corp": { "source": { "source": "github", "repo": "patterson-agents/patterson-corp" }, "autoUpdate": true }, "patterson-labs": { "source": { "source": "github", "repo": "patterson-agents/patterson-labs" } } }}| Half | Key | Mechanism | Result |
|---|---|---|---|
| Extend | extraKnownMarketplaces.patterson-labs |
objects deep-merge | patterson-labs joins patterson-corp, patterson-dental, and patterson-vet. No earlier layer loses an entry. |
| Override | extraKnownMarketplaces.patterson-corp.autoUpdate |
later files override scalars | 10-enterprise.json set false; 40 sorts after 10; the effective value is true. |
Both rules are from CC-settings § Settings files. The effective merged policy is:
| Key | Value | Contributed by |
|---|---|---|
extraKnownMarketplaces.patterson-corp.source |
patterson-agents/patterson-corp |
10, restated by 40 |
extraKnownMarketplaces.patterson-corp.autoUpdate |
true |
40 overrides 10 |
extraKnownMarketplaces.patterson-dental |
github source | 20 |
extraKnownMarketplaces.patterson-vet |
github source | 20 |
extraKnownMarketplaces.patterson-labs |
github source | 40 |
enabledPlugins |
both patterson-corp plugins true |
30 |
patterson-labs is the incubation catalog named in this repository’s README topology table, and
autoUpdate: true makes Claude Code “refresh that marketplace and update its installed plugins in
the background after startup” (CC-settings § extraKnownMarketplaces) — a reasonable thing for a
team tracking incubating work to want, and a change that adds capability rather than removing it.
Enforcement switch — a forced enabledPlugins disable
// "enabledPlugins": {// "patterson-brand@patterson-corp": false// }A managed false is the team-tier enforcement switch, and it is genuinely an enforcement action:
managed enabledPlugins entries “block installation at all scopes and hide the plugin from the
marketplace”, and a plugin force-enabled by managed settings “cannot be disabled” from local
settings (CC-settings § enabledPlugins). Flipping one boolean removes a capability from every
developer on the team, with no local recourse. That is why the shipped file contains no false.
Numeric prefixes and gap allocation
Section titled “Numeric prefixes and gap allocation”The merge is alphabetical (CC-settings § Settings files), so the filename is the precedence
declaration. ls order and policy order are the same thing, which is the property worth protecting.
| Prefix | Tier | Reserved |
|---|---|---|
00- |
— | reserved; sorts before the enterprise layer, so nothing should claim it casually |
10- |
Enterprise | in use |
20- |
Sub-organization | in use |
30- |
Department | in use |
40- |
Team | in use |
50--90- |
— | free for tiers Patterson has not defined |
Tens leave nine insertion points between any two tiers without renaming a file. Renaming is the thing to avoid: a rename changes merge order for every key in the file at once, silently.
Two mechanical notes from the same source: hidden files starting with . are ignored, so a
.40-team.json.swp left by an editor is skipped rather than merged; and managed-settings.json — if
one exists in the same directory — “is merged first as the base”, meaning it sits below every
numbered fragment regardless of prefix.
Source of truth: docs/architecture/layered-settings.md in the patterson-corp repository.