Skip to content

fix(bin): make captain decision lookup archive-aware#901

Open
kuan0808 wants to merge 6 commits into
kunchenguid:mainfrom
kuan0808:fm/firstmate-decision-hold-archive-lookup
Open

fix(bin): make captain decision lookup archive-aware#901
kuan0808 wants to merge 6 commits into
kunchenguid:mainfrom
kuan0808:fm/firstmate-decision-hold-archive-lookup

Conversation

@kuan0808

@kuan0808 kuan0808 commented Jul 23, 2026

Copy link
Copy Markdown

Intent

Implement the minimal Firstmate-side integration for archive-aware resolved captain-decision lookup using the audited tasks-axi PR 21 pin. Durable decision identity reads must use explicit read-only tasks-axi show --include-archive --full with active-first canonical first-match behavior, while every mutation remains active-only. True absence must require the exact canonical NOT_FOUND envelope and stay distinct from missing or malformed archive-aware tool capability. Preserve active decisions, malformed records, duplicate semantics, privacy-safe output, other backends, and unrelated lifecycle behavior. Add Bash 3.2-compatible focused coverage for active hits, archive fallback, active shadowing, true misses, configured and default archive paths, capability absence, malformed output, archived mutation refusal, and a privacy-safe integration probe of the active local pin. Isolate all real-binary tests from ambient tasks-axi configuration. Keep exact mechanics in the script help/header and tests without changing tasks-axi, pin records, AGENTS.md, or policy unless semantics genuinely require it.

What Changed

  • Make durable captain-decision identity reads archive-aware with active-first lookup, strict output validation, and exact canonical NOT_FOUND handling.
  • Keep mutations active-only by rejecting archived hold changes while allowing resolved decisions to be verified and retried without archive mutation.
  • Add Bash 3.2-compatible regression coverage and documentation for archive fallback, shadowing, true misses, malformed capability output, duplicate fields, and the privacy-safe local integration probe.

Risk Assessment

✅ Low: Captain, the narrow validator fix correctly prevents malformed duplicate-title output from reaching mutation; only its recorded verification output is stale.

Testing

After inspecting the base-to-target delta and confirming Bash 3.2.57/tasks-axi 0.2.3, all focused, lifecycle, cleanup, projection, and brief suites passed; lifecycle and cleanup were rerun to definitive completion after an initial parallel yield, while a synthetic real-CLI transcript demonstrated archive fallback, active shadowing, exact miss handling, mutation refusal, and unchanged persisted files.

Evidence: Archive-aware lookup end-to-end CLI transcript
Archive-aware captain-decision lookup: end-to-end CLI evidence
Synthetic identifiers and content only; ambient tasks-axi HOME/overrides are unset.
bash: GNU bash, version 3.2.57(1)-release (arm64-apple-darwin25)
tasks-axi: 0.2.3

1) Archived record returned by the real active-first lookup:
task:
  id: demo-review-decision-route
  source: archive
  title: Synthetic resolved decision
  state: done
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: captain
  repo: sample
  priority: "-"
  created: "-"
  closed: 2026-07-23
  deps: none
  links: none
  body: "Resolution recorded by fm-decision-hold.\nDecision digest: synthetic-digest\nRouted identities: synthetic-route\n\nCaptain decision:\nUse the synthetic route.\n\nRouted work:\n- synthetic-route"

2) Firstmate durable verification succeeds from the default Done archive:
verified: demo-review unresolved-decision inventory

3) Attempting to mutate the archived identity is refused:
exit=1
fm-decision-hold: captain decision demo-review-decision-route is archived and cannot be mutated; use a new decision key for a new decision
active backlog unchanged: yes
Done archive unchanged: yes

4) A same-id active record becomes canonical and shadows archive history:
task:
  id: demo-review-decision-route
  source: active
  title: Synthetic active shadow
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: captain
  repo: sample
  priority: "-"
  created: 2026-07-23
  closed: "-"
  deps: none
  links: none
  body: ""
verification exit=1
fm-decision-hold: captain decision demo-review-decision-route is neither actively held nor durably resolved

5) True absence preserves the exact canonical envelope:
exit=1
error: "Task \"absent-synthetic-decision\" not found in this backlog"
code: NOT_FOUND
help[1]: Run `tasks-axi list` to see existing tasks

RESULT: archive fallback, active-first shadowing, exact miss handling, and active-only mutation behavior all demonstrated.

Dependency

  • tasks-axi PR 21 at unchanged audited head a2fff7a94f8bad1269e12c47b9866246d8376317 supplies show --include-archive --full plus active/archive provenance.
  • Firstmate refuses durable lookup when that capability is absent or incompatible.
  • The current local pin is temporary; an official release should replace it after parity verification.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 info
  • 🚨 bin/fm-decision-hold.sh:149 - Intent requires malformed archive-aware capability to remain distinct from absence. The new exact-one-field check omits title, although command_hold later consumes it. A malformed successful response containing duplicate title: rows can therefore pass validation and trigger tasks-axi hold; add title to the validated fields and cover this case before merging.

🔧 Fix: Reject duplicate titles before captain hold mutation
1 info still open:

  • ℹ️ docs/decision-hold-lifecycle.md:79 - This block claims to contain the test's exact summarized output, but the newly added regression prints ok - duplicate title output refuses active hold mutation and that line is missing here. Add it after the malformed-output case so the verification record remains accurate.
✅ **Test** - passed

✅ No issues found.

  • git diff --name-status 6db3b09b34dc23787969416bc4dde37adb02ac94 5e941fdbe9c3695ae4b2d984c41e0a94fabc5ccc plus implementation/test/help inspection
  • bash --version → GNU Bash 3.2.57; tasks-axi --version → 0.2.3
  • bash tests/fm-decision-hold-archive.test.sh
  • bash tests/fm-decision-hold-lifecycle.test.sh
  • bash tests/fm-teardown.test.sh
  • bash tests/fm-fleet-snapshot-view.test.sh
  • bash tests/fm-bearings-snapshot.test.sh
  • bash tests/fm-brief.test.sh
  • Isolated synthetic CLI probe using real tasks-axi: archived lookup and verification, archived mutation refusal with before/after SHA-256 checks, active-first shadowing, and exact canonical NOT_FOUND output
  • bash bin/fm-decision-hold.sh --help contract checks
  • git status --short --branch
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

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.

1 participant