This is a reference document for the source-tree organization rules Directory-level entity separation and Trash hygiene and archival defined in shared/AGENTS.shared.md ### Scope and ownership discipline. It is NOT installed into target projects — it is a methodology reference plus repo-local concretization for this monorepo.
Two rules govern source-tree hygiene:
- Directory-level entity separation — every source directory has one primary entity type and ownership/lifecycle contract; the directory's purpose must be expressible in one sentence; new files placed by classifying owner/lifecycle + I/O contract.
- Trash hygiene and archival — delete or archive obsolete files within the admitted change surface, subject to
Worktree safety; archival path with breadcrumb when deletion loses recoverable history.
An entity type is the kind of work the file does, classified by:
-
Actor or lifecycle that owns or invokes it. Runtime hook (PreToolUse/Stop, called by Claude/Codex CLI); agent-side wrapper (called by agent during session via tool); installer (called by maintainer during
--globalinstall); validator (called by CI or maintainer); gate (deny-on-fail check before publication action); skill/command (called by agent via Skill or slash-command); runtime helper (called by user or scripts in target projects after install). -
Input/output contract or side effects. What the file consumes (stdin envelope / argv / config file / file-system state) and produces (structured-deny JSON / exit code / written file / git ref / log entry). Two files with the same contract are the same entity type; two files with different contracts are not.
Platform variants (.sh/.ps1/.py) of the same command with the same contract count as one entity, not multiple.
shared/AGENTS.shared.md Directory-level entity separation requires directories to organize around one primary entity type. The Orchestrarium monorepo has three deliberately co-located directories that serve a documented design constraint and are exempt from the per-entity-type split:
-
src.claude/agents/scripts/— Claude pack: co-locates runtime hooks (check-bugfix-discipline.*,check-passive-polling-stop.*,hook_common.py), provider invocation wrappers (invoke-claude-api.*,invoke-claude-prompt.*,invoke-codex-prompt.*), publication gates (check-publication-safety.*), and pack validators (validate-skill-pack.*). -
src.codex/skills/lead/scripts/— Codex pack: same entity-type co-location pattern (minus the prompt-invocation wrappers, which are Claude-side only). -
scripts/(repo root) — co-locates installer scripts (install-{claude,codex,gemini,qwen}.{sh,ps1},install-hypothesis-hook.py), agents-mode helpers (normalize-agents-mode.py,sync-agents-mode-docs.py,validate-agents-mode-{contract,installers}.py), work-item helpers (agent-run-ledger.*,check-agent-run-ledger-contract.py,check-work-items-state.*,validate-work-item-state.*), and the publication gate (check-publication-gate.{sh,ps1}).
Rationale. These directories ship as flat units to user projects via scripts/install-{claude,codex}.{sh,ps1}. Install scripts hardcode the source-tree paths and the destination-tree paths. User documentation, hooks.json command paths, settings.json command paths, and operator memory of "where things live" all point at these paths. Splitting the directories into per-entity-type subdirectories would force:
- Every existing user install to migrate to a new layout (no clean rollover path for already-installed packs).
- Every Codex/Claude hook entry to update its command path (forcing re-trust on Codex side).
- Every documentation reference and example invocation across
INSTALL.md,CLAUDE.md,AGENTS.codex.md,README.md, and pack-internal docs to update.
The cost-vs-benefit of forcing this refactor on every existing operator install does not justify the gain from cleaner per-entity-type filesystem layout, because the existing naming convention (check-* / invoke-* / validate-* / install-* / etc.) already provides per-entity-type discoverability.
The exception is grandfathered, not extensible. New entity types added in the future MUST follow the shared rule:
- A new hook → typed subdirectory under
agents/hooks/orskills/lead/hooks/(creating the subdirectory if it does not yet exist), NOT into the co-located legacy dir. - A new wrapper → typed subdirectory under
agents/wrappers/, NOT alongside the co-located legacy dir. - A new validator → typed subdirectory under
validators/, NOT into rootscripts/if its lifecycle differs from existing co-located items. - Etc.
When in doubt, evaluate per the Rule 1 classification test (owner/lifecycle + I/O contract). The presence of three legacy co-located directories does not constitute permission to add a fourth or to grow the existing three.
Example: adding a new structural-enforcement hook.
A future maintainer wants to add check-active-probe-discipline.{py,sh,ps1} (catches "agent claimed X is unavailable without probe"). The classification:
- Actor/lifecycle: Stop event runtime hook, fired by Claude/Codex CLI's PreToolUse/Stop hook surface.
- I/O contract: reads PreToolUse Stop envelope from stdin; writes
{"decision":"block","reason":"..."}to stdout or exits 0.
This matches the existing hook entity type (same owner: runtime hook system; same contract: stdin JSON envelope → stdout deny payload). Per the grandfathered exception, the new hook belongs in a new typed subdirectory agents/hooks/ (creating it for this first new-entity-type hook), NOT in the legacy agents/scripts/ co-located dir.
If the grandfathered exception did not exist, the new hook would belong in the same place it does now (typed subdir). The exception merely formalizes that existing files stay where they are; new files follow the rule.
Example: replacing a script.
A maintainer rewrites scripts/validate-agents-mode-contract.py into scripts/validate-agents-mode-contract-v2.py because the v2 changes the public CLI surface and adopters need migration time.
- If the v1 file is preserved in
git logand migration docs reference both versions for ~1 release → keep v1 in place temporarily with a# DEPRECATED: replaced by validate-agents-mode-contract-v2.py — remove after 2026-Q3header comment. - If v1 has no callers and serves only history → delete it; git history preserves the file.
- If v1 captures a hard-won bug fix logic that v2 might lose → move to
scripts/archive/validate-agents-mode-contract-v1.pywith a one-line breadcrumb inscripts/README.mdexplaining why archived.
Subject to Worktree safety: do not delete or move v1 files that aren't part of the v2-replacement task. Restrict archival to files inside the admitted change surface.
- Shared rules:
shared/AGENTS.shared.md### Scope and ownership discipline. - Per-pack maintenance overlays:
AGENTS.md(Codex maintainer overlay),CLAUDE.md(Claude maintainer overlay) — both point at this reference. - Related rules:
Worktree safety(shared/AGENTS.shared.md### Operational and environment safety),Change-surface minimization,Ownership / extension-seam hygiene,Interface and encapsulation hygiene.
- Entity type: the kind of work a source file does, classified by actor/lifecycle plus input/output contract.
- Grandfathered exception: a documented co-located directory that exists for a deliberate design constraint, exempt from the per-entity-type split for existing contents but not extensible to new contents.
- Worktree safety: the existing rule against modifying files outside the admitted change surface (
shared/AGENTS.shared.md### Operational and environment safety). - Classification test: the two-signal placement check (actor/lifecycle + I/O contract) applied before adding or moving any source file.
- Repo-local concretization: per-repo extension of a shared rule, declared in
AGENTS.md/CLAUDE.mdor in a repo-specific shared reference like this document.