| Version | Supported |
|---|---|
| latest tagged release | yes |
main / unreleased |
no |
Only the latest tagged release is supported and recommended for production.
main contains unreleased development work; use it for evaluation and
contribution, not production deployment.
Report privately through GitHub's private vulnerability reporting:
https://github.com/alebgl77/tierdecay/security/advisories/new
Please do not open a public issue for security matters — that discloses the problem before there is a fix. We aim to acknowledge a report within 72 hours and will coordinate a fix and disclosure timeline with you from there.
TierDecay is markdown instruction files plus a Bash install.sh that copies
those files into your repository. There is no network service or runtime
daemon, no telemetry, and no secret handling — so the usual server-side and
credential surfaces do not apply here. The Claude Code adapter's local guard
hook requires Node.js to parse tool payloads; it is the only adapter-specific
runtime requirement and does not run as a service. Three surfaces are real and
in scope:
1. install.sh file operations. The installer runs in your shell with
your permissions and writes into your working tree (CLAUDE.md, AGENTS.md,
.claude/, .tierdecay/, etc.). It refuses to run from the checkout itself
and writes *.tierdecay sidecars rather than clobbering existing files, but
it is still a script that touches your filesystem. Read it before running it,
run it from the repo you intend to equip, and review the diff it produces.
Bugs in its path handling, overwrite guards, or detection logic are in scope.
Uninstall never removes learned state. If an owned artifact's recorded source
is missing, uninstall preserves the installed file and relinquishes the
selected target's ownership rather than treating the missing source as proof
that deletion is safe. Review any preserved files yourself.
2. The instruction files themselves. This is the interesting surface. The
adapters and the compiled playbook steer an autonomous coding agent, so a
malicious edit to an adapter file, or a poisoned playbook entry, can
influence what that agent does in your repository — the injection lives in
context, not in code. TierDecay's integrity invariants (core/SPEC.md §5)
exist precisely to contain playbook self-poisoning: only the orchestrator
writes the ledger and playbook, executor diffs touching them are rejected at
VERIFY, any acceptance failure while an entry was referenced quarantines it,
and the playbook is hard-capped. A defect that lets an executor write state,
lets a quarantined entry keep applying, or otherwise bypasses a §5
invariant is a security bug and in scope — as is a supply-chain edit that
smuggles hostile instructions into an adapter or template.
3. Distribution and shared-repo surface. The files are trivially forkable, and the playbook is loaded into the agent's context every session — which makes two indirect attacks realistic:
- Look-alike / tampered checkout. Anything named "tierdecay" is not this
project. Install from a tagged release of this repository, not from an
arbitrary clone of
mainor a fork: releases from this repo carry aSHA256SUMSasset — verify the archive against it before runninginstall.sh(sha256sum -c SHA256SUMSon Linux orshasum -a 256 -c SHA256SUMSon macOS). Readinstall.shand the adapter you install; they are short on purpose. - Shared repositories. If you commit
.tierdecay/(or the Claude Code adapter's ledger/playbook under.claude/), you share learned state with your team — and anyone with write access to the repo can steer every teammate's agent through a poisoned playbook entry. Choose deliberately: commit the state and review playbook diffs with the same scrutiny as code, or add it to.gitignoreand keep state per-machine (no shared poisoning, no shared learning). Never let a playbook diff through review unread.
The §5 integrity invariants are protocol-level rules interpreted by a language model, plus whatever technical enforcement your CLI can add. Be precise about which layer you are relying on:
- Protocol (all adapters): only the orchestrator/DISTILL phase writes state; VERIFY rejects executor diffs touching it. This is an instruction a model follows — strong in practice, but the same class of mechanism as a prompt injection, so it must not be your only layer.
- Technical (Claude Code adapter):
executorandheavy-executorcarry a defense-in-depthPreToolUseguard hook (.claude/hooks/tierdecay-guard.sh). It canonicalizes structured target paths and blocks observable shell references to.claude/or.tierdecay/; the shippedsettings.jsonadditionallyask-gates state writes behind explicit human approval. This is not a security boundary: dynamic Bash that constructs a target without a literal state-path reference, and TOCTOU changes between inspection and execution, cannot be ruled out. VERIFY therefore remains mandatory. For a strong guarantee, remove Bash from executor tools or enforce OS-level filesystem isolation. Plugin variant: Claude Code ignoreshooks:frontmatter on plugin agents, so the plugin registers the same guard as a session-widePreToolUsehook with--executors-only. It enforces only when the hook payload'sagent_typenamesexecutororheavy-executor(optionallytierdecay:-prefixed) and passes every other caller. It therefore relies on the client reportingagent_typefor subagent tool calls; a client that omits it leaves plugin executors unguarded at this layer. A plugin cannot ship permission rules either: add the twoaskrules yourself (tierdecay-initprints them). Run the active-hook smoke check against the plugin too. Codex adapter:.codex/hooks.jsonregisters the same guard with--executors-onlyonPreToolUseforapply_patchandBash; it parses every file header of anapply_patchenvelope and resolves each target against the session directory. It shares the plugin variant's dependency onagent_type(Codex reports it inside subagents), runs only after you trust it with/hooks, and executor roles additionally run in theworkspace-writesandbox. Antigravity adapter: no hook is shipped (its hook input does not yet identify the calling subagent reliably); layers 1 and 3, the executors'sandboxcommand policy, andtierdecay doctorcarry integrity there. MCP server:tierdecay mcpis read-only by default — every tool is annotatedreadOnlyHintand none writes. The single write tool,tierdecay_record, exists only when the server is started with--allow-ledger-append true; MCP tools are visible to every agent in a client session, so enable it only for the orchestrator's own session. The append itself validates the row, rejects duplicates, and writes atomically under an exclusive lock. - Human: review state diffs like code (see above), and treat an unexpected prompt to approve a state write as a red flag — that prompt IS the alarm going off.
A bypass of layer 2, or a shipped default that weakens it, is a security bug and in scope.
Repository regression suites exercise guard payloads and native Windows paths; the model-policy test checks aliases and hook registration/frontmatter shape. These are not live Claude Code integration tests. Platform- or capability-dependent fixture skips are reported explicitly, and security failures must not be suppressed. After an upgrade, review and merge sidecars without dropping learned state or hardened permissions, reload the session and agents, and run the active-hook smoke check in the native adapter guide using a disposable project. A passing structural check cannot prove a client's hook is active.
Out of scope: the behavior of the underlying coding CLIs and models themselves, and anything a user does after editing the shipped files by hand. The invariants assume the files you install match the ones in this repository — verify what you install.