ctxrot
v0.5.27v0.5.27: ctxrot now follows the SHARED autonomy switch (harness_core::autonomy, written by `condukt state autonomy-set`) instead of ignoring it. `Config::load` applies the switch as a DEFAULT LAYER below both the config file and the env: with the switch on and nothing configured, `auto_distill_on_band` and `auto_compact_enabled` both read true, but an explicit config.toml value or `CTXROT_AUTO_COMPACT` / `CTXROT_AUTO_DISTILL_ON_BAND` always wins -- one switch must never override an explicit human decision. New `ctxrot autonomy` prints `{"autonomous":b,"auto_distill_on_band":b,"auto_compact_enabled":b,"source":s}` and exits 0 (a report, not a gate). A switch file that exists but cannot be read is fail-closed: `autonomous:false`, `source:"undetermined-switch-file"` and a stderr warning naming it -- never a silent off. v0.5.22: new `ctxrot handoff-record` (PostToolUse:Read) / `ctxrot handoff` (PreToolUse:Task) hooks address one measured pattern from real session transcripts — a parent session Reads a large file, then dispatches a Task/subagent whose prompt concerns that same file, and the subagent pays for a redundant fresh Read of content the parent already has. handoff-record caches a Read's content (session_id + resolved absolute path + content, capped per-entry, bounded ring buffer on disk) once it clears a size floor; handoff matches a dispatching Task's prompt against that session's cached paths (substring match only — never a bare filename, and never across sessions, since there is no sibling-to-sibling correlation id in the hook payload) and splices the cached content into the prompt via `hookSpecificOutput.updatedInput`, so the subagent's first Read becomes unnecessary. This does NOT reduce total resident tokens system-wide — the content still occupies the subagent's context exactly once either way — it only avoids the wasted round trip and a subagent walking into preguard's size gate with no recourse; docs are explicit that this is not a token-count win. True concurrent sibling-subagent deduplication was investigated and found structurally infeasible via Claude Code's current hook API (confirmed: no parent_tool_use_id/batch-correlation field exists in PreToolUse/PostToolUse payloads) and was deliberately NOT attempted. bin/ctxrot (the POSIX launcher)'s missing-binary fallback gained the two new subcommands to its non-verdict exit-0 branch (they were previously absent and would have fallen through to the CLI-command `exit 1` default, which would have broken PreToolUse:Task on a host with no bundled binary); tests/launcher_missing_binary.rs's observability-hooks test now covers both. v0.5.21: `bin/ctxrot` (the POSIX launcher) no longer maps a MISSING per-platform binary to a blanket silent `exit 0`. A missing build means the check did not run, and exit-0-with-no-output is byte-identical to a clean run, so every verdict-bearing subcommand silently read as "nothing to flag": preguard granted the load gate, toolguard let an unmeasured payload through, stop ended the turn as if the budget check had passed, and statusline rendered the blank bar that reads as headroom (the 3b1eb24 fail-open). Each now resolves the cannot-determine on the restrictive side of its OWN protocol — preguard emits permissionDecision `ask` (a refusal to guess, not a deny that would be unescapable), toolguard emits an additionalContext "UNMEASURED" marker, stop emits `{"decision":"block"}` bounded by `stop_hook_active` exactly like harness_core::gate::run's panic barrier (empty stdin = manual run exits 1 with no fabricated decision), and statusline prints the explicit `unknown` band. The CLI/skill-consumed subcommands (note/metrics/ctx/usage/eval/…), whose empty stdout would be read as real data ("no notes", "nothing dropped"), now exit 1 like bin/evalkit. Only the pure-observability hooks (guard/rescue/restore/distill-bg — injected prose with no machine consumer) keep exit 0, and they still report on stderr; README.ja.md gains the classification table enumerating each one's downstream consumers, and src/main.rs's stale "on any error we exit 0 and stay silent" module docstring was corrected to match the code. New tests/launcher_missing_binary.rs pins all of it (plus that a PRESENT binary is still exec'd with args passed through). v0.5.16: cargo fmt --all reformatting only (fixes the 'build & commit plugin binaries' smoke workflow's `cargo fmt --all --check` gate, chronically red on main since 2026-07-21 per scripts/check-ci-red.py); no behavior change. Context-rot guard for Claude Code: detect, rescue, restore, distill, and CONTROL what loads into context (rule-based allow/deny gate + /ctx pin/drop/load + switchable carryover). Subscription-native (hooks + subagent + skill, no API key). v0.5.14: Stop hook now runs under harness-core's run_guarded panic barrier (fail-closed block on crash instead of silent allow).
By yukineko0 GitHub starsUpdated yesterday
Directory evidence
- Runtimes
- Claude Code
- Parsed components
- 2 skill or MCP entries
- Source updated
- Sep 23, 2026
- Manifest status
- Canonical path parsed
The directory validates manifest shape and source location. It does not execute the plugin or provide a security endorsement. Review the indexing methodology →
Install ctxrot for Claude Code
claude plugin marketplace add IchenDEV/agent-plugin-mkt
claude plugin marketplace update agent-plugin-marketplace
claude plugin install ctxrot@agent-plugin-marketplacePaste and run these commands in a terminal with Claude Code. They add and refresh the PluginsMP catalog, then install this plugin.
The installer fetches third-party code from the source repository shown on this page. This directory validates manifest structure and source location, but does not perform a security audit; review the manifest, components, and source before installing.
Get the source manually
git clone https://github.com/yukineko/claude-harnessesClone the source repository, then follow its setup instructions to add the plugin to a compatible client. The plugin root is crates/ctxrot/.
Plugin files
├── .claude-plugin/plugin.json├── skills/ctx/SKILL.md└── skills/distill/SKILL.md
Included Skills2
context に何を載せるか/載せないかを明示制御する。/ctx load <path> で意図的にロード(巨大なら sub-agent 経由で要約だけ)、/ctx pin で次セッション以降も再浮上、/ctx unload(=drop) で除外、/ctx list で現状確認。hooks + binary だけで動き subscription で完結(API キー不要)。
context-rot 対策の能動蒸留。現在の会話を蒸留して ctxrot ストアへ退避し、main context を「要約+リンク」に置換する。context 使用率が高い時、長い会話を畳みたい時、/compact の前に使う。
Plugin manifests1
{
"name": "ctxrot",
"version": "0.5.27",
"description": "v0.5.27: ctxrot now follows the SHARED autonomy switch (harness_core::autonomy, written by `condukt state autonomy-set`) instead of ignoring it. `Config::load` applies the switch as a DEFAULT LAYER below both the config file and the env: with the switch on and nothing configured, `auto_distill_on_band` and `auto_compact_enabled` both read true, but an explicit config.toml value or `CTXROT_AUTO_COMPACT` / `CTXROT_AUTO_DISTILL_ON_BAND` always wins -- one switch must never override an explicit human decision. New `ctxrot autonomy` prints `{\"autonomous\":b,\"auto_distill_on_band\":b,\"auto_compact_enabled\":b,\"source\":s}` and exits 0 (a report, not a gate). A switch file that exists but cannot be read is fail-closed: `autonomous:false`, `source:\"undetermined-switch-file\"` and a stderr warning naming it -- never a silent off. v0.5.22: new `ctxrot handoff-record` (PostToolUse:Read) / `ctxrot handoff` (PreToolUse:Task) hooks address one measured pattern from real session transcripts — a parent session Reads a large file, then dispatches a Task/subagent whose prompt concerns that same file, and the subagent pays for a redundant fresh Read of content the parent already has. handoff-record caches a Read's content (session_id + resolved absolute path + content, capped per-entry, bounded ring buffer on disk) once it clears a size floor; handoff matches a dispatching Task's prompt against that session's cached paths (substring match only — never a bare filename, and never across sessions, since there is no sibling-to-sibling correlation id in the hook payload) and splices the cached content into the prompt via `hookSpecificOutput.updatedInput`, so the subagent's first Read becomes unnecessary. This does NOT reduce total resident tokens system-wide — the content still occupies the subagent's context exactly once either way — it only avoids the wasted round trip and a subagent walking into preguard's size gate with no recourse; docs are explicit that this is not a token-count win. True concurrent sibling-subagent deduplication was investigated and found structurally infeasible via Claude Code's current hook API (confirmed: no parent_tool_use_id/batch-correlation field exists in PreToolUse/PostToolUse payloads) and was deliberately NOT attempted. bin/ctxrot (the POSIX launcher)'s missing-binary fallback gained the two new subcommands to its non-verdict exit-0 branch (they were previously absent and would have fallen through to the CLI-command `exit 1` default, which would have broken PreToolUse:Task on a host with no bundled binary); tests/launcher_missing_binary.rs's observability-hooks test now covers both. v0.5.21: `bin/ctxrot` (the POSIX launcher) no longer maps a MISSING per-platform binary to a blanket silent `exit 0`. A missing build means the check did not run, and exit-0-with-no-output is byte-identical to a clean run, so every verdict-bearing subcommand silently read as \"nothing to flag\": preguard granted the load gate, toolguard let an unmeasured payload through, stop ended the turn as if the budget check had passed, and statusline rendered the blank bar that reads as headroom (the 3b1eb24 fail-open). Each now resolves the cannot-determine on the restrictive side of its OWN protocol — preguard emits permissionDecision `ask` (a refusal to guess, not a deny that would be unescapable), toolguard emits an additionalContext \"UNMEASURED\" marker, stop emits `{\"decision\":\"block\"}` bounded by `stop_hook_active` exactly like harness_core::gate::run's panic barrier (empty stdin = manual run exits 1 with no fabricated decision), and statusline prints the explicit `unknown` band. The CLI/skill-consumed subcommands (note/metrics/ctx/usage/eval/…), whose empty stdout would be read as real data (\"no notes\", \"nothing dropped\"), now exit 1 like bin/evalkit. Only the pure-observability hooks (guard/rescue/restore/distill-bg — injected prose with no machine consumer) keep exit 0, and they still report on stderr; README.ja.md gains the classification table enumerating each one's downstream consumers, and src/main.rs's stale \"on any error we exit 0 and stay silent\" module docstring was corrected to match the code. New tests/launcher_missing_binary.rs pins all of it (plus that a PRESENT binary is still exec'd with args passed through). v0.5.16: cargo fmt --all reformatting only (fixes the 'build & commit plugin binaries' smoke workflow's `cargo fmt --all --check` gate, chronically red on main since 2026-07-21 per scripts/check-ci-red.py); no behavior change. Context-rot guard for Claude Code: detect, rescue, restore, distill, and CONTROL what loads into context (rule-based allow/deny gate + /ctx pin/drop/load + switchable carryover). Subscription-native (hooks + subagent + skill, no API key). v0.5.14: Stop hook now runs under harness-core's run_guarded panic barrier (fail-closed block on crash instead of silent allow).",
"author": {
"name": "yukineko"
},
"keywords": [
"context",
"hooks",
"memory",
"subagent",
"rust"
]
}For maintainers
If you maintain this plugin, link to this source-backed listing from your README so users can review its manifest and indexed components.
[ctxrot on Agent Plugins Marketplace](https://pluginsmp.com/plugins/ctxrot)