flower
/
All briefs
complete draft note flower

Dogfood the decisions feature (#95) → refine → integrate decision_* into daemon/agent charters

canonical · plan

Spec

markdown

hand-off · dispatch

Dispatch

Auto-dispatch

when it reaches planned

Design-loop

design pass before build

This brief is complete — dispatch is closed.

#123 done fresh flower · flower/170-decision-charters
agent: claude 1 scratchpad
You are being dispatched from flower Brief #170: Dogfood the decisions feature (#95) → refine → integrate decision_* into daemon/agent charters

Recall pointer:
- Use recall_brief with id 170 for the full folder if you need provenance.

Target:
- project: flower (/Users/mikeferrara/Documents/code/flower)
- branch: flower/170-decision-charters
- worktree: not specified
- kind: fresh

Current brief spec:
## Goal
Dogfood the merged **decisions** feature (#95 spine) in real daemon/agent work, refine the rough edges as they surface, and — once it's proven solid — **update the charters** (spawn-packet rendering + `DaemonCharterDefaults` + `AgentConventions`) to weave `decision_*` into the right daemons/agents at the right levels. This is a **tracking + adoption** brief; the charter-integration is the eventual dispatchable deliverable, **gated on dogfooding**.

## What's shipped & dogfoodable NOW (grounded — git log + tool schemas, 2026-07-04)
- **PR-0** — `brief_questions` table + `BriefQuestion` model **renamed to `decisions` / `Decision`**. Operator-facing questions are now one unified `Decision` model: **brief-attached** decisions (via `brief_ask`) and **standalone** decisions (via `decision_ask`) share it.
- **PR-1** — decisions **spine tracer**: `decision_ask` → `/decisions` board → `decision_answer` → `recall_decisions` (pull answers addressed to your canonical `{project}-{role}` ref, delivered-once) → `decision_ack`. **`confirm` (Approve/Decline) is the only interactive affordance in PR-1.** `assigned_to` defaults to the caller's canonical ref; `is_blocking` marks caller-blocked.
- **PR-2** — Decision **events / broadcasts / auto-participant / auto-link**.

## Not yet (do NOT block dogfooding on these)
- **PR-3** — `single_choice` / `multi_choice` / `text` affordances + `options` (only `confirm` is interactive today).
- **PR-9** — standalone decision **search** (`buildDecisionChunks`, `recall_search` indexing) — `planned`.
- Remaining #95 PRs (4–8) + charter integration (this brief).

## Dogfooding plan (phased)
**Phase 1 — use it for real.** Route genuine standalone "waiting on your call" moments (NOT tied to a specific brief) through `decision_ask` (confirm-type for now); pull answers via `recall_decisions` each heartbeat + `decision_ack`. Keep brief-scoped questions on `brief_ask` (now a brief-attached `Decision`).
- **refine (me):** raise standalone operator calls via `decision_ask`; drain `recall_decisions` on the poll tick, act, `decision_ack`.
- **orchestrator / ops:** drain `recall_decisions` each heartbeat; observe routing to the correct canonical role.

**Phase 2 — capture friction.** As we use it, log: does `recall_decisions` reliably deliver to the right `{project}-{role}`? Is `confirm`-only limiting (i.e. is PR-3 needed sooner)? Is the `/decisions` board legible / does it distinguish blocking vs not? Does PR-2 auto-link attach the right context? Route real gaps to `flower_feedback`, #95 child PRs (feature gaps), or new briefs.

**Phase 3 — integrate into charters (the payoff; dispatchable once Phase 1–2 prove it).** Update spawn-packet rendering + `DaemonCharterDefaults` (+ `AgentConventions`) so decisions are woven in at the right places/levels/daemons/agents — e.g. "drain `recall_decisions` each heartbeat," "raise blocking operator calls via `decision_ask(is_blocking=true)`," and codify the split: **`brief_ask` = brief-scoped decision, `decision_ask` = standalone decision.** Coordinate with **#155** (also edits `DaemonCharterDefaults`) to avoid churn.

## Acceptance (this tracker)
- The decisions spine has been used on **real** operator calls (not synthetic), with friction captured as feedback / child-briefs.
- A concrete, agreed **charter-integration change set** is specced (which daemons/agents call which `decision_*` tools, at which loop points) and ready to dispatch.
- Feature-gap findings are routed to #95's remaining PRs; adoption/charter findings handled here.

## Relationships
- **#95** — parent decisions build (spine PR-0/1/2 merged; PR-3/PR-9 pending). This brief is adoption/dogfooding, not a build PR.
- **#155** — also edits `DaemonCharterDefaults`; sequence charter edits together.
- **#143** — adversarial review (`brief_review`) also shipped in the same wave.

## Provenance
Operator ask (2026-07-04): "check if decision_* is wired; if so, create a brief to dogfood it, refine, then update charters to get it into the mix at the appropriate places/levels/daemons/agents." Grounded by flower-refine: #95 PR-0/1/2 merged (spine live, confirm-type interactive); PR-3 (choices) / PR-9 (search) pending.

Recent/key trace events:
[3] plan_proposed flower-refine: ## Goal
Dogfood the merged **decisions** feature (#95 spine) in real daemon/agent work, refine the rough edges as they surface, and — once it's proven solid — **update the charters** (spawn-packet rendering + `DaemonCharterDefaults` + `AgentConventions`) to weave `decision_*` into the right daemons/agents at the right levels. This is a **tracking + adoption** brief; the charter-integration is the eventual dispatchable deliverable, **gated on dogfooding**.

## What's shipped & dogfoodable NOW (grounded — git log + tool schemas, 2026-07-04)
- **PR-0** — `brief_questions` table + `BriefQuestion` model **renamed to `decisions` / `Decision`**. Operator-facing questions are now one unified `Decision` model: **brief-attached** decisions (via `brief_ask`) and **standalone** decisions (via `decision_ask`) share it.
- **PR-1** — decisions **spine tracer**: `decision_ask` → `/decisions` board → `decision_answer` → `recall_decisions` (pull answers addressed to your canonical `{project}-{role}` ref, delivered-once) → `decision_ack`. **`confirm` (Approve/Decline) is the only interactive affordance in PR-1.** `assigned_to` defaults to the caller's canonical ref; `is_blocking` marks caller-blocked.
- **PR-2** — Decision **events / broadcasts / auto-participant / auto-link**.

## Not yet (do NOT block dogfooding on these)
- **PR-3** — `single_choice` / `multi_choice` / `text` affordances + `options` (only `confirm` is interactive today).
- **PR-9** — standalone decision **search** (`buildDecisionChunks`, `recall_search` indexing) — `planned`.
- Remaining #95 PRs (4–8) + charter integration (this brief).

## Dogfooding plan (phased)
**Phase 1 — use it for real.** Route genuine standalone "waiting on your call" moments (NOT tied to a specific brief) through `decision_ask` (confirm-type for now); pull answers via `recall_decisions` each heartbeat + `decision_ack`. Keep brief-scoped questions on `brief_ask` (now a brief-attached `Decision`).
- **refine (me):** raise standalone operator calls via `decision_ask`; drain `recall_decisions` on the poll tick, act, `decision_ack`.
- **orchestrator / ops:** drain `recall_decisions` each heartbeat; observe routing to the correct canonical role.

**Phase 2 — capture friction.** As we use it, log: does `recall_decisions` reliably deliver to the right `{project}-{role}`? Is `confirm`-only limiting (i.e. is PR-3 needed sooner)? Is the `/decisions` board legible / does it distinguish blocking vs not? Does PR-2 auto-link attach the right context? Route real gaps to `flower_feedback`, #95 child PRs (feature gaps), or new briefs.

**Phase 3 — integrate into charters (the payoff; dispatchable once Phase 1–2 prove it).** Update spawn-packet rendering + `DaemonCharterDefaults` (+ `AgentConventions`) so decisions are woven in at the right places/levels/daemons/agents — e.g. "drain `recall_decisions` each heartbeat," "raise blocking operator calls via `decision_ask(is_blocking=true)`," and codify the split: **`brief_ask` = brief-scoped decision, `decision_ask` = standalone decision.** Coordinate with **#155** (also edits `DaemonCharterDefaults`) to avoid churn.

## Acceptance (this tracker)
- The decisions spine has been used on **real** operator calls (not synthetic), with friction captured as feedback / child-briefs.
- A concrete, agreed **charter-integration change set** is specced (which daemons/agents call which `decision_*` tools, at which loop points) and ready to dispatch.
- Feature-gap findings are routed to #95's remaining PRs; adoption/charter findings handled here.

## Relationships
- **#95** — parent decisions build (spine PR-0/1/2 merged; PR-3/PR-9 pending). This brief is adoption/dogfooding, not a build PR.
- **#155** — also edits `DaemonCharterDefaults`; sequence charter edits together.
- **#143** — adversarial review (`brief_review`) also shipped in the same wave.

## Provenance
Operator ask (2026-07-04): "check if decision_* is wired; if so, create a brief to dogfood it, refine, then update charters to get it into the mix at the appropriate places/levels/daemons/agents." Grounded by flower-refine: #95 PR-0/1/2 merged (spine live, confirm-type interactive); PR-3 (choices) / PR-9 (search) pending.
[4] status_change flower-refine: (no body)
[5] note_added flower-refine: Phase 1 kicked off (2026-07-04). Posted the first real dogfood: **decision #33** (standalone, `confirm`) via `decision_ask` for the #36-v2 call — `assigned_to=flower-refine`, `project=flower`, `is_blocking=false`.

Observations so far:
- ✅ `decision_ask` succeeded first try — no migration error (the orchestrator's recent decisions-migration fix held).
- ✅ Correctly standalone: `subject_type` / `brief_id` null; `assigned_to` defaulted to the caller's canonical ref (`flower-refine`).
- Next: once the operator answers on `/decisions`, `recall_decisions(flower-refine)` should deliver it (released + assigned + unacked) → `decision_ack(33)` → then act on the answer (create #36 v2 or wait). Will log any delivery/routing/legibility friction here.
[6] note_added flower-refine: Phase 1 dogfood RESULT (2026-07-04) — decision #33 closed the FULL loop: `decision_ask` → operator answered on /decisions (approve) → `recall_decisions` delivered it → `decision_ack`. All four steps worked; `recall_decisions` returned 0 after ack (delivered-once ledger confirmed). Acted on the answer → created #36 v2 as brief #176 (blocked on #103).

Positive signals: `decision_ask` (standalone confirm), `recall_decisions` (both with and without the `project` filter), and `decision_ack` all worked cleanly. Release is synchronous (`released_at` == `answered_at`).

Friction captured:
1. **Pull-only latency → idea #79.** Decisions are pull-only, so the assignee is up to a full poll interval (~15m; longer dormant) behind on answers — reads to the operator as "answered but not seen." NOT a `recall_decisions` bug (verified). Suggest waking/notifying the assignee on `decision_answer` (PR-2 broadcast / poke). Ties #157/#155 (wake-on-operator-action) — this is the #1 real adoption gap.
2. **Minor:** `flower_feedback.summary` 255-char cap rejected two longer drafts with no truncation hint (noted in #79).
[7] link_added flower-refine: (no body)
[8] note_added flower-refine: **Dogfooding update (flower-refine, 2026-07-04) — the two Phase-1 frictions now appear RESOLVED, observed first-hand from the brief #226 decision loop.**

While refining #226 I processed a full 3-decision loop end-to-end as the assignee, which yields two grounding updates for this tracker:

1. **`single_choice` + `options` affordance is LIVE (part of PR-3 has shipped).** Decisions #55/#56/#57 on #226 were `decision_type=single_choice` with full `options` lists, answered by the operator on /decisions and delivered via `recall_decisions` carrying the chosen option. So this brief's "Not yet → PR-3 (only `confirm` interactive today)" grounding is now **stale for brief-attached decisions** (raised via `brief_ask`). Caveat: confirmed only for **brief-attached** decisions; whether **standalone** `decision_ask` also accepts single_choice/options is not yet verified — worth a quick check before charter wording.

2. **Wake-on-operator-answer now works — friction #1 / idea #79 (pull-only latency) appears ADDRESSED.** On the #226 answers I was woken by three `decision_wake` signals (targeted at my daemon id, one per answered decision, each naming decision_id + header + "run recall_decisions to pull and ack it"), PLUS a confirming orchestrator poke. So the assignee is no longer purely pull-latency-bound — operator answers now generate a wake. This closes the #1 adoption gap identified via decision #33.

Net: the two biggest Phase-1/2 frictions (confirm-only, pull-latency) both look resolved, which materially advances toward the **Phase 3 gate** (charter integration). Filed a positive dogfooding note to /feedback (note #111). Raising a Phase-3-go decision to the operator (next event).
[9] agent_question flower-refine: Phase-1/2 dogfooding has now closed the two main frictions (confirm-only → single_choice is live; pull-latency → decision_wake fires on answer + orchestrator poke). Per this tracker's plan, Phase 3 = spec the charter-integration change set (weave decision_* into spawn-packet rendering + DaemonCharterDefaults + AgentConventions, coordinating with #155). Proceed to Phase 3 now?
[10] participant_joined operator:mike: (no body)
[11] operator_answer operator:mike: {"choice":"Yes, but first quickly verify standalone decision_ask also supports single_choice/options, then spec Phase 3"}
[12] note_added flower-refine: **#58 answered + verify done + operator's two new feature asks (write-in / "discuss") — analysis (flower-refine, 2026-07-04)**

**Decision #58 = "Yes, but verify standalone `decision_ask` supports single_choice/options first, then spec Phase 3."** → **Verify DONE (acked):** `decision_ask` fully exposes `decision_type` (confirm | single_choice | multi_choice | text), object `options` ({key,label,recommended,detail}), `allow_write_in`, `allow_multi`, `is_blocking`, `assigned_to`, and `parent_answer_id` (follow-up threading). So standalone decisions already have the full rich affordance set. **Phase 3 gate cleared** — will spec the charter-integration change set next (grounding on #155 first for DaemonCharterDefaults sequencing).

**Operator's two new asks (raised "Re: #170"), grounded against the shipped #95 build:**

1. **Free-form write-in when the preset options don't fit.** Largely ALREADY SHIPPED: #95 **PR-3 (#119, complete)** added `allow_write_in` (commit "object options + recommended + allow_write_in") + the `text` type + the four affordances. So today: **standalone `decision_ask` supports `allow_write_in` and `text`**; **but `brief_ask` does NOT** — its MCP schema only exposes `options` + `allow_multi` (no `allow_write_in`, no per-option `recommended`, no `decision_type`). **The real gap = brief_ask ↔ decision_ask affordance parity** (a small `brief_ask` schema widening + verify the write-in box actually renders in the redesigned /decisions feed from #216). NB #196 is already parked to re-ask its Q42/43/44 using exactly these richer types once the surface is dogfooded.

2. **A "Let's talk about this" discussion-stage response.** Genuinely NEW. Distinct from the shipped **follow-up chains** (PR-6/#122), which are *daemon-initiated, post-answer*. This is *operator-initiated, pre-resolution, NON-resolving*. Strawman: a "Discuss / Clarify" affordance on any decision that posts an operator prompt, keeps the decision OPEN (does not resolve), and wakes the assigned daemon (`decision_wake` — now works) to reply via the follow-up-thread infra; the thread accumulates until the operator picks a real answer to resolve. Reuses `decision_answers` + threading + decision_wake — not a from-scratch build. Pushback/considerations: keep it BOUNDED (clarification, not open-ended chat — Solo is the durable chat bus); state stays `open`/awaiting until resolved; the daemon must be live to reply (fine now); overlaps but differs from `text` write-in (write-in RESOLVES one-shot per Q18; discuss CONTINUES). Warrants its own brief + a light design pass.

**Proposed decomposition (routing feature-gaps out of this tracker per its own plan):**
- **#170 (here):** proceed to Phase 3 charter-integration spec (the #58-authorized deliverable).
- **New #95-child (small):** `brief_ask` affordance parity with `decision_ask` (`allow_write_in` + `recommended` + `decision_type`) + verify write-in renders. Unblocks #196's parked dogfood.
- **New brief (design):** operator-initiated non-resolving "Discuss/Clarify" decision affordance.

Awaiting operator confirm on creating the two feature briefs; proceeding with Phase 3 spec regardless.
[13] plan_proposed flower-refine: **Phase 3 — decisions charter-integration change set (SPECCED, ready to dispatch). flower-refine, 2026-07-04.**

Gate cleared by decision #58 (verify done: `decision_ask` has the full rich affordance set). Grounded against #155 (COMPLETE/merged, commit 8c58c6f): the auto-arm work already rewrote the exact files this touches, so Phase 3 builds ON TOP of charter **v4**.

### Where (files)
- `app/Support/DaemonCharterDefaults.php` — **bump version v4 → v5** (so `PromptTemplateSeeder` re-plants).
- `app/Support/AgentConventions.php`.
- `app/Services/Daemons/SpawnPacketService.php` (spawn-packet kickoff text).
- Tests: `DaemonCharterDefaultsTest`, `AgentConventionsTest`, `SpawnPacketServiceTest`.
- **MANDATORY post-merge on MAIN:** re-seed `PromptTemplateSeeder` (same P1 gate as #155 — charters live in `prompt_templates` DB; skipping it means newly-spawned daemons get stale v4 bodies with no decision guidance).

### What to weave in (the decision_* conventions)
1. **Loop point — drain answered decisions every heartbeat/wake.** All roles + AgentConventions: "On each heartbeat AND every wake, if you have answered decisions: `recall_decisions(actor_ref=<canonical {project}-{role}>)` → act → `decision_ack` each. `decision_wake` also arrives as an orchestrator poke — handle it on that wake." (Currently practiced ad hoc; codify it.)
2. **Codify the ask-split** (AgentConventions + per-role):
   - **Brief-scoped question** (about a specific brief) → `brief_ask` (brief-attached decision).
   - **Standalone "waiting on your call"** (not tied to a brief) → `decision_ask`, picking `decision_type` (confirm | single_choice | multi_choice | text), `allow_write_in` when preset options may not fit, `recommended` on the best option, `is_blocking=true` only when genuinely blocked.
   - **Known asymmetry to note in-charter:** `brief_ask` lacks write-in/recommended/type today → prefer `decision_ask` when you need rich affordances until the parity fix (feature follow-up #1) lands.
3. **Blocking semantics:** `is_blocking=true` only when the daemon truly can't proceed; else non-blocking so it keeps doing other work while awaiting (matches how I ran #226/#170 non-blocking).
4. **Reset inheritance:** decisions are role-addressed (`{project}-{role}`), so a reset successor inherits unacked decisions — codify "on boot, `recall_decisions` to pick up anything inherited" (exactly what happened this session).
5. **Role placement:** orchestrator already drains `recall_signals` incl. delivering `decision_wake` pokes — add draining its own role's `recall_decisions`; ops/refine/other + spawn-packet kickoff get the drain + ask-split lines.

### Sequencing / scope
- Mechanical charter-text + conventions + tests (like #155) → **does NOT need a design-loop**; spec → `planned` → normal single-worker dispatch, authored against current master.
- Soft-depends on feature follow-up #1 (`brief_ask` parity) but does NOT block on it — charter ships pointing to `decision_ask` for rich affordances now, tightened once parity lands.
- The "Discuss/Clarify" feature (follow-up #2) is out of scope here; charter gets a one-line touch-up once it ships.

Moving #170 → `planned`. NO auto-dispatch (not flagged); orchestrator owns the dispatch. The two feature follow-ups remain pending operator confirm (separate briefs).
[14] status_change flower-refine: (no body)

Recommended linked context:
{
    "todos": [],
    "scratchpads": [
        {
            "id": 378,
            "solo_scratchpad_id": "1070",
            "name": "flower-refine — reset handoff (2026-07-04)",
            "archived": false,
            "revision": 2
        }
    ]
}

Execution notes:
- Treat the brief as the source of truth.
- Keep work scoped to this dispatch request.
- Use brief_append / brief_update_status when reporting material progress; as your final dispatched-worker step, call brief_dispatch_complete with dispatch_request_id (or brief_id) and actor_ref.
- Codex workers should verify mutating Flower tools with tool_search query `brief_append brief_dispatch_complete flower_feedback` (limit 20) when tool availability is in doubt; report raw SEE/LOAD vs NOT visible instead of silently using local fallbacks.
- Add a git commit trailer `Brief: #170` to every commit for this brief so flower can exact-link commits back to the brief.

provenance · append-only

Trace

live
or paste a screenshot uploading…
  1. link added 20h ago
    agent · system:commit-trailer
  2. participant joined 20h ago
    system · system:commit-trailer
  3. merged 21h ago

    Merged flower/170-decision-charters (weave decision_* into daemon/agent charters — DaemonCharterDefaults v4→v5, reset-successor recall_decisions grounding, dropped #228 parity caveat) to master by flower-orchestrator (daemon 40). Suite green 1221. POST-MERGE: ran PromptTemplateSeeder --force so new daemons render v5 bodies. Standing daemons pick up v5 on next reset.

    agent · flower-orchestrator
  4. status change 21h ago
    agent · flower-170-worker
  5. dispatched 21h ago

    Dispatch request #123 marked done.

    agent · flower-170-worker
  6. note added 21h ago

    **Phase 3 BUILT + committed (flower-170-worker, 2026-07-04).** Branch `flower/170-decision-charters` (off master @ 6ec9ea5), commit **c34e2dd** (`Brief: #170`). Built exactly the refine-specced charter-integration change set (event 2897) on charter **v4** → bumped to **v5**. Additive + backward-compatible: no charter keys renamed, all existing charter tests preserved, seed counts unchanged (still 4 roles). **What landed:** - **`AgentConventions::daemonLines()`** (shared block — renders into ALL role charters via `{{daemon_conventions}}`, so live effect on next spawn/reset with NO re-seed): (1) drain answered decisions each heartbeat AND every wake — `recall_decisions(actor_ref) → act → decision_ack` (delivered-once ledger), incl. `decision_wake` poke handling; (2) reset-inheritance — role-addressed decisions survive a reset, pull `recall_decisions` on boot; (3) the ask-split — brief-scoped → `brief_ask`, standalone → `decision_ask`, both now sharing the full `confirm|single_choice|multi_choice|text` + `options/recommended/allow_write_in` set, `is_blocking` only when truly blocked. - **`AgentConventions::workingAgentLines()`** — dispatched-worker ask-split line (`brief_ask` vs `decision_ask`). - **`DaemonCharterDefaults`** (v4→v5, needs re-seed): orchestrator loop-1 drains its own decisions + delivers `decision_wake` pokes; ops cycle-6 drains each cycle/wake; refine ask-step codifies the split + drain. Lead unchanged (already escalates via `decision_ask`; inherits shared block). - **`SpawnPacketService`** — reset-successor grounding pulls `recall_decisions` for inherited unacked decisions. **#228 parity applied:** dropped the stale "prefer decision_ask until parity" caveat — charter now states brief_ask ↔ decision_ask parity directly (both expose the full affordance set). **Tests:** bumped v4→v5 assertions (3 spots) + the dispatch golden fixture; added decision-convention coverage to AgentConventionsTest / DaemonCharterDefaultsTest / SpawnPacketServiceTest (incl. a rendered-charter expansion test). Full suite **GREEN (1214 passed, 1 pre-existing skip)**, pint clean. **⚠️ MANDATORY post-merge on MAIN (same P1 gate as #155):** after merge, **re-seed `PromptTemplateSeeder`** so newly-spawned daemons render the v5 bodies (the v5 bodies live in the `prompt_templates` DB; the shared-block additions render live but the per-role body anchors need the re-plant). Coordinate charter-body sequencing with #155 (already merged/complete — this builds on top of its v4). Did NOT merge — leaving that + the re-seed to the orchestrator on MAIN.

    agent · flower-170-worker
  7. participant joined 21h ago
    system · flower-170-worker
  8. dispatched 21h ago

    Dispatch request #123 queued for flower.

    agent · flower-orchestrator
  9. status change 21h ago
    agent · flower-orchestrator
  10. participant joined 21h ago
    system · flower-orchestrator
  11. status change 1d ago
    agent · flower-refine
  12. plan proposed 1d ago

    **Phase 3 — decisions charter-integration change set (SPECCED, ready to dispatch). flower-refine, 2026-07-04.** Gate cleared by decision #58 (verify done: `decision_ask` has the full rich affordance set). Grounded against #155 (COMPLETE/merged, commit 8c58c6f): the auto-arm work already rewrote the exact files this touches, so Phase 3 builds ON TOP of charter **v4**. ### Where (files) - `app/Support/DaemonCharterDefaults.php` — **bump version v4 → v5** (so `PromptTemplateSeeder` re-plants). - `app/Support/AgentConventions.php`. - `app/Services/Daemons/SpawnPacketService.php` (spawn-packet kickoff text). - Tests: `DaemonCharterDefaultsTest`, `AgentConventionsTest`, `SpawnPacketServiceTest`. - **MANDATORY post-merge on MAIN:** re-seed `PromptTemplateSeeder` (same P1 gate as #155 — charters live in `prompt_templates` DB; skipping it means newly-spawned daemons get stale v4 bodies with no decision guidance). ### What to weave in (the decision_* conventions) 1. **Loop point — drain answered decisions every heartbeat/wake.** All roles + AgentConventions: "On each heartbeat AND every wake, if you have answered decisions: `recall_decisions(actor_ref=<canonical {project}-{role}>)` → act → `decision_ack` each. `decision_wake` also arrives as an orchestrator poke — handle it on that wake." (Currently practiced ad hoc; codify it.) 2. **Codify the ask-split** (AgentConventions + per-role): - **Brief-scoped question** (about a specific brief) → `brief_ask` (brief-attached decision). - **Standalone "waiting on your call"** (not tied to a brief) → `decision_ask`, picking `decision_type` (confirm | single_choice | multi_choice | text), `allow_write_in` when preset options may not fit, `recommended` on the best option, `is_blocking=true` only when genuinely blocked. - **Known asymmetry to note in-charter:** `brief_ask` lacks write-in/recommended/type today → prefer `decision_ask` when you need rich affordances until the parity fix (feature follow-up #1) lands. 3. **Blocking semantics:** `is_blocking=true` only when the daemon truly can't proceed; else non-blocking so it keeps doing other work while awaiting (matches how I ran #226/#170 non-blocking). 4. **Reset inheritance:** decisions are role-addressed (`{project}-{role}`), so a reset successor inherits unacked decisions — codify "on boot, `recall_decisions` to pick up anything inherited" (exactly what happened this session). 5. **Role placement:** orchestrator already drains `recall_signals` incl. delivering `decision_wake` pokes — add draining its own role's `recall_decisions`; ops/refine/other + spawn-packet kickoff get the drain + ask-split lines. ### Sequencing / scope - Mechanical charter-text + conventions + tests (like #155) → **does NOT need a design-loop**; spec → `planned` → normal single-worker dispatch, authored against current master. - Soft-depends on feature follow-up #1 (`brief_ask` parity) but does NOT block on it — charter ships pointing to `decision_ask` for rich affordances now, tightened once parity lands. - The "Discuss/Clarify" feature (follow-up #2) is out of scope here; charter gets a one-line touch-up once it ships. Moving #170 → `planned`. NO auto-dispatch (not flagged); orchestrator owns the dispatch. The two feature follow-ups remain pending operator confirm (separate briefs).

    agent · flower-refine
  13. note added 1d ago

    **#58 answered + verify done + operator's two new feature asks (write-in / "discuss") — analysis (flower-refine, 2026-07-04)** **Decision #58 = "Yes, but verify standalone `decision_ask` supports single_choice/options first, then spec Phase 3."** → **Verify DONE (acked):** `decision_ask` fully exposes `decision_type` (confirm | single_choice | multi_choice | text), object `options` ({key,label,recommended,detail}), `allow_write_in`, `allow_multi`, `is_blocking`, `assigned_to`, and `parent_answer_id` (follow-up threading). So standalone decisions already have the full rich affordance set. **Phase 3 gate cleared** — will spec the charter-integration change set next (grounding on #155 first for DaemonCharterDefaults sequencing). **Operator's two new asks (raised "Re: #170"), grounded against the shipped #95 build:** 1. **Free-form write-in when the preset options don't fit.** Largely ALREADY SHIPPED: #95 **PR-3 (#119, complete)** added `allow_write_in` (commit "object options + recommended + allow_write_in") + the `text` type + the four affordances. So today: **standalone `decision_ask` supports `allow_write_in` and `text`**; **but `brief_ask` does NOT** — its MCP schema only exposes `options` + `allow_multi` (no `allow_write_in`, no per-option `recommended`, no `decision_type`). **The real gap = brief_ask ↔ decision_ask affordance parity** (a small `brief_ask` schema widening + verify the write-in box actually renders in the redesigned /decisions feed from #216). NB #196 is already parked to re-ask its Q42/43/44 using exactly these richer types once the surface is dogfooded. 2. **A "Let's talk about this" discussion-stage response.** Genuinely NEW. Distinct from the shipped **follow-up chains** (PR-6/#122), which are *daemon-initiated, post-answer*. This is *operator-initiated, pre-resolution, NON-resolving*. Strawman: a "Discuss / Clarify" affordance on any decision that posts an operator prompt, keeps the decision OPEN (does not resolve), and wakes the assigned daemon (`decision_wake` — now works) to reply via the follow-up-thread infra; the thread accumulates until the operator picks a real answer to resolve. Reuses `decision_answers` + threading + decision_wake — not a from-scratch build. Pushback/considerations: keep it BOUNDED (clarification, not open-ended chat — Solo is the durable chat bus); state stays `open`/awaiting until resolved; the daemon must be live to reply (fine now); overlaps but differs from `text` write-in (write-in RESOLVES one-shot per Q18; discuss CONTINUES). Warrants its own brief + a light design pass. **Proposed decomposition (routing feature-gaps out of this tracker per its own plan):** - **#170 (here):** proceed to Phase 3 charter-integration spec (the #58-authorized deliverable). - **New #95-child (small):** `brief_ask` affordance parity with `decision_ask` (`allow_write_in` + `recommended` + `decision_type`) + verify write-in renders. Unblocks #196's parked dogfood. - **New brief (design):** operator-initiated non-resolving "Discuss/Clarify" decision affordance. Awaiting operator confirm on creating the two feature briefs; proceeding with Phase 3 spec regardless.

    agent · flower-refine
  14. operator answer 1d ago

    {"choice":"Yes, but first quickly verify standalone decision_ask also supports single_choice/options, then spec Phase 3"}

    operator · operator:mike
  15. participant joined 1d ago
    system · operator:mike
  16. agent question 1d ago

    Phase-1/2 dogfooding has now closed the two main frictions (confirm-only → single_choice is live; pull-latency → decision_wake fires on answer + orchestrator poke). Per this tracker's plan, Phase 3 = spec the charter-integration change set (weave decision_* into spawn-packet rendering + DaemonCharterDefaults + AgentConventions, coordinating with #155). Proceed to Phase 3 now?

    agent · flower-refine
  17. note added 1d ago

    **Dogfooding update (flower-refine, 2026-07-04) — the two Phase-1 frictions now appear RESOLVED, observed first-hand from the brief #226 decision loop.** While refining #226 I processed a full 3-decision loop end-to-end as the assignee, which yields two grounding updates for this tracker: 1. **`single_choice` + `options` affordance is LIVE (part of PR-3 has shipped).** Decisions #55/#56/#57 on #226 were `decision_type=single_choice` with full `options` lists, answered by the operator on /decisions and delivered via `recall_decisions` carrying the chosen option. So this brief's "Not yet → PR-3 (only `confirm` interactive today)" grounding is now **stale for brief-attached decisions** (raised via `brief_ask`). Caveat: confirmed only for **brief-attached** decisions; whether **standalone** `decision_ask` also accepts single_choice/options is not yet verified — worth a quick check before charter wording. 2. **Wake-on-operator-answer now works — friction #1 / idea #79 (pull-only latency) appears ADDRESSED.** On the #226 answers I was woken by three `decision_wake` signals (targeted at my daemon id, one per answered decision, each naming decision_id + header + "run recall_decisions to pull and ack it"), PLUS a confirming orchestrator poke. So the assignee is no longer purely pull-latency-bound — operator answers now generate a wake. This closes the #1 adoption gap identified via decision #33. Net: the two biggest Phase-1/2 frictions (confirm-only, pull-latency) both look resolved, which materially advances toward the **Phase 3 gate** (charter integration). Filed a positive dogfooding note to /feedback (note #111). Raising a Phase-3-go decision to the operator (next event).

    agent · flower-refine
  18. link added 1d ago
    agent · flower-refine
  19. note added 1d ago

    Phase 1 dogfood RESULT (2026-07-04) — decision #33 closed the FULL loop: `decision_ask` → operator answered on /decisions (approve) → `recall_decisions` delivered it → `decision_ack`. All four steps worked; `recall_decisions` returned 0 after ack (delivered-once ledger confirmed). Acted on the answer → created #36 v2 as brief #176 (blocked on #103). Positive signals: `decision_ask` (standalone confirm), `recall_decisions` (both with and without the `project` filter), and `decision_ack` all worked cleanly. Release is synchronous (`released_at` == `answered_at`). Friction captured: 1. **Pull-only latency → idea #79.** Decisions are pull-only, so the assignee is up to a full poll interval (~15m; longer dormant) behind on answers — reads to the operator as "answered but not seen." NOT a `recall_decisions` bug (verified). Suggest waking/notifying the assignee on `decision_answer` (PR-2 broadcast / poke). Ties #157/#155 (wake-on-operator-action) — this is the #1 real adoption gap. 2. **Minor:** `flower_feedback.summary` 255-char cap rejected two longer drafts with no truncation hint (noted in #79).

    agent · flower-refine
  20. note added 1d ago

    Phase 1 kicked off (2026-07-04). Posted the first real dogfood: **decision #33** (standalone, `confirm`) via `decision_ask` for the #36-v2 call — `assigned_to=flower-refine`, `project=flower`, `is_blocking=false`. Observations so far: - ✅ `decision_ask` succeeded first try — no migration error (the orchestrator's recent decisions-migration fix held). - ✅ Correctly standalone: `subject_type` / `brief_id` null; `assigned_to` defaulted to the caller's canonical ref (`flower-refine`). - Next: once the operator answers on `/decisions`, `recall_decisions(flower-refine)` should deliver it (released + assigned + unacked) → `decision_ack(33)` → then act on the answer (create #36 v2 or wait). Will log any delivery/routing/legibility friction here.

    agent · flower-refine
  21. status change 1d ago
    agent · flower-refine
  22. plan proposed 1d ago

    ## Goal Dogfood the merged **decisions** feature (#95 spine) in real daemon/agent work, refine the rough edges as they surface, and — once it's proven solid — **update the charters** (spawn-packet rendering + `DaemonCharterDefaults` + `AgentConventions`) to weave `decision_*` into the right daemons/agents at the right levels. This is a **tracking + adoption** brief; the charter-integration is the eventual dispatchable deliverable, **gated on dogfooding**. ## What's shipped & dogfoodable NOW (grounded — git log + tool schemas, 2026-07-04) - **PR-0** — `brief_questions` table + `BriefQuestion` model **renamed to `decisions` / `Decision`**. Operator-facing questions are now one unified `Decision` model: **brief-attached** decisions (via `brief_ask`) and **standalone** decisions (via `decision_ask`) share it. - **PR-1** — decisions **spine tracer**: `decision_ask` → `/decisions` board → `decision_answer` → `recall_decisions` (pull answers addressed to your canonical `{project}-{role}` ref, delivered-once) → `decision_ack`. **`confirm` (Approve/Decline) is the only interactive affordance in PR-1.** `assigned_to` defaults to the caller's canonical ref; `is_blocking` marks caller-blocked. - **PR-2** — Decision **events / broadcasts / auto-participant / auto-link**. ## Not yet (do NOT block dogfooding on these) - **PR-3** — `single_choice` / `multi_choice` / `text` affordances + `options` (only `confirm` is interactive today). - **PR-9** — standalone decision **search** (`buildDecisionChunks`, `recall_search` indexing) — `planned`. - Remaining #95 PRs (4–8) + charter integration (this brief). ## Dogfooding plan (phased) **Phase 1 — use it for real.** Route genuine standalone "waiting on your call" moments (NOT tied to a specific brief) through `decision_ask` (confirm-type for now); pull answers via `recall_decisions` each heartbeat + `decision_ack`. Keep brief-scoped questions on `brief_ask` (now a brief-attached `Decision`). - **refine (me):** raise standalone operator calls via `decision_ask`; drain `recall_decisions` on the poll tick, act, `decision_ack`. - **orchestrator / ops:** drain `recall_decisions` each heartbeat; observe routing to the correct canonical role. **Phase 2 — capture friction.** As we use it, log: does `recall_decisions` reliably deliver to the right `{project}-{role}`? Is `confirm`-only limiting (i.e. is PR-3 needed sooner)? Is the `/decisions` board legible / does it distinguish blocking vs not? Does PR-2 auto-link attach the right context? Route real gaps to `flower_feedback`, #95 child PRs (feature gaps), or new briefs. **Phase 3 — integrate into charters (the payoff; dispatchable once Phase 1–2 prove it).** Update spawn-packet rendering + `DaemonCharterDefaults` (+ `AgentConventions`) so decisions are woven in at the right places/levels/daemons/agents — e.g. "drain `recall_decisions` each heartbeat," "raise blocking operator calls via `decision_ask(is_blocking=true)`," and codify the split: **`brief_ask` = brief-scoped decision, `decision_ask` = standalone decision.** Coordinate with **#155** (also edits `DaemonCharterDefaults`) to avoid churn. ## Acceptance (this tracker) - The decisions spine has been used on **real** operator calls (not synthetic), with friction captured as feedback / child-briefs. - A concrete, agreed **charter-integration change set** is specced (which daemons/agents call which `decision_*` tools, at which loop points) and ready to dispatch. - Feature-gap findings are routed to #95's remaining PRs; adoption/charter findings handled here. ## Relationships - **#95** — parent decisions build (spine PR-0/1/2 merged; PR-3/PR-9 pending). This brief is adoption/dogfooding, not a build PR. - **#155** — also edits `DaemonCharterDefaults`; sequence charter edits together. - **#143** — adversarial review (`brief_review`) also shipped in the same wave. ## Provenance Operator ask (2026-07-04): "check if decision_* is wired; if so, create a brief to dogfood it, refine, then update charters to get it into the mix at the appropriate places/levels/daemons/agents." Grounded by flower-refine: #95 PR-0/1/2 merged (spine live, confirm-type interactive); PR-3 (choices) / PR-9 (search) pending.

    agent · flower-refine
  23. note added 1d ago

    Operator ask (2026-07-04): the decisions feature (#95) spine is merged and wired — dogfood it in real daemon/agent work, refine rough edges as they surface, and when it's solid update the charters to weave decision_* into the right daemons/agents at the right levels. This brief tracks that arc (dogfood → refine → charter-integrate).

    agent · flower-refine
  24. participant joined 1d ago
    system · flower-refine

epic · dependencies

Relationships

epic parent

depends on

No dependencies — dispatchable once planned.

agents · waves

Participants

  • flower-refine participant · active
  • operator:mike participant · active
  • flower-orchestrator participant · active
  • flower-170-worker participant · active
  • system:commit-trailer participant · active

trace · graph

Links

  • Commit #4055 execution
  • Scratchpad #378 execution

scope

Projects

  • flower · primary

dogfood · read-only

Agent’s-eye view

The literal recall_brief payload an agent gets — same service path as the MCP tool.