@adlc/flail-detector

中文文档
1.12.0发布于 2026/10/10MITES Module构建来源已验证近 30 天下载 8821

Session-log flail analysis — mechanical two-strike rule for build agents (C6/P4 supervisor).

原始使用文档
文档目录16 节
  1. Usage
  2. Arguments
  3. Flags
  4. Exit Codes
  5. Signals
  6. 1. repeated-error
  7. 2. scope-violation
  8. 3. edit-churn
  9. 4. size
  10. 5. budget
  11. Input Handling
  12. Output
  13. Examples
  14. ADLC Phase
  15. Relationship to Sibling Tools
  16. Core Gaps

flail-detector

Session-log flail analysis — mechanical two-strike rule. ADLC phase C6 / P4 supervisor.

Watches a build session log for flail signatures. On trigger: emits verdict flail, prints a recommendation block, and exits 2 so CI can gate. Fully deterministic; no LLM calls.

Usage

flail-detector <log-file> [--scope <glob>...] [--max-repeat <n>] [--max-bytes <n>] [--spent-tokens <n>] [--budget <n>] [--record] [--ticket <id>] [--json]

Arguments

ArgumentDescription
<log-file>Path to the session log file to analyze (required)

Flags

FlagDefaultDescription
--scope <glob>(none)Declared-scope glob pattern (repeatable). When given, file paths found in tool-log lines that fall outside ALL supplied globs are flagged as scope violations.
--max-repeat <n>2Trigger the repeated-error signal when a normalized error signature appears >= n times.
--max-bytes <n>(no limit)Trigger the size signal when the log file exceeds n bytes.
--spent-tokens <n>(none)Measured token spend for this ticket (e.g. from adlc spend --ticket <id> --json). Must be given with --budget.
--budget <n>(none)The ticket's declared token budget (ticket.budget, or model-router's emitted per-ticket budget). Triggers the budget signal when --spent-tokens exceeds it. Must be given with --spent-tokens — either alone is a usage error.
--recordoffOn a clean verdict, append a flail-check entry to .adlc/manifest.jsonl (ADLC P4 evidence — see @adlc/runner). Never writes on a flail verdict, and never on a could-not-analyze outcome (issue #622).
--ticket <id>(none)Ticket to scope the recorded manifest entry to. Optional — recorded as null when omitted, same as rails-guard --record.
--jsonoffMachine-readable JSON output for orchestrators.
--help—Print help and exit 0.

Exit Codes

CodeMeaning
0Gate passes — no flail signals detected (clean)
1Operational error — file not found, bad argument, or could-not-analyze: the log had nothing to analyze (no non-empty lines). Never a pass — nothing is recorded even with --record.
2Gate fails — one or more flail signals triggered

Signals

1. repeated-error

Lines matching /error|exception|failed|cannot|ENOENT/i are normalized (lowercase; strip digits, hex literals, quoted strings, and absolute paths), then counted per unique signature. Any signature occurring >= --max-repeat times triggers this signal.

Normalization ensures that Error: cannot find module "lodash" at line 42 and Error: cannot find module "express" at line 99 collapse to the same signature — the error kind is what matters, not the varying operands.

2. scope-violation

Only active when --scope is given. File paths extracted from common tool-log patterns:

  • Writing <path>
  • Editing <path>
  • Created <path>
  • "file_path":"<path>" (JSON tool-log format)

Path-bearing verbs (Writing, Editing, Created) must open the line, optionally after indentation and log prefixes: timestamps (12:03:01 Writing <path>), bracketed fields ([INFO] Editing <path>), or upper-case level names (WARN Created <path>). A verb anywhere else is prose and yields no path, so a tool result such as File created successfully at: <path> is not read as a write to successfully.

Any path that does not match at least one --scope glob is a violation.

3. edit-churn

The same file path appearing in >= 3 write/edit log lines (regardless of which verb — Writing, Editing, or Created). Indicates the agent is cycling back to the same file repeatedly.

4. size

When --max-bytes is given, triggers if the log file byte count exceeds the threshold.

5. budget

When both --spent-tokens and --budget are given, triggers if measured spend exceeds the ticket's declared ceiling — ADLC.md C6's "token spend past the ticket budget" trigger. Neither figure comes from the log itself: flail-detector doesn't measure tokens, it only compares two numbers the caller supplies. Pair with adlc spend for the measured side and model-router's emitted budget (or the ticket's own declared budget field) for the ceiling. Giving only one of the two flags is a usage error (exit 1) rather than a silent no-op.

Input Handling

If more than half the non-empty lines of the log parse as JSON objects, the file is treated as JSONL: string values of the keys content, text, and message are recursively extracted and fed into the signal detectors. All other files are treated as plain text, one line at a time.

Output

Human-readable (default):

flail-detector: FLAIL
  bytes: 361
  signals:
    repeated-error (1 signature(s)):
      [2x] error: cannot resolve module at line in
    scope-violation (1 path(s) outside scope):
      /etc/hosts
    edit-churn (1 file(s) edited >= 3 times):
      [3x] src/index.ts

  recommendation:
    Kill the session. Append these dead-ends to the ticket: error: cannot resolve module at line in

Machine-readable (--json):

{
  "verdict": "flail",
  "signals": [...],
  "bytes": 361,
  "recommendation": "Kill the session. Append these dead-ends to the ticket: ..."
}

When the log has nothing to analyze — it is empty or whitespace-only — the verdict is could-not-analyze and the exit code is 1, not 0:

{
  "verdict": "could-not-analyze",
  "reasons": ["log has no non-empty lines (empty or whitespace-only file)"],
  "bytes": 0,
  "signals": []
}

In text mode the same outcome prints flail-detector: could not analyze — <reasons> to stderr. It is an operational outcome, never a pass: a supervisor pointed at a log path that was never written must not get a green P4 gate, and --record writes no flail-check entry for it (issue #622).

Scope is deliberately not part of this decision: a well-behaved session may contain no writes at all, and supervisors such as @adlc/fleet pass the ticket's --scope on every consult — so a log with lines but no extractable file path is analyzed normally (repeated-error, size and budget signals still fire; the scope signals simply have nothing to flag). Under-extraction of paths from real logs was addressed in issue #623.

Examples

# Analyze a plain-text session log
flail-detector session.log

# Enforce scope (write/edit must stay inside src/ or test/)
flail-detector session.log --scope 'src/**' --scope 'test/**'

# Raise the error-repeat threshold to 3
flail-detector session.log --max-repeat 3

# Flag oversized logs (e.g. > 1 MB context)
flail-detector session.log --max-bytes 1048576

# Flag token spend past the ticket's declared budget
flail-detector session.log --spent-tokens 85000 --budget 50000

# JSON for orchestrators
flail-detector session.log --json

# Record P4 evidence on a clean pass (adlc run p4 requires this)
flail-detector session.log --scope 'src/**' --record --ticket T42

ADLC Phase

C6 / P4 supervisor. Encodes the two-strike regeneration rule mechanically. See ADLC.md §C6 for the design rationale.

Intended to be invoked by a P4 supervisor after each build attempt. On flail (exit 2): kill the session, append the dead-end signatures to the ticket, and regenerate fresh. On second trigger: escalate to P2 — the ticket is wrong, not the agent.

Relationship to Sibling Tools

  • rails-guard (C5): enforces frozen rails on git diffs; flail-detector watches live session logs for behavioral drift.
  • consensus-fix (C7): fan-out fix strategy invoked after flail is confirmed; flail-detector is the upstream gate that triggers it.
  • premortem (C2): upstream risk analysis; flail-detector catches the risk materializing at runtime.

Core Gaps

None. This tool uses only parseArgs, opError, printJson, sha256, pass, gateFail, and globMatch from @adlc/core. No LLM, no git. --record is the one ledger write this tool performs, via @adlc/gate-manifest's appendManifestEntry, mirroring rails-guard's --record (issue #106) — without it, adlc run p4's flail-check requirement could never be satisfied by any documented flow.

版本与发布记录

@adlc/flail-detector 共发布 18 个版本,首次发布于 2026/06/14;过去 12 个月发布了 18 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.12.0latest2026/10/1027 天前
1.11.12026/09/091 个月前
1.11.02026/08/252 个月前
1.10.02026/08/112 个月前
1.9.02026/08/092 个月前
1.8.02026/08/082 个月前

关于 @adlc/flail-detector 的常见问题

@adlc/flail-detector 是什么?

Session-log flail analysis — mechanical two-strike rule for build agents (C6/P4 supervisor).

如何安装 @adlc/flail-detector?

在项目目录运行 npm install @adlc/flail-detector,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 flail-detector,可以用 npx flail-detector 直接运行。

@adlc/flail-detector 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/adlc__flail-detector 是否存在。

@adlc/flail-detector 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adlc/flail-detector 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@adlc/flail-detector 可以商用吗?

@adlc/flail-detector 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adlc/flail-detector 的下载量有多少?

根据 npm 官方下载统计,@adlc/flail-detector 在 2026/10/05 – 2026/11/03 这 30 天内被下载 8,821 次,日均约 294 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adlc/flail-detector 还在维护吗?

最新版本 1.12.0 发布于 2026/10/10(27 天前);至今共发布 18 个版本,其中过去 12 个月发布了 18 个;首次发布于 2026/06/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。