audit D2: FAIL message enumerates 41 task ids beside a count of 33 (shared details accumulator across two severity branches)
まだ誰も着手していません。
評価
調査の方向性
Start with the D2 "Human review queue" block in agents/audit/audit.sh and trace how severity buckets build their counts and detail lists. Review the suggested per-bucket-list approach and the regression-test description; add functional coverage that extracts and runs the D2 block against synthetic queues. Done means each emitted count matches its listed IDs and the listed ages meet the stated threshold, with the full bats suite passing.
索引モデルが issue の本文から書いたものです。
説明
Context
- Framework version: 1.6.258
- Project: 050-email-archive (shared-tooling mode)
- Reported: 2026-09-24T22:35:14Z
Description
Summary
agents/audit/audit.sh's D2 "Human review queue" check emits a FAIL message whose
enumerated id list does not match its own stated count, because the count is
partitioned by severity and the list is not.
Measured on a consumer project (Pen) 2026-09-25:
before: stated_count=33 ids_listed=41 ids_under_30d=8
after: stated_count=33 ids_listed=33 min_listed_age=39d (threshold 30d)
Root cause
The block maintained three counters (d2_fail, d2_warn, d2_info) but one
shared detail string d2_details, appended by both the >= 720 (FAIL, >30d)
branch and the >= 336 (WARN, 14-30d) branch:
if [ "$age_hours" -ge 720 ]; then
d2_fail=$((d2_fail + 1))
d2_details="$d2_details $t_id(${age_days}d)" # <-- shared
elif [ "$age_hours" -ge 336 ]; then
d2_warn=$((d2_warn + 1))
d2_details="$d2_details $t_id(${age_days}d)" # <-- same string
The FAIL emitter then interpolated that union list beside the fail-only count:
fail "D2: Human review queue - $d2_fail task(s) waiting >30d:$d2_details"
Neither predicate is wrong. The defect is that the count and the list are two
independently-maintained representations of one fact, and only one of them is
partitioned by severity. 33 fail + 8 warn = 41 listed.
Consequence: a reader triaging "the 33 overdue tasks" works 8 tasks that are not
overdue, and the message's self-consistency cannot be relied on for the audit's
other reported figures.
Suggested fix - the general form, not a D2-only filter
Please avoid the narrow fix of adding a >= 720 guard to the string append. That
leaves count and list still independently maintained. The shape that makes the
divergence unrepresentable is per-bucket lists with counts derived from them:
d2_fail_ids=(); d2_warn_ids=()
...
d2_fail_ids+=("$t_id(${age_days}d)") # per severity
...
d2_fail=${#d2_fail_ids[@]} # count DERIVED from the list
d2_warn=${#d2_warn_ids[@]}
No second number is left to drift. The same reasoning applies anywhere else in
audit.sh where a count and an enumerated list are built side by side.
Two notes from applying it:
- Use
if-blocks, not[ "$d2_fail" -gt 0 ] && d2_fail_details=...- the
short-circuit form returns 1 on an empty bucket, which would abort the audit if
audit.shis ever run underset -e. - Dropping the warn ids from the FAIL output is a deliberate scope call, not a
regression: D2 is anif/elifseverity escalation that has always reported only
the worst bucket, and its count has always been fail-only. Those ids were never
intentionally emitted there.
Regression test
Consumer-side patch adds tests/unit/d2_review_queue.bats (9 cases). Six are
functional, not static greps: they awk-extract the real D2 block from audit.sh
between new # D2-BLOCK-START/END markers, stub fail/warn/pass, run it against
synthetic review queues, and assert stated count == len(enumerated list) plus
"youngest listed age > stated threshold" against the message the audit would print.
A static-only test would NOT have caught this bug - the offending line was an
ordinary string interpolation with nothing greppable to forbid. Please do not adopt
the tests/unit/c001_single_emitter.bats static-pin pattern for this one. The new
test was verified to discriminate: replayed against the pre-fix block verbatim it
reports stated=3 ids_listed=5 min_listed_age=18d and both assertions fail.
Three additional static pins forbid the shared accumulator returning (no bare
d2_details outside comments; no d2_fail=$((d2_fail + 1)); the two emitters must
interpolate different variables and never each other's).
Full vendored bats suite after the change: 236 pass, 0 fail (227 before, +9).
Unrelated, found while filing this
fw upstream report --attach-patch REF builds the patch with
git diff "$attach_patch" (lib/upstream.sh:258) - a single-ref diff, i.e. working
tree vs that commit, not the commit's own change. On any repo with unrelated
uncommitted files that silently attaches them to a public issue. It probably wants
git diff "$attach_patch~1" "$attach_patch" or git show. I dropped the flag rather
than publish unrelated working-tree content.
Context
Filed from a consumer project under a standing condition that every vendored
.agentic-framework/ patch is paired with an upstream request. Continues #57-#61.
Consumer task: T-2148, arc-009. Class concern there: the audit surface reports
figures that fail independent verification - this is the third instance (cf. #61
duplicate C-001 emitters, #57 fabric-drift false positives).
Reported via fw upstream report from field installation
- 主要言語
- Shell
- スター
- 16
- フォーク
- 6
- 平均マージ
- 6時間 24分
- マージ済み PR(30日)
- 5
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
DimitriGeelen/agentic-engineering-framework のほかの issue
-
area:cli bug severity:low status:fixed-on-bleeding-edge triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
DimitriGeelen/agentic-engineering-framework#100 · コメント 5 件 ·
-
area:cli bug severity:medium status:fixed-on-bleeding-edge triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
DimitriGeelen/agentic-engineering-framework#97 · コメント 5 件 ·
-
area:context bug severity:low status:fixed-on-bleeding-edge triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
DimitriGeelen/agentic-engineering-framework#96 · コメント 5 件 ·
-
area:docs bug severity:medium status:in-progress triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
DimitriGeelen/agentic-engineering-framework#95 · コメント 4 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
DimitriGeelen/agentic-engineering-framework の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
level/task type/enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
wazuh/wazuh-installation-assistant#1177 ·
メンテナーはふだん 1 日以内に返信
-
package-update
難易度 2/5 1〜3時間 初心者へのやさしさ 63/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
ComputeCanada/puppet-magic_castle#634 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
AltimateAI/altimate-code#1590 ·
メンテナーはふだん 1 日以内に返信