Skip to content

feat: surface post_condition symmetrically with pre_condition#8

Merged
santoshkumarradha merged 1 commit into
mainfrom
feat/post-condition-surfacing
Apr 20, 2026
Merged

feat: surface post_condition symmetrically with pre_condition#8
santoshkumarradha merged 1 commit into
mainfrom
feat/post-condition-surfacing

Conversation

@santoshkumarradha
Copy link
Copy Markdown
Member

Summary

post_condition is stored on every task and emitted in JSON payloads but is invisible in the text output an agent actually reads during claim and completion. Only pre_condition printed on go, creating an asymmetry: agents had to remember to request JSON mode to see their own acceptance criteria. This PR closes that gap with a pure surfacing change — zero schema impact.

What changes

  • plandb go prints post-condition (acceptance): … right after pre-condition: …. Declarative, not executed (that's post_hook's role).
  • plandb done missing---result hint now fires when either downstream dependents exist or a post_condition is set, and names the reason so the agent understands why.
  • The pre-existing trailing post-condition: … echo on done is kept — it reads as a verification reminder at the moment the transition commits.

Why this shape

pre_condition / post_condition are the declarative half of the pair — shown to the agent, agent self-verifies. pre_hook / post_hook are the executable half — shell hooks that actually run and warn on failure. We already had the executable side symmetric. The declarative side was half-wired: stored, emitted in JSON, but never printed on go. This PR restores symmetry with one eprintln! and one hint extension.

Follow-up roadmap (NOT in this PR — deliberate)

While auditing the surfacing model I inventoried everything an agent stores vs. what's auto-injected at claim time. Opening this as a separate investigation. Below is the product-level verdict per candidate, scored on "does it earn its context cost?":

Candidate Where to surface Cost Verdict
Upstream artifacts Inline with existing handoff line: t-xyz → <result> [artifacts: report.md, data.csv] +1 line per upstream, only if artifacts exist Ship next — handoff already there, trivial extension, high ROI
Retry context On reclaim only: previously failed: <last_error first 120ch> 0 lines normally, 1 line on retry Ship next — surgical, fires exactly when useful
Parent framing (for subtasks) parent: t-abc "<title>" at claim 1 line for subtasks, 0 for roots Worth it — cheap situational anchor
Upstream task_files upstream touched: src/foo.rs, src/bar.rs alongside handoff 1 line if set Worth it — saves agent re-discovering scope
Sibling done-count (composites) siblings: 3/5 done — count only, no titles 1 line for subtasks in composites Worth it — 1 token of coordination
Learnings BM25 recall pooled into existing context slot on go 0 net (pools) Needs decision — either lazy-recall like context, or deprecate the table. Currently write-only.
progress_note on resume Only when task was paused: resumed: <note> 0 lines normally, 1 on resume Worth it — critical on resume, invisible otherwise
Full event history Never auto Skip — bloat with ~0 signal; agent queries events if debugging
Metadata blob Never auto Skip — freeform, no shape
Non-dep sibling results Never Skip — violates the dep model; if needed, add the edge
Mid-task recall Never auto Skip — agent calls search itself when context shifts

Budget: worst-case addition to the go payload is ~6 lines on top of today's ~10-15. The rule applied throughout: nothing surfaces unless an agent would regret not having it the moment after claim. History, siblings-full, metadata all fail that test. Retry context, parent framing, upstream artifacts all pass it.

Test plan

  • cargo build — green
  • cargo test — 8/8 pass
  • bash tests/functional_test.sh — 131/131 pass (added 3 assertions for text-mode surfacing)
  • Manually verified: task without post_condition sees no extra output (no spurious blank lines)

post_condition was stored on tasks and emitted in JSON payloads but
never shown in the text output an agent sees when claiming or
completing a task. Only pre_condition printed on `go`, so agents had
to opt into JSON mode to see their own acceptance criteria.

Changes:
- `plandb go` now prints post_condition as "post-condition (acceptance)"
  right after pre_condition. Symmetric with how pre is already handled.
- `plandb done` missing-result hint now mentions post_condition so the
  agent knows a verifiable result is expected (previously only fired
  when downstream dependents existed).
- The existing trailing echo of post_condition on done transition is
  preserved — it reads as a verification reminder.

Zero schema change. Pure surfacing fix. JSON payload unchanged.

Test: tests/functional_test.sh adds three assertions verifying the
text-mode output on go/done.
@santoshkumarradha santoshkumarradha force-pushed the feat/post-condition-surfacing branch from 4f6b318 to 29342f3 Compare April 20, 2026 23:50
@santoshkumarradha santoshkumarradha merged commit ae832ba into main Apr 20, 2026
3 checks passed
@santoshkumarradha santoshkumarradha deleted the feat/post-condition-surfacing branch April 20, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant