Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…

)\nTABLE_RE = re.compile(r'^\\[([A-Za-z0-9_.@\"\\-/]+)\\]\\s*

Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…

)\nOPERATIONAL_RULE_RE = re.compile(\n r\"(Git Safety|Public Issue Replies|Investigation Honesty|Verification|Response Style|Commit|Security)\",\n re.IGNORECASE,\n)\nCJK_CONTEXT_RE = re.compile(r\"[\\u3400-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]\")\nASSIGNMENT_RE = re.compile(r\"[A-Za-z_][A-Za-z0-9_]*=.*\")\n# Assignments that choose the interpreter, its imports, or injected libraries.\nRISKY_ENV_RE = re.compile(r\"(PATH|PYTHON[A-Za-z0-9_]*|LD_[A-Za-z0-9_]+|DYLD_[A-Za-z0-9_]+)=\")\n# Builtins and reserved words have no file to verify.\nSHELL_BUILTINS = frozenset({\n \"cd\", \"exec\", \"source\", \".\", \"export\", \"eval\", \"set\", \"unset\", \"true\", \"false\", \":\",\n \"[\", \"[[\", \"((\", \"test\", \"echo\", \"printf\", \"exit\", \"return\", \"local\", \"declare\",\n \"typeset\", \"readonly\", \"shift\", \"trap\", \"builtin\", \"command\", \"type\", \"wait\", \"alias\",\n \"unalias\", \"read\", \"ulimit\", \"umask\", \"pushd\", \"popd\", \"hash\", \"getopts\", \"let\", \"shopt\",\n \"for\", \"case\", \"select\", \"function\", \"in\", \"}\", \")\", \"fi\", \"done\", \"esac\",\n})\n# Reserved words that introduce the next command word.\nCOMMAND_PREFIX_WORDS = frozenset({\"!\", \"{\", \"(\", \"if\", \"then\", \"else\", \"elif\", \"do\", \"while\", \"until\"})\nCONTROL_OPERATORS = frozenset({\";\", \"&&\", \"||\", \"|\", \"&\", \";;\", \"|&\"})\nREDIRECT_OPERATORS = frozenset({\"\u003c\", \">\", \">>\", \"\u003c\u003c\", \"\u003c\u003c-\", \"\u003c\u003c\u003c\", \"\u003c>\", \">|\", \"&>\", \"&>>\", \">&\", \"\u003c&\"})\nENV_FLAGS = frozenset({\"-i\", \"--ignore-environment\", \"-0\", \"--null\", \"-v\", \"--debug\", \"--\"})\nMAX_FILE_BYTES = 2_000_000\nMAX_CONTEXT_PROJECT_FILES = 50_000\nMAX_CONTEXT_MATCH_EVALUATIONS = 2_000_000\n_AUDIT_ROOT: Optional[Path] = None\n_AUDIT_HOME: Optional[Path] = None\n_TRUSTED_SCRIPT_ROOT = Path(__file__).resolve().parent\n\n\ndef contained(path: Path, root: Path) -> bool:\n try:\n path.relative_to(root)\n return True\n except ValueError:\n return False\n\n\ndef sensitive_path(path: Path, home: Path) -> bool:\n for protected in (\n home / \".ssh\",\n home / \".aws\",\n home / \".gnupg\",\n home / \".config\" / \"gh\",\n ):\n if path == protected or contained(path, protected):\n return True\n for part in path.parts:\n lowered = part.lower()\n if lowered == \"secrets\":\n return True\n if \"credential\" in lowered:\n return True\n if lowered == \".env\" or lowered.startswith(\".env.\"):\n return True\n return False\n\n\ndef audit_scope(path: Path) -> Optional[Path]:\n absolute = path if path.is_absolute() else Path.cwd() / path\n for root in (_AUDIT_ROOT, _AUDIT_HOME, _TRUSTED_SCRIPT_ROOT):\n if root is not None and contained(absolute, root):\n return root\n return None\n\n\ndef resolve_audit_file(path: Path) -> Optional[Path]:\n scope = audit_scope(path)\n if scope is None:\n return None\n absolute = path if path.is_absolute() else Path.cwd() / path\n home = _AUDIT_HOME or Path.home().resolve()\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in str(absolute)):\n return None\n if sensitive_path(absolute, home):\n return None\n try:\n resolved = path.resolve(strict=True)\n except OSError:\n return None\n if not contained(resolved, scope) or sensitive_path(resolved, home):\n return None\n return resolved if resolved.is_file() else None\n\n\ndef resolve_audit_dir(path: Path) -> Optional[Path]:\n scope = audit_scope(path)\n if scope is None:\n return None\n absolute = path if path.is_absolute() else Path.cwd() / path\n home = _AUDIT_HOME or Path.home().resolve()\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in str(absolute)):\n return None\n if sensitive_path(absolute, home):\n return None\n try:\n resolved = path.resolve(strict=True)\n except OSError:\n return None\n if not contained(resolved, scope) or sensitive_path(resolved, home):\n return None\n return resolved if resolved.is_dir() else None\n\n\ndef rel(path: Path, root: Path) -> str:\n try:\n value = path.resolve().relative_to(root).as_posix()\n except ValueError:\n value = path.as_posix()\n return safe_label(value)\n\n\ndef safe_label(value: str, limit: int = 500) -> str:\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in value):\n value = json.dumps(value, ensure_ascii=False)\n return value if len(value) \u003c= limit else f\"{value[: limit - 3]}...\"\n\n\ndef read_bytes(path: Path, limit: Optional[int] = None) -> bytes:\n resolved = resolve_audit_file(path)\n if resolved is None:\n return b\"\"\n byte_limit = limit or MAX_FILE_BYTES\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n descriptor = os.open(resolved, flags)\n except OSError:\n return b\"\"\n try:\n chunks: list[bytes] = []\n remaining = byte_limit\n while remaining:\n chunk = os.read(descriptor, min(65_536, remaining))\n if not chunk:\n break\n chunks.append(chunk)\n remaining -= len(chunk)\n return b\"\".join(chunks)\n except OSError:\n return b\"\"\n finally:\n os.close(descriptor)\n\n\ndef read(path: Path, limit: Optional[int] = None) -> str:\n return read_bytes(path, limit).decode(\"utf-8\", errors=\"replace\")\n\n\ndef yes(path: Path) -> str:\n return \"yes\" if resolve_audit_file(path) is not None else \"no\"\n\n\ndef print_list(\n title: str,\n items: list[str],\n empty: str = \"(none)\",\n limit: Optional[int] = None,\n) -> None:\n print(f\"{title}:\")\n shown = items if limit is None else items[:limit]\n if not shown:\n print(f\" {empty}\")\n return\n for item in shown:\n print(f\" {safe_label(item)}\")\n if limit is not None and len(items) > limit:\n print(f\" ... {len(items) - limit} more\")\n\n\ndef load_json(path: Path) -> tuple[Optional[object], Optional[str]]:\n if resolve_audit_file(path) is None:\n return None, None\n try:\n return json.loads(read(path)), None\n except json.JSONDecodeError as exc:\n return None, f\"{path.name}: invalid JSON at line {exc.lineno}\"\n\n\ndef redact_sensitive_entries(value: object, prefix: str = \"\") -> list[str]:\n entries: list[str] = []\n if isinstance(value, dict):\n for key, child in value.items():\n child_prefix = f\"{prefix}.{key}\" if prefix else str(key)\n if SENSITIVE_RE.search(str(key)):\n entries.append(f\"{safe_label(child_prefix)}=[REDACTED]\")\n continue\n entries.extend(redact_sensitive_entries(child, child_prefix))\n elif isinstance(value, list):\n for index, child in enumerate(value):\n entries.extend(redact_sensitive_entries(child, f\"{prefix}[{index}]\"))\n return entries\n\n\ndef string_list(value: object) -> list[str]:\n if isinstance(value, list):\n return [\n safe_label(str(item)) if not SENSITIVE_RE.search(str(item)) else \"[REDACTED]\"\n for item in value\n ]\n if isinstance(value, dict):\n return sorted(safe_label(str(key)) for key in value)\n if isinstance(value, str):\n return [\"[REDACTED]\" if SENSITIVE_RE.search(value) else safe_label(value)]\n return []\n\n\ndef skill_root_count(path: Path, include_root_md: bool) -> int:\n directory = resolve_audit_dir(path)\n if directory is None:\n return 0\n count = sum(\n 1\n for candidate in directory.rglob(\"SKILL.md\")\n if resolve_audit_file(candidate) is not None\n )\n if include_root_md:\n count += sum(\n 1\n for candidate in directory.glob(\"*.md\")\n if candidate.name != \"SKILL.md\" and resolve_audit_file(candidate) is not None\n )\n return count\n\n\ndef same_physical_file(left: Path, right: Path) -> bool:\n left_resolved = resolve_audit_file(left)\n right_resolved = resolve_audit_file(right)\n if left_resolved is None or right_resolved is None:\n return False\n try:\n return left_resolved.samefile(right_resolved)\n except OSError:\n return False\n\n\ndef unique_physical_files(paths: list[Path]) -> list[Path]:\n unique: list[Path] = []\n seen: set[tuple[int, int]] = set()\n for path in paths:\n canonical = resolve_audit_file(path)\n if canonical is None:\n continue\n try:\n stat = canonical.stat()\n except OSError:\n continue\n identity = (stat.st_dev, stat.st_ino)\n if identity in seen:\n continue\n seen.add(identity)\n unique.append(path)\n return unique\n\n\ndef project_instruction_files(root: Path) -> list[Path]:\n files = [\n root / \"AGENTS.md\",\n root / \"CLAUDE.md\",\n root / \".github\" / \"copilot-instructions.md\",\n root / \"GEMINI.md\",\n ]\n instructions_dir = root / \".github\" / \"instructions\"\n if resolve_audit_dir(instructions_dir) is not None:\n files.extend(sorted(instructions_dir.glob(\"*.md\")))\n return unique_physical_files(files)\n\n\nWALK_EXCLUDED_DIRS = {\n \".git\", \".hg\", \".svn\", \"node_modules\", \"dist\", \"build\", \".next\",\n \"__pycache__\", \".venv\", \"venv\", \"target\", \"coverage\", \".cache\",\n \".pytest_cache\", \".mypy_cache\", \".ruff_cache\", \"Pods\", \"Carthage\",\n \".swiftpm\", \".gradle\",\n}\n\nPROJECT_INSTRUCTION_MODES = (\n \"claude-md\",\n \"claude-md-or-agents-md\",\n \"claude-md-and-agents-md\",\n \"managed-only\",\n)\n\n\ndef project_instructions_mode(settings_path: Path) -> str:\n \"\"\"Which files Claude Code loads as project instructions.\n\n The built-in `cc-plugin-agents-md` mod (`agents-md` before v2.1.285)\n decides whether an `AGENTS.md` counts. Since v2.1.277 it is on by default\n in `claude-md-or-agents-md`: a root `CLAUDE.md` wins, otherwise\n `AGENTS.md` loads. `pluginConfigs` only changes that mode, and disabling\n the plugin in `enabledPlugins` turns `AGENTS.md` off altogether.\n \"\"\"\n default = \"claude-md-or-agents-md\"\n value, _ = load_json(settings_path)\n if not isinstance(value, dict):\n return default\n ids = (\"cc-plugin-agents-md@builtin\", \"agents-md@builtin\")\n enabled = value.get(\"enabledPlugins\")\n if isinstance(enabled, dict) and any(enabled.get(key) is False for key in ids):\n return \"claude-md\"\n configs = value.get(\"pluginConfigs\")\n if not isinstance(configs, dict):\n return default\n for key in ids:\n entry = configs.get(key)\n options = entry.get(\"options\") if isinstance(entry, dict) else None\n mode = options.get(\"instructionFiles\") if isinstance(options, dict) else None\n if mode in PROJECT_INSTRUCTION_MODES:\n return mode\n return default\n\n\ndef nested_agents_files(root: Path) -> list[Path]:\n \"\"\"`AGENTS.md` below the root, which only some runtimes walk into.\"\"\"\n resolved = resolve_audit_dir(root)\n if resolved is None:\n return []\n found: list[Path] = []\n for path in sorted(resolved.rglob(\"AGENTS.md\")):\n if path.parent == resolved:\n continue\n if any(part.startswith(\".\") or part in WALK_EXCLUDED_DIRS for part in path.relative_to(resolved).parts[:-1]):\n continue\n found.append(path)\n return unique_physical_files(found)\n\n\ndef claude_delegates_to_agents(path: Path) -> bool:\n text = read(path, 20_000)\n if not text:\n return False\n meaningful = [\n line.strip()\n for line in text.splitlines()\n if line.strip() and not line.strip().startswith(\"#\")\n ]\n return any(\"AGENTS.md\" in line for line in meaningful)\n\n\ndef has_operational_rules(path: Path) -> bool:\n text = read(path, 40_000)\n if not text:\n return False\n return len(set(m.group(1).lower() for m in OPERATIONAL_RULE_RE.finditer(text))) >= 2\n\n\ndef looks_identity_only(path: Path) -> bool:\n text = read(path, 40_000)\n if not text:\n return False\n return \"nian-identity:start\" in text and not has_operational_rules(path)\n\n\ndef rule_paths(text: str) -> list[str]:\n if not text.startswith(\"---\"):\n return []\n lines = text.splitlines()\n paths: list[str] = []\n in_paths = False\n for line in lines[1:]:\n stripped = line.strip()\n if stripped == \"---\":\n break\n if stripped == \"paths:\":\n in_paths = True\n continue\n if in_paths and stripped.startswith(\"-\"):\n value = stripped[1:].strip().strip('\"\\'')\n if value:\n paths.append(value)\n continue\n if in_paths and stripped and not line.startswith((\" \", \"\\t\")):\n in_paths = False\n return paths\n\n\ndef selector_pattern(selector: str) -> re.Pattern[str]:\n \"\"\"Compile Claude's slash-aware * / ** path glob subset.\"\"\"\n pattern = [\"^\"]\n index = 0\n while index \u003c len(selector):\n char = selector[index]\n if char == \"*\":\n if index + 1 \u003c len(selector) and selector[index + 1] == \"*\":\n if index + 2 \u003c len(selector) and selector[index + 2] == \"/\":\n pattern.append(\"(?:.*/)?\")\n index += 3\n else:\n pattern.append(\".*\")\n index += 2\n else:\n pattern.append(\"[^/]*\")\n index += 1\n elif char == \"?\":\n pattern.append(\"[^/]\")\n index += 1\n else:\n pattern.append(re.escape(char))\n index += 1\n pattern.append(\"$\")\n return re.compile(\"\".join(pattern))\n\n\ndef context_units(text: str) -> int:\n \"\"\"Conservative language-neutral context estimate for rule budgeting.\"\"\"\n cjk_characters = len(CJK_CONTEXT_RE.findall(text))\n non_cjk_words = len(CJK_CONTEXT_RE.sub(\" \", text).split())\n return non_cjk_words + cjk_characters\n\n\ndef project_relative_files(root: Path) -> tuple[list[str], bool]:\n excluded = WALK_EXCLUDED_DIRS\n paths: list[str] = []\n for dirpath, dirnames, filenames in os.walk(root, followlinks=False):\n current = Path(dirpath)\n dirnames[:] = sorted(\n name\n for name in dirnames\n if name not in excluded and not (current / name).is_symlink()\n )\n for filename in sorted(filenames):\n path = current / filename\n if path.is_symlink() or not path.is_file():\n continue\n try:\n relative = path.relative_to(root).as_posix()\n except ValueError:\n continue\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in relative):\n continue\n paths.append(relative)\n if len(paths) >= MAX_CONTEXT_PROJECT_FILES:\n return paths, True\n return paths, False\n\n\ndef summarize_rule_context(\n rule_roots: list[tuple[str, Path]], root: Path\n) -> tuple[str, list[str]]:\n path_counts: Counter[str] = Counter()\n path_words: Counter[str] = Counter()\n path_units: Counter[str] = Counter()\n rule_entries: list[tuple[str, int, int, list[re.Pattern[str]]]] = []\n scoped_files = 0\n scoped_words = 0\n scoped_units = 0\n always_files = 0\n always_words = 0\n always_units = 0\n rule_files: list[tuple[str, Path]] = []\n seen_rules: set[Path] = set()\n for scope, rule_root in rule_roots:\n if resolve_audit_dir(rule_root) is None:\n continue\n for path in sorted(rule_root.glob(\"*.md\")):\n canonical = resolve_audit_file(path)\n if canonical is None or canonical in seen_rules:\n continue\n seen_rules.add(canonical)\n rule_files.append((scope, path))\n selector_count = 0\n for scope, path in rule_files:\n text = read(path)\n words = len(text.split())\n units = context_units(text)\n paths = rule_paths(text)\n if paths:\n scoped_files += 1\n scoped_words += words\n scoped_units += units\n selector_count += len(paths)\n rule_entries.append(\n (\n f\"{scope}:{path.name}\",\n words,\n units,\n [selector_pattern(selector) for selector in paths],\n )\n )\n for selector in paths:\n path_counts[selector] += 1\n path_words[selector] += words\n path_units[selector] += units\n else:\n always_files += 1\n always_words += words\n always_units += units\n ranked = sorted(\n path_counts,\n key=lambda selector: (path_units[selector], path_counts[selector], selector),\n reverse=True,\n )\n effective_loads: list[tuple[int, int, str, list[str]]] = []\n project_files, project_files_truncated = project_relative_files(root)\n match_evaluations = 0\n match_budget_exhausted = False\n for relative in project_files:\n matching: list[tuple[str, int, int]] = []\n for name, words, units, patterns in rule_entries:\n matched = False\n for pattern in patterns:\n if match_evaluations >= MAX_CONTEXT_MATCH_EVALUATIONS:\n match_budget_exhausted = True\n break\n match_evaluations += 1\n if pattern.fullmatch(relative):\n matched = True\n break\n if match_budget_exhausted:\n break\n if matched:\n matching.append((name, words, units))\n if match_budget_exhausted:\n break\n if matching:\n effective_loads.append(\n (\n sum(units for _, _, units in matching),\n sum(words for _, words, _ in matching),\n relative,\n [name for name, _, _ in matching],\n )\n )\n effective_loads.sort(key=lambda item: (item[0], item[2]), reverse=True)\n findings: list[str] = []\n oversized_files: list[str] = []\n for scope, path in rule_files:\n text = read(path)\n words = len(text.split())\n units = context_units(text)\n if units > 5_000:\n oversized_files.append(\n f\"{scope}:{path.name} words={words} context_units={units}\"\n )\n if always_units > 5_000:\n findings.append(\n \"always-loaded rules exceed 5000 context units: \"\n f\"words={always_words} context_units={always_units}\"\n )\n if ranked and path_units[ranked[0]] > 10_000:\n findings.append(\n \"one path selector loads more than 10000 context units: \"\n f\"{ranked[0]} words={path_words[ranked[0]]} \"\n f\"context_units={path_units[ranked[0]]}\"\n )\n if effective_loads and effective_loads[0][0] > 10_000:\n units, words, relative, matching_rules = effective_loads[0]\n findings.append(\n \"one project path loads more than 10000 effective context units: \"\n f\"{relative} words={words} context_units={units} \"\n f\"rules={','.join(matching_rules)}\"\n )\n if oversized_files:\n findings.append(\"oversized path rules: \" + \", \".join(oversized_files[:5]))\n if project_files_truncated:\n findings.append(\n f\"project path inventory exceeded {MAX_CONTEXT_PROJECT_FILES} files\"\n )\n if match_budget_exhausted:\n findings.append(\n \"path rule matching exceeded \"\n f\"{MAX_CONTEXT_MATCH_EVALUATIONS} evaluations\"\n )\n status = \"WARN\" if findings else \"PASS\"\n lines = [\n \"=== PATH-SCOPED CONTEXT ===\",\n f\"path_context_status: {status}\",\n f\"path_context_rule_roots_scanned: {len(rule_roots)}\",\n f\"path_context_selectors: {selector_count}\",\n f\"path_context_project_files: {len(project_files)}\",\n f\"path_context_project_files_truncated: {'yes' if project_files_truncated else 'no'}\",\n f\"path_context_match_evaluations: {match_evaluations}\",\n f\"path_context_match_budget_exhausted: {'yes' if match_budget_exhausted else 'no'}\",\n f\"path_scoped_rule_files: {scoped_files}\",\n f\"path_scoped_rule_words: {scoped_words}\",\n f\"path_scoped_rule_context_units: {scoped_units}\",\n f\"always_loaded_rule_files: {always_files}\",\n f\"always_loaded_rule_words: {always_words}\",\n f\"always_loaded_rule_context_units: {always_units}\",\n \"largest_path_triggers:\",\n ]\n if not ranked:\n lines.append(\" (none)\")\n else:\n for selector in ranked[:10]:\n lines.append(\n f\" selector={safe_label(selector)} files={path_counts[selector]} \"\n f\"combined_words={path_words[selector]} \"\n f\"combined_context_units={path_units[selector]}\"\n )\n lines.append(\"largest_effective_paths:\")\n if not effective_loads:\n lines.append(\" (none)\")\n else:\n for units, words, relative, matching_rules in effective_loads[:10]:\n lines.append(\n f\" path={safe_label(relative)} words={words} \"\n f\"context_units={units} \"\n f\"rules={safe_label(','.join(matching_rules))}\"\n )\n lines.append(\"path_context_findings:\")\n lines.extend(f\" {item}\" for item in (findings or [\"(none)\"]))\n return status, lines\n\n\ndef skill_name(path: Path) -> str:\n for line in read(path, 8_000).splitlines()[:40]:\n match = re.match(r\"^name:\\s*[\\\"']?([^\\\"']+?)[\\\"']?\\s*$\", line.strip())\n if match:\n return safe_label(match.group(1).strip())\n return \"\"\n\n\ndef display_path(path: Path, root: Path, home: Path) -> str:\n for base, prefix in ((root, \"project:/\"), (home, \"~/\")):\n try:\n return safe_label(prefix + path.relative_to(base).as_posix())\n except ValueError:\n continue\n return safe_label(path.as_posix())\n\n\ndef broken_symlink(path: Path) -> bool:\n if not path.is_symlink():\n return False\n try:\n path.resolve(strict=True)\n except FileNotFoundError:\n return True\n except (OSError, RuntimeError):\n pass\n return False\n\n\ndef candidate_skill_files(root: Path, home: Path) -> tuple[list[Path], int, list[Path]]:\n roots = [\n root / \".claude\" / \"skills\",\n root / \".agents\" / \"skills\",\n root / \".codex\" / \"skills\",\n home / \".claude\" / \"skills\",\n home / \".agents\" / \"skills\",\n home / \".codex\" / \"skills\",\n ]\n candidates: list[Path] = []\n broken_links: set[Path] = set()\n repository_roots: set[Path] = set()\n for skill_root in roots:\n if broken_symlink(skill_root):\n broken_links.add(skill_root)\n if resolve_audit_dir(skill_root) is None:\n continue\n candidates.extend(skill_root.glob(\"*/SKILL.md\"))\n for child in skill_root.iterdir():\n if broken_symlink(child):\n broken_links.add(child)\n continue\n if resolve_audit_dir(child) is not None and broken_symlink(child / \"SKILL.md\"):\n broken_links.add(child / \"SKILL.md\")\n if not child.is_symlink():\n continue\n try:\n resolved = child.resolve(strict=True)\n except OSError:\n continue\n if resolve_audit_dir(resolved) is None:\n continue\n if (\n resolve_audit_dir(resolved / \"skills\") is not None\n or resolve_audit_dir(resolved / \"plugins\") is not None\n ):\n repository_roots.add(resolved)\n for repository in repository_roots:\n candidates.extend(repository.glob(\"skills/*/SKILL.md\"))\n unique: dict[Path, Path] = {}\n mirrors_collapsed = 0\n for path in candidates:\n canonical = resolve_audit_file(path)\n if canonical is None:\n continue\n if canonical in unique:\n mirrors_collapsed += 1\n continue\n unique[canonical] = path\n return sorted(unique.values()), mirrors_collapsed, sorted(broken_links)\n\n\ndef skill_runtime(path: Path, root: Path, home: Path) -> str:\n for base, runtime in (\n (root / \".claude\" / \"skills\", \"claude\"),\n (home / \".claude\" / \"skills\", \"claude\"),\n (root / \".agents\" / \"skills\", \"agents\"),\n (home / \".agents\" / \"skills\", \"agents\"),\n (root / \".codex\" / \"skills\", \"codex\"),\n (home / \".codex\" / \"skills\", \"codex\"),\n ):\n try:\n path.relative_to(base)\n return runtime\n except ValueError:\n continue\n return \"other\"\n\n\ndef summarize_skill_duplicates(root: Path, home: Path) -> tuple[str, list[str]]:\n by_name: dict[str, list[tuple[Path, str, str]]] = defaultdict(list)\n skill_files, mirrors_collapsed, broken_links = candidate_skill_files(root, home)\n for path in skill_files:\n name = skill_name(path)\n if not name:\n continue\n try:\n raw = read_bytes(path)\n if not raw:\n continue\n digest = hashlib.sha256(raw).hexdigest()\n except OSError:\n continue\n by_name[name].append((path, digest, skill_runtime(path, root, home)))\n duplicate_lines: list[str] = []\n cross_runtime_lines: list[str] = []\n cross_runtime_conflicts: list[str] = []\n for name, entries in sorted(by_name.items()):\n if len(entries) \u003c 2:\n continue\n by_runtime: dict[str, list[tuple[Path, str]]] = defaultdict(list)\n for path, digest, runtime in entries:\n by_runtime[runtime].append((path, digest))\n same_runtime = {\n runtime: runtime_entries\n for runtime, runtime_entries in by_runtime.items()\n if len(runtime_entries) > 1\n }\n if same_runtime:\n flattened = [item for group in same_runtime.values() for item in group]\n digest_counts = Counter(digest for _, digest in flattened)\n exact_duplicate = any(count > 1 for count in digest_counts.values())\n kind = \"exact-copy\" if exact_duplicate else \"name-collision\"\n surfaces = \", \".join(\n display_path(path, root, home) for path, _ in flattened[:6]\n )\n duplicate_lines.append(f\"{name}: kind={kind} surfaces={surfaces}\")\n elif len(by_runtime) > 1:\n runtimes = \",\".join(sorted(by_runtime))\n digests = {digest for _path, digest, _runtime in entries}\n content = \"identical\" if len(digests) == 1 else \"divergent\"\n line = f\"{name}: runtimes={runtimes} content={content}\"\n cross_runtime_lines.append(line)\n if content == \"divergent\":\n cross_runtime_conflicts.append(line)\n source_skill_files = (\n unique_physical_files(list((root / \"skills\").glob(\"*/SKILL.md\")))\n if resolve_audit_dir(root / \"skills\") is not None\n else []\n )\n lines = [\n \"=== SKILL ROUTING DUPLICATES ===\",\n f\"skill_files_scanned: {sum(len(entries) for entries in by_name.values())}\",\n f\"mirrored_skill_files_collapsed: {mirrors_collapsed}\",\n f\"source_skill_files_scanned: {len(source_skill_files)}\",\n f\"duplicate_skill_names: {len(duplicate_lines)}\",\n \"duplicate_skills:\",\n ]\n lines.extend(f\" {line}\" for line in (duplicate_lines or [\"(none)\"]))\n lines.append(f\"cross_runtime_shared_skill_names: {len(cross_runtime_lines)}\")\n lines.append(\"cross_runtime_skills:\")\n lines.extend(f\" {line}\" for line in (cross_runtime_lines or [\"(none)\"]))\n lines.append(f\"cross_runtime_conflicts: {len(cross_runtime_conflicts)}\")\n lines.append(f\"broken_skill_links: {len(broken_links)}\")\n if broken_links:\n lines.append(\"broken_skill_link_paths:\")\n lines.extend(f\" {display_path(path, root, home)}\" for path in broken_links)\n return (\"WARN\" if duplicate_lines or cross_runtime_conflicts or broken_links else \"PASS\"), lines\n\n\ndef parse_codex_config(\n path: Path,\n) -> tuple[dict[str, str], list[str], list[str], list[str], list[str]]:\n projects: dict[str, str] = {}\n features: list[str] = []\n plugins: list[str] = []\n marketplaces: list[str] = []\n redacted: list[str] = []\n if resolve_audit_file(path) is None:\n return projects, features, plugins, marketplaces, redacted\n\n section = \"\"\n for raw in read(path).splitlines():\n line = raw.strip()\n if not line or line.startswith(\"#\"):\n continue\n project_match = PROJECT_RE.match(line)\n if project_match:\n section = f'projects.\"{project_match.group(1)}\"'\n projects.setdefault(project_match.group(1), \"\")\n continue\n table_match = TABLE_RE.match(line)\n if table_match:\n section = table_match.group(1)\n marketplace_match = re.match(r'marketplaces\\.([A-Za-z0-9_.@-]+)

Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…

, section)\n plugin_match = re.fullmatch(r'plugins\\.(?:\"([^\"]+)\"|([A-Za-z0-9_@-]+))', section)\n if marketplace_match:\n marketplaces.append(marketplace_match.group(1))\n if plugin_match:\n plugins.append(plugin_match.group(1) or plugin_match.group(2))\n continue\n\n if SENSITIVE_RE.search(line):\n key = line.split(\"=\", 1)[0].strip() if \"=\" in line else \"sensitive\"\n redacted.append(f\"{key}=[REDACTED]\")\n continue\n\n if \"=\" not in line:\n continue\n key, value = [part.strip() for part in line.split(\"=\", 1)]\n plugin_match = re.fullmatch(r'plugins\\.(?:\"([^\"]+)\"|([A-Za-z0-9_@-]+))', section)\n if plugin_match and key == \"enabled\":\n name = plugin_match.group(1) or plugin_match.group(2)\n if value.split(\"#\", 1)[0].strip() == \"false\" and name in plugins:\n plugins.remove(name)\n if section == \"features\" and value.split(\"#\", 1)[0].strip().strip('\"').lower() == \"true\":\n features.append(key)\n elif section.startswith('projects.\"') and key == \"trust_level\":\n project = section[len('projects.\"'): -1]\n projects[project] = value.strip('\"')\n\n return (\n projects,\n sorted(set(features)),\n sorted(set(plugins)),\n sorted(set(marketplaces)),\n sorted(set(redacted)),\n )\n\n\ndef shell_tokens(command: str) -> list[str]:\n try:\n lexer = shlex.shlex(command, posix=True, punctuation_chars=True)\n lexer.whitespace_split = True\n return list(lexer)\n except ValueError:\n return []\n\n\ndef command_word_index(tokens: list[str], start: int = 0) -> int:\n \"\"\"Return the executed word of the simple command at start, or -1 for an unmodeled prefix.\n\n Skips assignments, redirections, reserved prefix words, and env, exec and command\n prefixes in any order. An index at the end or on a control operator means no word.\n \"\"\"\n index = start\n while index \u003c len(tokens):\n token = tokens[index]\n if token in CONTROL_OPERATORS:\n return index\n if ASSIGNMENT_RE.fullmatch(token) or token in COMMAND_PREFIX_WORDS:\n index += 1\n elif token in REDIRECT_OPERATORS:\n index += 2\n elif token.isdigit() and index + 1 \u003c len(tokens) and tokens[index + 1] in REDIRECT_OPERATORS:\n index += 3\n elif Path(token).name == \"env\":\n index += 1\n while index \u003c len(tokens) and tokens[index].startswith(\"-\"):\n flag = tokens[index]\n if flag in {\"-u\", \"--unset\"}:\n index += 2\n elif flag in ENV_FLAGS or flag.startswith(\"--unset=\"):\n index += 1\n else:\n return -1\n elif token == \"exec\":\n index += 1\n while index \u003c len(tokens) and tokens[index].startswith(\"-\"):\n flag = tokens[index]\n if flag == \"-a\":\n index += 2\n elif set(flag[1:]) \u003c= {\"c\", \"l\"}:\n index += 1\n else:\n return -1\n elif token == \"time\":\n index += 1\n while index \u003c len(tokens) and tokens[index] in {\"-p\", \"--\"}:\n index += 1\n elif token == \"command\" and index + 1 \u003c len(tokens) and tokens[index + 1] == \"-p\":\n index += 2\n elif token == \"command\" and index + 1 \u003c len(tokens) and not tokens[index + 1].startswith(\"-\"):\n index += 1\n elif token.startswith(\"-\"):\n return -1\n else:\n return index\n return index\n\n\ndef hook_command_words(tokens: list[str]) -> list[Optional[str]]:\n \"\"\"Executed word of each simple command in a hook; None marks an unmodeled prefix.\"\"\"\n words: list[Optional[str]] = []\n index = 0\n while index \u003c len(tokens):\n word_index = command_word_index(tokens, index)\n if word_index \u003c 0:\n words.append(None)\n word_index = index\n elif word_index \u003c len(tokens) and tokens[word_index] not in CONTROL_OPERATORS:\n words.append(tokens[word_index])\n while word_index \u003c len(tokens) and tokens[word_index] not in CONTROL_OPERATORS:\n word_index += 1\n index = word_index + 1\n return words\n\n\ndef runtime_inventory(root: Path, home: Path) -> list[str]:\n \"\"\"Inspect configured sources without starting servers or exposing arguments.\"\"\"\n lines = [\"=== RUNTIME CONFIGURATION ===\",\n \"runtime_probe: static; no servers started\",\n \"plugin_mcp_coverage: Claude user registry; Codex plugin state not inspected\"]\n servers: dict[str, dict[str, tuple[str, dict]]] = {\"claude\": {}, \"codex\": {}}\n sources = [\n (\"claude:user\", home / \".claude.json\"),\n (\"claude:project\", root / \".mcp.json\"),\n (\"claude:global\", home / \".claude\" / \"settings.json\"),\n (\"claude:shared\", root / \".claude\" / \"settings.json\"),\n (\"claude:local\", root / \".claude\" / \"settings.local.json\"),\n (\"codex:global\", home / \".codex\" / \"hooks.json\"),\n ]\n def executable_state(command: object) -> str:\n if not isinstance(command, str) or not command:\n return \"remote\"\n if \"$\" in command:\n return \"unresolved\"\n if command.startswith(\"~/\"):\n path = home / command[2:]\n elif Path(command).is_absolute():\n path = Path(command)\n elif \"/\" in command or \"\\\\\" in command:\n return \"relative; runtime working directory required\"\n else:\n return \"found\" if shutil.which(command) else \"missing\"\n return \"found\" if path.is_file() and os.access(path, os.X_OK) else \"missing\"\n\n settings, _ = load_json(home / \".claude\" / \"settings.json\")\n installed, _ = load_json(home / \".claude\" / \"plugins\" / \"installed_plugins.json\")\n if isinstance(settings, dict) and isinstance(installed, dict):\n registry = installed.get(\"plugins\", {})\n enabled_plugins = settings.get(\"enabledPlugins\", {})\n for name, enabled in enabled_plugins.items() if isinstance(enabled_plugins, dict) else []:\n if enabled is not True or not isinstance(registry, dict):\n continue\n entries = registry.get(name, [])\n for entry in entries if isinstance(entries, list) else []:\n if isinstance(entry, dict) and entry.get(\"scope\") == \"user\" and isinstance(entry.get(\"installPath\"), str):\n sources.append((\"claude:plugin:\" + str(name), Path(entry[\"installPath\"]) / \".mcp.json\"))\n # Claude resolves same-name MCP servers as local > project > user.\n precedence = {\"claude:user\": 1, \"claude:project\": 2, \"claude:local-project\": 3}\n disabled_names: set[str] = set()\n disabled_mcpjson: set[str] = set()\n approved_mcpjson: set[str] = set()\n approve_all_mcpjson = False\n user_servers: dict[str, dict] = {}\n # Claude names plugin servers plugin:\u003cplugin>:\u003cserver>; that name is what disable lists hold.\n plugin_runtime_names: dict[str, str] = {}\n\n def listed(name: Optional[str], names: set[str]) -> bool:\n # Approval and disable lists may hold the normalized form Claude shows in /mcp.\n if name is None:\n return False\n return name in names or re.sub(r\"[^A-Za-z0-9_-]\", \"_\", name) in {\n re.sub(r\"[^A-Za-z0-9_-]\", \"_\", item) for item in names\n }\n\n def add_claude_server(name: str, label: str, config: dict) -> None:\n if label == \"claude:user\":\n user_servers[name] = config\n existing = servers[\"claude\"].get(name)\n if existing and precedence.get(existing[0], 0) > precedence.get(label, 0) > 0:\n return\n servers[\"claude\"][name] = (label, config)\n\n for label, path in sources:\n data, error = load_json(path)\n if error:\n lines.append(f\"{label} config=invalid\")\n if not isinstance(data, dict):\n continue\n if label in {\"claude:user\", \"claude:project\"} or \":plugin:\" in label:\n mappings = data.get(\"mcpServers\", data if \":plugin:\" in label else {})\n for name, config in mappings.items() if isinstance(mappings, dict) else []:\n if isinstance(config, dict):\n server_name = label + \":\" + str(name) if \":plugin:\" in label else str(name)\n if \":plugin:\" in label:\n plugin = label.split(\":plugin:\", 1)[1].split(\"@\", 1)[0]\n plugin_runtime_names[server_name] = f\"plugin:{plugin}:{name}\"\n add_claude_server(server_name, label, config)\n elif \"mcpServers\" in data:\n # Claude reads MCP servers from ~/.claude.json, .mcp.json and plugins, never settings files.\n lines.append(f\"{label} mcp_servers=ignored; not an MCP source\")\n approval_sources: list[dict] = []\n if label in {\"claude:global\", \"claude:shared\", \"claude:local\"}:\n approval_sources.append(data)\n if label == \"claude:user\":\n projects = data.get(\"projects\", {})\n local = projects.get(str(root), {}) if isinstance(projects, dict) else {}\n local = local if isinstance(local, dict) else {}\n mappings = local.get(\"mcpServers\", {})\n for name, config in mappings.items() if isinstance(mappings, dict) else []:\n if isinstance(config, dict):\n add_claude_server(str(name), \"claude:local-project\", config)\n names = local.get(\"disabledMcpServers\", [])\n if isinstance(names, list):\n disabled_names.update(n for n in names if isinstance(n, str))\n approval_sources.append(local)\n for source in approval_sources:\n for key, target in ((\"disabledMcpjsonServers\", disabled_mcpjson),\n (\"enabledMcpjsonServers\", approved_mcpjson)):\n names = source.get(key, [])\n if isinstance(names, list):\n target.update(n for n in names if isinstance(n, str))\n if source.get(\"enableAllProjectMcpServers\") is True:\n approve_all_mcpjson = True\n hooks = data.get(\"hooks\", {})\n if not isinstance(hooks, dict):\n continue\n for event, groups in hooks.items():\n for group in groups if isinstance(groups, list) else []:\n if not isinstance(group, dict):\n continue\n handlers = group.get(\"hooks\", [])\n for handler in handlers if isinstance(handlers, list) else []:\n if not isinstance(handler, dict):\n continue\n kind = handler.get(\"type\", \"unknown\")\n lines.append(f\"{label} hook={safe_label(str(event))} type={safe_label(str(kind))}\")\n command = handler.get(\"command\", \"\")\n if kind == \"command\" and isinstance(command, str):\n states: list[str] = []\n for word in hook_command_words(shell_tokens(command)):\n if word is None:\n state = \"unverified; unmodeled command prefix\"\n elif word in SHELL_BUILTINS or set(word) \u003c= set(\"();\u003c>|&\"):\n continue\n else:\n state = executable_state(word)\n if state not in states:\n states.append(state)\n lines.append(f\"{label} hook_executable={state}\")\n elif kind == \"mcp_tool\":\n if not handler.get(\"server\") or not handler.get(\"tool\"):\n lines.append(f\"{label} mcp_hook=missing server or tool\")\n elif kind not in {\"prompt\", \"agent\", \"http\", \"command\"}:\n lines.append(f\"{label} hook_type=unverified\")\n\n # Codex runs without config.toml and still applies its default limit; no ~/.codex means no budget.\n codex_config = home / \".codex\" / \"config.toml\"\n codex = {} if (home / \".codex\").is_dir() else None\n if codex is not None and codex_config.exists() and yes(codex_config) == \"no\":\n codex = None\n lines.append(\"codex_runtime_config: unavailable; config.toml is outside the audit scope\")\n elif yes(codex_config) == \"yes\":\n codex = None\n # TOML parsing is optional on Python 3.9/3.10; report the gap, never a false zero.\n try:\n import tomllib\n except ImportError:\n lines.append(\"codex_runtime_config: unavailable; Python 3.11+ TOML parser required\")\n else:\n try:\n codex = tomllib.loads(read(codex_config))\n except (ValueError, OSError):\n lines.append(\"codex_runtime_config: invalid\")\n if codex is not None:\n mappings = codex.get(\"mcp_servers\", {})\n for name, config in mappings.items() if isinstance(mappings, dict) else []:\n if isinstance(config, dict):\n servers[\"codex\"][name] = (\"codex:user\", config)\n limit = codex.get(\"project_doc_max_bytes\", 32768)\n if isinstance(limit, int) and not isinstance(limit, bool) and limit > 0:\n # Codex charges only project docs against the limit; ~/.codex/AGENTS.md is separate.\n project_file = next((p for p in [root / \"AGENTS.override.md\", root / \"AGENTS.md\"] if read(p).strip()), None)\n total = len(read_bytes(project_file)) if project_file else 0\n lines.append(\"instruction_budget_scope: user config and current root project doc; global AGENTS.md not charged; ancestors, nested and fallback-name docs not included\")\n lines.append(f\"project_instruction_bytes: {total}\")\n lines.append(f\"project_instruction_limit: {limit}\")\n lines.append(f\"project_instruction_limit_exceeded: {'yes' if total > limit else 'no'}\")\n for runtime, entries in servers.items():\n for name, (label, config) in sorted(entries.items()):\n # .mcp.json entries load only once approved; until then a same-name user server stays live.\n rejected = label == \"claude:project\" and listed(name, disabled_mcpjson)\n pending = (label == \"claude:project\" and not rejected\n and not approve_all_mcpjson and not listed(name, approved_mcpjson))\n if (rejected or pending) and name in user_servers:\n label, config = \"claude:user\", user_servers[name]\n rejected = pending = False\n disabled = config.get(\"enabled\") is False or config.get(\"disabled\") is True\n if runtime == \"claude\" and (\n rejected\n or listed(name, disabled_names)\n or listed(plugin_runtime_names.get(name), disabled_names)\n ):\n disabled = True\n state = \"disabled\" if disabled else \"pending\" if pending else \"enabled\"\n executable = \"skipped\" if disabled else executable_state(config.get(\"command\"))\n lines.append(f\"{label} mcp={safe_label(name)} state={state} executable={executable}\")\n return lines\n\n\ndef permission_rules(data: object, key: str) -> list[str]:\n if not isinstance(data, dict):\n return []\n permissions = data.get(\"permissions\")\n if not isinstance(permissions, dict):\n return []\n value = permissions.get(key)\n if not isinstance(value, list):\n return []\n return [str(item) for item in value if isinstance(item, str)]\n\n\ndef parse_permission_rule(rule: str) -> tuple[str, str] | None:\n match = re.fullmatch(r\"([A-Za-z][A-Za-z0-9_]*)\\((.*)\\)\", rule.strip())\n if not match:\n return None\n return match.group(1), match.group(2).strip()\n\n\ndef normalized_rule_targets(rules: list[str], tool: str) -> list[str]:\n targets: list[str] = []\n for rule in rules:\n parsed = parse_permission_rule(rule)\n if parsed is None or parsed[0].lower() != tool.lower():\n continue\n targets.append(parsed[1].replace(\"\\\\\", \"/\").lower())\n return targets\n\n\ndef expand_permission_target(target: str, home: Path) -> str:\n normalized = target.strip().replace(\"\\\\\", \"/\")\n home_text = home.resolve().as_posix().lower()\n lowered = normalized.lower()\n for prefix in (\"${home}\", \"$home\", \"~\"):\n if lowered == prefix:\n return home_text\n if lowered.startswith(prefix + \"/\"):\n return home_text + normalized[len(prefix):].lower()\n return lowered\n\n\ndef target_covers_samples(target: str, home: Path, samples: tuple[str, ...]) -> bool:\n pattern = expand_permission_target(target, home)\n home_text = home.resolve().as_posix().lower()\n return all(\n fnmatch.fnmatchcase(f\"{home_text}/{sample.lower()}\", pattern)\n for sample in samples\n )\n\n\ndef target_covers_command(target: str, command: str) -> bool:\n escaped = re.escape(command.lower())\n return re.fullmatch(rf\"{escaped}(?::\\*|\\s+\\*.*)\", target.strip()) is not None\n\n\ndef resolve_command_path(token: str, home: Path, project_root: Path) -> Path | None:\n if token.startswith(\"~/\"):\n candidate = home / token[2:]\n elif token.startswith(\"$HOME/\"):\n candidate = home / token[6:]\n elif token.startswith(\"${HOME}/\"):\n candidate = home / token[8:]\n else:\n candidate = Path(token)\n if not candidate.is_absolute():\n candidate = project_root / candidate\n return resolve_audit_file(candidate)\n\n\ndef resolve_hook_handler(command: str, home: Path, project_root: Path) -> Path | None:\n tokens = shell_tokens(command)\n command_index = command_word_index(tokens)\n if command_index \u003c 0 or command_index >= len(tokens) or tokens[command_index] in CONTROL_OPERATORS:\n return None\n # PATH, PYTHONPATH and loader overrides can swap what the hook runs, `!` can invert its exit\n # status, and a redirect can cut it off from the tool input on stdin, so the floor credits none.\n if any(\n RISKY_ENV_RE.match(token) or token in COMMAND_PREFIX_WORDS or token in REDIRECT_OPERATORS\n or token == \"time\"\n for token in tokens[:command_index]\n ):\n return None\n\n executable = tokens[command_index]\n if Path(executable).name in {\"python\", \"python3\"}:\n safe_flags = {\"-B\", \"-E\", \"-I\", \"-O\", \"-OO\", \"-P\", \"-q\", \"-s\", \"-S\", \"-u\", \"-v\"}\n for index, token in enumerate(tokens[command_index + 1 :], command_index + 1):\n if token == \"--\":\n continue\n if token.startswith(\"-\"):\n if token not in safe_flags:\n return None\n continue\n if index != len(tokens) - 1:\n return None\n resolved = resolve_command_path(token, home, project_root)\n return resolved if resolved is not None and resolved.suffix == \".py\" else None\n return None\n return None\n\n\ndef hook_handler_enforces_pipe_block(path: Path) -> bool:\n canonical = Path(__file__).with_name(\"block-pipe-to-shell.py\")\n candidate_bytes = read_bytes(path)\n canonical_bytes = read_bytes(canonical)\n return bool(candidate_bytes) and candidate_bytes == canonical_bytes\n\n\ndef has_pretool_bash_hook(\n data: object,\n home: Path,\n project_root: Path,\n) -> bool:\n if not isinstance(data, dict):\n return False\n hooks = data.get(\"hooks\")\n if not isinstance(hooks, dict):\n return False\n pretool = hooks.get(\"PreToolUse\")\n if not isinstance(pretool, list):\n return False\n for group in pretool:\n if not isinstance(group, dict) or group.get(\"matcher\") != \"Bash\":\n continue\n handlers = group.get(\"hooks\")\n if not isinstance(handlers, list):\n continue\n for handler in handlers:\n if not isinstance(handler, dict) or handler.get(\"type\") != \"command\":\n continue\n command = handler.get(\"command\")\n if not isinstance(command, str):\n continue\n path = resolve_hook_handler(command, home, project_root)\n if path is not None and hook_handler_enforces_pipe_block(path):\n return True\n return False\n\n\ndef deny_category_status(\n rules: list[str],\n hook_present: bool,\n home: Path,\n) -> dict[str, bool]:\n reads = normalized_rule_targets(rules, \"Read\")\n bash = normalized_rule_targets(rules, \"Bash\")\n return {\n \"ssh_directory\": any(\n target_covers_samples(target, home, (\".ssh/id_key\", \".ssh/config\"))\n for target in reads\n ),\n \"aws_directory\": any(\n target_covers_samples(target, home, (\".aws/credentials\", \".aws/config\"))\n for target in reads\n ),\n \"gnupg_directory\": any(\n target_covers_samples(\n target,\n home,\n (\".gnupg/private-keys-v1.d/key\", \".gnupg/gpg.conf\"),\n )\n for target in reads\n ),\n \"gh_directory\": any(\n target_covers_samples(\n target,\n home,\n (\".config/gh/hosts.yml\", \".config/gh/config.yml\"),\n )\n for target in reads\n ),\n \"env_files\": any(\n target_covers_samples(\n target,\n home,\n (\"project/.env\", \"project/.env.local\"),\n )\n for target in reads\n ),\n \"credential_files\": any(\n target_covers_samples(\n target,\n home,\n (\"project/credentials.json\", \"project/service-credentials.txt\"),\n )\n for target in reads\n ),\n \"secrets_directories\": any(\n target_covers_samples(\n target,\n home,\n (\"project/secrets/token\", \"project/secrets/nested/key\"),\n )\n for target in reads\n ),\n \"outbound_shell\": all(\n any(target_covers_command(target, command) for target in bash)\n for command in (\"ssh\", \"scp\", \"nc\")\n ),\n \"pipe_to_shell\": hook_present,\n \"git_reset_hard\": any(\n target_covers_command(target, \"git reset --hard\") for target in bash\n ),\n }\n\n\ndef has_task_scoped_env_policy(paths: list[Path]) -> bool:\n for path in paths:\n text = read(path, 200_000).lower()\n if \".env\" not in text:\n continue\n if re.search(\n r\"task.scoped|current task|task needs|read when needed|\"\n r\"当前任务|确需|外传|写出|不进产出|\"\n r\"do not (?:print|output|commit|exfiltrate)\",\n text,\n ):\n return True\n return False\n\n\ndef summarize_claude_permissions(\n global_path: Path,\n shared_path: Path,\n local_path: Path,\n env_instruction_policy: bool,\n) -> tuple[str, list[str], list[str]]:\n sources = [\n (\"global\", global_path),\n (\"shared\", shared_path),\n (\"local\", local_path),\n ]\n loaded: dict[str, object] = {}\n errors: list[str] = []\n for label, path in sources:\n data, error = load_json(path)\n if error:\n errors.append(f\"{label}: {error}\")\n loaded[label] = data\n\n rules = {\n label: {\n key: permission_rules(loaded[label], key)\n for key in (\"allow\", \"deny\", \"ask\")\n }\n for label, _path in sources\n }\n combined_allow = [\n rule for label, _path in sources for rule in rules[label][\"allow\"]\n ]\n combined_deny = [\n rule for label, _path in sources for rule in rules[label][\"deny\"]\n ]\n home = global_path.parent.parent\n hook_present = any(\n has_pretool_bash_hook(\n loaded[label],\n home,\n path.parent.parent,\n )\n for label, path in sources\n )\n categories = deny_category_status(combined_deny, hook_present, home)\n required_categories = {\n name: present for name, present in categories.items() if name != \"env_files\"\n }\n missing = [name for name, present in required_categories.items() if not present]\n env_policy_complete = categories[\"env_files\"] or env_instruction_policy\n if not env_policy_complete:\n missing.append(\"env_policy\")\n broad_read_allow = any(\n \"**\" in target\n for target in normalized_rule_targets(combined_allow, \"Read\")\n )\n credential_floor = all(required_categories.values()) and env_policy_complete\n settings_surface_present = any(yes(path) == \"yes\" for _label, path in sources)\n findings: list[str] = list(errors)\n if settings_surface_present and not credential_floor:\n findings.append(\n \"configured global + shared project + local project deny floor is incomplete: \"\n + \", \".join(missing)\n )\n lines = [\n \"=== CLAUDE PERMISSION SURFACE ===\",\n f\"global_settings_json: {yes(global_path)}\",\n f\"shared_project_settings_json: {yes(shared_path)}\",\n f\"local_project_settings_json: {yes(local_path)}\",\n ]\n for label, _path in sources:\n lines.extend(\n f\"{label}_{key}_count: {len(rules[label][key])}\"\n for key in (\"allow\", \"deny\", \"ask\")\n )\n lines.extend([\n f\"broad_read_allow_present: {'yes' if broad_read_allow else 'no'}\",\n f\"pretool_pipe_to_shell_hook: {'yes' if hook_present else 'no'}\",\n f\"env_instruction_policy: {'yes' if env_instruction_policy else 'no'}\",\n \"configured_sensitive_deny_floor_complete: \"\n + (\n \"not_applicable\"\n if not settings_surface_present\n else (\"yes\" if credential_floor else \"no\")\n ),\n ])\n lines.extend(\n f\"deny_{name}: {'yes' if present else 'no'}\"\n for name, present in categories.items()\n )\n lines.append(\"permission_findings:\")\n lines.extend(f\" {item}\" for item in (findings or [\"(none)\"]))\n status = \"WARN\" if findings else \"PASS\"\n return status, lines, findings\n\n\ndef project_trust(projects: dict[str, str], root: Path) -> str:\n root_text = root.as_posix()\n if root_text in projects:\n return f\"exact:{safe_label(projects[root_text] or 'configured')}\"\n candidates = []\n for project, level in projects.items():\n try:\n project_path = Path(project).expanduser().resolve()\n except OSError:\n continue\n if project_path == root:\n return f\"exact:{safe_label(level or 'configured')}\"\n try:\n root.relative_to(project_path)\n except ValueError:\n continue\n candidates.append(\n (len(project_path.as_posix()), level or \"configured\", project_path.as_posix())\n )\n if candidates:\n _, level, project = sorted(candidates, reverse=True)[0]\n return f\"inherited:{safe_label(level)} from {safe_label(project)}\"\n return \"missing\"\n\n\ndef summarize_pi_surface(root: Path, home: Path) -> tuple[str, list[str]]:\n global_settings = home / \".pi\" / \"agent\" / \"settings.json\"\n project_settings = root / \".pi\" / \"settings.json\"\n settings_sources = [\n (\"global_settings\", global_settings),\n (\"project_settings\", project_settings),\n ]\n\n configured_skills: list[str] = []\n configured_packages: list[str] = []\n redacted_entries: list[str] = []\n findings: list[str] = []\n malformed = False\n\n for label, path in settings_sources:\n data, error = load_json(path)\n if error:\n malformed = True\n findings.append(error)\n continue\n if not isinstance(data, dict):\n continue\n configured_skills.extend(\n f\"{label}.skills: {item}\" for item in string_list(data.get(\"skills\"))\n )\n configured_packages.extend(\n f\"{label}.packages: {item}\" for item in string_list(data.get(\"packages\"))\n )\n redacted_entries.extend(\n f\"{label}.{item}\" for item in redact_sensitive_entries(data)\n )\n\n package_path = root / \"package.json\"\n package_pi_skills: list[str] = []\n data, error = load_json(package_path)\n if error:\n findings.append(error)\n elif isinstance(data, dict):\n pi_manifest = data.get(\"pi\")\n if isinstance(pi_manifest, dict):\n package_pi_skills = string_list(pi_manifest.get(\"skills\"))\n\n pi_skill_dirs = [\n (\"global_pi_skill_roots\", home / \".pi\" / \"agent\" / \"skills\", True),\n (\"project_pi_skill_roots\", root / \".pi\" / \"skills\", True),\n (\"global_agents_skill_roots\", home / \".agents\" / \"skills\", False),\n (\"project_agents_skill_roots\", root / \".agents\" / \"skills\", False),\n ]\n skill_counts = [\n f\"{label}: {skill_root_count(path, include_root_md)}\"\n for label, path, include_root_md in pi_skill_dirs\n ]\n\n has_pi_surface = (\n yes(global_settings) == \"yes\"\n or yes(project_settings) == \"yes\"\n or bool(package_pi_skills)\n or any(not line.endswith(\": 0\") for line in skill_counts)\n or bool(configured_skills)\n or bool(configured_packages)\n )\n if not has_pi_surface:\n findings.append(\"no Pi settings, package manifest, or skill directories found\")\n\n status = \"WARN\" if malformed else \"PASS\"\n lines = [\n \"=== PI SURFACE ===\",\n f\"pi_status: {status}\",\n f\"global_settings_json: {yes(global_settings)}\",\n f\"project_settings_json: {yes(project_settings)}\",\n f\"package_json: {yes(package_path)}\",\n ]\n lines.extend(skill_counts)\n lines.append(\"package_pi_skills:\")\n lines.extend(f\" {item}\" for item in (package_pi_skills or [\"(none)\"]))\n lines.append(\"configured_skills:\")\n lines.extend(f\" {item}\" for item in (configured_skills or [\"(none)\"]))\n lines.append(\"configured_packages:\")\n lines.extend(f\" {item}\" for item in (configured_packages or [\"(none)\"]))\n lines.append(\"redacted_pi_entries:\")\n lines.extend(f\" {item}\" for item in (redacted_entries or [\"(none)\"]))\n lines.append(\"pi_findings:\")\n lines.extend(f\" {item}\" for item in (findings or [\"(none)\"]))\n return status, lines\n\n\ndef main() -> int:\n global _AUDIT_ROOT, _AUDIT_HOME\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"root\", nargs=\"?\", default=\".\", help=\"Repo root (default: cwd)\")\n parser.add_argument(\n \"mode\", nargs=\"?\", default=\"summary\", choices=(\"summary\", \"deep\"),\n help=\"Output detail level\",\n )\n args = parser.parse_args()\n root = Path(args.root).resolve()\n mode = args.mode\n home = Path(os.environ.get(\"HOME\", str(Path.home()))).expanduser().resolve()\n _AUDIT_ROOT = root\n _AUDIT_HOME = home\n\n if not root.is_dir():\n print(f\"Repo root not found: {safe_label(root.as_posix())}\", file=sys.stderr)\n return 2\n\n instruction_files = project_instruction_files(root)\n agents = root / \"AGENTS.md\"\n claude = root / \"CLAUDE.md\"\n claude_aliases_agents = (\n yes(agents) == \"yes\" and yes(claude) == \"yes\" and same_physical_file(agents, claude)\n )\n claude_delegates = claude_aliases_agents or claude_delegates_to_agents(claude)\n github_instructions_dir = root / \".github\" / \"instructions\"\n github_instruction_count = (\n len(unique_physical_files(list(github_instructions_dir.glob(\"*.md\"))))\n if resolve_audit_dir(github_instructions_dir) is not None else 0\n )\n\n instruction_findings: list[str] = []\n if not instruction_files:\n instruction_findings.append(\"no project agent instruction files\")\n if yes(agents) == \"yes\" and yes(claude) == \"yes\" and not claude_delegates:\n claude_lines = len(read(claude).splitlines())\n agents_lines = len(read(agents).splitlines())\n if claude_lines > 20 and agents_lines > 20:\n instruction_findings.append(\n \"AGENTS.md and CLAUDE.md both contain substantial guidance without delegation\"\n )\n\n global_codex_agents = home / \".codex\" / \"AGENTS.md\"\n codex_config = home / \".codex\" / \"config.toml\"\n projects, features, plugins, marketplaces, redacted = parse_codex_config(codex_config)\n trust = project_trust(projects, root) if yes(codex_config) == \"yes\" else \"unavailable\"\n codex_findings: list[str] = []\n if yes(global_codex_agents) == \"no\" and yes(codex_config) == \"no\":\n codex_findings.append(\"Codex surface not found\")\n elif yes(codex_config) == \"yes\" and trust == \"missing\":\n codex_findings.append(\"current project is not configured in Codex trust table\")\n\n global_claude = home / \".claude\" / \"CLAUDE.md\"\n global_claude_settings = home / \".claude\" / \"settings.json\"\n instructions_mode = project_instructions_mode(global_claude_settings)\n agents_fallback_on = instructions_mode in (\n \"claude-md-or-agents-md\",\n \"claude-md-and-agents-md\",\n )\n nested_agents = nested_agents_files(root)\n shared_project_settings = root / \".claude\" / \"settings.json\"\n local_project_settings = root / \".claude\" / \"settings.local.json\"\n project_rules = root / \".claude\" / \"rules\"\n global_rules = home / \".claude\" / \"rules\"\n project_skill_roots = [\n root / \".claude\" / \"skills\",\n root / \".agents\" / \"skills\",\n root / \".codex\" / \"skills\",\n ]\n global_skills = home / \".claude\" / \"skills\"\n claude_findings: list[str] = []\n if yes(claude) == \"yes\" and claude_delegates:\n if claude_aliases_agents:\n claude_findings.append(\"CLAUDE.md resolves to the same physical file as AGENTS.md\")\n else:\n claude_findings.append(\"CLAUDE.md delegates to AGENTS.md\")\n claude_reads_agents = yes(agents) == \"yes\" and agents_fallback_on\n if yes(global_claude) == \"no\" and yes(claude) == \"no\" and not claude_reads_agents:\n claude_findings.append(\"Claude instruction surface not found\")\n # A root CLAUDE.md switches the whole project off the AGENTS.md path, so the\n # nested guides stop loading with it. The one exception is the both mode,\n # where AGENTS.md is read beside CLAUDE.md and the walk still reaches them,\n # unless CLAUDE.md IS that AGENTS.md, in which case the deduplicated chain\n # is skipped and the nested files go dark again. Measured all four ways.\n both_mode = instructions_mode == \"claude-md-and-agents-md\"\n nested_hidden = nested_agents and yes(claude) == \"yes\" and (\n not both_mode or claude_aliases_agents\n )\n if nested_hidden:\n claude_findings.append(\n f\"a root CLAUDE.md hides {len(nested_agents)} nested AGENTS.md from Claude\"\n )\n\n if (\n yes(global_claude) == \"yes\"\n and has_operational_rules(global_claude)\n and yes(global_codex_agents) == \"yes\"\n and looks_identity_only(global_codex_agents)\n ):\n codex_findings.append(\n \"global Codex AGENTS.md has identity/memory context but lacks operational rules present in global Claude CLAUDE.md\"\n )\n codex_config_text = read(codex_config) if yes(codex_config) == \"yes\" else \"\"\n if (\n 'sandbox_mode = \"danger-full-access\"' in codex_config_text\n and 'approval_policy = \"never\"' in codex_config_text\n ):\n codex_findings.append(\n \"Codex runs danger-full-access with approval_policy=never; Codex has no command-level deny mechanism, so the only levers are sandbox_mode and approval_policy -- surface once as a user tradeoff, not a per-project fix\"\n )\n\n permission_status, permission_lines, permission_findings = summarize_claude_permissions(\n global_claude_settings,\n shared_project_settings,\n local_project_settings,\n has_task_scoped_env_policy([global_claude, global_codex_agents, agents, claude]),\n )\n duplicate_status, duplicate_lines = summarize_skill_duplicates(root, home)\n path_context_status, path_context_lines = summarize_rule_context(\n [(\"project\", project_rules), (\"global\", global_rules)], root\n )\n\n conflict_findings: list[str] = []\n if yes(agents) == \"yes\" and yes(claude) == \"yes\" and not claude_delegates:\n conflict_findings.append(\"AGENTS.md and CLAUDE.md both exist; verify they do not diverge\")\n if duplicate_status == \"WARN\":\n conflict_findings.append(\"active skill routing has broken links, name collisions, or divergent copies\")\n\n instruction_status = \"FAIL\" if not instruction_files else (\"WARN\" if instruction_findings else \"PASS\")\n codex_status = \"WARN\" if codex_findings else \"PASS\"\n claude_status = (\n \"WARN\"\n if (\n (\n claude_findings\n and any(\n marker in \" \".join(claude_findings)\n for marker in (\"surface not found\", \"hides\")\n )\n )\n or permission_status == \"WARN\"\n or path_context_status == \"WARN\"\n )\n else \"PASS\"\n )\n conflict_status = \"WARN\" if conflict_findings else \"PASS\"\n\n print(\"=== AGENT INSTRUCTION SURFACE ===\")\n print(f\"agent_instruction_status: {instruction_status}\")\n print(f\"mode: {mode}\")\n print(f\"AGENTS.md: {yes(agents)}\")\n print(f\"CLAUDE.md: {yes(claude)}\")\n print(f\"claude_aliases_agents: {'yes' if claude_aliases_agents else 'no'}\")\n print(f\"claude_delegates_to_agents: {'yes' if claude_delegates else 'no'}\")\n print(f\".github/copilot-instructions.md: {yes(root / '.github' / 'copilot-instructions.md')}\")\n print(f\".github/instructions/*.md: {github_instruction_count}\")\n print(f\"GEMINI.md: {yes(root / 'GEMINI.md')}\")\n print_list(\"instruction_files\", [rel(path, root) for path in instruction_files])\n print_list(\"instruction_findings\", instruction_findings)\n\n print(\"=== CODEX SURFACE ===\")\n print(f\"codex_status: {codex_status}\")\n print(f\"global_agents_md: {yes(global_codex_agents)}\")\n print(f\"global_config_toml: {yes(codex_config)}\")\n print(f\"project_trust: {trust}\")\n print_list(\"features\", features, limit=20 if mode == \"summary\" else None)\n print_list(\"enabled_plugins\", plugins, limit=20 if mode == \"summary\" else None)\n print_list(\"marketplaces\", marketplaces, limit=20 if mode == \"summary\" else None)\n print_list(\"redacted_config_entries\", redacted)\n print_list(\"codex_findings\", codex_findings)\n\n print(\"=== CLAUDE SURFACE ===\")\n print(f\"claude_status: {claude_status}\")\n print(f\"global_claude_md: {yes(global_claude)}\")\n print(f\"project_instructions_mode: {instructions_mode}\")\n print(f\"nested_agents_md: {len(nested_agents)}\")\n print(f\"global_settings_json: {yes(global_claude_settings)}\")\n print(f\"project_claude_md: {yes(claude)}\")\n print(f\"shared_settings_json: {yes(shared_project_settings)}\")\n print(f\"settings_local_json: {yes(local_project_settings)}\")\n rule_count = len(unique_physical_files(list(project_rules.glob(\"*.md\"))))\n local_skill_count = len(unique_physical_files([\n path\n for skill_root in project_skill_roots\n if resolve_audit_dir(skill_root) is not None\n for path in skill_root.glob(\"*/SKILL.md\")\n ]))\n global_skill_count = len(\n unique_physical_files(list(global_skills.glob(\"*/SKILL.md\")))\n )\n print(f\"project_rules: {rule_count}\")\n print(f\"project_skills: {local_skill_count}\")\n source_skill_count = (\n len(unique_physical_files(list((root / \"skills\").glob(\"*/SKILL.md\"))))\n if resolve_audit_dir(root / \"skills\") is not None\n else 0\n )\n print(f\"source_skills: {source_skill_count}\")\n print(f\"global_skills: {global_skill_count}\")\n print_list(\"claude_findings\", claude_findings)\n\n for line in permission_lines:\n print(safe_label(line, 2_000))\n\n for line in runtime_inventory(root, home):\n print(safe_label(line, 2_000))\n\n for line in path_context_lines:\n print(safe_label(line, 2_000))\n\n for line in duplicate_lines:\n print(safe_label(line, 2_000))\n\n _, pi_lines = summarize_pi_surface(root, home)\n for line in pi_lines:\n print(safe_label(line, 2_000))\n\n print(\"=== INSTRUCTION CONFLICTS ===\")\n print(f\"conflict_status: {conflict_status}\")\n print_list(\"conflict_findings\", conflict_findings)\n return 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":70059,"content_sha256":"f2f15313ca15607791c37ced9f74b83f9ea6613a2432714903ddacdfc4be7651"},{"filename":"scripts/check_doc_refs.py","content":"#!/usr/bin/env python3\n\"\"\"Check that doc references (@path, ~/.claude/..., docs/..., references/...) in\nAGENTS.md, CLAUDE.md, .claude/rules/*.md, and .claude/skills/*/SKILL.md resolve\nto real files. Prints `doc references: ok` on success, otherwise lists every\nMISSING reference with source location.\n\nRun as: python3 check_doc_refs.py [ROOT]\nROOT defaults to the current working directory.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nimport os\nimport re\nimport sys\nfrom pathlib import Path\n\n\nREF_RE = re.compile(\n r\"(?\u003c![\\w/.-])(\"\n r\"@[A-Za-z0-9_~/.-]+(?:\\.md|/)|\"\n r\"~/\\.claude/[A-Za-z0-9_/.-]+(?:\\.md|/)|\"\n r\"(?:docs|references)/[A-Za-z0-9_/.-]+\\.md\"\n r\")\"\n)\nMAX_SOURCE_BYTES = 1_000_000\n\n\ndef safe_label(value: str, limit: int = 500) -> str:\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in value):\n value = json.dumps(value, ensure_ascii=False)\n return value if len(value) \u003c= limit else f\"{value[: limit - 3]}...\"\n\n\ndef is_repo_file(path: Path, root: Path) -> bool:\n \"\"\"Return true only for a regular file reached without any symlink hop.\"\"\"\n try:\n relative = path.relative_to(root)\n except ValueError:\n return False\n if not relative.parts:\n return False\n current = root\n try:\n for part in relative.parts:\n current /= part\n if current.is_symlink():\n return False\n return current.is_file()\n except OSError:\n return False\n\n\ndef is_repo_dir(path: Path, root: Path) -> bool:\n \"\"\"Return true only for a directory reached without any symlink hop.\"\"\"\n try:\n relative = path.relative_to(root)\n except ValueError:\n return False\n current = root\n try:\n if current.is_symlink():\n return False\n for part in relative.parts:\n current /= part\n if current.is_symlink():\n return False\n return current.is_dir()\n except OSError:\n return False\n\n\ndef read_source(path: Path, root: Path) -> str:\n if not is_repo_file(path, root):\n return \"\"\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n descriptor = os.open(path, flags)\n except OSError:\n return \"\"\n try:\n chunks: list[bytes] = []\n remaining = MAX_SOURCE_BYTES\n while remaining:\n chunk = os.read(descriptor, min(65_536, remaining))\n if not chunk:\n break\n chunks.append(chunk)\n remaining -= len(chunk)\n except OSError:\n return \"\"\n finally:\n os.close(descriptor)\n return b\"\".join(chunks).decode(\"utf-8\", errors=\"replace\")\n\n\ndef resolve_ref(source: Path, raw: str, root: Path, home: Path) -> Path:\n ref = raw[1:] if raw.startswith(\"@\") else raw\n\n if ref.startswith(\"~/\"):\n return Path(os.path.abspath(home / ref[2:]))\n\n path = Path(ref)\n if path.is_absolute():\n return path\n\n if raw.startswith(\"@\"):\n return Path(os.path.abspath(root / ref))\n\n if ref.startswith(\"docs/\"):\n return Path(os.path.abspath(root / ref))\n\n if ref.startswith(\"references/\"):\n source_parts = source.relative_to(root).parts\n if len(source_parts) >= 4 and source_parts[:2] == (\".claude\", \"skills\"):\n skill_root = root.joinpath(*source_parts[:3])\n return Path(os.path.abspath(skill_root / ref))\n return Path(os.path.abspath(root / ref))\n\n return Path(os.path.abspath(source.parent / ref))\n\n\ndef target_status(target: Path, raw: str, root: Path, home: Path) -> str:\n scope = home / \".claude\" if raw.startswith(\"~/\") else root\n # The global instruction file is commonly a deliberate link to a managed\n # rules repository. Report that trust boundary without reading through it.\n # Other linked references stay failures: treating arbitrary global rule\n # links as advisory would hide real escaped targets.\n symlink_status = \"external\" if raw == \"~/.claude/CLAUDE.md\" else \"missing\"\n try:\n relative = target.relative_to(scope)\n except ValueError:\n return \"external\"\n current = scope\n try:\n if current.is_symlink():\n return symlink_status\n for part in relative.parts:\n current /= part\n if current.is_symlink():\n return symlink_status\n except OSError:\n return \"missing\"\n if raw.endswith(\"/\"):\n return \"exists\" if is_repo_dir(target, scope) else \"missing\"\n return \"exists\" if is_repo_file(target, scope) else \"missing\"\n\n\ndef collect_scan_files(root: Path) -> list[Path]:\n scan_files: list[Path] = []\n for candidate in (root / \"AGENTS.md\", root / \"CLAUDE.md\"):\n if is_repo_file(candidate, root):\n scan_files.append(candidate)\n for pattern in (\".claude/rules/*.md\", \".claude/skills/*/SKILL.md\"):\n scan_files.extend(\n path for path in sorted(root.glob(pattern)) if is_repo_file(path, root)\n )\n return scan_files\n\n\ndef main() -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"root\", nargs=\"?\", default=\".\", help=\"Project root (default: cwd)\")\n args = parser.parse_args()\n root = Path(args.root).resolve()\n home = Path(os.environ.get(\"HOME\", \"\")).expanduser()\n\n scan_files = collect_scan_files(root)\n\n missing: list[str] = []\n unverifiable: list[str] = []\n seen: set[tuple[Path, int, str]] = set()\n for path in scan_files:\n in_fence = False\n for lineno, line in enumerate(\n read_source(path, root).splitlines(), start=1\n ):\n stripped = line.lstrip()\n if stripped.startswith(\"```\") or stripped.startswith(\"~~~\"):\n in_fence = not in_fence\n continue\n if in_fence:\n continue\n\n for match in REF_RE.finditer(line):\n raw = match.group(1)\n key = (path, lineno, raw)\n if key in seen:\n continue\n seen.add(key)\n\n target = resolve_ref(path, raw, root, home)\n status = target_status(target, raw, root, home)\n source = path.relative_to(root)\n if status == \"missing\":\n missing.append(\n f\"MISSING: {safe_label(source.as_posix())}:{lineno} \"\n f\"-> {safe_label(raw)}\"\n )\n elif status == \"external\":\n unverifiable.append(\n f\"UNVERIFIED_EXTERNAL: {safe_label(source.as_posix())}:{lineno} \"\n f\"-> {safe_label(raw)}\"\n )\n\n if missing:\n print(\"\\n\".join(missing + unverifiable))\n return 1\n\n if unverifiable:\n print(\"\\n\".join(unverifiable))\n return 0\n\n print(\"doc references: ok\")\n return 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":6952,"content_sha256":"a43a5ecb6c6d97a642f96bb21b29381c7f6ed3af67c2e60a027bfbda062ca9f3"},{"filename":"scripts/check_maintainability.py","content":"#!/usr/bin/env python3\n\"\"\"AI maintainability audit: project shape, context surface, verification surface,\ndecision artifacts, drift markers, generated mirrors, and markdown links.\n\nRun as: python3 check_maintainability.py [ROOT] [summary|deep]\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport hashlib\nimport json\nimport os\nimport re\nimport subprocess\nimport sys\nimport urllib.parse\nfrom collections import Counter\nfrom pathlib import Path\n\n\n# Mechanical definitions (excluded dirs, source extensions, marker regex,\n# minified filter) are kept identical with skills/check/scripts/audit_signals.py\n# by tests/python/test_auditor_alignment.py; thresholds stay per-product.\nEXCLUDED_DIRS = {\n \".git\", \".hg\", \".svn\", \"node_modules\", \"dist\", \"build\", \".next\",\n \"__pycache__\", \".turbo\", \"target\", \".venv\", \"venv\", \"vendor\",\n \"coverage\", \".cache\", \".parcel-cache\", \".pytest_cache\", \".mypy_cache\",\n \".ruff_cache\", \"Pods\", \"Carthage\", \".swiftpm\", \".gradle\",\n}\n\nSOURCE_EXTS = {\n \".bash\", \".c\", \".cc\", \".cpp\", \".cs\", \".css\", \".go\", \".h\", \".hpp\",\n \".html\", \".java\", \".js\", \".jsx\", \".kt\", \".lua\", \".m\", \".mjs\", \".mm\",\n \".md\", \".php\", \".py\", \".rb\", \".rs\", \".scss\", \".sh\", \".swift\", \".ts\",\n \".tsx\", \".vue\", \".yaml\", \".yml\", \".zsh\",\n}\n\nMARKER_RE = re.compile(r\"\\b(TODO|FIXME|HACK|XXX)\\b\", re.IGNORECASE)\nMARKER_EXAMPLE_RE = re.compile(r\"\\b(example|placeholder|fixture|marker|taxonomy)\\b\", re.IGNORECASE)\nMINIFIED_RE = re.compile(r\"\\.min\\.[a-z]+$\", re.IGNORECASE)\nMAKE_RE = re.compile(r\"^([A-Za-z0-9_.-]+)\\s*:(?![=])\")\nMAKE_CMD_RE = re.compile(r\"\\bmake\\s+([A-Za-z0-9_.-]+)\\b\")\nNPM_CMD_RE = re.compile(r\"\\b(?:npm|pnpm|yarn|bun)\\s+run\\s+([A-Za-z0-9:_-]+)\\b\")\nCOMMAND_LINE_RE = re.compile(r\"^(?:make|npm|pnpm|yarn|bun)\\s+\")\nVERIFIER_NAME_RE = re.compile(\n r\"(?:^|[-_:.])(test|check|lint|type|build|package|verify|smoke)(?:$|[-_:.])\",\n re.IGNORECASE,\n)\nHOLLOW_COMMAND_RE = re.compile(\n r\"^(?:echo\\b.*|printf\\b.*|true|false|:|exit(?:\\s+\\d+)?|set\\s+-[^\\s]+|\"\n r\"cd\\b.*|(?:export|readonly|local)\\b.*|trap\\b.*|umask\\b.*|\"\n r\"(?:mkdir|touch|chmod|chown|cp|mv|rm)\\b.*|\"\n r\"[A-Za-z_][A-Za-z0-9_]*=.*)$\",\n re.IGNORECASE,\n)\nSHELL_OPTION_RE = re.compile(\n r\"^set(?:\\s+[-+][A-Za-z0-9_-]+)*(?:\\s+[A-Za-z0-9_-]+)*$\",\n re.IGNORECASE,\n)\nVERIFIER_COMMAND_RE = re.compile(\n r\"(?:\"\n r\"^(?:test|\\[)\\s+|\"\n r\"\\bgit\\s+diff\\s+--check\\b|\"\n r\"^(?:sudo\\s+)?(?:shellcheck|pytest|ruff|mypy|eslint|stylelint|biome|hadolint)\\b|\"\n r\"\\bpython(?:3)?\\s+-m\\s+(?:pytest|unittest|compileall|py_compile)\\b|\"\n r\"\\b(?:cargo|go|mvn|gradle|deno)\\s+(?:test|check|build|verify|vet|clippy)\\b|\"\n r\"\\bswift\\s+(?:build|test)\\b|\"\n r\"\\b(?:npm|pnpm|yarn|bun)\\s+(?:test|check|lint|build|verify|pack)\\b|\"\n r\"(?:^|[\\s/])[A-Za-z0-9_.-]*(?:test|check|verify|lint|smoke|build)\"\n r\"[A-Za-z0-9_./-]*\\.(?:sh|py)\\b\"\n r\")\",\n re.IGNORECASE,\n)\nSETUP_ONLY_COMMAND_RE = re.compile(\n r\"(?:\"\n r\"\\b(?:apt-get|apt|brew)\\s+(?:install|update|upgrade)\\b|\"\n r\"\\bpython(?:3)?\\s+-m\\s+pip\\s+install\\b|\"\n r\"\\bpip(?:3)?\\s+install\\b|\"\n r\"\\b(?:npm|pnpm|yarn|bun)\\s+(?:install|add|publish|view)\\b|\"\n r\"\\b(?:curl|wget)\\b|\"\n r\"--version\\b\"\n r\")\",\n re.IGNORECASE,\n)\nMARKDOWN_LINK_RE = re.compile(r\"!?\\[[^\\]]*\\]\\(([^)]+)\\)\")\nURL_RE = re.compile(r\"^[A-Za-z][A-Za-z0-9+.-]*:\")\nRUSTDOC_LINK_RE = re.compile(\n r\"(?:^|/)(?:constant|enum|fn|macro|mod|static|struct|trait|type|union)\\.\"\n r\"[^/]+\\.html$\"\n)\nACTIONABLE_COMMAND_RE = re.compile(\n r\"(?:\"\n r\"\\b(?:run|execute|invoke)\\s+$|\"\n r\"\\b(?:build|check|package|test|verify)\\s+(?:using|via|with)\\s+$|\"\n r\"\\b(?:command|verification|verifier)\\s*:\\s*$\"\n r\")\",\n re.IGNORECASE,\n)\nMAX_TEXT_BYTES = 2_000_000\nMAX_MIRROR_DIGEST_BYTES = 16_000_000\nSECRET_TOKEN_RE = re.compile(\n r\"\\b(?:sk-[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9]{12,}|\"\n r\"github_pat_[A-Za-z0-9_]{12,}|xox[baprs]-[A-Za-z0-9-]{10,}|\"\n r\"AKIA[A-Z0-9]{16}|eyJ[A-Za-z0-9_-]{20,}\\.[A-Za-z0-9_-]{10,}\\.\"\n r\"[A-Za-z0-9_-]{10,})\\b\"\n)\nSECRET_ASSIGNMENT_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_-])\"\n r\"(?P\u003cname>-{0,2}(?P\u003cquote>[\\x22\\x27]?)(?:[A-Za-z0-9]+[_-])*\"\n r\"(?:secret[_-]access[_-]key|private[_-]?key|api[_-]?key|\"\n r\"authorization|password|passwd|pwd|token|secret)(?P=quote))\"\n r\"(?![A-Za-z0-9_-])\"\n r\"(?P\u003cseparator>\\s*[:=]\\s*)\"\n r\"(?:Bearer\\s+|Basic\\s+)?(?:\\\"(?:\\\\[^\\r\\n]|[^\\\"\\\\\\r\\n])*(?:\\\"|\\\\?(?=\\r?\\n|\\Z))|\"\n r\"\\x27(?:\\\\[^\\r\\n]|[^\\x27\\\\\\r\\n])*(?:\\x27|\\\\?(?=\\r?\\n|\\Z))|[^\\s,;]+)\",\n re.IGNORECASE,\n)\nPRIVATE_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])(?:~[/\\\\]|/(?:Users|home|private|tmp|var)/)\"\n r\"[^\\s`\\\"'\u003c>]+\"\n)\nWINDOWS_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])(?:[A-Za-z]:\\\\|\\\\\\\\)[^\\s`\\\"'\u003c>]+\"\n)\n\n\n# The file-walk helpers below are deliberately duplicated in\n# skills/check/scripts/audit_signals.py. Both scripts ship standalone\n# (see packaging.allowlist) and run inside an arbitrary target project, so\n# they import only stdlib. Do not hoist them into a shared scripts/\n# module: it is dev-only, not on the ship allowlist, and would couple a\n# standalone tool to the install layout.\ndef rel(path: Path, root: Path) -> str:\n try:\n value = path.resolve().relative_to(root).as_posix()\n except ValueError:\n value = path.as_posix()\n return safe_label(value)\n\n\ndef safe_label(value: str, limit: int = 500) -> str:\n if any(ord(char) \u003c 32 or ord(char) == 127 for char in value):\n value = json.dumps(value, ensure_ascii=False)\n return value if len(value) \u003c= limit else f\"{value[: limit - 3]}...\"\n\n\ndef redact_command_label(value: str) -> str:\n \"\"\"Keep verifier inventory useful without emitting secrets or host paths.\"\"\"\n value = SECRET_TOKEN_RE.sub(\"[REDACTED]\", value)\n value = SECRET_ASSIGNMENT_RE.sub(\n lambda match: f\"{match.group('name')}{match.group('separator')}[REDACTED]\",\n value,\n )\n value = PRIVATE_PATH_RE.sub(\"[PATH]\", value)\n return WINDOWS_PATH_RE.sub(\"[PATH]\", value)\n\n\ndef is_excluded(path: Path, root: Path) -> bool:\n parts = path.relative_to(root).parts if path.is_absolute() else path.parts\n if any(part in EXCLUDED_DIRS for part in parts):\n return True\n return bool(MINIFIED_RE.search(path.name))\n\n\ndef is_repo_file(path: Path, root: Path) -> bool:\n \"\"\"Return true only for a regular file reached without any symlink hop.\"\"\"\n try:\n relative = path.relative_to(root)\n except ValueError:\n return False\n if not relative.parts:\n return False\n current = root\n try:\n for part in relative.parts:\n current /= part\n if current.is_symlink():\n return False\n return current.is_file()\n except OSError:\n return False\n\n\ndef is_repo_dir(path: Path, root: Path) -> bool:\n \"\"\"Return true only for a directory reached without any symlink hop.\"\"\"\n try:\n relative = path.relative_to(root)\n except ValueError:\n return False\n current = root\n try:\n for part in relative.parts:\n current /= part\n if current.is_symlink():\n return False\n return current.is_dir()\n except OSError:\n return False\n\n\ndef is_safe_repo_reference(path: Path, root: Path) -> bool:\n \"\"\"Allow documentation symlinks only when their final target stays in-repo.\"\"\"\n try:\n path.relative_to(root)\n resolved = path.resolve(strict=True)\n resolved.relative_to(root.resolve())\n return resolved.is_file() or resolved.is_dir()\n except (OSError, RuntimeError, ValueError):\n return False\n\n\ndef read_text(path: Path, root: Path, limit: int | None = None) -> str:\n if not is_repo_file(path, root):\n return \"\"\n byte_limit = limit or MAX_TEXT_BYTES\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n descriptor = os.open(path, flags)\n except OSError:\n return \"\"\n try:\n chunks: list[bytes] = []\n remaining = byte_limit\n while remaining:\n chunk = os.read(descriptor, min(65_536, remaining))\n if not chunk:\n break\n chunks.append(chunk)\n remaining -= len(chunk)\n except OSError:\n return \"\"\n finally:\n os.close(descriptor)\n return b\"\".join(chunks).decode(\"utf-8\", errors=\"replace\")\n\n\ndef file_digest(path: Path, root: Path) -> tuple[int, bytes] | None:\n \"\"\"Hash a stable regular file without trusting a shared prefix.\"\"\"\n if not is_repo_file(path, root):\n return None\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n descriptor = os.open(path, flags)\n except OSError:\n return None\n try:\n before = os.fstat(descriptor)\n if before.st_size > MAX_MIRROR_DIGEST_BYTES:\n return None\n digest = hashlib.sha256()\n while True:\n chunk = os.read(descriptor, 65_536)\n if not chunk:\n break\n digest.update(chunk)\n after = os.fstat(descriptor)\n if (before.st_size, before.st_mtime_ns) != (after.st_size, after.st_mtime_ns):\n return None\n return before.st_size, digest.digest()\n except OSError:\n return None\n finally:\n os.close(descriptor)\n\n\ndef iter_files(root: Path) -> list[Path]:\n try:\n proc = subprocess.run(\n [\n \"git\",\n \"-c\",\n \"core.fsmonitor=false\",\n \"-C\",\n str(root),\n \"ls-files\",\n \"--cached\",\n \"--others\",\n \"--exclude-standard\",\n \"-z\",\n ],\n stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL,\n check=False,\n )\n if proc.returncode == 0 and proc.stdout:\n files = []\n for raw_path in proc.stdout.split(b\"\\0\"):\n if not raw_path:\n continue\n path = root / os.fsdecode(raw_path)\n if is_repo_file(path, root) and not is_excluded(path, root):\n files.append(path)\n return files\n except OSError:\n pass\n\n files = []\n for dirpath, dirnames, filenames in os.walk(root):\n current = Path(dirpath)\n dirnames[:] = [\n name for name in dirnames\n if name not in EXCLUDED_DIRS and is_repo_dir(current / name, root)\n ]\n if is_excluded(current, root):\n continue\n for filename in filenames:\n path = current / filename\n if is_repo_file(path, root) and not is_excluded(path, root):\n files.append(path)\n return files\n\n\ndef collapse_generated_mirrors(\n files: list[Path], root: Path\n) -> tuple[list[Path], int, list[str], list[str]]:\n \"\"\"Fold byte-identical Codex plugin mirrors into their source files.\"\"\"\n file_set = set(files)\n digests: dict[Path, tuple[int, bytes] | None] = {}\n\n def digest(path: Path) -> tuple[int, bytes] | None:\n if path not in digests:\n digests[path] = file_digest(path, root)\n return digests[path]\n\n logical: list[Path] = []\n collapsed = 0\n drifted: list[str] = []\n coverage_gaps: list[str] = []\n for path in files:\n try:\n parts = path.relative_to(root).parts\n except ValueError:\n logical.append(path)\n continue\n source: Path | None = None\n if len(parts) >= 4 and parts[0] == \"plugins\" and parts[2] in {\"skills\", \"rules\"}:\n source = root.joinpath(*parts[2:])\n if source is not None and source in file_set:\n mirror_digest = digest(path)\n source_digest = digest(source)\n if mirror_digest is None or source_digest is None:\n coverage_gaps.append(\n f\"{rel(path, root)} -> {rel(source, root)}\"\n )\n elif mirror_digest == source_digest:\n collapsed += 1\n continue\n else:\n drifted.append(f\"{rel(path, root)} -> {rel(source, root)}\")\n logical.append(path)\n return logical, collapsed, drifted, coverage_gaps\n\n\ndef line_count(path: Path, root: Path) -> int:\n if not is_repo_file(path, root):\n return 0\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n with os.fdopen(os.open(path, flags), \"rb\") as handle:\n return sum(1 for _ in handle)\n except OSError:\n return 0\n\n\ndef print_list(items: list[str], empty: str = \"(none)\", limit: int | None = None) -> None:\n shown = items if limit is None else items[:limit]\n if not shown:\n print(f\" {empty}\")\n return\n for item in shown:\n print(f\" {safe_label(item)}\")\n if limit is not None and len(items) > limit:\n print(f\" ... {len(items) - limit} more\")\n\n\ndef instruction_paths(root: Path) -> list[Path]:\n candidates = [\n root / \"AGENTS.md\",\n root / \"CLAUDE.md\",\n root / \".github\" / \"copilot-instructions.md\",\n root / \"GEMINI.md\",\n ]\n instructions_dir = root / \".github\" / \"instructions\"\n if is_repo_dir(instructions_dir, root):\n candidates.extend(sorted(instructions_dir.glob(\"*.md\")))\n rules_dir = root / \".claude\" / \"rules\"\n if is_repo_dir(rules_dir, root):\n candidates.extend(sorted(rules_dir.glob(\"*.md\")))\n return [\n path for path in candidates\n if is_repo_file(path, root) and not is_excluded(path, root)\n ]\n\n\ndef has_substantive_instruction_evidence(path: Path, root: Path) -> bool:\n \"\"\"Reject empty/frontmatter/heading-only placeholders as context evidence.\"\"\"\n in_frontmatter = False\n frontmatter_seen = False\n for raw_line in read_text(path, root, 200_000).splitlines():\n line = raw_line.strip()\n if not line:\n continue\n if line == \"---\" and not frontmatter_seen:\n in_frontmatter = True\n frontmatter_seen = True\n continue\n if line == \"---\" and in_frontmatter:\n in_frontmatter = False\n continue\n if in_frontmatter or line.startswith(\"#\") or line.startswith(\"\u003c!--\"):\n continue\n return True\n return False\n\n\ndef find_text_signal(paths: list[Path], patterns: list[str], root: Path) -> bool:\n regexes = [re.compile(pattern, re.IGNORECASE) for pattern in patterns]\n for path in paths:\n text = read_text(path, root, 200_000)\n if any(regex.search(text) for regex in regexes):\n return True\n return False\n\n\ndef parse_makefile(\n root: Path,\n) -> tuple[set[str], list[str], dict[str, tuple[list[str], list[str]]]]:\n makefile = root / \"Makefile\"\n targets: set[str] = set()\n commands: list[str] = []\n specs: dict[str, tuple[list[str], list[str]]] = {}\n if not is_repo_file(makefile, root):\n return targets, commands, specs\n current_target: str | None = None\n for line in read_text(makefile, root).splitlines():\n match = MAKE_RE.match(line)\n if match:\n target = match.group(1)\n current_target = None\n if target.startswith(\".\"):\n continue\n targets.add(target)\n remainder = line.split(\":\", 1)[1]\n dependencies_text, separator, inline_recipe = remainder.partition(\";\")\n dependencies = [\n item for item in dependencies_text.split()\n if not item.startswith(\"#\") and not item.startswith(\"$\")\n ]\n recipes = [inline_recipe.strip()] if separator and inline_recipe.strip() else []\n specs[target] = (dependencies, recipes)\n current_target = target\n if VERIFIER_NAME_RE.search(target):\n commands.append(f\"make {target}\")\n continue\n if current_target and line.startswith(\"\\t\"):\n dependencies, recipes = specs[current_target]\n recipes.append(line.strip())\n elif line.strip() and not line.lstrip().startswith(\"#\"):\n current_target = None\n return targets, commands, specs\n\n\ndef parse_package_json(root: Path) -> tuple[set[str], list[str], dict[str, str]]:\n package = root / \"package.json\"\n script_names: set[str] = set()\n commands: list[str] = []\n script_specs: dict[str, str] = {}\n if not is_repo_file(package, root):\n return script_names, commands, script_specs\n try:\n data = json.loads(read_text(package, root))\n except json.JSONDecodeError:\n return script_names, commands, script_specs\n scripts = data.get(\"scripts\", {})\n if not isinstance(scripts, dict):\n return script_names, commands, script_specs\n for name in sorted(scripts):\n script_names.add(name)\n value = scripts[name]\n if isinstance(value, str):\n script_specs[name] = value\n if VERIFIER_NAME_RE.search(name):\n commands.append(f\"npm run {name}\")\n return script_names, commands, script_specs\n\n\ndef parse_ci_commands(root: Path) -> list[tuple[str, str]]:\n workflows_dir = root / \".github\" / \"workflows\"\n workflows = (\n sorted(path for path in workflows_dir.glob(\"*.yml\") if is_repo_file(path, root))\n if is_repo_dir(workflows_dir, root) else []\n )\n workflows += (\n sorted(path for path in workflows_dir.glob(\"*.yaml\") if is_repo_file(path, root))\n if is_repo_dir(workflows_dir, root) else []\n )\n commands: list[tuple[str, str]] = []\n for workflow in workflows:\n lines = read_text(workflow, root).splitlines()\n index = 0\n while index \u003c len(lines):\n raw = lines[index]\n line = raw.strip()\n if line.startswith(\"- run:\"):\n command = line.split(\"- run:\", 1)[1].strip()\n elif line.startswith(\"run:\"):\n command = line.split(\"run:\", 1)[1].strip()\n else:\n index += 1\n continue\n if command in {\"|\", \">\", \"|-\", \">-\"}:\n base_indent = len(raw) - len(raw.lstrip())\n block: list[str] = []\n index += 1\n while index \u003c len(lines):\n candidate = lines[index]\n candidate_indent = len(candidate) - len(candidate.lstrip())\n if candidate.strip() and candidate_indent \u003c= base_indent:\n break\n if candidate.strip():\n block.append(candidate.strip())\n index += 1\n command = \"; \".join(block)\n else:\n if len(command) >= 2 and command[0] == command[-1] and command[0] in \"'\\\"\":\n command = command[1:-1]\n index += 1\n if command:\n label = redact_command_label(f\"{rel(workflow, root)}: {command}\")\n commands.append((label, command))\n return commands\n\n\ndef shell_script_has_verifier_evidence(path: Path, root: Path) -> bool:\n \"\"\"Reject scripts whose only behavior is setup, printing, or a fixed exit.\"\"\"\n text = read_text(path, root, 200_000)\n meaningful: list[str] = []\n for raw_line in text.splitlines():\n line = raw_line.strip()\n if not line or line.startswith(\"#!\") or line.startswith(\"#\"):\n continue\n normalized = line.lstrip(\"@-+\")\n normalized = re.split(r\"\\s+#\", normalized, maxsplit=1)[0].rstrip()\n if (\n HOLLOW_COMMAND_RE.fullmatch(normalized)\n or SHELL_OPTION_RE.fullmatch(normalized)\n or SETUP_ONLY_COMMAND_RE.search(normalized)\n ):\n continue\n meaningful.append(line)\n return bool(meaningful)\n\n\ndef command_is_verifier_candidate(command: str) -> bool:\n \"\"\"Return whether a command claims or resembles a verification entrypoint.\"\"\"\n normalized = command.strip().lstrip(\"@-+\").strip()\n if any(VERIFIER_NAME_RE.search(target) for target in MAKE_CMD_RE.findall(normalized)):\n return True\n if any(VERIFIER_NAME_RE.search(script) for script in NPM_CMD_RE.findall(normalized)):\n return True\n script_call = re.search(r\"(?:^|\\s)(?:bash\\s+|sh\\s+)?([^\\s;&|]+)\", normalized)\n if script_call and VERIFIER_NAME_RE.search(Path(script_call.group(1)).name):\n return True\n return bool(VERIFIER_COMMAND_RE.search(normalized))\n\n\ndef command_has_verifier_evidence(\n command: str,\n root: Path,\n make_specs: dict[str, tuple[list[str], list[str]]],\n package_specs: dict[str, str],\n visiting: frozenset[str] = frozenset(),\n trusted_entrypoint: bool = False,\n) -> bool:\n \"\"\"Return whether a discovered command can do more than print or exit.\"\"\"\n normalized = command.strip().lstrip(\"@-+\").strip()\n if not normalized:\n return False\n\n make_only = re.fullmatch(\n r\"(?:make|\\$\\(MAKE\\))\\s+([A-Za-z0-9_.-]+)(?:\\s+[^;&|]+)?\", normalized\n )\n if make_only:\n target = make_only.group(1)\n if not trusted_entrypoint and not VERIFIER_NAME_RE.search(target):\n return False\n key = f\"make:{target}\"\n if key in visiting or target not in make_specs:\n return False\n dependencies, recipes = make_specs[target]\n next_visiting = visiting | {key}\n if any(\n command_has_verifier_evidence(\n recipe, root, make_specs, package_specs, next_visiting, True\n )\n for recipe in recipes\n ):\n return True\n return any(\n command_has_verifier_evidence(\n f\"make {dependency}\", root, make_specs, package_specs, next_visiting, True\n )\n for dependency in dependencies\n if dependency in make_specs\n )\n\n package_only = re.fullmatch(\n r\"(?:npm|pnpm|yarn|bun)\\s+(?:run\\s+)?([A-Za-z0-9:_-]+)(?:\\s+[^;&|]+)?\",\n normalized,\n )\n if package_only:\n script = package_only.group(1)\n builtin_verifier = script == \"pack\" and \"--dry-run\" in normalized\n if (\n not trusted_entrypoint\n and not builtin_verifier\n and not VERIFIER_NAME_RE.search(script)\n ):\n return False\n key = f\"package:{script}\"\n if key in visiting:\n return False\n if script in package_specs:\n return command_has_verifier_evidence(\n package_specs[script], root, make_specs, package_specs, visiting | {key}, True\n )\n if re.match(r\"(?:npm|pnpm|yarn|bun)\\s+run\\s+\", normalized):\n return False\n if not builtin_verifier:\n return False\n\n script_call = re.fullmatch(\n r\"(?:(?:bash|sh)\\s+)?(\\.?\\.?/[A-Za-z0-9_./-]+\\.sh)(?:\\s+.*)?\",\n normalized,\n )\n if script_call:\n script_path = root / script_call.group(1)\n named_as_verifier = bool(VERIFIER_NAME_RE.search(script_path.name))\n return (trusted_entrypoint or named_as_verifier) and shell_script_has_verifier_evidence(\n script_path, root\n )\n\n fragments = [\n fragment.strip().lstrip(\"@-+\").strip()\n for fragment in re.split(r\"\\s*(?:&&|\\|\\||;)\\s*\", normalized)\n if fragment.strip()\n ]\n substantive = [\n fragment for fragment in fragments\n if not HOLLOW_COMMAND_RE.fullmatch(fragment)\n and not SHELL_OPTION_RE.fullmatch(fragment)\n and not SETUP_ONLY_COMMAND_RE.search(fragment)\n ]\n if not substantive:\n return False\n return trusted_entrypoint or any(\n VERIFIER_COMMAND_RE.search(fragment) for fragment in substantive\n )\n\n\ndef scan_markdown_links(files: list[Path], root: Path) -> list[str]:\n missing: list[str] = []\n markdown_files = [path for path in files if path.suffix.lower() == \".md\"]\n for path in markdown_files:\n fence: tuple[str, int] | None = None\n for lineno, line in enumerate(read_text(path, root).splitlines(), 1):\n fence_match = re.match(r\"^\\s{0,3}(`{3,}|~{3,})\", line)\n if fence_match:\n marker = fence_match.group(1)\n if fence is None:\n fence = (marker[0], len(marker))\n elif marker[0] == fence[0] and len(marker) >= fence[1]:\n fence = None\n continue\n if fence is not None:\n continue\n for raw in MARKDOWN_LINK_RE.findall(strip_markdown_inline_code(line)):\n target = raw.strip().split()[0].strip(\"\u003c>\")\n if not target or target.startswith(\"#\") or URL_RE.match(target):\n continue\n target = urllib.parse.unquote(target.split(\"#\", 1)[0])\n if not target:\n continue\n # A leading slash is a site-root route, not a filesystem-relative\n # Markdown reference. Its validity belongs to the site's route or\n # link checker; treating it as /path/on/the/audit-host is a false\n # broken-doc finding.\n if target.startswith(\"/\"):\n continue\n if is_rustdoc_generated_link(path, target, root):\n continue\n full = path.parent / target\n if not is_safe_repo_reference(full, root):\n missing.append(f\"{rel(path, root)}:{lineno} -> {target}\")\n return missing\n\n\ndef strip_markdown_inline_code(line: str) -> str:\n \"\"\"Blank inline code spans while preserving non-code Markdown text.\"\"\"\n output: list[str] = []\n open_ticks = 0\n index = 0\n while index \u003c len(line):\n if line[index] != \"`\":\n output.append(line[index] if open_ticks == 0 else \" \")\n index += 1\n continue\n end = index\n while end \u003c len(line) and line[end] == \"`\":\n end += 1\n run = end - index\n if open_ticks == 0:\n open_ticks = run\n elif run == open_ticks:\n open_ticks = 0\n output.extend(\" \" * run)\n index = end\n return \"\".join(output)\n\n\ndef is_rustdoc_generated_link(source: Path, target: str, root: Path) -> bool:\n \"\"\"Recognize links that Rustdoc resolves only in generated crate docs.\"\"\"\n if not RUSTDOC_LINK_RE.search(target):\n return False\n current = source.parent\n while True:\n if is_repo_file(current / \"Cargo.toml\", root):\n return True\n if current == root:\n return False\n try:\n current.relative_to(root)\n except ValueError:\n return False\n current = current.parent\n\n\ndef actionable_inline_command_snippets(line: str) -> list[str]:\n snippets: list[str] = []\n for match in re.finditer(r\"`([^`]+)`\", line):\n if ACTIONABLE_COMMAND_RE.search(line[: match.start()]):\n snippets.append(match.group(1))\n return snippets\n\n\ndef verification_surface(\n root: Path, instruction_files: list[Path], files: list[Path]\n) -> tuple[list[str], list[str], list[str], list[str], set[str], set[str]]:\n make_targets, make_commands, make_specs = parse_makefile(root)\n package_scripts, package_commands, package_specs = parse_package_json(root)\n ci_commands = parse_ci_commands(root)\n commands = make_commands + package_commands + [label for label, _ in ci_commands]\n evidence: list[str] = []\n hollow: list[str] = []\n\n for command in make_commands + package_commands:\n destination = evidence if command_has_verifier_evidence(\n command, root, make_specs, package_specs\n ) else hollow\n destination.append(command)\n for label, raw_command in ci_commands:\n if command_has_verifier_evidence(raw_command, root, make_specs, package_specs):\n evidence.append(label)\n elif command_is_verifier_candidate(raw_command):\n hollow.append(label)\n\n if is_repo_file(root / \"Cargo.toml\", root):\n commands.extend([\"cargo test\", \"cargo check\"])\n evidence.extend([\"cargo test\", \"cargo check\"])\n if is_repo_file(root / \"go.mod\", root):\n commands.append(\"go test ./...\")\n evidence.append(\"go test ./...\")\n if is_repo_file(root / \"Package.swift\", root):\n commands.append(\"swift test\")\n evidence.append(\"swift test\")\n pyproject = root / \"pyproject.toml\"\n pytest_configured = is_repo_file(root / \"pytest.ini\", root) or (\n is_repo_file(pyproject, root)\n and bool(re.search(r\"\\bpytest\\b\", read_text(pyproject, root, 200_000), re.IGNORECASE))\n )\n python_tests_present = any(\n path.suffix.lower() == \".py\"\n and (\n path.name.startswith(\"test_\")\n or path.name.endswith(\"_test.py\")\n or any(\n part.lower() in {\"test\", \"tests\", \"spec\", \"specs\"}\n for part in path.relative_to(root).parts[:-1]\n )\n )\n for path in files\n )\n if pytest_configured:\n commands.append(\"pytest\")\n if python_tests_present:\n evidence.append(\"pytest\")\n if is_repo_file(root / \"pom.xml\", root):\n commands.append(\"mvn test\")\n evidence.append(\"mvn test\")\n if is_repo_file(root / \"deno.json\", root) or is_repo_file(root / \"deno.jsonc\", root):\n commands.append(\"deno test\")\n evidence.append(\"deno test\")\n\n missing: list[str] = []\n for path in instruction_files:\n text = read_text(path, root, 200_000)\n snippets: list[str] = []\n for raw_line in text.splitlines():\n snippets.extend(actionable_inline_command_snippets(raw_line))\n stripped = raw_line.strip().strip(\"`\")\n if COMMAND_LINE_RE.match(stripped):\n snippets.append(stripped)\n for snippet in snippets:\n for target in MAKE_CMD_RE.findall(snippet):\n if target not in make_targets:\n missing.append(f\"{rel(path, root)} references missing make target: {target}\")\n for script in NPM_CMD_RE.findall(snippet):\n if script not in package_scripts:\n missing.append(f\"{rel(path, root)} references missing package script: {script}\")\n\n unique_commands = list(dict.fromkeys(commands))\n unique_evidence = list(dict.fromkeys(evidence))\n unique_hollow = list(dict.fromkeys(hollow))\n unique_missing = list(dict.fromkeys(missing))\n return (\n unique_commands,\n unique_evidence,\n unique_hollow,\n unique_missing,\n make_targets,\n package_scripts,\n )\n\n\ndef main() -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"root\", nargs=\"?\", default=\".\", help=\"Repo root (default: cwd)\")\n parser.add_argument(\n \"mode\", nargs=\"?\", default=\"summary\", choices=(\"summary\", \"deep\"),\n help=\"Output detail level\",\n )\n args = parser.parse_args()\n root = Path(args.root).resolve()\n mode = args.mode\n\n if not root.is_dir():\n print(f\"Repo root not found: {safe_label(root.as_posix())}\", file=sys.stderr)\n return 2\n\n files = iter_files(root)\n (\n logical_files,\n generated_mirror_files_collapsed,\n generated_mirror_drift,\n generated_mirror_coverage_gaps,\n ) = collapse_generated_mirrors(files, root)\n tracked_count = len(files)\n extensions = Counter(path.suffix.lower() or \"(none)\" for path in files)\n detected_manifests = [\n name\n for name in [\n \"Makefile\", \"package.json\", \"Cargo.toml\", \"go.mod\", \"Package.swift\",\n \"pyproject.toml\",\n \"pytest.ini\", \"pom.xml\", \"deno.json\", \"deno.jsonc\",\n ]\n if is_repo_file(root / name, root)\n ]\n workflows_dir = root / \".github\" / \"workflows\"\n workflow_count = 0\n if is_repo_dir(workflows_dir, root):\n workflow_count = sum(\n 1\n for path in list(workflows_dir.glob(\"*.yml\")) + list(workflows_dir.glob(\"*.yaml\"))\n if is_repo_file(path, root)\n )\n if workflow_count:\n detected_manifests.append(f\".github/workflows ({workflow_count})\")\n\n source_files = [path for path in logical_files if path.suffix.lower() in SOURCE_EXTS]\n implementation_files = [\n path\n for path in source_files\n if path.suffix.lower() not in {\".css\", \".html\", \".md\", \".scss\", \".yaml\", \".yml\"}\n ]\n source_stats: list[tuple[int, int, Path]] = []\n for path in source_files:\n try:\n size = path.stat().st_size\n except OSError:\n size = 0\n source_stats.append((line_count(path, root), size, path))\n source_stats.sort(key=lambda item: (item[0], item[1]), reverse=True)\n\n dir_counts: Counter[str] = Counter()\n for path in files:\n relative_parts = Path(rel(path, root)).parts\n top = relative_parts[0] if len(relative_parts) > 1 else \".\"\n dir_counts[top] += 1\n\n instruction_files = instruction_paths(root)\n instruction_evidence_files = [\n path for path in instruction_files\n if has_substantive_instruction_evidence(path, root)\n ]\n instruction_verification = find_text_signal(\n instruction_files,\n [r\"verification\", r\"test plan\", r\"make test\", r\"npm test\", r\"pytest\", r\"cargo test\", r\"验证\", r\"测试\"],\n root,\n )\n boundaries = find_text_signal(\n instruction_files,\n [r\"not for\", r\"do not\", r\"non-?goals?\", r\"scope\", r\"boundar\", r\"never\", r\"avoid\", r\"边界\", r\"非目标\", r\"不要\"],\n root,\n )\n (\n commands,\n verifier_evidence,\n hollow_verifiers,\n missing_references,\n make_targets,\n package_scripts,\n ) = verification_surface(root, instruction_files, files)\n stable_make_targets = sorted(make_targets & {\"check\", \"test\", \"verify\"})\n stable_package_commands = {\n f\"npm run {name}\" for name in package_scripts & {\"check\", \"test\", \"verify\"}\n } & set(verifier_evidence)\n wrapper_warnings: list[str] = []\n if (\n len(commands) >= 2\n and is_repo_file(root / \"Makefile\", root)\n and not stable_make_targets\n and not stable_package_commands\n ):\n wrapper_warnings.append(\n \"multiple verification commands discovered without a recognized make/npm default; \"\n \"check documented or native entrypoints before recommending a wrapper\"\n )\n\n decision_artifacts = {\n \"docs_dir\": is_repo_dir(root / \"docs\", root),\n \"specs_dir\": is_repo_dir(root / \"specs\", root),\n \"specify_dir\": is_repo_dir(root / \".specify\", root),\n \"handoff_md\": any(\n path.name.upper() == \"HANDOFF.MD\" and is_repo_file(path, root)\n for path in root.glob(\"*.md\")\n ),\n \"changelog\": any(\n path.name.upper().startswith(\"CHANGELOG\") and is_repo_file(path, root)\n for path in root.glob(\"*\")\n ),\n \"issue_templates\": is_repo_dir(root / \".github\" / \"ISSUE_TEMPLATE\", root),\n \"pr_template\": any(\n is_repo_file(path, root)\n for path in [\n root / \".github\" / \"pull_request_template.md\",\n root / \".github\" / \"PULL_REQUEST_TEMPLATE.md\",\n ]\n ),\n }\n\n todo_counts: Counter[str] = Counter()\n todo_total = 0\n fixture_marker_lines_ignored = 0\n for path in source_files:\n text = read_text(path, root, 200_000)\n # Count marker-bearing lines, not marker words. Documentation often names\n # the full marker family in one rule line; treating that as four issues\n # makes the checker flag itself instead of real open-task piles.\n relative = Path(rel(path, root))\n is_fixture = (\n any(part in {\"test\", \"tests\", \"spec\", \"specs\", \"fixtures\"} for part in relative.parts)\n or bool(re.search(r\"(?:^|[._-])(?:test|tests|spec|specs)(?:[._-]|$)\", relative.name.lower()))\n )\n count = 0\n for line in text.splitlines():\n if not MARKER_RE.search(line):\n continue\n marker_taxonomy = all(marker in line.upper() for marker in (\"TODO\", \"FIXME\", \"HACK\", \"XXX\"))\n documented_example = (\n path.suffix.lower() == \".md\" and MARKER_EXAMPLE_RE.search(line)\n )\n if is_fixture or marker_taxonomy or documented_example:\n fixture_marker_lines_ignored += 1\n continue\n count += 1\n if count:\n todo_counts[rel(path, root)] += count\n todo_total += count\n\n todo_hotspots = [\n f\"{path} markers={count}\" for path, count in todo_counts.most_common(8 if mode == \"deep\" else 5)\n ]\n\n doc_ref_status = \"unavailable\"\n doc_ref_detail = \"\"\n checker = Path(__file__).with_name(\"check_doc_refs.py\")\n if checker.is_file():\n proc = subprocess.run(\n [sys.executable, \"-I\", str(checker), str(root)],\n encoding=\"utf-8\",\n errors=\"replace\",\n stdout=subprocess.PIPE,\n stderr=subprocess.STDOUT,\n check=False,\n )\n doc_ref_status = \"pass\" if proc.returncode == 0 else \"fail\"\n if proc.stdout.strip():\n first_lines = proc.stdout.strip().splitlines()[:8]\n doc_ref_detail = \" | \".join(first_lines)\n\n has_verifier_evidence = bool(verifier_evidence)\n verification_expected = bool(\n implementation_files or detected_manifests or workflow_count\n )\n context_expected = bool(\n implementation_files\n or workflow_count\n or any(manifest != \"Makefile\" for manifest in detected_manifests)\n )\n context_findings: list[str] = []\n verification_warnings: list[str] = []\n drift_warnings: list[str] = []\n\n if context_expected and not instruction_evidence_files:\n context_findings.append(\n \"no tracked instruction evidence; non-obvious project constraint reachability is unknown\"\n )\n if verification_expected and not has_verifier_evidence:\n if hollow_verifiers:\n verification_warnings.append(\n \"discovered verifier entrypoints are hollow or non-substantive\"\n )\n elif commands:\n verification_warnings.append(\n \"commands were discovered, but none provide substantive verifier evidence\"\n )\n else:\n verification_warnings.append(\"no substantive verifier evidence discovered\")\n if missing_references:\n verification_warnings.append(\"instruction references missing commands\")\n if generated_mirror_drift:\n drift_warnings.append(\"generated mirrors differ from their source files\")\n if generated_mirror_coverage_gaps:\n drift_warnings.append(\"generated mirror comparison exceeded the bounded digest surface\")\n if doc_ref_status == \"fail\":\n drift_warnings.append(\"broken documentation references\")\n\n markdown_missing: list[str] = []\n markdown_link_status = \"SKIPPED\"\n if mode == \"deep\":\n markdown_missing = scan_markdown_links(files, root)\n markdown_link_status = \"WARN\" if markdown_missing else \"PASS\"\n if markdown_missing:\n drift_warnings.append(\"broken Markdown links\")\n\n if instruction_evidence_files:\n context_status = \"PASS\"\n elif context_expected:\n context_status = \"UNKNOWN\"\n else:\n context_status = \"NOT_APPLICABLE\"\n verification_status = (\n \"FAIL\"\n if verification_expected and not has_verifier_evidence\n else (\"WARN\" if verification_warnings else \"PASS\")\n )\n decision_status = \"PASS\"\n wrapper_status = \"WARN\" if wrapper_warnings else \"PASS\"\n drift_status = \"WARN\" if drift_warnings else \"PASS\"\n\n if context_status == \"FAIL\" or verification_status == \"FAIL\" or doc_ref_status == \"fail\":\n overall = \"FAIL\"\n elif context_status == \"UNKNOWN\" or \"WARN\" in {\n context_status, verification_status, decision_status, wrapper_status,\n drift_status, markdown_link_status,\n }:\n overall = \"WARN\"\n else:\n overall = \"PASS\"\n\n top_ext = [f\"{ext} files={count}\" for ext, count in extensions.most_common(10)]\n largest_sources = [\n f\"{rel(path, root)} lines={lines} bytes={size}\"\n for lines, size, path in source_stats[: (10 if mode == \"deep\" else 5)]\n ]\n largest_dirs = [f\"{directory} files={count}\" for directory, count in dir_counts.most_common(8)]\n\n print(\"=== PROJECT SHAPE ===\")\n print(f\"maintainability_status: {overall}\")\n print(f\"mode: {mode}\")\n print(f\"tracked_files: {tracked_count}\")\n print(f\"generated_mirror_files_collapsed: {generated_mirror_files_collapsed}\")\n print(f\"generated_mirror_files_drifted: {len(generated_mirror_drift)}\")\n print(f\"generated_mirror_comparison_gaps: {len(generated_mirror_coverage_gaps)}\")\n print(\"generated_mirror_drift:\")\n print_list(generated_mirror_drift, limit=10)\n print(\"generated_mirror_coverage_gaps:\")\n print_list(generated_mirror_coverage_gaps, limit=10)\n print(\"top_extensions:\")\n print_list(top_ext)\n print(\"largest_source_files:\")\n print_list(largest_sources)\n print(\"largest_directories:\")\n print_list(largest_dirs)\n\n print(\"=== AI CONTEXT SURFACE ===\")\n print(f\"context_status: {context_status}\")\n print(f\"AGENTS.md: {'yes' if is_repo_file(root / 'AGENTS.md', root) else 'no'}\")\n print(f\"CLAUDE.md: {'yes' if is_repo_file(root / 'CLAUDE.md', root) else 'no'}\")\n print(f\".github/copilot-instructions.md: {'yes' if is_repo_file(root / '.github' / 'copilot-instructions.md', root) else 'no'}\")\n github_instruction_count = (\n sum(\n 1\n for path in (root / \".github\" / \"instructions\").glob(\"*.md\")\n if is_repo_file(path, root)\n )\n if is_repo_dir(root / \".github\" / \"instructions\", root) else 0\n )\n print(f\".github/instructions/*.md: {github_instruction_count}\")\n print(f\"GEMINI.md: {'yes' if is_repo_file(root / 'GEMINI.md', root) else 'no'}\")\n print(f\"verification_guidance: {'yes' if instruction_verification else 'no'}\")\n print(f\"boundary_guidance: {'yes' if boundaries else 'no'}\")\n print(\"context_findings:\")\n print_list(context_findings)\n print(\"instruction_files:\")\n print_list([rel(path, root) for path in instruction_files])\n print(\"instruction_evidence_files:\")\n print_list([rel(path, root) for path in instruction_evidence_files])\n\n print(\"=== VERIFICATION SURFACE ===\")\n print(f\"verification_status: {verification_status}\")\n print(\"detected_manifests:\")\n print_list(detected_manifests)\n print(\"commands:\")\n print_list(commands, limit=12 if mode == \"summary\" else None)\n print(\"verifier_evidence:\")\n print_list(verifier_evidence, limit=12 if mode == \"summary\" else None)\n print(\"hollow_verifiers:\")\n print_list(hollow_verifiers, limit=12 if mode == \"summary\" else None)\n print(\"missing_referenced_commands:\")\n print_list(missing_references, limit=10 if mode == \"summary\" else None)\n print(\"verification_findings:\")\n print_list(verification_warnings)\n\n print(\"=== VERIFICATION WRAPPER SURFACE ===\")\n print(f\"wrapper_status: {wrapper_status}\")\n print(f\"makefile_present: {'yes' if is_repo_file(root / 'Makefile', root) else 'no'}\")\n print(\"stable_make_targets:\")\n print_list([f\"make {target}\" for target in stable_make_targets])\n print(\"wrapper_findings:\")\n print_list(wrapper_warnings)\n\n print(\"=== DECISION ARTIFACTS ===\")\n print(f\"decision_artifacts_status: {decision_status}\")\n for key, value in decision_artifacts.items():\n print(f\"{key}: {'yes' if value else 'no'}\")\n\n print(\"=== DRIFT MARKERS ===\")\n print(f\"drift_status: {drift_status}\")\n print(f\"todo_markers: {todo_total}\")\n print(f\"fixture_or_instruction_marker_lines_ignored: {fixture_marker_lines_ignored}\")\n print(\"todo_hotspots:\")\n print_list(todo_hotspots)\n print(f\"broken_doc_references: {doc_ref_status}\")\n if doc_ref_detail and (mode == \"deep\" or doc_ref_status == \"fail\"):\n print(f\"broken_doc_reference_detail: {safe_label(doc_ref_detail)}\")\n print(\"drift_findings:\")\n print_list(drift_warnings)\n\n print(\"=== MARKDOWN LINK SURFACE ===\")\n print(f\"markdown_link_status: {markdown_link_status}\")\n print(\"missing_markdown_links:\")\n if mode == \"deep\":\n print_list(markdown_missing, limit=20)\n else:\n print(\" (skipped: deep mode only)\")\n return 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":44407,"content_sha256":"e3dd6bff7114b30152b03f88a023d088551a98c144b93a1897d0eebe0e2f2ab4"},{"filename":"scripts/check_verifier_output.py","content":"#!/usr/bin/env python3\n\"\"\"Scan a verifier log for stale external paths and suggest cache-clean commands.\n\nDetects /tmp/ and /private/tmp/ file references that no longer exist; these are\nthe signature of stale worktrees pointed at by a verifier (golangci-lint cache,\ngo build cache, npm cache, etc.).\n\nRun as: python3 check_verifier_output.py ROOT LOG_FILE\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport re\nimport sys\nfrom pathlib import Path\n\n\nTOKEN_RE = re.compile(\n r\"(?P\u003cpath>(?:/|\\.\\./)(?:[^\\s:'\\\"(),]+/)*[^\\s:'\\\"(),]+\\.[A-Za-z0-9_+-]+)\"\n)\nTMP_RE = re.compile(r\"(^|/)(private/)?tmp/\")\n\n\ndef main() -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"root\", help=\"Repo root\")\n parser.add_argument(\"log_file\", help=\"Verifier log to scan\")\n args = parser.parse_args()\n\n root = Path(args.root).resolve()\n log_file = Path(args.log_file).resolve()\n if not root.is_dir():\n print(f\"Repo root not found: {root}\", file=sys.stderr)\n return 2\n if not log_file.is_file():\n print(f\"Log file not found: {log_file}\", file=sys.stderr)\n return 2\n\n text = log_file.read_text(encoding=\"utf-8\", errors=\"replace\")\n\n def normalize(token: str) -> Path:\n if token.startswith(\"/\"):\n return Path(token)\n return (root / token).resolve()\n\n paths: list[Path] = []\n for match in TOKEN_RE.finditer(text):\n token = match.group(\"path\").rstrip(\".\")\n if \"/.git/\" in token:\n continue\n path = normalize(token)\n if TMP_RE.search(path.as_posix()):\n paths.append(path)\n\n unique_paths = []\n seen = set()\n for path in paths:\n value = path.as_posix()\n if value in seen:\n continue\n seen.add(value)\n unique_paths.append(path)\n\n stale_paths = [path for path in unique_paths if not path.exists()]\n existing_paths = [path for path in unique_paths if path.exists()]\n lower = text.lower()\n\n actions: list[str] = []\n if stale_paths:\n if \"golangci-lint\" in lower or \"errcheck\" in lower:\n actions.append(\"golangci-lint cache clean\")\n if re.search(r\"\\bgo (test|vet|build)\\b\", lower) or \"go-build\" in lower:\n actions.append(\"go clean -cache -testcache\")\n if \"npm\" in lower or \"node_modules\" in lower:\n actions.append(\"npm cache verify\")\n if not actions:\n actions.append(\"rerun the verifier after removing stale temporary worktrees\")\n\n status = \"WARN\" if stale_paths else \"PASS\"\n\n print(\"=== VERIFIER OUTPUT SURFACE ===\")\n print(f\"verifier_output_status: {status}\")\n print(f\"log_file: {log_file}\")\n print(\"stale_paths:\")\n if stale_paths:\n for path in stale_paths[:20]:\n print(f\" {path}\")\n if len(stale_paths) > 20:\n print(f\" ... {len(stale_paths) - 20} more\")\n else:\n print(\" (none)\")\n print(\"existing_tmp_paths:\")\n if existing_paths:\n for path in existing_paths[:10]:\n print(f\" {path}\")\n if len(existing_paths) > 10:\n print(f\" ... {len(existing_paths) - 10} more\")\n else:\n print(\" (none)\")\n print(\"recommended_actions:\")\n if actions:\n for action in dict.fromkeys(actions):\n print(f\" {action}\")\n else:\n print(\" (none)\")\n print(\"verifier_findings:\")\n if stale_paths:\n print(\" stale external verifier paths detected\")\n else:\n print(\" (none)\")\n return 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":3561,"content_sha256":"15b7be020d913b2a59805e7af8bad5674f53f69a4c3bf96d817fcf0e9d4c07bb"},{"filename":"scripts/check-agent-context.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nSCRIPT_PATH=\"${BASH_SOURCE[0]}\"\ncase \"$SCRIPT_PATH\" in\n */*) SCRIPT_BASE=\"${SCRIPT_PATH%/*}\" ;;\n *) SCRIPT_BASE=\".\" ;;\nesac\nSCRIPT_DIR=\"$(cd \"$SCRIPT_BASE\" && pwd -P)\"\nunset WAZA_PYTHON DOC_REF_CHECKER GIT_INSTALL_ROOT BASH_ENV ENV\n\nsanitize_health_path() {\n local target=\"$1\"\n local entry physical safe=\"\"\n local -a path_entries=()\n target=$(cd \"$target\" 2>/dev/null && pwd -P) || target=$(pwd -P)\n IFS=: read -r -a path_entries \u003c\u003c\u003c \"${PATH:-}\"\n for entry in \"${path_entries[@]}\"; do\n [ -n \"$entry\" ] || continue\n case \"$entry\" in\n /*) ;;\n *) continue ;;\n esac\n [ -d \"$entry\" ] || continue\n physical=$(cd \"$entry\" 2>/dev/null && pwd -P) || continue\n case \"$physical/\" in\n \"$target/\"*) continue ;;\n esac\n safe=\"${safe:+$safe:}$physical\"\n done\n printf '%s\\n' \"$safe\"\n}\n\ncanonical_health_executable() {\n local current=\"$1\"\n local parent name link readlink_bin=\"\"\n local depth=0\n case \"$current\" in\n /*) ;;\n *) return 1 ;;\n esac\n while [ \"$depth\" -lt 32 ]; do\n parent=\"${current%/*}\"\n name=\"${current##*/}\"\n [ -n \"$parent\" ] || parent=\"/\"\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n if [ \"$parent\" = \"/\" ]; then\n current=\"/$name\"\n else\n current=\"$parent/$name\"\n fi\n if [ ! -L \"$current\" ]; then\n [ -f \"$current\" ] && [ -x \"$current\" ] || return 1\n printf '%s\\n' \"$current\"\n return 0\n fi\n if [ -z \"$readlink_bin\" ]; then\n if [ -x /usr/bin/readlink ]; then\n readlink_bin=/usr/bin/readlink\n else\n readlink_bin=$(type -P readlink 2>/dev/null || true)\n fi\n [ -n \"$readlink_bin\" ] || return 1\n fi\n link=$(\"$readlink_bin\" \"$current\") || return 1\n case \"$link\" in\n /*) current=\"$link\" ;;\n *) current=\"$parent/$link\" ;;\n esac\n depth=$((depth + 1))\n done\n return 1\n}\n\nHEALTH_TARGET=$(cd \"${1:-$PWD}\" 2>/dev/null && pwd -P) || HEALTH_TARGET=$(pwd -P)\nPATH=\"$(sanitize_health_path \"$HEALTH_TARGET\")\"\nexport PATH\nPYTHON_BIN=\"\"\nfor candidate in python3 python; do\n resolved=$(type -P \"$candidate\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n resolved=$(canonical_health_executable \"$resolved\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n if [ \"$HEALTH_TARGET\" = \"/\" ]; then\n continue\n fi\n case \"$resolved/\" in\n \"$HEALTH_TARGET/\"*) continue ;;\n esac\n \"$resolved\" --version >/dev/null 2>&1 || continue\n \"$resolved\" -I -c 'import sys; raise SystemExit(sys.version_info \u003c (3, 9))' \\\n >/dev/null 2>&1 || continue\n PYTHON_BIN=\"$resolved\"\n break\ndone\n[ -n \"$PYTHON_BIN\" ] || exit 127\nexec \"$PYTHON_BIN\" -I \"$SCRIPT_DIR/check_agent_context.py\" \"$@\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2694,"content_sha256":"d4c74fe963cf9f71c9020e7ef93d0f4d4b20ed202f5f99686570a5850a9a7ba1"},{"filename":"scripts/check-doc-refs.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nROOT=\"${1:-$PWD}\"\nROOT=\"$(cd \"$ROOT\" && pwd -P)\"\nSCRIPT_PATH=\"${BASH_SOURCE[0]}\"\ncase \"$SCRIPT_PATH\" in\n */*) SCRIPT_BASE=\"${SCRIPT_PATH%/*}\" ;;\n *) SCRIPT_BASE=\".\" ;;\nesac\nSCRIPT_DIR=\"$(cd \"$SCRIPT_BASE\" && pwd -P)\"\n\nunset WAZA_PYTHON DOC_REF_CHECKER GIT_INSTALL_ROOT BASH_ENV ENV\n\nsanitize_health_path() {\n local target=\"$1\"\n local entry physical safe=\"\"\n local -a path_entries=()\n target=$(cd \"$target\" 2>/dev/null && pwd -P) || target=$(pwd -P)\n IFS=: read -r -a path_entries \u003c\u003c\u003c \"${PATH:-}\"\n for entry in \"${path_entries[@]}\"; do\n [ -n \"$entry\" ] || continue\n case \"$entry\" in\n /*) ;;\n *) continue ;;\n esac\n [ -d \"$entry\" ] || continue\n physical=$(cd \"$entry\" 2>/dev/null && pwd -P) || continue\n case \"$physical/\" in\n \"$target/\"*) continue ;;\n esac\n safe=\"${safe:+$safe:}$physical\"\n done\n printf '%s\\n' \"$safe\"\n}\n\ncanonical_health_executable() {\n local current=\"$1\"\n local parent name link readlink_bin=\"\"\n local depth=0\n case \"$current\" in\n /*) ;;\n *) return 1 ;;\n esac\n while [ \"$depth\" -lt 32 ]; do\n parent=\"${current%/*}\"\n name=\"${current##*/}\"\n [ -n \"$parent\" ] || parent=\"/\"\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n if [ \"$parent\" = \"/\" ]; then\n current=\"/$name\"\n else\n current=\"$parent/$name\"\n fi\n if [ ! -L \"$current\" ]; then\n [ -f \"$current\" ] && [ -x \"$current\" ] || return 1\n printf '%s\\n' \"$current\"\n return 0\n fi\n if [ -z \"$readlink_bin\" ]; then\n if [ -x /usr/bin/readlink ]; then\n readlink_bin=/usr/bin/readlink\n else\n readlink_bin=$(type -P readlink 2>/dev/null || true)\n fi\n [ -n \"$readlink_bin\" ] || return 1\n fi\n link=$(\"$readlink_bin\" \"$current\") || return 1\n case \"$link\" in\n /*) current=\"$link\" ;;\n *) current=\"$parent/$link\" ;;\n esac\n depth=$((depth + 1))\n done\n return 1\n}\n\nHEALTH_TARGET=\"$ROOT\"\nPATH=\"$(sanitize_health_path \"$HEALTH_TARGET\")\"\nexport PATH\nPYTHON_BIN=\"\"\nfor candidate in python3 python; do\n resolved=$(type -P \"$candidate\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n resolved=$(canonical_health_executable \"$resolved\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n if [ \"$HEALTH_TARGET\" = \"/\" ]; then\n continue\n fi\n case \"$resolved/\" in\n \"$HEALTH_TARGET/\"*) continue ;;\n esac\n \"$resolved\" --version >/dev/null 2>&1 || continue\n \"$resolved\" -I -c 'import sys; raise SystemExit(sys.version_info \u003c (3, 9))' \\\n >/dev/null 2>&1 || continue\n PYTHON_BIN=\"$resolved\"\n break\ndone\n[ -n \"$PYTHON_BIN\" ] || exit 127\nexec \"$PYTHON_BIN\" -I \"$SCRIPT_DIR/check_doc_refs.py\" \"$ROOT\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2682,"content_sha256":"be790dffc718986ff854bfdd684f717025634371e79bfc869f4fdbd4e275069f"},{"filename":"scripts/check-maintainability.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nSCRIPT_PATH=\"${BASH_SOURCE[0]}\"\ncase \"$SCRIPT_PATH\" in\n */*) SCRIPT_BASE=\"${SCRIPT_PATH%/*}\" ;;\n *) SCRIPT_BASE=\".\" ;;\nesac\nSCRIPT_DIR=\"$(cd \"$SCRIPT_BASE\" && pwd -P)\"\nunset WAZA_PYTHON DOC_REF_CHECKER GIT_INSTALL_ROOT BASH_ENV ENV\n\nsanitize_health_path() {\n local target=\"$1\"\n local entry physical safe=\"\"\n local -a path_entries=()\n target=$(cd \"$target\" 2>/dev/null && pwd -P) || target=$(pwd -P)\n IFS=: read -r -a path_entries \u003c\u003c\u003c \"${PATH:-}\"\n for entry in \"${path_entries[@]}\"; do\n [ -n \"$entry\" ] || continue\n case \"$entry\" in\n /*) ;;\n *) continue ;;\n esac\n [ -d \"$entry\" ] || continue\n physical=$(cd \"$entry\" 2>/dev/null && pwd -P) || continue\n case \"$physical/\" in\n \"$target/\"*) continue ;;\n esac\n safe=\"${safe:+$safe:}$physical\"\n done\n printf '%s\\n' \"$safe\"\n}\n\ncanonical_health_executable() {\n local current=\"$1\"\n local parent name link readlink_bin=\"\"\n local depth=0\n case \"$current\" in\n /*) ;;\n *) return 1 ;;\n esac\n while [ \"$depth\" -lt 32 ]; do\n parent=\"${current%/*}\"\n name=\"${current##*/}\"\n [ -n \"$parent\" ] || parent=\"/\"\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n if [ \"$parent\" = \"/\" ]; then\n current=\"/$name\"\n else\n current=\"$parent/$name\"\n fi\n if [ ! -L \"$current\" ]; then\n [ -f \"$current\" ] && [ -x \"$current\" ] || return 1\n printf '%s\\n' \"$current\"\n return 0\n fi\n if [ -z \"$readlink_bin\" ]; then\n if [ -x /usr/bin/readlink ]; then\n readlink_bin=/usr/bin/readlink\n else\n readlink_bin=$(type -P readlink 2>/dev/null || true)\n fi\n [ -n \"$readlink_bin\" ] || return 1\n fi\n link=$(\"$readlink_bin\" \"$current\") || return 1\n case \"$link\" in\n /*) current=\"$link\" ;;\n *) current=\"$parent/$link\" ;;\n esac\n depth=$((depth + 1))\n done\n return 1\n}\n\nHEALTH_TARGET=$(cd \"${1:-$PWD}\" 2>/dev/null && pwd -P) || HEALTH_TARGET=$(pwd -P)\nPATH=\"$(sanitize_health_path \"$HEALTH_TARGET\")\"\nexport PATH\nPYTHON_BIN=\"\"\nfor candidate in python3 python; do\n resolved=$(type -P \"$candidate\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n resolved=$(canonical_health_executable \"$resolved\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n if [ \"$HEALTH_TARGET\" = \"/\" ]; then\n continue\n fi\n case \"$resolved/\" in\n \"$HEALTH_TARGET/\"*) continue ;;\n esac\n \"$resolved\" --version >/dev/null 2>&1 || continue\n \"$resolved\" -I -c 'import sys; raise SystemExit(sys.version_info \u003c (3, 9))' \\\n >/dev/null 2>&1 || continue\n PYTHON_BIN=\"$resolved\"\n break\ndone\n[ -n \"$PYTHON_BIN\" ] || exit 127\nexec \"$PYTHON_BIN\" -I \"$SCRIPT_DIR/check_maintainability.py\" \"$@\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2696,"content_sha256":"a1a0120494315953f135b95da133f30d67ed9c61850ee8d618f7f6afaa88a43b"},{"filename":"scripts/check-verifier-output.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nSCRIPT_PATH=\"${BASH_SOURCE[0]}\"\ncase \"$SCRIPT_PATH\" in\n */*) SCRIPT_BASE=\"${SCRIPT_PATH%/*}\" ;;\n *) SCRIPT_BASE=\".\" ;;\nesac\nSCRIPT_DIR=\"$(cd \"$SCRIPT_BASE\" && pwd -P)\"\nunset WAZA_PYTHON DOC_REF_CHECKER GIT_INSTALL_ROOT BASH_ENV ENV\n\nsanitize_health_path() {\n local target=\"$1\"\n local entry physical safe=\"\"\n local -a path_entries=()\n target=$(cd \"$target\" 2>/dev/null && pwd -P) || target=$(pwd -P)\n IFS=: read -r -a path_entries \u003c\u003c\u003c \"${PATH:-}\"\n for entry in \"${path_entries[@]}\"; do\n [ -n \"$entry\" ] || continue\n case \"$entry\" in\n /*) ;;\n *) continue ;;\n esac\n [ -d \"$entry\" ] || continue\n physical=$(cd \"$entry\" 2>/dev/null && pwd -P) || continue\n case \"$physical/\" in\n \"$target/\"*) continue ;;\n esac\n safe=\"${safe:+$safe:}$physical\"\n done\n printf '%s\\n' \"$safe\"\n}\n\ncanonical_health_executable() {\n local current=\"$1\"\n local parent name link readlink_bin=\"\"\n local depth=0\n case \"$current\" in\n /*) ;;\n *) return 1 ;;\n esac\n while [ \"$depth\" -lt 32 ]; do\n parent=\"${current%/*}\"\n name=\"${current##*/}\"\n [ -n \"$parent\" ] || parent=\"/\"\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n if [ \"$parent\" = \"/\" ]; then\n current=\"/$name\"\n else\n current=\"$parent/$name\"\n fi\n if [ ! -L \"$current\" ]; then\n [ -f \"$current\" ] && [ -x \"$current\" ] || return 1\n printf '%s\\n' \"$current\"\n return 0\n fi\n if [ -z \"$readlink_bin\" ]; then\n if [ -x /usr/bin/readlink ]; then\n readlink_bin=/usr/bin/readlink\n else\n readlink_bin=$(type -P readlink 2>/dev/null || true)\n fi\n [ -n \"$readlink_bin\" ] || return 1\n fi\n link=$(\"$readlink_bin\" \"$current\") || return 1\n case \"$link\" in\n /*) current=\"$link\" ;;\n *) current=\"$parent/$link\" ;;\n esac\n depth=$((depth + 1))\n done\n return 1\n}\n\nHEALTH_TARGET=$(cd \"${1:-$PWD}\" 2>/dev/null && pwd -P) || HEALTH_TARGET=$(pwd -P)\nPATH=\"$(sanitize_health_path \"$HEALTH_TARGET\")\"\nexport PATH\nPYTHON_BIN=\"\"\nfor candidate in python3 python; do\n resolved=$(type -P \"$candidate\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n resolved=$(canonical_health_executable \"$resolved\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n if [ \"$HEALTH_TARGET\" = \"/\" ]; then\n continue\n fi\n case \"$resolved/\" in\n \"$HEALTH_TARGET/\"*) continue ;;\n esac\n \"$resolved\" --version >/dev/null 2>&1 || continue\n \"$resolved\" -I -c 'import sys; raise SystemExit(sys.version_info \u003c (3, 9))' \\\n >/dev/null 2>&1 || continue\n PYTHON_BIN=\"$resolved\"\n break\ndone\n[ -n \"$PYTHON_BIN\" ] || exit 127\nexec \"$PYTHON_BIN\" -I \"$SCRIPT_DIR/check_verifier_output.py\" \"$@\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2696,"content_sha256":"c4de5fb4f5a2375d0aa917b4f883d0a11449f8079938797b822c17fd38fae480"},{"filename":"scripts/collect-data.sh","content":"#!/usr/bin/env bash\n# Collect agent configuration data for health audit.\n# Outputs labeled sections for each data source.\n# Run from any directory; uses pwd as the project root.\n#\n# Known failure modes (for interpreting (unavailable) output):\n# trusted Python missing -> conversation, MCP/hooks/allowedTools, and skill-security sections print \"(unavailable)\"\n# settings.local.json absent -> hooks, MCP, allowedTools all show \"(unavailable)\"; normal for global-settings-only projects\n# MEMORY.md path -> built via sed on pwd; unusual chars produce wrong project key; verify manually if (none) seems wrong\n# Conversation scope -> summary scans 3 recent previous project files across Claude/Codex; deep streams all previous project files; every file modified in the live window is excluded\n# MCP token estimate -> assumes ~25 tools/server, ~200 tokens/tool; treat as directional, not precise\nset -euo pipefail\n\nP=$(pwd)\nSETTINGS=\"$P/.claude/settings.local.json\"\n# The first argument is retained for launcher compatibility. It is an audit\n# hint only; file, contributor, and skill counts never select requirements.\nAUDIT_HINT=\"${1:-auto}\"\nMODE=\"${2:-summary}\"\nSCRIPT_PATH=\"${BASH_SOURCE[0]}\"\ncase \"$SCRIPT_PATH\" in\n */*) SCRIPT_BASE=\"${SCRIPT_PATH%/*}\" ;;\n *) SCRIPT_BASE=\".\" ;;\nesac\nSCRIPT_DIR=\"$(cd \"$SCRIPT_BASE\" && pwd -P)\"\nunset WAZA_PYTHON DOC_REF_CHECKER GIT_INSTALL_ROOT BASH_ENV ENV\nunset WAZA_HEALTH_MODE WAZA_HEALTH_DEEP\n\nsanitize_health_path() {\n local target=\"$1\"\n local entry physical safe=\"\"\n local -a path_entries=()\n target=$(cd \"$target\" 2>/dev/null && pwd -P) || target=$(pwd -P)\n IFS=: read -r -a path_entries \u003c\u003c\u003c \"${PATH:-}\"\n for entry in \"${path_entries[@]}\"; do\n [ -n \"$entry\" ] || continue\n case \"$entry\" in\n /*) ;;\n *) continue ;;\n esac\n [ -d \"$entry\" ] || continue\n physical=$(cd \"$entry\" 2>/dev/null && pwd -P) || continue\n case \"$physical/\" in\n \"$target/\"*) continue ;;\n esac\n safe=\"${safe:+$safe:}$physical\"\n done\n printf '%s\\n' \"$safe\"\n}\n\ncanonical_health_executable() {\n local current=\"$1\"\n local parent name link readlink_bin=\"\"\n local depth=0\n case \"$current\" in\n /*) ;;\n *) return 1 ;;\n esac\n while [ \"$depth\" -lt 32 ]; do\n parent=\"${current%/*}\"\n name=\"${current##*/}\"\n [ -n \"$parent\" ] || parent=\"/\"\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n if [ \"$parent\" = \"/\" ]; then\n current=\"/$name\"\n else\n current=\"$parent/$name\"\n fi\n if [ ! -L \"$current\" ]; then\n [ -f \"$current\" ] && [ -x \"$current\" ] || return 1\n printf '%s\\n' \"$current\"\n return 0\n fi\n if [ -z \"$readlink_bin\" ]; then\n if [ -x /usr/bin/readlink ]; then\n readlink_bin=/usr/bin/readlink\n else\n readlink_bin=$(type -P readlink 2>/dev/null || true)\n fi\n [ -n \"$readlink_bin\" ] || return 1\n fi\n link=$(\"$readlink_bin\" \"$current\") || return 1\n case \"$link\" in\n /*) current=\"$link\" ;;\n *) current=\"$parent/$link\" ;;\n esac\n depth=$((depth + 1))\n done\n return 1\n}\n\nHEALTH_TARGET=$(cd \"$P\" 2>/dev/null && pwd -P) || HEALTH_TARGET=$(pwd -P)\nHEALTH_HOME=$(cd \"$HOME\" 2>/dev/null && pwd -P) || HEALTH_HOME=\"$HOME\"\nPATH=\"$(sanitize_health_path \"$HEALTH_TARGET\")\"\nexport PATH\nPYTHON_BIN=\"\"\nfor candidate in python3 python; do\n resolved=$(type -P \"$candidate\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n resolved=$(canonical_health_executable \"$resolved\" 2>/dev/null || true)\n [ -n \"$resolved\" ] || continue\n if [ \"$HEALTH_TARGET\" = \"/\" ]; then\n continue\n fi\n case \"$resolved/\" in\n \"$HEALTH_TARGET/\"*) continue ;;\n esac\n \"$resolved\" --version >/dev/null 2>&1 || continue\n \"$resolved\" -I -c 'import sys; raise SystemExit(sys.version_info \u003c (3, 9))' \\\n >/dev/null 2>&1 || continue\n PYTHON_BIN=\"$resolved\"\n break\ndone\n\nsafe_health_text() {\n printf '%s' \"$1\" | LC_ALL=C tr '\\000-\\037\\177' '_'\n printf '\\n'\n}\n\npath_has_controls() {\n case \"$1\" in\n *

Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…

\\n'*|*

Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…

\\r'*) return 0 ;;\n esac\n printf '%s' \"$1\" | LC_ALL=C grep -q '[[:cntrl:]]'\n}\n\nif path_has_controls \"$P\" || path_has_controls \"$HOME\" || path_has_controls \"$SCRIPT_DIR\"; then\n echo \"Health cannot audit roots whose paths contain control characters.\" >&2\n exit 2\nfi\n\nhealth_path_label() {\n local path=\"$1\" label home_prefix='~'\n case \"$path\" in\n \"$HEALTH_TARGET\") label='project:/' ;;\n \"$HEALTH_TARGET\"/*) label=\"project:/${path#\"$HEALTH_TARGET\"/}\" ;;\n \"$HOME\") label=\"${home_prefix}/\" ;;\n \"$HOME\"/*) label=\"${home_prefix}/${path#\"$HOME\"/}\" ;;\n \"$HEALTH_HOME\") label=\"${home_prefix}/\" ;;\n \"$HEALTH_HOME\"/*) label=\"${home_prefix}/${path#\"$HEALTH_HOME\"/}\" ;;\n *) label=\"external:/${path##*/}\" ;;\n esac\n safe_health_text \"$label\"\n}\n\nredact_health_stream() {\n if [ -z \"$PYTHON_BIN\" ]; then\n echo \"(unavailable: trusted Python missing; content withheld)\"\n return 0\n fi\n \"$PYTHON_BIN\" -I -c '\nimport re, sys\nlimit = 131072\nraw = sys.stdin.buffer.read(limit + 1)\ntruncated = len(raw) > limit\ntext = raw[:limit].decode(\"utf-8\", errors=\"replace\")\ntext = re.sub(r\"-----BEGIN [^-\\r\\n]+-----.*?(?:-----END [^-\\r\\n]+-----|\\Z)\", \"[REDACTED PRIVATE KEY]\", text, flags=re.I | re.S)\ntext = re.sub(r\"\\b(?:sk-[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9]{12,}|github_pat_[A-Za-z0-9_]{12,}|xox[baprs]-[A-Za-z0-9-]{10,}|AKIA[A-Z0-9]{16}|eyJ[A-Za-z0-9_-]{20,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,})\\b\", \"[REDACTED]\", text)\ntext = re.sub(r\"(?\u003c![A-Za-z0-9_-])(?P\u003cname>-{0,2}(?P\u003cquote>[\\x22\\x27]?)(?:[A-Za-z0-9]+[_-])*(?:secret[_-]access[_-]key|private[_-]?key|api[_-]?key|authorization|password|passwd|pwd|token|secret)(?P=quote))(?![A-Za-z0-9_-])(?P\u003cseparator>\\s*[:=]\\s*)(?:Bearer\\s+|Basic\\s+)?(?:\\\"(?:\\\\[^\\r\\n]|[^\\\"\\\\\\r\\n])*(?:\\\"|\\\\?(?=\\r?\\n|\\Z))|\\x27(?:\\\\[^\\r\\n]|[^\\x27\\\\\\r\\n])*(?:\\x27|\\\\?(?=\\r?\\n|\\Z))|[^\\s,;]+)\", lambda m: m.group(\"name\") + m.group(\"separator\") + \"[REDACTED]\", text, flags=re.I)\ntext = re.sub(r\"(?\u003c![A-Za-z0-9_])(?:~[/\\\\]|/(?:Users|home|private|tmp|var|etc|opt|Volumes)/)[^\\s`\\\"\\x27\u003c>]+\", \"[PATH]\", text)\ntext = re.sub(r\"(?\u003c![A-Za-z0-9_])(?:[A-Za-z]:\\\\|\\\\\\\\)[^\\s`\\\"\\x27\u003c>]+\", \"[PATH]\", text)\ntext = re.sub(r\"[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\x9f]\", \"\", text)\nsys.stdout.write(text)\nif text and not text.endswith(\"\\n\"):\n sys.stdout.write(\"\\n\")\nif truncated:\n sys.stdout.write(\"content_truncated: yes\\n\")\n'\n}\n\nprint_redacted_file() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ]; then\n echo \"(none)\"\n return 0\n fi\n LC_ALL=C head -c 131073 \"$canonical\" 2>/dev/null | redact_health_stream\n}\n\nprint_sensitive_file_summary() {\n local label=\"$1\" file=\"$2\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ]; then\n echo \"${label}_present: no\"\n return 0\n fi\n echo \"${label}_present: yes\"\n echo \"${label}_lines: $(count_file_lines \"$canonical\")\"\n echo \"${label}_words: $(count_file_words \"$canonical\")\"\n echo \"${label}_bytes: $(wc -c \u003c \"$canonical\" | tr -d ' ')\"\n}\n\ncase \"$MODE\" in\n summary|deep) ;;\n *) MODE=\"summary\" ;;\nesac\nPROJECT_KEY=$(printf '%s' \"$P\" | sed 's|[/_]|-|g; s|^-||')\nCONVO_DIR=\"$HOME/.claude/projects/-${PROJECT_KEY}\"\n\nresolve_health_helper() {\n local name=\"$1\"\n [ -f \"$SCRIPT_DIR/$name\" ] || return 1\n printf '%s\\n' \"$SCRIPT_DIR/$name\"\n}\n\ncount_project_files() {\n local count\n count=$(git -c core.fsmonitor=false -C \"$P\" ls-files 2>/dev/null | wc -l | tr -d ' ' || true)\n if [ -z \"$count\" ] || [ \"$count\" = \"0\" ]; then\n count=$(find \"$P\" -type f \\\n -not -path \"*/.git/*\" \\\n -not -path \"*/node_modules/*\" \\\n -not -path \"*/dist/*\" \\\n -not -path \"*/build/*\" \\\n 2>/dev/null | wc -l | tr -d ' ')\n fi\n printf '%s\\n' \"${count:-0}\"\n}\n\ncount_contributors() {\n local count\n count=$(git -c core.fsmonitor=false -C \"$P\" log -n 500 --format='%ae' 2>/dev/null | sort -u | wc -l | tr -d ' ' || true)\n printf '%s\\n' \"${count:-0}\"\n}\n\ncount_ci_workflows() {\n local count=0\n if [ -d \"$P/.github/workflows\" ]; then\n count=$(find \"$P/.github/workflows\" -maxdepth 1 -type f \\( -name \"*.yml\" -o -name \"*.yaml\" \\) 2>/dev/null | wc -l | tr -d ' ')\n fi\n printf '%s\\n' \"${count:-0}\"\n}\n\ncount_local_skills() {\n local count=0\n count=$(for dir in \"$P/skills\" \"$P/.claude/skills\" \"$P/.agents/skills\" \"$P/.codex/skills\"; do\n [ -d \"$dir\" ] || continue\n list_skill_files \"$dir\"\n done | while IFS= read -r f; do\n canonical_skill_file \"$f\" || true\n done | sort -u | wc -l | tr -d ' ')\n printf '%s\\n' \"${count:-0}\"\n}\n\nresolve_symlink() {\n readlink -f \"$1\" 2>/dev/null && return\n # macOS fallback: resolve symlink chain manually\n local target=\"$1\"\n local depth=0\n while [ -L \"$target\" ] && [ \"$depth\" -lt 32 ]; do\n local dir\n dir=$(cd \"$(dirname \"$target\")\" && pwd -P)\n target=$(readlink \"$target\")\n case \"$target\" in /*) ;; *) target=\"$dir/$target\" ;; esac\n depth=$((depth + 1))\n done\n if [ -d \"$target\" ]; then\n (cd \"$target\" 2>/dev/null && pwd -P) || return 1\n elif [ -e \"$target\" ]; then\n local parent base\n parent=${target%/*}\n base=${target##*/}\n parent=$(cd \"$parent\" 2>/dev/null && pwd -P) || return 1\n printf '%s/%s\\n' \"$parent\" \"$base\"\n else\n return 1\n fi\n}\n\ncount_file_lines() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -n \"$canonical\" ]; then\n wc -l \u003c \"$canonical\" | tr -d ' '\n else\n echo 0\n fi\n}\n\ncount_file_words() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -n \"$canonical\" ]; then\n wc -w \u003c \"$canonical\" | tr -d ' '\n else\n echo 0\n fi\n}\n\ncount_file_bytes() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -n \"$canonical\" ]; then\n wc -c \u003c \"$canonical\" | tr -d ' '\n else\n echo 0\n fi\n}\n\ncount_file_cjk_chars() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ] || [ -z \"$PYTHON_BIN\" ]; then\n echo 0\n return\n fi\n \"$PYTHON_BIN\" -I -c 'import re,sys; from pathlib import Path; text=Path(sys.argv[1]).read_text(encoding=\"utf-8\",errors=\"replace\"); print(len(re.findall(r\"[\\u3400-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]\", text)))' \"$canonical\" 2>/dev/null || echo 0\n}\n\ncount_file_context_units() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ] || [ -z \"$PYTHON_BIN\" ]; then\n count_file_words \"$file\"\n return\n fi\n \"$PYTHON_BIN\" -I -c 'import re,sys; from pathlib import Path; text=Path(sys.argv[1]).read_text(encoding=\"utf-8\",errors=\"replace\"); cjk=re.compile(r\"[\\u3400-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]\"); print(len(cjk.sub(\" \", text).split()) + len(cjk.findall(text)))' \"$canonical\" 2>/dev/null || count_file_words \"$file\"\n}\n\ncontext_units_from_stream() {\n if [ -z \"$PYTHON_BIN\" ]; then\n wc -w | tr -d ' '\n return\n fi\n \"$PYTHON_BIN\" -I -c 'import re,sys; text=sys.stdin.read(); cjk=re.compile(r\"[\\u3400-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]\"); print(len(cjk.sub(\" \", text).split()) + len(cjk.findall(text)))'\n}\n\nlist_rule_files() {\n local rule_dir file canonical\n for rule_dir in \"$P/.claude/rules\" \"$HOME/.claude/rules\"; do\n [ -d \"$rule_dir\" ] || continue\n while IFS= read -r -d '' file; do\n path_has_controls \"$file\" && continue\n canonical=$(canonical_health_file \"$file\" || true)\n [ -n \"$canonical\" ] || continue\n printf '%s\\n' \"$canonical\"\n done \u003c \u003c(find \"$rule_dir\" -type f -name \"*.md\" -print0 2>/dev/null || true)\n done | LC_ALL=C sort -u\n}\n\nprint_rule_files() {\n local found=0 shown=0\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n found=1\n shown=$((shown + 1))\n if [ \"$shown\" -gt 50 ]; then\n continue\n fi\n echo \"--- $(health_path_label \"$f\") ---\"\n print_redacted_file \"$f\"\n done \u003c \u003c(list_rule_files)\n [ \"$found\" -eq 1 ] || echo \"(none)\"\n [ \"$shown\" -le 50 ] || echo \"rule_files_truncated: $((shown - 50))\"\n}\n\nprint_file_summary() {\n local label=\"$1\"\n local file=\"$2\"\n local canonical\n\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ]; then\n echo \"${label}_present: no\"\n return\n fi\n\n echo \"${label}_present: yes\"\n echo \"${label}_lines: $(count_file_lines \"$canonical\")\"\n echo \"${label}_words: $(count_file_words \"$canonical\")\"\n\n local headings\n headings=$(grep -nE '^[[:space:]]*#{1,3}[[:space:]]+' \"$canonical\" 2>/dev/null | head -8 || true)\n if [ -n \"$headings\" ]; then\n echo \"${label}_headings:\"\n printf '%s\\n' \"$headings\" | sed 's/^/ /'\n fi\n}\n\nprint_settings_summary() {\n local file=\"$1\" canonical\n canonical=$(canonical_health_file \"$file\" || true)\n if [ -z \"$canonical\" ]; then\n echo \"settings_local_json: no\"\n return\n fi\n\n echo \"settings_local_json: yes\"\n echo \"settings_local_json_lines: $(count_file_lines \"$canonical\")\"\n echo \"settings_local_json_bytes: $(wc -c \u003c \"$canonical\" | tr -d ' ')\"\n}\n\nprint_rule_file_summary() {\n local files count=0 shown=0\n files=$(list_rule_files)\n if [ -z \"$files\" ]; then\n echo \"rule_files: 0\"\n return\n fi\n\n count=$(printf '%s\\n' \"$files\" | wc -l | tr -d ' ')\n echo \"rule_files: $count\"\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n shown=$((shown + 1))\n [ \"$shown\" -le 50 ] || continue\n echo \"path=$(health_path_label \"$f\") lines=$(count_file_lines \"$f\") words=$(count_file_words \"$f\")\"\n done \u003c\u003cEOF\n$files\nEOF\n [ \"$count\" -le 50 ] || echo \"rule_file_summaries_truncated: $((count - 50))\"\n}\n\nrule_has_paths_frontmatter() {\n local file=\"$1\"\n awk '\n NR == 1 && $0 == \"---\" { frontmatter = 1; next }\n frontmatter && $0 == \"---\" { exit(found ? 0 : 1) }\n frontmatter && $0 ~ /^paths:[[:space:]]*$/ { found = 1 }\n END { if (!frontmatter) exit 1 }\n ' \"$file\"\n}\n\nrules_word_count() {\n local scope=\"${1:-all}\" words=0\n if [ -d \"$P/.claude/rules\" ] || [ -d \"$HOME/.claude/rules\" ]; then\n words=$(while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n if [ \"$scope\" = \"scoped\" ] && ! rule_has_paths_frontmatter \"$f\"; then\n continue\n fi\n if [ \"$scope\" = \"always\" ] && rule_has_paths_frontmatter \"$f\"; then\n continue\n fi\n cat \"$f\"\n done \u003c \u003c(list_rule_files) | wc -w | tr -d ' ')\n fi\n printf '%s\\n' \"${words:-0}\"\n}\n\nrules_context_unit_count() {\n local scope=\"${1:-all}\"\n if [ ! -d \"$P/.claude/rules\" ] && [ ! -d \"$HOME/.claude/rules\" ]; then\n echo 0\n return\n fi\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n if [ \"$scope\" = \"scoped\" ] && ! rule_has_paths_frontmatter \"$f\"; then\n continue\n fi\n if [ \"$scope\" = \"always\" ] && rule_has_paths_frontmatter \"$f\"; then\n continue\n fi\n cat \"$f\"\n done \u003c \u003c(list_rule_files) | context_units_from_stream\n}\n\ncollect_skill_descriptions_raw() {\n local f description helper\n helper=$(resolve_health_helper read_skill_description.py || true)\n [ -n \"$helper\" ] && [ -n \"$PYTHON_BIN\" ] || return 0\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n description=$(\"$PYTHON_BIN\" -I \"$helper\" \"$f\" 2>/dev/null || true)\n [ -n \"$description\" ] && printf '%s:description: %s\\n' \"$(health_path_label \"$f\")\" \"$description\"\n done \u003c \u003c(list_direct_skill_files)\n}\n\nskill_description_inventory_status() {\n local helper\n if [ -z \"$PYTHON_BIN\" ]; then\n echo \"unavailable_python\"\n return\n fi\n helper=$(resolve_health_helper read_skill_description.py || true)\n if [ -z \"$helper\" ]; then\n echo \"unavailable_helper\"\n else\n echo \"available\"\n fi\n}\n\nprint_skill_descriptions() {\n local out count status\n status=$(skill_description_inventory_status)\n echo \"skill_description_inventory_status: $status\"\n if [ \"$status\" != \"available\" ]; then\n echo \"(unavailable: skill description parser)\"\n return\n fi\n out=$(printf '%s\\n' \"$HEALTH_SKILL_DESCRIPTIONS\" | sort -u | awk 'NR \u003c= 101')\n if [ -n \"$out\" ]; then\n count=$(printf '%s\\n' \"$out\" | wc -l | tr -d ' ')\n printf '%s\\n' \"$out\" | awk 'NR \u003c= 100' | redact_health_stream\n [ \"$count\" -le 100 ] || echo \"skill_descriptions_truncated: yes\"\n else\n echo \"(none)\"\n fi\n}\n\nprint_skill_description_summary() {\n local out count status\n status=$(skill_description_inventory_status)\n echo \"skill_description_inventory_status: $status\"\n if [ \"$status\" != \"available\" ]; then\n echo \"skill_descriptions: unavailable\"\n return\n fi\n out=$(printf '%s\\n' \"$HEALTH_SKILL_DESCRIPTIONS\" | sort -u)\n if [ -z \"$out\" ]; then\n echo \"skill_descriptions: 0\"\n return\n fi\n\n count=$(printf '%s\\n' \"$out\" | wc -l | tr -d ' ')\n echo \"skill_descriptions: $count\"\n printf '%s\\n' \"$out\" | awk 'NR \u003c= 20 {\n marker=\":description: \"\n position=index($0, marker)\n if (!position) next\n path=substr($0, 1, position - 1)\n description=substr($0, position + length(marker))\n printf \"path=%s description_chars=%d\\n\", path, length(description)\n }'\n if [ \"$count\" -gt 20 ]; then\n echo \"skill_descriptions_truncated: yes\"\n fi\n}\n\nskill_description_word_count() {\n local words\n words=$(printf '%s\\n' \"$HEALTH_SKILL_DESCRIPTIONS\" | wc -w | tr -d ' ')\n printf '%s\\n' \"${words:-0}\"\n}\n\nskill_description_context_unit_count() {\n printf '%s\\n' \"$HEALTH_SKILL_DESCRIPTIONS\" | context_units_from_stream\n}\n\nlist_skill_files() {\n local dir=\"$1\" link target file relative\n [ -d \"$dir\" ] || return 0\n path_has_controls \"$dir\" && return 0\n path_is_sensitive \"$dir\" && return 0\n while IFS= read -r -d '' file; do\n path_has_controls \"$file\" && continue\n printf '%s\\n' \"$file\"\n done \u003c \u003c(find \"$dir\" -maxdepth 4 \\\n \\( -type d \\( -iname 'secrets' -o -iname '.env' -o -iname '.env.*' -o -iname '*credential*' \\) -prune \\) \\\n -o -name \"SKILL.md\" -print0 2>/dev/null || true)\n while IFS= read -r -d '' link; do\n [ -n \"$link\" ] || continue\n path_has_controls \"$link\" && continue\n target=$(resolve_symlink \"$link\" || true)\n if [ -z \"$target\" ] || [ ! -d \"$target\" ]; then\n continue\n fi\n path_has_controls \"$target\" && continue\n path_is_sensitive \"$target\" && continue\n if is_project_skill_path \"$link\" && ! path_is_within \"$target\" \"$HEALTH_TARGET\"; then\n continue\n fi\n if [ -f \"$target/SKILL.md\" ]; then\n printf '%s/SKILL.md\\n' \"$link\"\n elif [ -d \"$target/skills\" ]; then\n while IFS= read -r -d '' file; do\n relative=${file#\"$target\"/}\n path_has_controls \"$file\" && continue\n printf '%s/%s\\n' \"$link\" \"$relative\"\n done \u003c \u003c(find \"$target/skills\" -maxdepth 2 -name \"SKILL.md\" -print0 2>/dev/null || true)\n fi\n done \u003c \u003c(find \"$dir\" -mindepth 1 -maxdepth 1 -type l -print0 2>/dev/null || true)\n}\n\ndirect_skill_roots() {\n printf '%s\\n' \\\n \"$P/.claude/skills\" \\\n \"$P/.agents/skills\" \\\n \"$P/.codex/skills\" \\\n \"$HOME/.claude/skills\" \\\n \"$HOME/.agents/skills\" \\\n \"$HOME/.codex/skills\"\n}\n\nsource_skill_roots() {\n printf '%s\\n' \"$P/skills\"\n}\n\nlist_direct_skill_files() {\n local dir\n while IFS= read -r dir; do\n [ -d \"$dir\" ] || continue\n list_skill_files \"$dir\"\n done \u003c \u003c(direct_skill_roots) | while IFS= read -r file; do\n canonical_skill_file \"$file\" || true\n done | sort -u\n}\n\ncodex_plugin_candidate_skill_roots() {\n local cache=\"$HOME/.codex/plugins/cache\" dir\n [ -d \"$cache\" ] || return 0\n while IFS= read -r -d '' dir; do\n path_has_controls \"$dir\" && continue\n printf '%s\\n' \"$dir\"\n done \u003c \u003c(find \"$cache\" -mindepth 4 -maxdepth 4 -type d -name skills -print0 2>/dev/null || true) \\\n | LC_ALL=C sort\n}\n\nskill_roots() {\n local plugin_roots\n plugin_roots=$(codex_plugin_candidate_skill_roots)\n source_skill_roots\n direct_skill_roots\n [ -n \"$plugin_roots\" ] && printf '%s\\n' \"$plugin_roots\"\n}\n\npath_is_within() {\n local path=\"$1\" root=\"$2\"\n [ \"$path\" = \"$root\" ] || case \"$path/\" in \"$root/\"*) return 0 ;; *) return 1 ;; esac\n}\n\nis_project_skill_path() {\n local path=\"$1\"\n case \"$path/\" in\n \"$P/skills/\"*|\"$P/.claude/skills/\"*|\"$P/.agents/skills/\"*|\"$P/.codex/skills/\"*) return 0 ;;\n *) return 1 ;;\n esac\n}\n\nis_declared_skill_path() {\n local path=\"$1\"\n case \"$path/\" in\n \"$P/skills/\"*|\"$P/.claude/skills/\"*|\"$P/.agents/skills/\"*|\"$P/.codex/skills/\"*|\\\n \"$HOME/.claude/skills/\"*|\"$HOME/.agents/skills/\"*|\"$HOME/.codex/skills/\"*|\\\n \"$HOME/.codex/plugins/cache/\"*) return 0 ;;\n *) return 1 ;;\n esac\n}\n\npath_is_sensitive() {\n local path=\"$1\" lower\n case \"$path/\" in\n \"$HOME/.ssh/\"*|\"$HOME/.aws/\"*|\"$HOME/.gnupg/\"*|\"$HOME/.config/gh/\"*|\\\n \"$HEALTH_HOME/.ssh/\"*|\"$HEALTH_HOME/.aws/\"*|\"$HEALTH_HOME/.gnupg/\"*|\"$HEALTH_HOME/.config/gh/\"*) return 0 ;;\n esac\n lower=$(printf '%s' \"/$path/\" | tr '[:upper:]' '[:lower:]')\n case \"$lower\" in\n */.env/*|*/.env.*/*|*/secrets/*|*/*credential*/*) return 0 ;;\n *) return 1 ;;\n esac\n}\n\ncanonical_health_file() {\n local file=\"$1\" canonical scope_root\n path_has_controls \"$file\" && return 1\n case \"$file/\" in\n \"$P/\"*|\"$HEALTH_TARGET/\"*) scope_root=\"$HEALTH_TARGET\" ;;\n \"$HOME/\"*|\"$HEALTH_HOME/\"*) scope_root=\"$HEALTH_HOME\" ;;\n *) return 1 ;;\n esac\n canonical=$(resolve_symlink \"$file\" 2>/dev/null || true)\n [ -n \"$canonical\" ] && [ -f \"$canonical\" ] || return 1\n path_has_controls \"$canonical\" && return 1\n path_is_sensitive \"$canonical\" && return 1\n path_is_within \"$canonical\" \"$scope_root\" || return 1\n printf '%s\\n' \"$canonical\"\n}\n\ncanonical_skill_file() {\n local file=\"$1\" dir base canonical\n path_has_controls \"$file\" && return 1\n is_declared_skill_path \"$file\" || return 1\n [ -L \"$file\" ] && return 1\n dir=${file%/*}\n base=${file##*/}\n dir=$(cd \"$dir\" 2>/dev/null && pwd -P) || return 1\n canonical=\"$dir/$base\"\n path_is_sensitive \"$canonical\" && return 1\n if is_project_skill_path \"$file\" && ! path_is_within \"$canonical\" \"$HEALTH_TARGET\"; then\n return 1\n fi\n [ -f \"$canonical\" ] || return 1\n printf '%s\\n' \"$canonical\"\n}\n\nlist_all_skill_files() {\n local dir f\n while IFS= read -r dir; do\n [ -d \"$dir\" ] || continue\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n canonical_skill_file \"$f\"\n done \u003c \u003c(list_skill_files \"$dir\")\n done \u003c \u003c(skill_roots) | sort -u\n}\n\nlist_security_skill_files() {\n local dir\n while IFS= read -r dir; do\n [ -d \"$dir\" ] || continue\n list_skill_files \"$dir\"\n done \u003c \u003c(skill_roots) | sort -u\n}\n\nprint_skill_root_coverage() {\n local dir link target\n local direct_present=0 source_present=0 plugin_candidates=0 rejected_roots=0\n while IFS= read -r dir; do\n [ -d \"$dir\" ] && direct_present=$((direct_present + 1))\n [ -d \"$dir\" ] || continue\n while IFS= read -r -d '' link; do\n [ -n \"$link\" ] || continue\n path_has_controls \"$link\" && continue\n target=$(resolve_symlink \"$link\" || true)\n if [ -z \"$target\" ] || path_has_controls \"$target\" || path_is_sensitive \"$target\" || { is_project_skill_path \"$link\" && ! path_is_within \"$target\" \"$HEALTH_TARGET\"; }; then\n rejected_roots=$((rejected_roots + 1))\n fi\n done \u003c \u003c(find \"$dir\" -mindepth 1 -maxdepth 1 -type l -print0 2>/dev/null || true)\n done \u003c \u003c(direct_skill_roots)\n while IFS= read -r dir; do\n [ -d \"$dir\" ] && source_present=$((source_present + 1))\n done \u003c \u003c(source_skill_roots)\n plugin_candidates=$(codex_plugin_candidate_skill_roots | wc -l | tr -d ' ')\n echo \"direct_skill_roots_declared: 6\"\n echo \"direct_skill_roots_present: $direct_present\"\n echo \"source_skill_roots_declared: 1\"\n echo \"source_skill_roots_present: $source_present\"\n echo \"codex_plugin_candidate_roots_scanned: ${plugin_candidates:-0}\"\n echo \"codex_plugin_activation_status: unknown\"\n echo \"codex_plugin_activation_gap: cache_presence_only_cannot_prove_active_routing\"\n echo \"rejected_sensitive_or_escaped_skill_roots: $rejected_roots\"\n}\n\nsanitize_git_remote() {\n local remote=\"$1\" scheme rest authority path host\n remote=$(safe_health_text \"$remote\")\n case \"$remote\" in\n *://*)\n scheme=${remote%%://*}\n rest=${remote#*://}\n rest=${rest%%\\#*}\n rest=${rest%%\\?*}\n authority=${rest%%/*}\n if [ \"$authority\" = \"$rest\" ]; then\n path=\"\"\n else\n path=\"/${rest#*/}\"\n fi\n authority=${authority##*@}\n [ -n \"$authority\" ] || { printf '%s\\n' \"redacted\"; return; }\n printf '%s://%s%s\\n' \"$scheme\" \"$authority\" \"$path\"\n ;;\n *@*:*)\n rest=${remote%%\\#*}\n rest=${rest%%\\?*}\n rest=${rest#*@}\n host=${rest%%:*}\n path=${rest#*:}\n if [ -z \"$host\" ] || [ -z \"$path\" ]; then\n printf '%s\\n' \"redacted\"\n return\n fi\n printf 'ssh://%s/%s\\n' \"$host\" \"$path\"\n ;;\n /*|./*|../*)\n printf '%s\\n' \"local\"\n ;;\n *)\n rest=${remote%%\\#*}\n rest=${rest%%\\?*}\n rest=${rest##*@}\n printf '%s\\n' \"${rest:-redacted}\"\n ;;\n esac\n}\n\nis_current_health_skill() {\n [ -f \"$SCRIPT_DIR/../SKILL.md\" ] && [ \"$1\" -ef \"$SCRIPT_DIR/../SKILL.md\" ]\n}\n\nlist_conversation_files() {\n local file canonical mtime\n [ -d \"$CONVO_DIR\" ] || return 0\n while IFS= read -r -d '' file; do\n path_has_controls \"$file\" && continue\n canonical=$(canonical_health_file \"$file\" || true)\n [ -n \"$canonical\" ] || continue\n path_is_within \"$canonical\" \"$CONVO_DIR\" || continue\n mtime=$(stat -f '%m' \"$canonical\" 2>/dev/null || stat -c '%Y' \"$canonical\" 2>/dev/null || echo 0)\n printf '%s\\t%s\\n' \"$mtime\" \"$canonical\"\n done \u003c \u003c(find \"$CONVO_DIR\" -maxdepth 1 -type f -name '*.jsonl' -print0 2>/dev/null || true) \\\n | sort -nr | cut -f2-\n}\n\nprint_mcp_access_denials() {\n local files file canonical chunk found=0\n files=$(list_conversation_files | head -5)\n if [ -z \"$files\" ]; then\n echo \"(no conversation files)\"\n return\n fi\n while IFS= read -r file; do\n path_is_within \"$file\" \"$CONVO_DIR\" || continue\n canonical=$(canonical_health_file \"$file\" || true)\n [ -n \"$canonical\" ] || continue\n path_is_within \"$canonical\" \"$CONVO_DIR\" || continue\n chunk=$(head -c 1048576 \"$canonical\" | grep -Em 2 'Access denied - path outside allowed directories|tool-results/.+ not in ' 2>/dev/null || true)\n if [ -n \"$chunk\" ]; then\n found=1\n printf '%s\\n' \"$chunk\" | redact_health_stream\n fi\n done \u003c\u003cEOF\n$files\nEOF\n [ \"$found\" -eq 1 ] || echo \"(none found)\"\n}\n\nPROJECT_FILES=$(count_project_files)\nCONTRIBUTORS=$(count_contributors)\nCI_WORKFLOWS=$(count_ci_workflows)\n\necho \"[1/12] Project signals...\"\necho \"=== PROJECT SIGNALS ===\"\necho \"project_files: $PROJECT_FILES\"\necho \"contributors: $CONTRIBUTORS\"\necho \"ci_workflows: $CI_WORKFLOWS\"\necho \"skills: $(count_local_skills)\"\necho \"claude_md_lines: $(count_file_lines \"$P/CLAUDE.md\")\"\necho \"collection_mode: $MODE\"\necho \"audit_hint: $AUDIT_HINT\"\n\necho \"[2/12] CLAUDE.md (global + local)...\"\necho \"=== CLAUDE.md (global) ===\"\nif [ \"$MODE\" = \"deep\" ]; then\n print_redacted_file \"$HOME/.claude/CLAUDE.md\"\nelse\n print_file_summary \"global_claude_md\" \"$HOME/.claude/CLAUDE.md\"\nfi\necho \"=== CLAUDE.md (local) ===\"\nif [ \"$MODE\" = \"deep\" ]; then\n print_redacted_file \"$P/CLAUDE.md\"\nelse\n print_file_summary \"local_claude_md\" \"$P/CLAUDE.md\"\nfi\n\necho \"[3/12] Settings, hooks, MCP...\"\necho \"=== settings.local.json ===\"\nprint_settings_summary \"$SETTINGS\"\n\necho \"[4/12] Rules + skill descriptions...\"\n# One per-run snapshot keeps inventory and both budget estimates consistent.\nHEALTH_SKILL_DESCRIPTIONS=$(collect_skill_descriptions_raw)\necho \"=== rules/ ===\"\nif [ \"$MODE\" = \"deep\" ]; then\n print_rule_files\nelse\n print_rule_file_summary\nfi\necho \"=== skill descriptions ===\"\nif [ \"$MODE\" = \"deep\" ]; then\n print_skill_descriptions\nelse\n print_skill_description_summary\nfi\n\necho \"[5/12] Context budget estimate...\"\necho \"=== STARTUP CONTEXT ESTIMATE ===\"\necho \"global_claude_words: $(count_file_words \"$HOME/.claude/CLAUDE.md\")\"\necho \"global_claude_cjk_chars: $(count_file_cjk_chars \"$HOME/.claude/CLAUDE.md\")\"\necho \"global_claude_bytes: $(count_file_bytes \"$HOME/.claude/CLAUDE.md\")\"\necho \"global_claude_context_units: $(count_file_context_units \"$HOME/.claude/CLAUDE.md\")\"\necho \"local_claude_words: $(count_file_words \"$P/CLAUDE.md\")\"\necho \"local_claude_cjk_chars: $(count_file_cjk_chars \"$P/CLAUDE.md\")\"\necho \"local_claude_bytes: $(count_file_bytes \"$P/CLAUDE.md\")\"\necho \"local_claude_context_units: $(count_file_context_units \"$P/CLAUDE.md\")\"\necho \"rules_words: $(rules_word_count always)\"\necho \"rules_context_units: $(rules_context_unit_count always)\"\necho \"path_scoped_rules_words: $(rules_word_count scoped)\"\necho \"path_scoped_rules_context_units: $(rules_context_unit_count scoped)\"\necho \"skill_desc_words: $(skill_description_word_count)\"\necho \"skill_desc_context_units: $(skill_description_context_unit_count)\"\necho \"skill_description_inventory_status: $(skill_description_inventory_status)\"\nif [ -n \"$PYTHON_BIN\" ]; then\nSAFE_SETTINGS=$(canonical_health_file \"$SETTINGS\" || true)\n\"$PYTHON_BIN\" -I - \"$SAFE_SETTINGS\" \"$MODE\" \u003c\u003c'PYEOF' 2>/dev/null || echo \"(unavailable)\"\nimport json\nimport os\nimport re\nimport sys\n\npath = sys.argv[1]\nmode = sys.argv[2]\ntry:\n if os.path.getsize(path) > 1048576:\n raise ValueError('settings file exceeds 1 MiB collection limit')\n with open(path) as fh:\n d = json.load(fh)\nexcept Exception:\n msg = '(unavailable: settings.local.json missing or malformed)'\n print('=== PROJECT-LOCAL hooks ===')\n print(msg)\n print('=== PROJECT-LOCAL MCP ===')\n print(msg)\n print('=== MCP FILESYSTEM ===')\n print(msg)\n print('=== allowedTools count ===')\n print(msg)\n sys.exit(0)\n\nprint('=== PROJECT-LOCAL hooks ===')\nhooks = d.get('hooks', {})\nif isinstance(hooks, dict):\n names = sorted(hooks.keys())\n print(f'hook_events: {len(names)}')\n print('hook_event_names:', ', '.join(names[:20]) if names else '(none)')\n if len(names) > 20:\n print('hook_event_names_truncated:', len(names) - 20)\n handler_count = 0\n matcher_count = 0\n for groups in hooks.values():\n if not isinstance(groups, list):\n continue\n for group in groups:\n if not isinstance(group, dict):\n continue\n matcher_count += int(bool(group.get('matcher')))\n handlers = group.get('hooks')\n if isinstance(handlers, list):\n handler_count += len(handlers)\n print('hook_matchers_configured:', matcher_count)\n print('hook_handlers_configured:', handler_count)\nelse:\n print('hook_events: (unknown format)')\n\nprint('=== PROJECT-LOCAL MCP ===')\nservers = d.get('mcpServers', d.get('enabledMcpjsonServers', {}))\nnames = list(servers.keys()) if isinstance(servers, dict) else list(servers)\ncount = len(names)\nsafe_names = [re.sub(r'[^A-Za-z0-9_.@+-]+', '_', str(name))[:80] for name in names[:20]]\nprint(f'servers({count}):', ', '.join(safe_names))\nif count > 20:\n print('server_names_truncated:', count - 20)\nprint('coverage: project settings only; see RUNTIME CONFIGURATION for global sources')\n\nprint('=== MCP FILESYSTEM ===')\nif isinstance(servers, list):\n print('filesystem_present: (array format -- check .mcp.json)')\n print('allowedDirectories: (not detectable)')\nelse:\n filesystem = servers.get('filesystem') if isinstance(servers, dict) else None\n allowed = []\n if isinstance(filesystem, dict):\n allowed = filesystem.get('allowedDirectories') or (\n filesystem.get('config', {}).get('allowedDirectories')\n if isinstance(filesystem.get('config'), dict)\n else []\n )\n if not allowed and isinstance(filesystem.get('args'), list):\n args = filesystem['args']\n for index, value in enumerate(args):\n if value in ('--allowed-directories', '--allowedDirectories') and index + 1 \u003c len(args):\n allowed = [args[index + 1]]\n break\n if not allowed:\n allowed = [value for value in args if value.startswith('/') or (value.startswith('~') and len(value) > 1)]\n print('filesystem_present:', 'yes' if filesystem else 'no')\n print('allowedDirectories_count:', len(allowed))\n\nprint('=== allowedTools count ===')\nprint(len(d.get('permissions', {}).get('allow', [])))\nPYEOF\nelse\n echo \"=== PROJECT-LOCAL hooks ===\"\n echo \"(unavailable)\"\n echo \"=== PROJECT-LOCAL MCP ===\"\n echo \"(unavailable)\"\n echo \"=== MCP FILESYSTEM ===\"\n echo \"(unavailable)\"\n echo \"=== allowedTools count ===\"\n echo \"(unavailable)\"\nfi\n\necho \"[6/12] Nested CLAUDE.md + gitignore...\"\necho \"=== NESTED CLAUDE.md ===\"\n_NESTED_CLAUDE=()\nwhile IFS= read -r -d '' f; do\n path_has_controls \"$f\" && continue\n f=$(canonical_health_file \"$f\" || true)\n [ -n \"$f\" ] || continue\n _NESTED_CLAUDE+=(\"$f\")\ndone \u003c \u003c(find \"$P\" -maxdepth 4 -type f -name \"CLAUDE.md\" -not -path \"$P/CLAUDE.md\" -not -path \"*/.git/*\" -not -path \"*/node_modules/*\" -print0 2>/dev/null || true)\n_NESTED_COUNT=${#_NESTED_CLAUDE[@]}\nif [ \"$_NESTED_COUNT\" -gt 0 ]; then\n _NESTED_SHOWN=0\n for f in \"${_NESTED_CLAUDE[@]}\"; do\n _NESTED_SHOWN=$((_NESTED_SHOWN + 1))\n [ \"$_NESTED_SHOWN\" -le 50 ] || continue\n health_path_label \"$f\"\n done\n [ \"$_NESTED_COUNT\" -le 50 ] || echo \"nested_claude_listing_truncated: $((_NESTED_COUNT - 50))\"\nelse\n echo \"(none)\"\nfi\necho \"=== GITIGNORE ===\"\n_GITIGNORE_HIT=$(git -c core.fsmonitor=false -C \"$P\" check-ignore -v .claude/settings.local.json 2>/dev/null || true)\nif [ -n \"$_GITIGNORE_HIT\" ]; then\n _GITIGNORE_SOURCE=${_GITIGNORE_HIT%%:*}\n case \"$_GITIGNORE_SOURCE\" in\n .gitignore|.claude/.gitignore)\n echo \"settings.local.json: gitignored\"\n ;;\n *)\n echo \"settings.local.json: ignored only by non-project rule ($(safe_health_text \"$_GITIGNORE_SOURCE\")) -- add a repo-local ignore rule\"\n ;;\n esac\nelse\n echo \"settings.local.json: NOT gitignored -- risk of committing tokens/credentials\"\nfi\n\necho \"[7/12] HANDOFF.md + MEMORY.md...\"\necho \"=== HANDOFF.md ===\"\nprint_sensitive_file_summary \"handoff\" \"$P/HANDOFF.md\"\necho \"=== MEMORY.md ===\"\nif [ -f \"$HOME/.claude/projects/-${PROJECT_KEY}/memory/MEMORY.md\" ]; then\n print_sensitive_file_summary \"memory\" \"$HOME/.claude/projects/-${PROJECT_KEY}/memory/MEMORY.md\"\nelse\n echo \"memory_present: no\"\nfi\n\necho \"[8/12] Conversation signals + extract...\"\nCONVERSATION_AUDIT_SCRIPT=\"$(resolve_health_helper conversation_audit.py || true)\"\nif [ \"$AUDIT_HINT\" = \"instructions\" ]; then\n # Out of scope, not unavailable: an instruction-and-config audit does not need\n # session history, and calling a deliberate skip a coverage gap would train the\n # reader to ignore real ones.\n echo \"=== CONVERSATION COVERAGE ===\"\n echo \"(out of scope: instruction and config audit, session history not read)\"\n echo \"=== CONVERSATION FILES ===\"\n echo \"(out of scope)\"\n echo \"=== CONVERSATION SIGNALS ===\"\n echo \"(out of scope)\"\nelif [ -n \"$CONVERSATION_AUDIT_SCRIPT\" ] && [ -n \"$PYTHON_BIN\" ]; then\n \"$PYTHON_BIN\" -I \"$CONVERSATION_AUDIT_SCRIPT\" \"$CONVO_DIR\" \"$MODE\" \\\n --codex-root \"$HOME/.codex/sessions\" --project-root \"$P\"\nelse\n echo \"=== CONVERSATION COVERAGE ===\"\n echo \"(unavailable: conversation_audit.py or trusted Python missing)\"\n echo \"=== CONVERSATION FILES ===\"\n echo \"(unavailable)\"\n echo \"=== CONVERSATION SIGNALS ===\"\n echo \"(unavailable)\"\n echo \"=== CONVERSATION EXTRACT ===\"\n echo \"(unavailable)\"\n echo \"=== VERIFICATION RECEIPTS ===\"\n echo \"(unavailable)\"\nfi\n\nif [ \"$MODE\" = \"deep\" ]; then\necho \"=== MCP ACCESS DENIALS ===\"\nprint_mcp_access_denials\nelse\n echo \"=== MCP ACCESS DENIALS ===\" ; echo \"(skipped: summary mode; ask for a deep health audit or run collect-data.sh auto deep for access-denial scan)\"\nfi\n\necho \"[9/12] Agent config...\"\nif [ \"$MODE\" = \"deep\" ]; then\n echo \"=== AGENT CONFIG DETAIL ===\"\nelse\n echo \"=== AGENT CONFIG SUMMARY ===\"\nfi\nAGENT_CONTEXT_SCRIPT=\"$(resolve_health_helper check_agent_context.py || true)\"\nif [ -n \"$AGENT_CONTEXT_SCRIPT\" ] && [ -n \"$PYTHON_BIN\" ]; then\n if ! \"$PYTHON_BIN\" -I \"$AGENT_CONTEXT_SCRIPT\" \"$P\" \"$MODE\"; then\n echo \"(unavailable: check_agent_context.py failed)\"\n fi\nelse\n echo \"(unavailable: check_agent_context.py or trusted Python missing)\"\nfi\n\necho \"[10/12] AI maintainability...\"\nif [ \"$MODE\" = \"deep\" ]; then\n echo \"=== AI MAINTAINABILITY DETAIL ===\"\nelse\n echo \"=== AI MAINTAINABILITY SUMMARY ===\"\nfi\nMAINTAINABILITY_SCRIPT=\"$(resolve_health_helper check_maintainability.py || true)\"\nif [ -n \"$MAINTAINABILITY_SCRIPT\" ] && [ -n \"$PYTHON_BIN\" ]; then\n if ! \"$PYTHON_BIN\" -I \"$MAINTAINABILITY_SCRIPT\" \"$P\" \"$MODE\"; then\n echo \"(unavailable: check_maintainability.py failed)\"\n fi\nelse\n echo \"(unavailable: check_maintainability.py or trusted Python missing)\"\nfi\n\necho \"[11/12] Skill inventory + frontmatter + provenance...\"\necho \"=== SKILL ROOT COVERAGE ===\"\nprint_skill_root_coverage\necho \"=== SKILL INVENTORY ===\"\n_SKILL_FOUND=0\n_SKILL_SHOWN=0\nwhile IFS= read -r f; do\n [ -n \"$f\" ] || continue\n _SKILL_FOUND=1\n _SKILL_SHOWN=$((_SKILL_SHOWN + 1))\n [ \"$_SKILL_SHOWN\" -le 200 ] || continue\n WORDS=$(wc -w \u003c \"$f\" | tr -d ' ')\n echo \"path=$(health_path_label \"$f\") words=$WORDS\"\ndone \u003c \u003c(list_all_skill_files)\n[ \"$_SKILL_FOUND\" -eq 1 ] || echo \"(none)\"\n[ \"$_SKILL_SHOWN\" -le 200 ] || echo \"skill_inventory_truncated: $((_SKILL_SHOWN - 200))\"\n\necho \"=== SKILL FRONTMATTER ===\"\nif [ \"$MODE\" = \"deep\" ]; then\n _FRONTMATTER_FOUND=0\n _FRONTMATTER_SHOWN=0\n while IFS= read -r f; do\n [ -n \"$f\" ] || continue\n _FRONTMATTER_FOUND=1\n _FRONTMATTER_SHOWN=$((_FRONTMATTER_SHOWN + 1))\n [ \"$_FRONTMATTER_SHOWN\" -le 200 ] || continue\n if head -1 \"$f\" | grep -q '^---'; then\n echo \"frontmatter=yes path=$(health_path_label \"$f\")\"\n else\n echo \"frontmatter=MISSING path=$(health_path_label \"$f\")\"\n fi\n done \u003c \u003c(list_all_skill_files)\n [ \"$_FRONTMATTER_FOUND\" -eq 1 ] || echo \"(none)\"\n [ \"$_FRONTMATTER_SHOWN\" -le 200 ] || echo \"skill_frontmatter_truncated: $((_FRONTMATTER_SHOWN - 200))\"\nelse\n echo \"(skipped: summary mode; use collect-data.sh auto deep to print skill frontmatter samples)\"\nfi\n\necho \"=== SKILL SYMLINK PROVENANCE ===\"\n_PROVENANCE_FOUND=0\n_PROVENANCE_SHOWN=0\nwhile IFS= read -r DIR; do\n [ -d \"$DIR\" ] || continue\n while IFS= read -r -d '' link; do\n [ -n \"$link\" ] || continue\n path_has_controls \"$link\" && continue\n _PROVENANCE_FOUND=1\n _PROVENANCE_SHOWN=$((_PROVENANCE_SHOWN + 1))\n [ \"$_PROVENANCE_SHOWN\" -le 100 ] || continue\n TARGET=$(resolve_symlink \"$link\" || true)\n if [ -z \"$TARGET\" ] || path_has_controls \"$TARGET\"; then\n echo \"link=$(safe_health_text \"${link##*/}\") target_scope=unresolved\"\n continue\n fi\n echo \"link=$(safe_health_text \"${link##*/}\") target_scope=$(health_path_label \"$TARGET\")\"\n GIT_ROOT=$(git -c core.fsmonitor=false -C \"$TARGET\" rev-parse --show-toplevel 2>/dev/null || echo \"\")\n if [ -n \"$GIT_ROOT\" ]; then\n RAW_REMOTE=$(git -c core.fsmonitor=false -C \"$GIT_ROOT\" remote get-url origin 2>/dev/null || echo \"unknown\")\n REMOTE=$(sanitize_git_remote \"$RAW_REMOTE\")\n unset RAW_REMOTE\n COMMIT=$(git -c core.fsmonitor=false -C \"$GIT_ROOT\" rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\n echo \" git_remote=$REMOTE commit=$COMMIT\"\n fi\n done \u003c \u003c(find \"$DIR\" -maxdepth 1 -type l -print0 2>/dev/null || true)\ndone \u003c \u003c(skill_roots)\n[ \"$_PROVENANCE_FOUND\" -eq 1 ] || echo \"(none)\"\n[ \"$_PROVENANCE_SHOWN\" -le 100 ] || echo \"skill_provenance_truncated: $((_PROVENANCE_SHOWN - 100))\"\n\necho \"[12/12] Full skill security scan...\"\nif [ \"$MODE\" = \"deep\" ]; then\necho \"=== SKILL SECURITY SCAN ===\"\n_SKILL_SCAN_FILES=()\nwhile IFS= read -r f; do\n [ -n \"$f\" ] || continue\n _SKILL_SCAN_FILES+=(\"$f\")\ndone \u003c \u003c(list_security_skill_files)\nSKILL_SECURITY_SCRIPT=\"$(resolve_health_helper scan_skill_security.py || true)\"\nif [ -n \"$SKILL_SECURITY_SCRIPT\" ] && [ -n \"$PYTHON_BIN\" ] && [ \"${#_SKILL_SCAN_FILES[@]}\" -gt 0 ]; then\n \"$PYTHON_BIN\" -I \"$SKILL_SECURITY_SCRIPT\" \\\n --project-root \"$HEALTH_TARGET\" \\\n --health-entrypoint \"$SCRIPT_DIR/../SKILL.md\" \\\n -- \"${_SKILL_SCAN_FILES[@]}\"\nelif [ \"${#_SKILL_SCAN_FILES[@]}\" -eq 0 ]; then\n echo \"(none)\"\nelse\n echo \"(unavailable: scan_skill_security.py or trusted Python missing)\"\nfi\nelse\n echo \"=== SKILL SECURITY SCAN ===\" ; echo \"(skipped: summary mode; deep mode scans discovered direct skill roots plus Codex plugin-cache candidates with bounded metadata; cache presence does not prove active routing)\"\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":40088,"content_sha256":"765c743a099b8034c5840bf915840ccf2e46b5a9aa91ba954731cfecc5ca3834"},{"filename":"scripts/conversation_audit.py","content":"#!/usr/bin/env python3\n\"\"\"Stream Claude and Codex project JSONL into bounded, redacted health evidence.\n\nDeep mode scans every previous session for signals. Summary mode scans up to\nthree recent previous sessions from a bounded candidate window. Every file\nmodified inside the live window is excluded so parallel active sessions cannot\nbecome evidence. Codex sessions are included when their session metadata resolves\ninside the target project root. This is a project-scoped audit unless the caller\nexplicitly enables all-project mode.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport hashlib\nimport json\nimport os\nimport re\nimport time\nfrom collections import Counter, deque\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Iterable, Optional\n\n\nMAX_SIGNALS = 20\nMAX_FILE_LIST = 10\nEXTRACT_HEAD = 30\nEXTRACT_TAIL = 120\nMAX_SIGNAL_CHARS = 320\nMAX_EXTRACT_CHARS = 800\nMAX_MESSAGE_CHARS = 4096\nMAX_RECORD_CHARS = 1_048_576\nMAX_CONTENT_ITEMS = 256\nMAX_TOOL_NAME_CHARS = 120\nLIVE_WINDOW_SECONDS = 300\nSUMMARY_CANDIDATE_LIMIT = 200\nMIN_CLONE_CONTEXT_MESSAGES = 4\n\nCONTEXT_RE = re.compile(\n r\"conversation was compressed|context limit|context window|truncat|/compact|\"\n r\"context management|token limit|window is full|compaction|\"\n r\"会话已压缩|上下文窗口|上下文限制\",\n re.IGNORECASE,\n)\nCORRECTION_RE = re.compile(\n r\"^(?:please[ :]*)?(?:you misunderstood|that(?:'s| is) not what i meant|\"\n r\"do not do that again|please don't|don't|do not|stop|next time|\"\n r\"use\\b.{0,100}\\binstead\\b|not\\b.{0,100}\\bbut\\b)|\"\n r\"^.{0,20}(?:你理解错|理解有误|我说的是|肯定不是|不是.{0,32}而是|\"\n r\"还是不对|怎么还有问题|还是有问题|请不要|不要再|不要|\"\n r\"别再|别用|下次|改成|改为|少一点|短一点|简单一点|去掉|统一成)\",\n re.IGNORECASE,\n)\nDELIVERY_RE = re.compile(\n r\"为啥不提交|都提交了吗|全部提交了吗|全部\\s*push(?:了吗)?|\"\n r\"push了吗|提交了吗|why (?:didn't|did not) you (?:commit|push)\",\n re.IGNORECASE,\n)\nPERSISTENCE_RE = re.compile(r\"^(?:继续|continue|keep going)[.!。!\\s]*$\", re.IGNORECASE)\nPLATFORM_INTERRUPTION_RE = re.compile(\n r\"API Error|No response requested|Request interrupted|response failed|\"\n r\"connection (?:closed|reset)|internal server error\",\n re.IGNORECASE,\n)\nJAPANESE_RE = re.compile(r\"[ぁ-んァ-ヶ]\")\nCJK_RE = re.compile(r\"[\\u3400-\\u9fffぁ-んァ-ヶ]\")\nJAPANESE_REQUEST_RE = re.compile(\n r\"(?:请\\s*)?(?:用|改用|切换到)\\s*(?:日语|日文).{0,12}(?:回复|回答|输出)|\"\n r\"(?:回复|回答|输出).{0,12}(?:日语|日文)|\"\n r\"(?:reply|respond|answer|output).{0,20}(?:in\\s+)?japanese|\"\n r\"(?:use|switch\\s+to)\\s+japanese(?:\\s+for\\s+(?:the\\s+)?(?:reply|response|answer|output))?|\"\n r\"日本語で.{0,12}(?:返信|回答|出力)\",\n re.IGNORECASE,\n)\nTHEME_PATTERNS = {\n \"authorization_delivery\": re.compile(\n r\"提交|commit|push|发布|publish|回复|关闭|close|不要提交|先不要提交\",\n re.IGNORECASE,\n ),\n \"completion_persistence\": re.compile(\n r\"全部|所有|彻底|查漏补缺|不要留下次|继续|做完|完成|仔细看看|\"\n r\"all of|everything|finish|keep going|continue\",\n re.IGNORECASE,\n ),\n \"simplicity_scope\": re.compile(\n r\"不要增加复杂度|如无必要勿增实体|过度设计|不要过度|臃肿|\"\n r\"keep it simple|over.?design|unnecessary\",\n re.IGNORECASE,\n ),\n \"brevity_style\": re.compile(\n r\"啰嗦|短一点|简短|简单一点|字太多|少一点|concise|shorter|too long\",\n re.IGNORECASE,\n ),\n \"visual_product_judgment\": re.compile(\n r\"图片|按钮|focus|边框|布局|界面|样式|高度|宽度|菜单|UI|视觉|\"\n r\"image|button|border|layout|menu\",\n re.IGNORECASE,\n ),\n \"localization_wording\": re.compile(\n r\"中文|英文|日语|日文|文案|翻译|单词|措辞|叫法|wording|translation\",\n re.IGNORECASE,\n ),\n \"release_version_truth\": re.compile(\n r\"版本|发布|release|nightly|preview|stable|appcast|已经上线|已经发布\",\n re.IGNORECASE,\n ),\n \"verification_evidence\": re.compile(\n r\"仔细|分析|判断|验证|测试|复核|看看所有|证据|verify|test|audit|evidence\",\n re.IGNORECASE,\n ),\n}\nINJECTED_PREFIXES = (\n \"\u003ctask-notification\",\n \"\u003cpermissions\",\n \"\u003cenvironment_context\",\n \"\u003cmulti_agent\",\n \"\u003csystem-reminder\",\n \"\u003crecommended_plugins\",\n \"# AGENTS.md instructions\",\n)\n\nURL_RE = re.compile(r\"https?://\\S+\", re.IGNORECASE)\nEMAIL_RE = re.compile(r\"\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b\", re.IGNORECASE)\nSECRET_RE = re.compile(\n r\"\\b(?:sk-[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9]{12,}|\"\n r\"github_pat_[A-Za-z0-9_]{12,}|xox[baprs]-[A-Za-z0-9-]{10,}|\"\n r\"AKIA[A-Z0-9]{16}|\"\n r\"eyJ[A-Za-z0-9_-]{20,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,})\\b\"\n)\nSECRET_ASSIGNMENT_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_-])\"\n r\"(?P\u003cname>-{0,2}(?P\u003cquote>[\\x22\\x27]?)(?:[A-Za-z0-9]+[_-])*\"\n r\"(?:secret[_-]access[_-]key|private[_-]?key|api[_-]?key|\"\n r\"authorization|password|passwd|pwd|token|secret)(?P=quote))\"\n r\"(?![A-Za-z0-9_-])\"\n r\"(?P\u003cseparator>\\s*[:=]\\s*)\"\n r\"(?:Bearer\\s+|Basic\\s+)?(?:\\\"(?:\\\\[^\\r\\n]|[^\\\"\\\\\\r\\n])*(?:\\\"|\\\\?(?=\\r?\\n|\\Z))|\"\n r\"\\x27(?:\\\\[^\\r\\n]|[^\\x27\\\\\\r\\n])*(?:\\x27|\\\\?(?=\\r?\\n|\\Z))|[^\\s,;]+)\",\n re.IGNORECASE,\n)\nPRIVATE_KEY_RE = re.compile(\n r\"-----BEGIN (?P\u003clabel>(?:(?:OPENSSH|RSA|EC|DSA|ENCRYPTED) )?PRIVATE KEY)-----\"\n r\".*?(?:-----END (?P=label)-----|$)\",\n re.DOTALL,\n)\nHASH_RE = re.compile(r\"\\b[0-9a-f]{32,}\\b\", re.IGNORECASE)\nABS_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])/(?:Users|home|private|tmp|var|etc|opt|Volumes)/[^\\s`\\\"'\u003c>]+\"\n)\nTILDE_PATH_RE = re.compile(r\"(?\u003c![A-Za-z0-9_])~/(?:[^\\s`\\\"'\u003c>]+)\")\nWINDOWS_ABS_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])(?:[A-Za-z]:\\\\|\\\\\\\\)[^\\s`\\\"'\u003c>]+\"\n)\n\n\n@dataclass\nclass ConversationFile:\n path: Path\n mtime: float\n mtime_ns: int\n size: int\n device: int\n inode: int\n runtime: str = \"claude_project_logs\"\n\n\n@dataclass\nclass Message:\n role: str\n text: str\n ordinal: int\n\n\n@dataclass\nclass Signal:\n label: str\n text: str\n file: str\n mtime: float\n ordinal: int\n runtime: str\n lineage: str\n message_index: int\n\n\n@dataclass\nclass ScanStats:\n files_read: int = 0\n bytes_read: int = 0\n records: int = 0\n messages: int = 0\n parse_errors: int = 0\n read_errors: int = 0\n changed_files: int = 0\n oversized_records: int = 0\n tool_calls: Counter[str] = field(default_factory=Counter)\n tool_results: int = 0\n tool_errors: int = 0\n\n\ndef flatten_text(content: object, limit: int = MAX_MESSAGE_CHARS) -> str:\n if isinstance(content, str):\n return content[:limit]\n if not isinstance(content, list):\n return \"\"\n parts: list[str] = []\n remaining = limit\n for item in content[:MAX_CONTENT_ITEMS]:\n value = \"\"\n if isinstance(item, str):\n value = item\n elif isinstance(item, dict) and item.get(\"type\") in {\n \"text\",\n \"input_text\",\n \"output_text\",\n }:\n candidate = item.get(\"text\")\n if isinstance(candidate, str):\n value = candidate\n if not value or remaining \u003c= 0:\n continue\n bounded = value[:remaining]\n parts.append(bounded)\n remaining -= len(bounded)\n if remaining \u003c= 0:\n break\n return \" \".join(parts)\n\n\ndef sanitize(text: str, limit: int) -> str:\n text = PRIVATE_KEY_RE.sub(\"\u003cprivate-key>\", text)\n text = SECRET_ASSIGNMENT_RE.sub(\n lambda match: f\"{match.group('name')}{match.group('separator')}\u003csecret>\",\n text,\n )\n text = SECRET_RE.sub(\"\u003csecret>\", text)\n text = EMAIL_RE.sub(\"\u003cemail>\", text)\n text = URL_RE.sub(\"\u003curl>\", text)\n text = ABS_PATH_RE.sub(\"\u003cpath>\", text)\n text = TILDE_PATH_RE.sub(\"\u003cpath>\", text)\n text = WINDOWS_ABS_PATH_RE.sub(\"\u003cpath>\", text)\n text = HASH_RE.sub(\"\u003chash>\", text)\n text = re.sub(r\"[\\r\\n\\t]+\", \" \", text)\n text = re.sub(r\"\\s{2,}\", \" \", text).strip()\n if len(text) > limit:\n return text[: limit - 1] + \"…\"\n return text\n\n\ndef message_from_record(record: dict[str, object], ordinal: int) -> Optional[Message]:\n if record.get(\"type\") == \"event_msg\":\n payload = record.get(\"payload\")\n if not isinstance(payload, dict):\n return None\n payload_type = payload.get(\"type\")\n if payload_type == \"turn_aborted\":\n reason = payload.get(\"reason\")\n detail = reason[:MAX_MESSAGE_CHARS] if isinstance(reason, str) else \"unknown\"\n return Message(\"platform\", f\"Codex turn_aborted: {detail}\", ordinal)\n if payload_type == \"error\":\n detail = flatten_text(payload.get(\"message\", \"\")) or \"structured error\"\n return Message(\"platform\", f\"Codex error: {detail}\", ordinal)\n\n if record.get(\"type\") == \"response_item\":\n payload = record.get(\"payload\")\n if not isinstance(payload, dict) or payload.get(\"type\") != \"message\":\n return None\n role = str(payload.get(\"role\") or \"\")\n if role not in {\"user\", \"assistant\", \"system\"}:\n return None\n text = flatten_text(payload.get(\"content\", \"\"))\n if not text.strip():\n return None\n if role == \"user\" and text.lstrip().startswith(INJECTED_PREFIXES):\n return None\n return Message(role=role, text=text, ordinal=ordinal)\n\n if record.get(\"isMeta\") or record.get(\"toolUseResult\") is not None:\n return None\n message = record.get(\"message\")\n message_dict = message if isinstance(message, dict) else {}\n role_value = message_dict.get(\"role\") or record.get(\"role\") or record.get(\"type\")\n role = str(role_value or \"\")\n if role not in {\"user\", \"assistant\", \"system\"}:\n return None\n content = message_dict.get(\"content\", record.get(\"content\", record.get(\"text\", \"\")))\n text = flatten_text(content)\n if not text.strip():\n return None\n if role == \"user\" and text.lstrip().startswith(INJECTED_PREFIXES):\n return None\n return Message(role=role, text=text, ordinal=ordinal)\n\n\ndef update_tool_receipts(record: dict[str, object], stats: ScanStats) -> None:\n if record.get(\"type\") == \"response_item\":\n payload = record.get(\"payload\")\n if isinstance(payload, dict):\n payload_type = payload.get(\"type\")\n if payload_type in {\"custom_tool_call\", \"function_call\", \"local_shell_call\"}:\n name = payload.get(\"name\") or payload_type\n stats.tool_calls[str(name)[:MAX_TOOL_NAME_CHARS]] += 1\n elif payload_type in {\n \"custom_tool_call_output\",\n \"function_call_output\",\n \"local_shell_call_output\",\n }:\n stats.tool_results += 1\n if (\n payload.get(\"status\") in {\"failed\", \"error\"}\n or payload.get(\"isError\") is True\n or payload.get(\"is_error\") is True\n ):\n stats.tool_errors += 1\n return\n\n message = record.get(\"message\")\n message_dict = message if isinstance(message, dict) else {}\n content = message_dict.get(\"content\", record.get(\"content\"))\n if isinstance(content, list):\n for item in content[:MAX_CONTENT_ITEMS]:\n if not isinstance(item, dict):\n continue\n if item.get(\"type\") == \"tool_use\":\n name = item.get(\"name\")\n stats.tool_calls[str(name or \"unknown\")[:MAX_TOOL_NAME_CHARS]] += 1\n elif item.get(\"type\") == \"tool_result\":\n stats.tool_results += 1\n if item.get(\"is_error\") is True:\n stats.tool_errors += 1\n if record.get(\"toolUseResult\") is not None:\n stats.tool_results += 1\n result = record.get(\"toolUseResult\")\n if isinstance(result, dict) and (\n result.get(\"isError\") is True or result.get(\"is_error\") is True\n ):\n stats.tool_errors += 1\n\n\ndef japanese_dominant(text: str) -> bool:\n kana = len(JAPANESE_RE.findall(text))\n cjk = len(CJK_RE.findall(text))\n return kana >= 4 and kana / max(cjk, 1) >= 0.25\n\n\ndef classify(message: Message, japanese_allowed: bool = False) -> Optional[str]:\n text = message.text.strip()\n if message.role == \"platform\":\n return \"PLATFORM INTERRUPTION\"\n if message.role == \"system\" and PLATFORM_INTERRUPTION_RE.search(text):\n return \"PLATFORM INTERRUPTION\"\n if CONTEXT_RE.search(text):\n return \"CONTEXT SIGNAL\"\n if (\n message.role == \"assistant\"\n and not japanese_allowed\n and japanese_dominant(text)\n ):\n return \"LANGUAGE SIGNAL assistant=ja\"\n if message.role != \"user\":\n return None\n if PERSISTENCE_RE.fullmatch(text):\n return \"PERSISTENCE SIGNAL\"\n if len(text) \u003c= 160 and DELIVERY_RE.search(text):\n return \"DELIVERY REMINDER\"\n if len(text) \u003c= 500 and CORRECTION_RE.search(text):\n return \"USER CORRECTION\"\n return None\n\n\ndef independent_signals(signals: list[Signal]) -> tuple[list[Signal], int]:\n \"\"\"Collapse shared-history clones while preserving repeated real turns.\"\"\"\n ordered = sorted(\n signals, key=lambda signal: (signal.mtime, signal.ordinal), reverse=True\n )\n accepted: list[Signal] = []\n seen: dict[tuple[str, str, str], set[tuple[str, str]]] = {}\n collapsed = 0\n for signal in ordered:\n normalized = re.sub(r\"\\s+\", \" \", signal.text).strip().casefold()\n key = (signal.label, normalized, signal.lineage)\n source = (signal.runtime, signal.file)\n is_clone = (\n signal.message_index >= MIN_CLONE_CONTEXT_MESSAGES\n and any(other_source != source for other_source in seen.get(key, set()))\n )\n if is_clone:\n collapsed += 1\n continue\n accepted.append(signal)\n seen.setdefault(key, set()).add(source)\n return accepted, collapsed\n\n\ndef scan_file(\n item: ConversationFile,\n stats: ScanStats,\n collect_messages: bool,\n) -> tuple[list[Signal], list[Message], bool, int]:\n signals: list[Signal] = []\n message_head: list[Message] = []\n message_tail: deque[Message] = deque(maxlen=EXTRACT_TAIL)\n message_count = 0\n stats.files_read += 1\n stats.bytes_read += item.size\n recent_platform_interruption = False\n japanese_allowed = False\n assistant_seen = False\n lineage = hashlib.sha256()\n descriptor = -1\n try:\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n descriptor = os.open(item.path, flags)\n before = os.fstat(descriptor)\n if (before.st_dev, before.st_ino) != (item.device, item.inode):\n os.close(descriptor)\n descriptor = -1\n stats.read_errors += 1\n return [], [], False, 0\n handle = os.fdopen(descriptor, encoding=\"utf-8\", errors=\"replace\")\n descriptor = -1\n with handle:\n ordinal = 0\n while True:\n line = handle.readline(MAX_RECORD_CHARS + 1)\n if not line:\n break\n ordinal += 1\n stats.records += 1\n if len(line) > MAX_RECORD_CHARS and not line.endswith(\"\\n\"):\n while line and not line.endswith(\"\\n\"):\n line = handle.readline(MAX_RECORD_CHARS + 1)\n stats.oversized_records += 1\n continue\n try:\n record = json.loads(line)\n except (json.JSONDecodeError, UnicodeError):\n stats.parse_errors += 1\n continue\n if not isinstance(record, dict):\n continue\n update_tool_receipts(record, stats)\n message = message_from_record(record, ordinal)\n if message is None:\n continue\n stats.messages += 1\n message_count += 1\n lineage.update(message.role.encode(\"utf-8\", errors=\"replace\"))\n lineage.update(b\"\\0\")\n lineage.update(message.text.encode(\"utf-8\", errors=\"replace\"))\n lineage.update(b\"\\0\")\n if collect_messages:\n if len(message_head) \u003c EXTRACT_HEAD:\n message_head.append(message)\n else:\n message_tail.append(message)\n label = classify(message, japanese_allowed)\n if label == \"USER CORRECTION\" and not assistant_seen:\n label = None\n if label == \"PLATFORM INTERRUPTION\":\n recent_platform_interruption = True\n elif label == \"PERSISTENCE SIGNAL\" and recent_platform_interruption:\n label = \"PLATFORM CONTINUATION\"\n recent_platform_interruption = False\n elif message.role == \"user\":\n recent_platform_interruption = False\n if message.role == \"user\":\n japanese_allowed = bool(JAPANESE_REQUEST_RE.search(message.text))\n elif message.role == \"assistant\" and label != \"PLATFORM INTERRUPTION\":\n assistant_seen = True\n if label:\n signals.append(\n Signal(\n label,\n message.text,\n sanitize(item.path.name, 240),\n item.mtime,\n ordinal,\n item.runtime,\n lineage.hexdigest(),\n message_count,\n )\n )\n except OSError:\n stats.read_errors += 1\n finally:\n if descriptor >= 0:\n os.close(descriptor)\n try:\n final_stat = item.path.stat(follow_symlinks=False)\n if (\n (final_stat.st_dev, final_stat.st_ino) != (item.device, item.inode)\n or final_stat.st_size != item.size\n or final_stat.st_mtime_ns != item.mtime_ns\n ):\n stats.changed_files += 1\n except OSError:\n stats.read_errors += 1\n messages = message_head + list(message_tail)\n return signals, messages, message_count > len(messages), message_count\n\n\ndef codex_project_matches(path: Path, project_root: Path) -> bool:\n try:\n if path.is_symlink():\n return False\n flags = os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0)\n with os.fdopen(\n os.open(path, flags), encoding=\"utf-8\", errors=\"replace\"\n ) as handle:\n for _index in range(40):\n line = handle.readline(MAX_RECORD_CHARS + 1)\n if not line:\n break\n if len(line) > MAX_RECORD_CHARS and not line.endswith(\"\\n\"):\n while line and not line.endswith(\"\\n\"):\n line = handle.readline(MAX_RECORD_CHARS + 1)\n continue\n try:\n record = json.loads(line)\n except (json.JSONDecodeError, UnicodeError):\n continue\n if not isinstance(record, dict) or record.get(\"type\") != \"session_meta\":\n continue\n payload = record.get(\"payload\")\n if not isinstance(payload, dict):\n return False\n cwd = payload.get(\"cwd\")\n if not isinstance(cwd, str) or not cwd:\n return False\n try:\n candidate = Path(cwd).expanduser().resolve()\n root = project_root.expanduser().resolve()\n candidate.relative_to(root)\n return True\n except (OSError, ValueError):\n return False\n except OSError:\n return False\n return False\n\n\ndef newest_candidates(\n directory: Path,\n recursive: bool,\n candidate_limit: Optional[int],\n) -> tuple[list[Path], bool]:\n if not recursive:\n return [path for path in directory.glob(\"*.jsonl\") if not path.is_symlink()], False\n if candidate_limit is None:\n return [path for path in directory.rglob(\"*.jsonl\") if not path.is_symlink()], False\n\n candidates: list[Path] = []\n stack = [directory]\n truncated = False\n while stack and len(candidates) \u003c= candidate_limit:\n current = stack.pop()\n try:\n entries = list(current.iterdir())\n except OSError:\n continue\n files = sorted(\n (\n entry\n for entry in entries\n if not entry.is_symlink()\n and entry.is_file()\n and entry.suffix == \".jsonl\"\n ),\n key=lambda entry: entry.name,\n reverse=True,\n )\n remaining = candidate_limit + 1 - len(candidates)\n candidates.extend(files[:remaining])\n truncated = truncated or len(files) > remaining\n directories = sorted(\n (entry for entry in entries if not entry.is_symlink() and entry.is_dir()),\n key=lambda entry: entry.name,\n )\n stack.extend(directories)\n return (\n candidates[:candidate_limit],\n truncated or len(candidates) > candidate_limit or bool(stack),\n )\n\n\ndef discover(\n directory: Path,\n runtime: str = \"claude_project_logs\",\n recursive: bool = False,\n project_root: Optional[Path] = None,\n candidate_limit: Optional[int] = None,\n) -> tuple[list[ConversationFile], int, bool]:\n files: list[ConversationFile] = []\n if directory.is_symlink() or not directory.is_dir():\n return files, 0, False\n try:\n scan_root = directory.resolve(strict=True)\n except OSError:\n return files, 0, False\n candidates, truncated = newest_candidates(scan_root, recursive, candidate_limit)\n for path in candidates:\n if path.is_symlink():\n continue\n try:\n path.relative_to(scan_root)\n except ValueError:\n continue\n if project_root is not None and not codex_project_matches(path, project_root):\n continue\n try:\n stat = path.stat(follow_symlinks=False)\n except OSError:\n continue\n files.append(\n ConversationFile(\n path=path,\n mtime=stat.st_mtime,\n mtime_ns=stat.st_mtime_ns,\n size=stat.st_size,\n device=stat.st_dev,\n inode=stat.st_ino,\n runtime=runtime,\n )\n )\n return (\n sorted(files, key=lambda item: (item.mtime, item.path.name), reverse=True),\n len(candidates),\n truncated,\n )\n\n\ndef percentage(numerator: int, denominator: int) -> str:\n if denominator \u003c= 0:\n return \"0.0\"\n return f\"{100.0 * numerator / denominator:.1f}\"\n\n\ndef print_file_manifest(\n files: list[ConversationFile],\n live_files: set[Path],\n signal_files: set[Path],\n extract_files: set[Path],\n) -> None:\n print(\"=== CONVERSATION FILES ===\")\n if not files:\n print(\"(no conversation files)\")\n return\n for item in files[:MAX_FILE_LIST]:\n live = \"yes\" if item.path in live_files else \"no\"\n print(\n f\"runtime={item.runtime} file={sanitize(item.path.name, 240)} \"\n f\"bytes={item.size} \"\n f\"live_by_recent_mtime={live} \"\n f\"signal_scan={'yes' if item.path in signal_files else 'no'} \"\n f\"extract={'yes' if item.path in extract_files else 'no'}\"\n )\n if len(files) > MAX_FILE_LIST:\n print(f\"conversation_file_listing_truncated: {len(files) - MAX_FILE_LIST}\")\n\n\ndef print_receipts(stats: ScanStats) -> None:\n print(\"=== VERIFICATION RECEIPTS ===\")\n print(f\"tool_calls_seen: {sum(stats.tool_calls.values())}\")\n print(f\"tool_results_seen: {stats.tool_results}\")\n print(f\"tool_errors_seen: {stats.tool_errors}\")\n if stats.tool_calls:\n rendered = \", \".join(\n f\"{name}={count}\" for name, count in stats.tool_calls.most_common(20)\n )\n print(f\"tool_call_names: {rendered}\")\n else:\n print(\"tool_call_names: (none)\")\n\n\ndef signal_theme_counts(signals: list[Signal]) -> Counter[str]:\n counts: Counter[str] = Counter()\n for signal in signals:\n if signal.label == \"PLATFORM INTERRUPTION\":\n counts[\"platform_interruption\"] += 1\n continue\n if signal.label == \"PLATFORM CONTINUATION\":\n counts[\"platform_continuation\"] += 1\n continue\n if signal.label == \"CONTEXT SIGNAL\":\n counts[\"context_pressure\"] += 1\n continue\n if signal.label.startswith(\"LANGUAGE SIGNAL\"):\n counts[\"language_drift\"] += 1\n continue\n if signal.label == \"PERSISTENCE SIGNAL\":\n counts[\"unfinished_persistence\"] += 1\n continue\n matched = False\n for theme, pattern in THEME_PATTERNS.items():\n if pattern.search(signal.text):\n counts[theme] += 1\n matched = True\n if not matched:\n counts[\"other_user_correction\"] += 1\n return counts\n\n\ndef audit(\n directory: Path,\n mode: str,\n codex_root: Optional[Path] = None,\n project_root: Optional[Path] = None,\n all_projects: bool = False,\n) -> int:\n files, discovery_candidates, discovery_limited = discover(\n directory,\n recursive=all_projects,\n )\n requested_runtimes = [\"claude_project_logs\"]\n runtime_roots_available = {\"claude_project_logs\": directory.is_dir()}\n if all_projects:\n requested_runtimes.append(\"codex_project_logs\")\n runtime_roots_available[\"codex_project_logs\"] = bool(\n codex_root is not None and codex_root.is_dir()\n )\n if (\n codex_root is not None\n and (project_root is not None or all_projects)\n ):\n if \"codex_project_logs\" not in requested_runtimes:\n requested_runtimes.append(\"codex_project_logs\")\n runtime_roots_available[\"codex_project_logs\"] = codex_root.is_dir()\n if codex_root.is_dir():\n codex_files, codex_candidates, codex_limited = discover(\n codex_root,\n runtime=\"codex_project_logs\",\n recursive=True,\n project_root=None if all_projects else project_root,\n candidate_limit=(\n SUMMARY_CANDIDATE_LIMIT\n if mode == \"summary\" and not all_projects\n else None\n ),\n )\n files.extend(codex_files)\n discovery_candidates += codex_candidates\n discovery_limited = discovery_limited or codex_limited\n files.sort(key=lambda item: (item.mtime, item.path.name), reverse=True)\n runtime_groups: dict[str, list[ConversationFile]] = {}\n for item in files:\n runtime_groups.setdefault(item.runtime, []).append(item)\n live_paths: set[Path] = set()\n now = time.time()\n for items in runtime_groups.values():\n if not items:\n continue\n recent = {\n item.path\n for item in items\n if 0 \u003c= now - item.mtime \u003c= LIVE_WINDOW_SECONDS\n }\n live_paths.update(recent)\n previous = [item for item in files if item.path not in live_paths]\n signal_selection = previous if mode == \"deep\" else previous[:3]\n extract_selection = previous[:3] if mode == \"deep\" else []\n signal_paths = {item.path for item in signal_selection}\n extract_paths = {item.path for item in extract_selection}\n total_previous_bytes = sum(item.size for item in previous)\n selected_signal_bytes = sum(item.size for item in signal_selection)\n\n stats = ScanStats()\n all_signals: list[Signal] = []\n extracts: dict[Path, tuple[list[Message], bool, int]] = {}\n for item in signal_selection:\n signals, messages, truncated, message_count = scan_file(\n item, stats, item.path in extract_paths\n )\n all_signals.extend(signals)\n if item.path in extract_paths:\n extracts[item.path] = (messages, truncated, message_count)\n\n print(\"=== CONVERSATION COVERAGE ===\")\n print(f\"conversation_runtime: {','.join(requested_runtimes)}\")\n print(f\"conversation_scope: {'all_projects' if all_projects else 'current_project'}\")\n print(f\"coverage_mode: {mode}\")\n print(f\"files_discovered: {len(files)}\")\n print(f\"discovery_candidates_examined: {discovery_candidates}\")\n print(f\"discovery_limited: {'yes' if discovery_limited else 'no'}\")\n if discovery_limited:\n print(f\"discovery_candidate_limit: {SUMMARY_CANDIDATE_LIMIT}\")\n print(f\"previous_files_available: {len(previous)}\")\n print(f\"live_files_skipped: {len(live_paths)}\")\n print(\n f\"live_skip_basis: mtime_within_{LIVE_WINDOW_SECONDS}s_per_runtime\"\n )\n print(f\"signal_scope: {'all_previous' if mode == 'deep' else 'recent_previous'}\")\n print(f\"signal_files_scanned: {stats.files_read}\")\n print(f\"extract_files_selected: {len(extract_selection)}\")\n print(f\"records_scanned: {stats.records}\")\n print(f\"messages_scanned: {stats.messages}\")\n print(f\"bytes_scanned: {stats.bytes_read}\")\n print(f\"previous_bytes_available: {total_previous_bytes}\")\n print(\n f\"previous_bytes_scanned_percent: \"\n f\"{percentage(selected_signal_bytes, total_previous_bytes)}\"\n )\n print(f\"parse_errors: {stats.parse_errors}\")\n print(f\"oversized_records: {stats.oversized_records}\")\n print(f\"read_errors: {stats.read_errors}\")\n print(f\"files_changed_during_scan: {stats.changed_files}\")\n scan_complete = (\n mode == \"deep\"\n and bool(previous)\n and len(signal_selection) == len(previous)\n and stats.files_read == len(signal_selection)\n and stats.parse_errors == 0\n and stats.oversized_records == 0\n and stats.read_errors == 0\n and stats.changed_files == 0\n )\n roots_available = all(runtime_roots_available.values())\n if not roots_available:\n coverage_status = \"unavailable\"\n elif not previous:\n coverage_status = \"no_data\"\n elif mode != \"deep\" or len(signal_selection) != len(previous):\n coverage_status = \"partial\"\n elif not scan_complete:\n coverage_status = \"incomplete\"\n elif live_paths:\n coverage_status = \"live_sessions_excluded\"\n else:\n coverage_status = \"complete\"\n print(f\"coverage_status: {coverage_status}\")\n print(f\"all_previous_files_scanned: {'yes' if scan_complete else 'no'}\")\n cross_runtime_complete = (\n coverage_status == \"complete\"\n and len(requested_runtimes) > 1\n and all(runtime in runtime_groups for runtime in requested_runtimes)\n )\n print(\n f\"cross_runtime_full_history: \"\n f\"{'yes' if cross_runtime_complete else 'no'}\"\n )\n print(\n f\"cross_project_full_history: \"\n f\"{'yes' if all_projects and cross_runtime_complete else 'no'}\"\n )\n for runtime in requested_runtimes:\n runtime_files = runtime_groups.get(runtime, [])\n runtime_previous = [item for item in runtime_files if item.path not in live_paths]\n print(\n f\"runtime_coverage: runtime={runtime} files={len(runtime_files)} \"\n f\"previous={len(runtime_previous)} bytes={sum(item.size for item in runtime_files)} \"\n f\"root_available={'yes' if runtime_roots_available[runtime] else 'no'}\"\n )\n\n print_file_manifest(files, live_paths, signal_paths, extract_paths)\n\n ordered_signals, duplicate_signals_collapsed = independent_signals(all_signals)\n emitted = ordered_signals[:MAX_SIGNALS]\n print(\"=== CONVERSATION SIGNALS ===\")\n print(f\"raw_signals_found: {len(all_signals)}\")\n print(f\"independent_signals: {len(ordered_signals)}\")\n print(f\"duplicate_signals_collapsed: {duplicate_signals_collapsed}\")\n print(f\"signals_found: {len(ordered_signals)}\")\n print(f\"signals_emitted: {len(emitted)}\")\n print(\n f\"signal_output_truncated: {'yes' if len(ordered_signals) > len(emitted) else 'no'}\"\n )\n if not emitted:\n print(\"(no conversation signals detected in declared scan scope)\")\n for signal in emitted:\n snippet = sanitize(signal.text, MAX_SIGNAL_CHARS)\n print(\n f\"{signal.label}: runtime={signal.runtime} file={signal.file} \"\n f\"record={signal.ordinal} text={snippet}\"\n )\n\n print(\"=== SIGNAL THEME SUMMARY ===\")\n theme_counts = signal_theme_counts(ordered_signals)\n print(f\"signals_classified: {len(ordered_signals)}\")\n print(\"theme_counts:\")\n if theme_counts:\n for theme, count in theme_counts.most_common():\n print(f\" {theme}: {count}\")\n else:\n print(\" (none)\")\n\n print(\"=== CONVERSATION EXTRACT ===\")\n if mode != \"deep\":\n print(\"(skipped: summary mode; deep mode samples the first 30 and last 120 messages from three previous sessions)\")\n elif not extract_selection:\n print(\"(no previous conversation files)\")\n else:\n for item in extract_selection:\n messages, truncated, total = extracts.get(item.path, ([], False, 0))\n print(\n f\"--- runtime={item.runtime} \"\n f\"file={sanitize(item.path.name, 240)} messages={total} \"\n f\"extract_truncated={'yes' if truncated else 'no'} ---\"\n )\n for message in messages:\n print(f\"{message.role.upper()}: {sanitize(message.text, MAX_EXTRACT_CHARS)}\")\n\n print_receipts(stats)\n return 0\n\n\ndef main(argv: Optional[Iterable[str]] = None) -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"directory\", type=Path)\n parser.add_argument(\"mode\", choices=(\"summary\", \"deep\"))\n parser.add_argument(\"--codex-root\", type=Path)\n parser.add_argument(\"--project-root\", type=Path)\n parser.add_argument(\n \"--all-projects\",\n action=\"store_true\",\n help=\"Explicit deep-audit mode: scan every project log under both roots\",\n )\n args = parser.parse_args(list(argv) if argv is not None else None)\n if args.all_projects and args.mode != \"deep\":\n parser.error(\"--all-projects requires deep mode\")\n if args.all_projects and args.project_root is not None:\n parser.error(\"--all-projects cannot be combined with --project-root\")\n if args.all_projects and args.codex_root is None:\n parser.error(\"--all-projects requires --codex-root\")\n if not args.all_projects and (args.codex_root is None) != (args.project_root is None):\n parser.error(\"--codex-root and --project-root must be provided together\")\n return audit(\n args.directory,\n args.mode,\n args.codex_root,\n args.project_root,\n args.all_projects,\n )\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":35269,"content_sha256":"afb2ffc43a6a0dc2ac86f11f1800fb858c9f3d22235fe48e9c3285e6da44aeea"},{"filename":"scripts/read_skill_description.py","content":"#!/usr/bin/env python3\n\"\"\"Print one bounded SKILL.md description, including YAML block scalars.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nfrom pathlib import Path\n\n\nMAX_BYTES = 1_048_576\nMAX_DESCRIPTION_CHARS = 4_000\n\n\ndef parse_description(text: str) -> str:\n lines = text.splitlines()\n if not lines or lines[0].strip() != \"---\":\n return \"\"\n index = 1\n while index \u003c len(lines):\n line = lines[index]\n if line.strip() == \"---\":\n return \"\"\n if not line.startswith(\"description:\"):\n index += 1\n continue\n raw = line.split(\":\", 1)[1].strip()\n if raw not in {\">\", \">-\", \">+\", \"|\", \"|-\", \"|+\"}:\n return raw.strip(\"\\\"'\")[:MAX_DESCRIPTION_CHARS]\n index += 1\n chunks: list[str] = []\n while index \u003c len(lines):\n continuation = lines[index]\n if continuation.strip() == \"---\" or (\n continuation and not continuation[0].isspace()\n ):\n break\n chunks.append(continuation.strip())\n index += 1\n return \" \".join(chunk for chunk in chunks if chunk)[:MAX_DESCRIPTION_CHARS]\n return \"\"\n\n\ndef main() -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"path\", type=Path)\n args = parser.parse_args()\n try:\n if args.path.stat().st_size > MAX_BYTES:\n return 2\n text = args.path.read_text(encoding=\"utf-8\", errors=\"replace\")\n except OSError:\n return 2\n description = parse_description(text)\n if description:\n print(description)\n return 0\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":1694,"content_sha256":"f60fa80d48306aea81b0e9ba269ef713565ce827592b78d0b932231893143107"},{"filename":"scripts/scan_skill_security.py","content":"#!/usr/bin/env python3\n\"\"\"Scan skill instruction surfaces and emit bounded, non-authoritative receipts.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport bisect\nimport hashlib\nimport os\nimport re\nimport subprocess\nfrom collections import Counter\nfrom dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import Iterable, Optional\n\n\nMAX_FILE_BYTES = 1_048_576\nMAX_SURFACE_FILES = 512\nMAX_ISSUES = 8\nMAX_MATCHES = 8\nMAX_SKILL_RECEIPTS = 200\nSURFACE_DIRS = (\"references\", \"agents\", \"scripts\")\n\nPATTERNS = {\n \"prompt_override\": re.compile(\n r\"ignore\\s+(?:all\\s+|any\\s+)?(?:previous|prior)\\s+instructions|\"\n r\"disregard\\s+(?:the\\s+)?(?:system|developer)\\s+prompt|jailbreak\",\n re.IGNORECASE | re.DOTALL,\n ),\n \"destructive_command\": re.compile(\n r\"rm\\s+-[A-Za-z]*r[A-Za-z]*f\\s+(?:/|~|\\$HOME)(?:\\s|$)|\"\n r\"git\\s+push\\s+[^\\n]*--force(?:-with-lease)?\",\n re.IGNORECASE,\n ),\n \"safety_bypass\": re.compile(\n r\"dangerously-skip-permissions|disable\\s+(?:all\\s+)?(?:safety|security)\\s+checks|\"\n r\"bypass\\s+(?:all\\s+)?(?:safety|security)\\s+checks\",\n re.IGNORECASE | re.DOTALL,\n ),\n}\n\nSHELL_NETWORK_COMMAND_RE = re.compile(\n r\"\\b(?:curl|wget)\\b(?:\\\\\\r?\\n|[^\\r\\n;&|]){0,960}\",\n re.IGNORECASE | re.DOTALL,\n)\nCODE_NETWORK_CALL_RE = re.compile(\n r\"\\brequests\\.(?:get|post|put|patch|delete|request)\\s*\\([^)]{0,960}\\)|\"\n r\"\\bfetch\\s*\\([^)]{0,960}\\)\",\n re.IGNORECASE | re.DOTALL,\n)\nSENSITIVE_ENV_NAME = (\n r\"[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|PASSWD|API_KEY|PRIVATE_KEY|\"\n r\"CREDENTIAL|AUTHORIZATION|AUTH_TOKEN|COOKIE|SESSION_KEY)[A-Z0-9_]*\"\n)\nSECRET_SOURCE_RE = re.compile(\n rf\"os\\.environ\\b|process\\.env\\b|\\$\\{{?{SENSITIVE_ENV_NAME}\\}}?\",\n re.IGNORECASE,\n)\n\nPEM_RE = re.compile(\n r\"-----BEGIN [^-\\r\\n]+-----.*?(?:-----END [^-\\r\\n]+-----|\\Z)\",\n re.IGNORECASE | re.DOTALL,\n)\nSECRET_RE = re.compile(\n r\"\\b(?:sk-[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9]{12,}|\"\n r\"github_pat_[A-Za-z0-9_]{12,}|xox[baprs]-[A-Za-z0-9-]{10,}|\"\n r\"AKIA[A-Z0-9]{16}|\"\n r\"eyJ[A-Za-z0-9_-]{20,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,})\\b\"\n)\nSECRET_ASSIGNMENT_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_-])\"\n r\"(?P\u003cname>-{0,2}(?P\u003cquote>[\\x22\\x27]?)(?:[A-Za-z0-9]+[_-])*\"\n r\"(?:secret[_-]access[_-]key|private[_-]?key|api[_-]?key|\"\n r\"authorization|password|passwd|pwd|token|secret)(?P=quote))\"\n r\"(?![A-Za-z0-9_-])\"\n r\"(?P\u003cseparator>\\s*[:=]\\s*)\"\n r\"(?:Bearer\\s+|Basic\\s+)?(?:\\\"(?:\\\\[^\\r\\n]|[^\\\"\\\\\\r\\n])*(?:\\\"|\\\\?(?=\\r?\\n|\\Z))|\"\n r\"\\x27(?:\\\\[^\\r\\n]|[^\\x27\\\\\\r\\n])*(?:\\x27|\\\\?(?=\\r?\\n|\\Z))|[^\\s,;]+)\",\n re.IGNORECASE,\n)\nABS_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])/(?:Users|home|private|tmp|var|etc|opt|Volumes)/[^\\s`\\\"'\u003c>]+\"\n)\nTILDE_PATH_RE = re.compile(r\"(?\u003c![A-Za-z0-9_])~/(?:[^\\s`\\\"'\u003c>]+)\")\nWINDOWS_ABS_PATH_RE = re.compile(\n r\"(?\u003c![A-Za-z0-9_])(?:[A-Za-z]:\\\\|\\\\\\\\)[^\\s`\\\"'\u003c>]+\"\n)\nCONTROL_RE = re.compile(r\"[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\x9f]\")\n\n\n@dataclass(frozen=True)\nclass SurfaceFile:\n path: Path\n relative: str\n surface: str\n identity: tuple[int, int]\n\n\n@dataclass(frozen=True)\nclass ReadResult:\n raw: Optional[bytes]\n issue: Optional[str]\n\n\ndef safe_label(value: str, limit: int = 240) -> str:\n return re.sub(r\"[^A-Za-z0-9._:/~+-]+\", \"_\", value)[:limit]\n\n\ndef contained(path: Path, root: Path) -> bool:\n try:\n path.relative_to(root)\n return True\n except ValueError:\n return False\n\n\ndef display_path(path: Path, project_root: Optional[Path], home: Path) -> str:\n absolute = path if path.is_absolute() else Path.cwd() / path\n try:\n absolute = absolute.parent.resolve(strict=True) / absolute.name\n except OSError:\n pass\n for root, prefix in ((project_root, \"project:/\"), (home, \"~/\")):\n if root is None:\n continue\n try:\n return prefix + absolute.relative_to(root).as_posix()\n except ValueError:\n continue\n return \"external:/\" + safe_label(path.name or \"unknown\")\n\n\ndef sensitive_reason(path: Path, home: Path) -> Optional[str]:\n protected = {\n \"ssh\": home / \".ssh\",\n \"aws\": home / \".aws\",\n \"gnupg\": home / \".gnupg\",\n \"gh\": home / \".config\" / \"gh\",\n }\n for name, root in protected.items():\n if path == root or contained(path, root):\n return f\"protected_{name}_path\"\n for part in path.parts:\n lowered = part.lower()\n if lowered == \"secrets\":\n return \"secrets_path\"\n if \"credential\" in lowered:\n return \"credentials_path\"\n if lowered == \".env\" or lowered.startswith(\".env.\"):\n return \"env_path\"\n return None\n\n\ndef git_revision(root: Path) -> str:\n try:\n result = subprocess.run(\n [\n \"git\",\n \"-c\",\n \"core.fsmonitor=false\",\n \"-C\",\n str(root),\n \"rev-parse\",\n \"--short\",\n \"HEAD\",\n ],\n text=True,\n stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL,\n check=False,\n timeout=3,\n )\n except (OSError, subprocess.TimeoutExpired):\n return \"unavailable\"\n return result.stdout.strip()[:40] if result.returncode == 0 else \"unversioned\"\n\n\ndef safe_excerpt(text: str) -> str:\n text = PEM_RE.sub(\"[REDACTED PRIVATE KEY]\", text)\n text = SECRET_ASSIGNMENT_RE.sub(\n lambda match: f\"{match.group('name')}{match.group('separator')}[REDACTED]\",\n text,\n )\n text = SECRET_RE.sub(\"[REDACTED]\", text)\n text = ABS_PATH_RE.sub(\"[PATH]\", text)\n text = TILDE_PATH_RE.sub(\"[PATH]\", text)\n text = WINDOWS_ABS_PATH_RE.sub(\"[PATH]\", text)\n text = CONTROL_RE.sub(\"\", text)\n text = re.sub(r\"\\s+\", \" \", text).strip()\n return text[:180]\n\n\ndef stable_read(path: Path, identity: tuple[int, int]) -> ReadResult:\n flags = os.O_RDONLY\n if hasattr(os, \"O_NOFOLLOW\"):\n flags |= os.O_NOFOLLOW\n try:\n descriptor = os.open(path, flags)\n except OSError as error:\n return ReadResult(None, f\"read_unavailable:{error.__class__.__name__}\")\n try:\n before = os.fstat(descriptor)\n if (before.st_dev, before.st_ino) != identity:\n return ReadResult(None, \"identity_changed_before_read\")\n chunks: list[bytes] = []\n remaining = MAX_FILE_BYTES + 1\n while remaining > 0:\n chunk = os.read(descriptor, min(65_536, remaining))\n if not chunk:\n break\n chunks.append(chunk)\n remaining -= len(chunk)\n after = os.fstat(descriptor)\n if (\n before.st_size != after.st_size\n or before.st_mtime_ns != after.st_mtime_ns\n ):\n return ReadResult(None, \"changed_during_read\")\n raw = b\"\".join(chunks)\n if len(raw) > MAX_FILE_BYTES:\n return ReadResult(raw[:MAX_FILE_BYTES], \"content_truncated\")\n return ReadResult(raw, None)\n except OSError as error:\n return ReadResult(None, f\"read_unavailable:{error.__class__.__name__}\")\n finally:\n os.close(descriptor)\n\n\ndef discover_surfaces(\n entrypoint: Path,\n entry_identity: tuple[int, int],\n home: Path,\n) -> tuple[list[SurfaceFile], list[str], dict[str, int]]:\n root = entrypoint.parent\n files = [SurfaceFile(entrypoint, \"SKILL.md\", \"entry\", entry_identity)]\n issues: list[str] = []\n counts = {\"entry\": 1, \"references\": 0, \"agents\": 0, \"scripts\": 0}\n seen = {entry_identity}\n entries_seen = 1\n traversal_limited = False\n\n def record_issue(issue: str) -> None:\n if len(issues) \u003c MAX_ISSUES + 1:\n issues.append(issue)\n\n for surface in SURFACE_DIRS:\n directory = root / surface\n if not directory.exists() and not directory.is_symlink():\n continue\n try:\n resolved_directory = directory.resolve(strict=True)\n except OSError as error:\n record_issue(f\"{surface}_unreadable:{error.__class__.__name__}\")\n continue\n reason = sensitive_reason(resolved_directory, home)\n if reason:\n record_issue(f\"{surface}_rejected:{reason}\")\n continue\n if not contained(resolved_directory, root) or not resolved_directory.is_dir():\n record_issue(f\"{surface}_outside_skill_root\")\n continue\n\n def walk_error(error: OSError) -> None:\n record_issue(f\"{surface}_walk_unavailable:{error.__class__.__name__}\")\n\n for current, directories, names in os.walk(\n directory,\n topdown=True,\n followlinks=False,\n onerror=walk_error,\n ):\n current_path = Path(current)\n kept_directories: list[str] = []\n for name in sorted(directories):\n entries_seen += 1\n if entries_seen > MAX_SURFACE_FILES:\n traversal_limited = True\n break\n candidate_directory = current_path / name\n if candidate_directory.is_symlink():\n record_issue(\n f\"directory_symlink_rejected:{safe_label(candidate_directory.relative_to(root).as_posix())}\"\n )\n continue\n if sensitive_reason(candidate_directory, home):\n record_issue(\n f\"sensitive_directory_rejected:{safe_label(candidate_directory.relative_to(root).as_posix())}\"\n )\n continue\n kept_directories.append(name)\n if traversal_limited:\n directories[:] = []\n record_issue(\"surface_entry_limit_reached\")\n break\n directories[:] = kept_directories\n for name in sorted(names):\n entries_seen += 1\n if entries_seen > MAX_SURFACE_FILES:\n traversal_limited = True\n record_issue(\"surface_entry_limit_reached\")\n directories[:] = []\n break\n candidate = current_path / name\n relative = candidate.relative_to(root).as_posix()\n if candidate.is_symlink():\n record_issue(f\"leaf_symlink_rejected:{safe_label(relative)}\")\n continue\n try:\n resolved = candidate.resolve(strict=True)\n stat = candidate.stat()\n except OSError as error:\n record_issue(\n f\"unreadable:{safe_label(relative)}:{error.__class__.__name__}\"\n )\n continue\n reason = sensitive_reason(resolved, home)\n if reason:\n record_issue(f\"sensitive_file_rejected:{safe_label(relative)}:{reason}\")\n continue\n if not contained(resolved, root):\n record_issue(f\"outside_skill_root:{safe_label(relative)}\")\n continue\n if not resolved.is_file():\n continue\n identity = (stat.st_dev, stat.st_ino)\n if identity in seen:\n continue\n seen.add(identity)\n files.append(SurfaceFile(resolved, relative, surface, identity))\n counts[surface] += 1\n if traversal_limited:\n break\n return files, issues, counts\n\n\ndef scan_text(text: str) -> list[tuple[str, int, str]]:\n matches: list[tuple[str, int, str]] = []\n line_starts = [0]\n line_starts.extend(match.end() for match in re.finditer(\"\\n\", text))\n for name, pattern in PATTERNS.items():\n for match in pattern.finditer(text):\n line_number = bisect.bisect_right(line_starts, match.start())\n excerpt_start = text.rfind(\"\\n\", 0, match.start()) + 1\n excerpt_end = text.find(\"\\n\", match.end())\n if excerpt_end \u003c 0:\n excerpt_end = len(text)\n matches.append(\n (name, line_number, safe_excerpt(text[excerpt_start:excerpt_end]))\n )\n if len(matches) >= MAX_MATCHES + 1:\n return matches\n network_calls = list(SHELL_NETWORK_COMMAND_RE.finditer(text))\n network_calls.extend(CODE_NETWORK_CALL_RE.finditer(text))\n network_calls.sort(key=lambda match: match.start())\n for command_match in network_calls:\n command_text = command_match.group(0)\n secret_match = SECRET_SOURCE_RE.search(command_text)\n if secret_match is None:\n continue\n line_number = bisect.bisect_right(line_starts, command_match.start())\n excerpt_start = text.rfind(\"\\n\", 0, command_match.start()) + 1\n absolute_secret_end = command_match.start() + secret_match.end()\n excerpt_end = text.find(\"\\n\", absolute_secret_end)\n if excerpt_end \u003c 0:\n excerpt_end = len(text)\n matches.append(\n (\n \"secret_exfiltration\",\n line_number,\n safe_excerpt(text[excerpt_start:excerpt_end]),\n )\n )\n if len(matches) >= MAX_MATCHES + 1:\n return matches\n return matches\n\n\ndef print_unreadable(path_label: str, issue: str) -> None:\n print(\n f\"path={path_label} scan_status=unreadable files_scanned=0 \"\n f\"bytes_scanned=0 coverage_issues=1\"\n )\n print(f\" coverage_issue={safe_label(issue)}\")\n\n\ndef scan_skill(\n path_label: str,\n entrypoint: Path,\n entry_identity: tuple[int, int],\n home: Path,\n emit: bool = True,\n) -> str:\n surfaces, issues, counts = discover_surfaces(entrypoint, entry_identity, home)\n matches: list[tuple[str, str, int, str]] = []\n bytes_scanned = 0\n entry_digest = \"unavailable\"\n read_files = 0\n for surface_file in surfaces:\n result = stable_read(surface_file.path, surface_file.identity)\n if result.issue:\n issues.append(\n f\"{safe_label(surface_file.relative)}:{safe_label(result.issue)}\"\n )\n if result.raw is None:\n continue\n raw = result.raw\n if surface_file.relative == \"SKILL.md\":\n entry_digest = hashlib.sha256(raw).hexdigest()\n bytes_scanned += len(raw)\n read_files += 1\n text = raw.decode(\"utf-8\", errors=\"replace\")\n for name, line_number, excerpt in scan_text(text):\n matches.append((surface_file.relative, name, line_number, excerpt))\n\n if matches and issues:\n status = \"review_matches_and_gaps\"\n elif matches:\n status = \"review_matches\"\n elif issues:\n status = \"coverage_gap\"\n else:\n status = \"no_pattern_match\"\n counts_text = \",\".join(f\"{name}:{count}\" for name, count in counts.items())\n if emit:\n print(\n f\"path={path_label} sha256={entry_digest} \"\n f\"source_revision={git_revision(entrypoint.parent)} scan_status={status} \"\n f\"files_scanned={read_files} bytes_scanned={bytes_scanned} \"\n f\"surfaces={counts_text} coverage_issues={len(issues)}\"\n )\n for issue in issues[:MAX_ISSUES]:\n print(f\" coverage_issue={safe_label(issue)}\")\n if len(issues) > MAX_ISSUES:\n print(f\" additional_coverage_issues={len(issues) - MAX_ISSUES}\")\n for relative, name, line_number, excerpt in matches[:MAX_MATCHES]:\n print(\n f\" file={safe_label(relative)} match={name} \"\n f\"line={line_number} excerpt={excerpt}\"\n )\n if len(matches) > MAX_MATCHES:\n print(f\" additional_matches={len(matches) - MAX_MATCHES}\")\n return status\n\n\ndef main(argv: Optional[Iterable[str]] = None) -> int:\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument(\"--project-root\", type=Path)\n parser.add_argument(\"--health-entrypoint\", type=Path)\n parser.add_argument(\"paths\", nargs=\"*\")\n args = parser.parse_args(list(argv) if argv is not None else None)\n\n home = Path.home().resolve()\n project_root = args.project_root.resolve() if args.project_root else None\n health_identity: Optional[tuple[int, int]] = None\n if args.health_entrypoint:\n try:\n health_stat = args.health_entrypoint.stat()\n health_identity = (health_stat.st_dev, health_stat.st_ino)\n except OSError:\n health_identity = None\n\n seen_roots: set[tuple[int, int]] = set()\n receipts = 0\n suppressed = 0\n statuses: Counter[str] = Counter()\n for raw_path in args.paths:\n candidate = Path(raw_path)\n label = display_path(candidate, project_root, home)\n if candidate.is_symlink():\n if receipts \u003c MAX_SKILL_RECEIPTS:\n print_unreadable(label, \"leaf_symlink_rejected\")\n else:\n suppressed += 1\n statuses[\"unreadable\"] += 1\n receipts += 1\n continue\n try:\n entrypoint = candidate.resolve(strict=True)\n entry_stat = candidate.stat()\n root_stat = entrypoint.parent.stat()\n except OSError as error:\n if receipts \u003c MAX_SKILL_RECEIPTS:\n print_unreadable(label, f\"entrypoint_unreadable:{error.__class__.__name__}\")\n else:\n suppressed += 1\n statuses[\"unreadable\"] += 1\n receipts += 1\n continue\n reason = sensitive_reason(entrypoint, home)\n if reason:\n if receipts \u003c MAX_SKILL_RECEIPTS:\n print_unreadable(label, f\"sensitive_entrypoint_rejected:{reason}\")\n else:\n suppressed += 1\n statuses[\"unreadable\"] += 1\n receipts += 1\n continue\n if project_root is not None:\n absolute_candidate = candidate if candidate.is_absolute() else Path.cwd() / candidate\n project_skill_roots = (\n project_root / \"skills\",\n project_root / \".claude\" / \"skills\",\n project_root / \".agents\" / \"skills\",\n project_root / \".codex\" / \"skills\",\n )\n from_project_surface = any(\n contained(absolute_candidate, root) for root in project_skill_roots\n )\n if from_project_surface and not contained(entrypoint, project_root):\n if receipts \u003c MAX_SKILL_RECEIPTS:\n print_unreadable(label, \"project_skill_escape_rejected\")\n else:\n suppressed += 1\n statuses[\"unreadable\"] += 1\n receipts += 1\n continue\n identity = (entry_stat.st_dev, entry_stat.st_ino)\n root_identity = (root_stat.st_dev, root_stat.st_ino)\n if health_identity is not None and identity == health_identity:\n continue\n if entrypoint.name != \"SKILL.md\" or not entrypoint.is_file():\n if receipts \u003c MAX_SKILL_RECEIPTS:\n print_unreadable(label, \"not_a_skill_entrypoint\")\n else:\n suppressed += 1\n statuses[\"unreadable\"] += 1\n receipts += 1\n continue\n if root_identity in seen_roots:\n continue\n seen_roots.add(root_identity)\n emit = receipts \u003c MAX_SKILL_RECEIPTS\n status = scan_skill(label, entrypoint, identity, home, emit=emit)\n statuses[status] += 1\n if not emit:\n suppressed += 1\n receipts += 1\n if receipts == 0:\n print(\"(none)\")\n elif suppressed:\n print(f\"skill_receipts_truncated: {suppressed}\")\n print(\n \"scan_status_totals: \"\n + \",\".join(f\"{name}:{count}\" for name, count in sorted(statuses.items()))\n )\n return 0\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":19946,"content_sha256":"4ab83c18721f4266ade44a7d0b2f44fdbf3e2cef622e33a845ae4a56310a1424"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Health: Agent-Assisted Engineering Health","type":"text"}]},{"type":"paragraph","content":[{"text":"Prefix your first line with 🥷 inline, not as its own paragraph.","type":"text"}]},{"type":"paragraph","content":[{"text":"Audit the current project's agent setup and AI coding maintainability against this framework: ","type":"text"},{"text":"agent config → instruction surfaces → tools/runtime → verifiers → maintainability","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Outcome Contract","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Evidence: collected health script output, tracked project instructions, runtime config summaries, verifier logs, hooks/MCP surfaces, and read-only live probes when needed.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Output: prioritized findings with status, impact, and next action, or a clear clean bill with residual risk.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Two lanes share one report:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent config health","type":"text","marks":[{"type":"strong"}]},{"text":": Codex/Claude/Pi instruction drift, permissions, hooks, MCP, skills, and memory supply chain.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AI maintainability health","type":"text","marks":[{"type":"strong"}]},{"text":": non-obvious constraint reachability, risk-backed hotspot ownership, verifier coverage, generated-artifact checks, and stale or misleading durable docs.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Output language:","type":"text","marks":[{"type":"strong"}]},{"text":" Follow the user's current language or explicit language request. Use applicable project and global defaults only when the request does not establish a language.","type":"text"}]},{"type":"paragraph","content":[{"text":"Budget posture:","type":"text","marks":[{"type":"strong"}]},{"text":" Start with the summary audit. Escalate automatically when the user asks for a deep, full, complete, thorough, \"深入\", \"完整\", \"彻底\", or \"继续跑完\" audit, when the user explicitly mentions AI coding code rot, Codex/Claude config drift, unclear context, missing verification, verifier output that points at stale paths, or \"代码变烂\", when current project instructions or remembered user preference says to run deep health checks by default, or when the summary pass exposes a critical ambiguity that cannot be resolved locally. Inventory counts never trigger escalation on their own. Otherwise do not read sampled conversation extracts or launch inspector subagents. Tell the user before escalating because deep health audits can consume significant token quota.","type":"text"}]},{"type":"paragraph","content":[{"text":"Conversation scope:","type":"text","marks":[{"type":"strong"}]},{"text":" When the request names only static material (","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", skills, rules, settings, \"只审查指令和配置\"), pass ","type":"text"},{"text":"instructions","type":"text","marks":[{"type":"code_inline"}]},{"text":" as the first argument to ","type":"text"},{"text":"collect-data.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" and the run skips session history, reporting it as out of scope rather than as a coverage gap. This is chosen from the request, not a switch the user has to know about. Otherwise: Summary scans up to three recent previous sessions for the current project across Claude and Codex from a bounded candidate window when those local histories exist. Deep streams every previous current-project session across both runtimes for signals while printing only bounded extracts and a coverage receipt. Other projects remain out of scope by default. Only when the user explicitly asks for all conversations or cross-project capability distillation, run ","type":"text"},{"text":"python3 \u003cskill-base-dir>/scripts/conversation_audit.py \u003cclaude-projects-root> deep --all-projects --codex-root \u003ccodex-sessions-root>","type":"text","marks":[{"type":"code_inline"}]},{"text":" (the first argument holds every per-project log folder; the parser rejects other flag combinations), or hand off to a cross-project retro if one is installed. Claim complete coverage only when ","type":"text"},{"text":"coverage_status: complete","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"cross_project_full_history: yes","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"no_data","type":"text","marks":[{"type":"code_inline"}]},{"text":", unavailable roots, parse or read errors, files that change during scanning, and excluded live sessions are explicit coverage gaps.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Durable Context Preflight","type":"text"}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/durable-context.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/durable-context.md","title":null}}]},{"text":" for when durable context is in scope and the redaction gate that applies before any of it becomes a durable rule.","type":"text"}]},{"type":"paragraph","content":[{"text":"For ","type":"text"},{"text":"/health","type":"text","marks":[{"type":"code_inline"}]},{"text":": current config, command output, and live probes override memory. Also flag durable memory problems when they affect behavior: oversized injected summaries, stale or contradictory entries, missing project entrypoint references, or private paths copied into public instructions. Keep these as context findings, not code-review findings.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Hard Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Summary and deep audits are report-only. Run only Health-owned collectors and read-only probes; a neutral Health request does not authorize project tests, verifiers, generators, builds, formatters, package installers, fixture refreshes, or snapshot updates.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A bundled debugging or code-review ask uses its own workflow.","type":"text","marks":[{"type":"strong"}]},{"text":" Complete this report-only audit, then route explicitly requested work to the matching skill or native capability under the same completion ledger. A review request still does not authorize repairs; explicit repair authorization applies to the repair phase, not to the collector.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Project instructions may define commands but do not authorize running them. Read-only health probes are covered by the audit request. A probe that starts an application, installs dependencies, or writes state requires explicit user authorization for that command unless already covered by the current request. State the command, expected writes, target paths, isolation, and rollback or disposable-environment plan before running it.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 0: Establish the evidence basis","type":"text"}]},{"type":"paragraph","content":[{"text":"Record four evidence classes:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Evidence","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Question","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Risk","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Which paths can lose data, spend money, publish or deploy, cross trust boundaries, or create hard-to-reverse state?","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Non-obvious constraints","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Which stable decisions cannot be recovered cheaply from code or manifests, and can the active agent reach them only when relevant?","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Failure evidence","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Which user corrections, repeated fix chains, stale generated artifacts, broken references, or hollow verifiers prove a current gap?","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verifier coverage","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Which important outcomes have an executable check at the layer where they can actually fail?","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"An absent map, a large file, many skills, or a high TODO count is informational until tied to one of these evidence classes. Prefer a narrow routed invariant plus an executable verifier over descriptive inventory.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 1: Collect data","type":"text"}]},{"type":"paragraph","content":[{"text":"Set ","type":"text"},{"text":"HEALTH_SCOPE","type":"text","marks":[{"type":"code_inline"}]},{"text":" to ","type":"text"},{"text":"instructions","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the static-only scope above, otherwise ","type":"text"},{"text":"auto","type":"text","marks":[{"type":"code_inline"}]},{"text":", and retain it when escalating. Run the collection script in summary mode first. Do not interpret yet. On Windows, use the Health-owned launcher so Git for Windows tools are added only to the Bash child process:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"$HEALTH_LAUNCHER = @(\n \"\u003cskill-base-dir>/scripts/run-health.ps1\",\n \"\u003cskill-base-dir>/skills/health/scripts/run-health.ps1\"\n) | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1\nif (-not $HEALTH_LAUNCHER) {\n throw \"Health launcher not found under the installed skill base; reinstall Waza.\"\n}\n$POWERSHELL = Join-Path ([Environment]::SystemDirectory) \"WindowsPowerShell\\v1.0\\powershell.exe\"\n& \"$POWERSHELL\" -NoLogo -NoProfile -ExecutionPolicy Bypass -File \"$HEALTH_LAUNCHER\" collect \"$HEALTH_SCOPE\"","type":"text"}]},{"type":"paragraph","content":[{"text":"-ExecutionPolicy Bypass","type":"text","marks":[{"type":"code_inline"}]},{"text":" applies only to this PowerShell process; do not change the user's machine or account execution policy.","type":"text"}]},{"type":"paragraph","content":[{"text":"On Linux and macOS, keep the direct Bash flow:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"HEALTH_SCRIPT=\"\"\nfor candidate in \\\n \"\u003cskill-base-dir>/scripts/collect-data.sh\" \\\n \"\u003cskill-base-dir>/skills/health/scripts/collect-data.sh\"; do\n [ -f \"$candidate\" ] && HEALTH_SCRIPT=\"$candidate\" && break\ndone\nif [ ! -f \"${HEALTH_SCRIPT:-}\" ]; then\n echo \"health collect-data.sh not found under the installed skill base; reinstall Waza\"\n exit 1\nfi\nBASH_ENV= ENV= /bin/bash -p \"$HEALTH_SCRIPT\" \"$HEALTH_SCOPE\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Sections may show ","type":"text"},{"text":"(unavailable)","type":"text","marks":[{"type":"code_inline"}]},{"text":" when tools are missing:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"trusted ","type":"text"},{"text":"python3","type":"text","marks":[{"type":"code_inline"}]},{"text":" missing: conversation, MCP/hooks/allowedTools, and skill-security sections unavailable","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"settings.local.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" absent: hooks/MCP may be unavailable (normal for global-only setups)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Treat ","type":"text"},{"text":"(unavailable)","type":"text","marks":[{"type":"code_inline"}]},{"text":" as insufficient data, not a finding. Do not flag those areas.","type":"text"}]},{"type":"paragraph","content":[{"text":"The collector includes both runtime-specific and agent-agnostic surfaces:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AGENT CONFIG SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"AGENT CONFIG DETAIL","type":"text","marks":[{"type":"code_inline"}]},{"text":" for Codex, Claude, Pi, and project instruction files; its sections start at ","type":"text"},{"text":"=== AGENT INSTRUCTION SURFACE ===","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AI MAINTAINABILITY SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"AI MAINTAINABILITY DETAIL","type":"text","marks":[{"type":"code_inline"}]},{"text":" for project signals, verification surface, generated mirrors, wrappers, and doc links; its sections start at ","type":"text"},{"text":"=== PROJECT SHAPE ===","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 1b: Runtime Inventory and MCP Check","type":"text"}]},{"type":"paragraph","content":[{"text":"Inspect configured global, project, and installed-plugin sources first, retaining source and enablement. Use the runtime inventory to flag missing hook and MCP executables; unknown working directories or plugin state remain coverage gaps. Call a harmless tool only on already connected servers. Never launch an unverified GUI executable just to test MCP. Record connected, failed, disabled, pending approval, or untested separately; static presence is not live health. Never emit credentials. Compare discovered instruction bytes with the effective configured limit and state any uninspected ancestors, nested files, or runtime overrides.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 1c: Safety and security checks","type":"text"}]},{"type":"paragraph","content":[{"text":"These run after collection and before the Step 2 analysis. The first two apply to every audit; the third only to projects with long-running or autonomous agents.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Security Baseline Checks","type":"text"}]},{"type":"paragraph","content":[{"text":"Run these on every audit. They are the floor, not the ceiling.","type":"text"}]},{"type":"paragraph","content":[{"text":"Deny-list floor.","type":"text","marks":[{"type":"strong"}]},{"text":" Apply this only when the runtime actually enforces the rule shape being recommended: agent permission settings, hook settings, MCP settings, allowed/denied tools, or a documented autonomous-agent launcher. In that case, the settings should deny, at minimum: credential and key directories (SSH, cloud providers, GPG, gh CLI), credential-bearing files (","type":"text"},{"text":"credentials*","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"secrets*","type":"text","marks":[{"type":"code_inline"}]},{"text":"), and pipe-to-shell installers. Treat ","type":"text"},{"text":".env","type":"text","marks":[{"type":"code_inline"}]},{"text":" as an explicit policy choice: either deny it at the permission layer, or allow task-scoped reads while the instruction layer forbids printing, committing, or exfiltrating its contents; warn only when neither layer defines the boundary. Report missing categories as one concise WARN; let the reviewer fill in exact local paths. Three calibrations: prefix/glob permission rules cannot reliably match pipes, so recommend the host's pre-execution hook for pipe-to-shell blocking instead of inventing glob variants, and name the hook's own tradeoff (string-matching hooks also fire on quoted text and heredocs that merely contain the pattern); before predicting an outbound-shell deny's blast radius, check which layer it matches at: a command-prefix deny on ","type":"text"},{"text":"ssh","type":"text","marks":[{"type":"code_inline"}]},{"text":" only blocks the agent invoking ","type":"text"},{"text":"ssh","type":"text","marks":[{"type":"code_inline"}]},{"text":" directly and leaves git's internal SSH transport alone, while a process- or sandbox-level block does break git-over-SSH push; and when a runtime has no command-level deny surface (Codex: the levers are ","type":"text"},{"text":"sandbox_mode","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"approval_policy","type":"text","marks":[{"type":"code_inline"}]},{"text":"), name that lever once as a user tradeoff instead of recommending deny keys the runtime cannot express. If no agent settings surface exists at all, report the deny-list as not applicable rather than a failure.","type":"text"}]},{"type":"paragraph","content":[{"text":"Permission-layer vs instruction-layer gating.","type":"text","marks":[{"type":"strong"}]},{"text":" An allowlist entry for a git write action (","type":"text"},{"text":"git push","type":"text","marks":[{"type":"code_inline"}]},{"text":") next to an instruction-layer rule (\"push only when the user says so\") is not automatically a contradiction: instructions decide when the action happens, permissions decide whether it re-prompts, and a user who explicitly authorizes pushes every session may keep push in allow deliberately to avoid double confirmation. Calibrate by reversibility and the user's own rules: actions the instructions forbid outright (","type":"text"},{"text":"git reset --hard","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"git stash","type":"text","marks":[{"type":"code_inline"}]},{"text":", force-push) belong in deny or ask; routine explicitly-authorized actions stay where the user put them, reported at most as a note. Escalate only when auto mode plus skipped prompts plus broad allow lets a write action run with zero user input in a session, and even then present the friction tradeoff for the user to choose instead of silently moving entries.","type":"text"}]},{"type":"paragraph","content":[{"text":"Environment override surface.","type":"text","marks":[{"type":"strong"}]},{"text":" Treat the following as attack surface, report when set in tracked files or shipped settings without a justification comment: API base-URL overrides (redirect all traffic to a third party), auto-trust flags for project-local MCP servers, wildcard tool allowlists (","type":"text"},{"text":"allowedTools: [\"*\"]","type":"text","marks":[{"type":"code_inline"}]},{"text":"), and permission-skip flags (","type":"text"},{"text":"--dangerously-skip-permissions","type":"text","marks":[{"type":"code_inline"}]},{"text":" or equivalents). Print file:line and the key name only; never print secrets.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Memory and Skill Supply Chain","type":"text"}]},{"type":"paragraph","content":[{"text":"Treat agent memory and third-party skills as supply-chain artifacts. They run with the user's privileges.","type":"text"}]},{"type":"paragraph","content":[{"text":"Memory hygiene.","type":"text","marks":[{"type":"strong"}]},{"text":" Audit the project's long-term agent memory store for secrets, tokens, or credentials (Critical), and for entries written by untrusted runs (subagent invoked on attacker-controlled input, /loop iteration over external content); recommend rotation after such runs. For high-risk one-off runs (untrusted PDFs, uncontrolled scraping, third-party scripts), recommend disabling memory persistence for that session entirely.","type":"text"}]},{"type":"paragraph","content":[{"text":"Skill supply chain.","type":"text","marks":[{"type":"strong"}]},{"text":" Third-party skills, plugins, and MCP servers run with the user's privileges. For each one not authored in this repo, check: source pinned to a release tag or revision (not ","type":"text"},{"text":"main","type":"text","marks":[{"type":"code_inline"}]},{"text":", a branch, or a remote git marketplace left tracking its latest head), hook handlers do not write to credential directories, MCP servers have explicit user consent (not auto-trusted by wildcard). Report unpinned sources or unreviewed hook handlers as Structural, not Critical, unless an active exploit signal is present.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Long-Running Agent Stop Conditions","type":"text"}]},{"type":"paragraph","content":[{"text":"For projects that use ","type":"text"},{"text":"/loop","type":"text","marks":[{"type":"code_inline"}]},{"text":", autonomous agents, or any long-running agent flow, load ","type":"text"},{"text":"references/long-running-agents.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" and audit the four hard stop signals it lists. Projects without such a flow skip this check.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 2: Analyze","type":"text"}]},{"type":"paragraph","content":[{"text":"Analyze locally from the summary output by default. When Budget posture escalates, re-run collection with ","type":"text"},{"text":"& \"$POWERSHELL\" -NoLogo -NoProfile -ExecutionPolicy Bypass -File \"$HEALTH_LAUNCHER\" collect \"$HEALTH_SCOPE\" deep","type":"text","marks":[{"type":"code_inline"}]},{"text":" on Windows, or ","type":"text"},{"text":"BASH_ENV= ENV= /bin/bash -p \"$HEALTH_SCRIPT\" \"$HEALTH_SCOPE\" deep","type":"text","marks":[{"type":"code_inline"}]},{"text":" on Linux and macOS. Then launch only the relevant inspectors in parallel. Redact credentials to ","type":"text"},{"text":"[REDACTED]","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deep inspector routing:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent 1","type":"text","marks":[{"type":"strong"}]},{"text":" (Context + Security): Read ","type":"text"},{"text":"agents/inspector-context.md","type":"text","marks":[{"type":"code_inline"}]},{"text":". Feed ","type":"text"},{"text":"CONVERSATION SIGNALS","type":"text","marks":[{"type":"code_inline"}]},{"text":" section.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent 2","type":"text","marks":[{"type":"strong"}]},{"text":" (Control + Behavior): Read ","type":"text"},{"text":"agents/inspector-control.md","type":"text","marks":[{"type":"code_inline"}]},{"text":". Feed the relevant runtime, hook, MCP, and permission evidence.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent 3","type":"text","marks":[{"type":"strong"}]},{"text":" (AI Maintainability): Read ","type":"text"},{"text":"agents/inspector-maintainability.md","type":"text","marks":[{"type":"code_inline"}]},{"text":". Feed only ","type":"text"},{"text":"PROJECT SIGNALS","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"AI MAINTAINABILITY SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"AI MAINTAINABILITY DETAIL","type":"text","marks":[{"type":"code_inline"}]},{"text":", and concrete verifier/drift receipts. Launch this agent only for deep health audits or explicit code-rot/AI-maintainability requests.","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fallback:","type":"text","marks":[{"type":"strong"}]},{"text":" If a subagent fails, analyze that layer locally and note \"(analyzed locally)\".","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Before reporting a deep audit as complete, wait for every launched inspector and reconcile its assigned scope. If one remains pending or fails without a local replacement pass, list that scope as unreviewed instead of issuing a whole-scope clean bill.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Gotchas","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"What happened","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rule","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Missed the local override","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always read ","type":"text"},{"text":"settings.local.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" too; it shadows the committed file","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Subagent timeout reported as MCP failure","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MCP failures come from the live probe, not data collection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flagged intentionally noisy hook as broken","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ask before calling a hook \"broken\"","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hook seemed not to fire, but it did -- a later UI element rendered above it","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hook firing order is not visual order. Before re-editing the hook config: (a) confirm with ","type":"text"},{"text":"--debug","type":"text","marks":[{"type":"code_inline"}]},{"text":" or by piping output, (b) check whether a diff dialog, permission prompt, or other UI element rendered on top and pushed the hook output offscreen, (c) only then suspect the hook itself.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Treated missing specs/docs as a failure","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Decision artifacts are optional by default. Escalate missing docs/specs only when active handoff risk, failure evidence, or the user request makes them necessary.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output","type":"text"}]},{"type":"paragraph","content":[{"text":"Health Report: {project} ({summary|deep}, evidence-based)","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Global findings report once.","type":"text","marks":[{"type":"strong"}]},{"text":" Findings in machine-global config (","type":"text"},{"text":"~/.claude","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"~/.codex","type":"text","marks":[{"type":"code_inline"}]},{"text":", global rules, skills, memory) are not project findings: label them ","type":"text"},{"text":"global","type":"text","marks":[{"type":"code_inline"}]},{"text":", report each once with its fix, and recommend one dedicated session for global cleanup instead of re-fixing per project. Before editing any global file, re-read its current state: when health runs across several projects in one day, another session may already have fixed or be mid-fix on the same file, and re-applying a variant of the same rule creates duplicate entries. Never edit the same global file from two concurrent sessions.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"[PASS] Passing checks (table, max 5 rows)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Finding format","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"- [severity] \u003csymptom> ({file}:{line} if known)\n Why: \u003cone-line reason>\n Action: \u003cexact command or edit to fix>","type":"text"}]},{"type":"paragraph","content":[{"text":"Action:","type":"text","marks":[{"type":"code_inline"}]},{"text":" must be copy-pasteable. Never write \"investigate X\" or \"consider Y\". If the fix is unknown, name the diagnostic command.","type":"text"}]},{"type":"paragraph","content":[{"text":"A finding refuted in the same breath (a TODO count that turns out to be vendored code or false positives) is not a finding; drop it or fold it into the passing table.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"[!] Critical -- fix now","type":"text"}]},{"type":"paragraph","content":[{"text":"Confirmed dangerous permissions, consequential rule violations, security findings, and leaked credentials. Server counts and estimated context percentages never establish Critical severity.","type":"text"}]},{"type":"paragraph","content":[{"text":"Example:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"[!] ","type":"text"},{"text":"settings.local.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" committed to git (exposes MCP tokens) Why: leaked token enables remote code execution via installed MCP servers Action: ","type":"text"},{"text":"git rm --cached .claude/settings.local.json && echo '.claude/settings.local.json' >> .gitignore","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"[~] Structural -- fix soon","type":"text"}]},{"type":"paragraph","content":[{"text":"Agent instructions in the wrong layer, missing hooks, oversized descriptions, verifier gaps.","type":"text"}]},{"type":"paragraph","content":[{"text":"Codex/Claude/Pi instruction drift.","type":"text","marks":[{"type":"strong"}]},{"text":" Use ","type":"text"},{"text":"AGENT CONFIG SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" first. ","type":"text"},{"text":"project_instructions_mode","type":"text","marks":[{"type":"code_inline"}]},{"text":" says which files Claude Code loads: on ","type":"text"},{"text":"claude-md","type":"text","marks":[{"type":"code_inline"}]},{"text":" an ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" alone reaches Codex and Cursor but not Claude, and ","type":"text"},{"text":"nested_agents_md","type":"text","marks":[{"type":"code_inline"}]},{"text":" counted together with a root ","type":"text"},{"text":"CLAUDE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" means those nested guides reach nobody on Claude, because the root file switches the whole project off the ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" path rather than just its own folder. The exception is ","type":"text"},{"text":"claude-md-and-agents-md","type":"text","marks":[{"type":"code_inline"}]},{"text":", where both are read and the nested files still load, unless ","type":"text"},{"text":"CLAUDE.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" is the same physical file as ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" and the deduplicated chain is skipped. Report a Structural finding when ","type":"text"},{"text":"AGENTS.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" and runtime-specific files both contain substantial guidance without delegation, when Codex ","type":"text"},{"text":"config.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":" lacks trust for the current project, when Pi settings or package metadata point at missing skill roots, when project agent instructions are missing, or when runtime-specific instructions contradict the shared project source of truth. Also report when important rules live only in ignored or private local instruction overlays but the tracked/public docs lack them; those overlays are private context, not durable project source of truth. Do not print raw config values. Secrets, tokens, keys, and passwords must appear only as ","type":"text"},{"text":"[REDACTED]","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Quick check from the project root, reusing ","type":"text"},{"text":"$HEALTH_SCRIPT","type":"text","marks":[{"type":"code_inline"}]},{"text":" resolved in Step 1 (standalone output has no ","type":"text"},{"text":"AGENT CONFIG SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" wrapper):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"& \"$POWERSHELL\" -NoLogo -NoProfile -ExecutionPolicy Bypass -File \"$HEALTH_LAUNCHER\" agent-context . summary","type":"text"}]},{"type":"paragraph","content":[{"text":"On Linux and macOS:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"BASH_ENV= ENV= /bin/bash -p \"${HEALTH_SCRIPT%/*}/check-agent-context.sh\" . summary","type":"text"}]},{"type":"paragraph","content":[{"text":"AI-maintainability findings.","type":"text","marks":[{"type":"strong"}]},{"text":" For the maintainability lane (verification surface, conversation-derived guidance, concentrated fix chains, risk-backed hotspot ownership, non-obvious constraint reachability, verifier wrapper, broken doc and Markdown references, stale verifier cache output), load ","type":"text"},{"text":"references/maintainability-findings.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" and work its checks with ","type":"text"},{"text":"AI MAINTAINABILITY SUMMARY","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"DETAIL","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"[-] Incremental -- nice to have","type":"text"}]},{"type":"paragraph","content":[{"text":"Outdated items, global vs local placement, context hygiene, stale allowedTools entries.","type":"text"}]},{"type":"paragraph","content":[{"text":"If no issues: ","type":"text"},{"text":"All relevant checks passed. Nothing to fix.","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"A report-only request never authorizes fixes; an explicit optimization or repair request continues into its authorized repair phase without another confirmation. The audit is not a heavy lint, typecheck, duplication, or architecture-rewrite substitute; ","type":"text"},{"text":"/health","type":"text","marks":[{"type":"code_inline"}]},{"text":" reports maintainability guardrails and concrete next actions only.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"health","author":"@skillopedia","source":{"stars":7495,"repo_name":"Waza","origin_url":"https://github.com/tw93/Waza/blob/HEAD/skills/health/SKILL.md","repo_owner":"tw93","body_sha256":"690e3b44f71deaa9b45baf67adaac40efc3e4e2278b89ed6bf2db4624d5bec4e","cluster_key":"2e46212c3ef9516a50966a7f64963362a2c1cff60e8d9a8fffc57895c720d5ff","clean_bundle":{"format":"clean-skill-bundle-v1","source":"tw93/Waza/skills/health/SKILL.md","text_bytes":279402,"source_commit":"58217546cd94fcf5ddcde4265c00a9377ed3192c","skills_sh_rank":1529,"attachment_count":19,"text_attachments":19,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/health/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"skills-sh-top20k-2026-11","description":"Audits agent config, instruction drift, hooks or MCP, and AI maintainability. Use when Claude, Codex, or Pi setup looks wrong. Not for application bugs or PR review.","when_to_use":"检查claude, 检查codex, 检查pi, Codex 配置, Pi 配置, agent instructions, 健康度, 配置检查, 配置对不对, AI coding 腐化, Claude ignoring instructions, Pi coding agent, check config, settings not working, audit config","dispatch_intent":"Codex/Claude/Pi ignoring instructions, agent config audit, hooks/MCP broken, health token usage, AI coding code rot, risk-backed hotspot ownership, unreachable project constraints, unclear context, missing verification, stale verifier output"}},"renderedAt":1793686867341}

Health: Agent-Assisted Engineering Health Prefix your first line with 🥷 inline, not as its own paragraph. Audit the current project's agent setup and AI coding maintainability against this framework: Find violations. Identify the misaligned layer. Calibrate to evidence and risk, not repository size. Outcome Contract - Outcome: a budget-aware health report that separates agent configuration risk from AI maintainability risk. - Done when: each finding names the misaligned layer, the concrete evidence, and a copy-pasteable action or diagnostic command. - Evidence: collected health script output…