Skip to content

feat(explain): add --last to trace the most recent decision#65

Merged
LanNguyenSi merged 2 commits intomasterfrom
feat/explain-last
May 5, 2026
Merged

feat(explain): add --last to trace the most recent decision#65
LanNguyenSi merged 2 commits intomasterfrom
feat/explain-last

Conversation

@LanNguyenSi
Copy link
Copy Markdown
Owner

Summary

  • Closes the "I just got a deny, what fired?" loop in one command instead of three. Previously you had to run harness audit --since 5m, read the policyName off the latest row, and feed it back into harness explain <name> --trace because Claude Code only surfaces the hook's stdout, not the policy that produced it.
  • Makes <policy> optional and adds --last to trace the most recent policy_decision row in the ledger (any policy). Pairs with --decision allow|deny|warn-degraded so an intervening allow does not hide the deny you actually want to inspect.
  • Mutual exclusion is enforced at the CLI layer: <policy> together with --last, --decision without --last, and an unknown --decision value all fail fast as EX_USAGE (64) with a precise message.
  • The trace renderer looks up the policy by name in the current manifest. If the policy has been renamed or removed since the decision fired, triggerMatched.event falls back to a clear placeholder rather than crashing.

Closes agent-tasks task 803cb974.

Test plan

  • npm run typecheck clean
  • npm test: 665/665 pass (8 new tests covering --last happy path, the --decision filter, missing-from-manifest fallback, friendly empty messages, and the three CLI mutual-exclusion paths)
  • node dist/cli/main.js explain --help prints the new flags with accurate dependency text
  • CHANGELOG entry under [Unreleased]

nguyen-si-pp and others added 2 commits May 5, 2026 17:44
After a fresh deny, Claude Code only shows the hook's stdout, not the
underlying policy name. Tracing the decision currently requires
running `harness audit --since 5m`, reading `payload.policyName` off
the latest row, and feeding that name back into
`harness explain <name> --trace`. Two steps too many for the common
"I just got a deny, what happened?" loop.

This change makes `<policy>` optional and adds two flags:

- `--last`: traces the most recent policy_decision row in the ledger,
  regardless of policy. Mutually exclusive with `<policy>`.
- `--decision <outcome>`: with `--last`, restricts to a single outcome
  (allow / deny / warn-degraded), so an intervening allow does not hide
  the deny you actually want to inspect.

The trace renderer looks up the policy by name in the current manifest
to populate `triggerMatched`. If the policy was renamed or removed
between when the decision fired and when `--last` is invoked, the
trigger event falls back to a clear `(unknown: policy not declared in
current manifest)` placeholder rather than crashing.

The CLI layer enforces the mutual-exclusion rule and validates the
`--decision` value up front, so each error path lands as EX_USAGE
with a precise message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@LanNguyenSi LanNguyenSi merged commit de4033e into master May 5, 2026
1 check passed
@LanNguyenSi LanNguyenSi mentioned this pull request May 6, 2026
10 tasks
LanNguyenSi added a commit that referenced this pull request May 6, 2026
Bump package.json 0.6.0 -> 0.7.0. Roll up CHANGELOG [Unreleased]
into [0.7.0] - 2026-05-06 with a one-paragraph headline plus
operator note. PR refs (#65, #66, #67, #68, #69) added to each
entry. README now references v0.7.0 in the prose and gains a
status checklist row for the workflows-as-data + session-export +
docs-split set. Two version-pinned tests bumped to match the new
binary header.

Theme: workflows-as-data and full-session audit forensics. No
schema bump (still version: 1); all new manifest fields are
additive and parse identically against 0.6.0 manifests.

Refs agent-tasks 1fe55885.

Co-authored-by: Lan Nguyen Si <nguyen-si@publicplan.de>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants