flower
/
All briefs
complete draft note flower

Fix PromptTemplateSeeder: default summarizer to DeepSeek + stop clobbering operator model overrides

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.

#57 done fresh flower · flower/162-seeder-deepseek-default
agent: claude
You are being dispatched from flower Brief #162: Fix PromptTemplateSeeder: default summarizer to DeepSeek + stop clobbering operator model overrides

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

Target:
- project: flower (/Users/mikeferrara/Documents/code/flower)
- branch: flower/162-seeder-deepseek-default
- worktree: not specified
- kind: fresh

Current brief spec:
## Objective
Make the segment_summary summarizer default to DeepSeek (OpenRouter/json) and stop the seeder from silently reverting an operator-chosen provider/model on re-seed.

## Problem (incident 2026-07-03, root cause of feedback #74)
`database/seeders/PromptTemplateSeeder.php` (L28-29) hardcodes the segment_summary default as provider=anthropic, model=claude-opus-4-8, via updateOrCreate keyed on 'segment_summary.default'. So ANY re-seed overwrites the live prompt_templates row (id=1) back to Opus. On 2026-07-03 15:41 a re-seed (likely during DB backup/restore work, commit fa5465d) clobbered the operator's deliberate deepseek/deepseek-v4-flash selection (set 2026-06-29 via Config UI, session 737) back to Opus. With the ANTHROPIC_API_KEY account out of credits, every SegmentSession job then threw InsufficientCreditsException (Sentry FLOWER-B) → sessions ingested but never segmented/indexed (operator saw this as #74 "Ingest broken?"). Ops applied the RUNTIME fix (reverted row id=1 to openrouter/deepseek-v4-flash + `queue:retry all`, failed_jobs 57→0, pipeline recovered). THIS brief is the durable code fix.

## Fix
1. Change the seeder's segment_summary default to provider=openrouter, model=deepseek/deepseek-v4-flash (json mode) — the intended production default. Prefer sourcing it from config (one source of truth, e.g. a `default` flag on a config('flower.summarize.models') entry) rather than a second hardcode.
2. Make the seed NON-CLOBBERING for provider/model: on re-seed, do NOT overwrite an existing row's provider/model (operator override wins) — create-only for those two fields, while still updating code-owned prompt body/schema fields.
3. Address the fallback: config/ai.php `'default' => env('AI_DEFAULT_PROVIDER','anthropic')` with AI_DEFAULT_PROVIDER unset means a blank-provider template silently falls back to anthropic. Either set AI_DEFAULT_PROVIDER=openrouter in .env(.example) or ensure the summary template always carries an explicit provider.

## Constraints / non-goals
- Don't change the live prompt text/schema seeding behavior, only the provider/model default + the clobber-guard.
- Add a test: re-running the seeder must NOT change an operator-set provider/model.

## Definition of done
Seeder default = deepseek; re-seed preserves an operator-set provider/model; test covers the non-clobber; verified `db:seed --class=PromptTemplateSeeder` on a row set to a custom model leaves provider/model intact.

Recent/key trace events:
[1] participant_joined flower-ops: (no body)
[2] note_added flower-ops: ## Objective
Make the segment_summary summarizer default to DeepSeek (OpenRouter/json) and stop the seeder from silently reverting an operator-chosen provider/model on re-seed.

## Problem (incident 2026-07-03, root cause of feedback #74)
`database/seeders/PromptTemplateSeeder.php` (L28-29) hardcodes the segment_summary default as provider=anthropic, model=claude-opus-4-8, via updateOrCreate keyed on 'segment_summary.default'. So ANY re-seed overwrites the live prompt_templates row (id=1) back to Opus. On 2026-07-03 15:41 a re-seed (likely during DB backup/restore work, commit fa5465d) clobbered the operator's deliberate deepseek/deepseek-v4-flash selection (set 2026-06-29 via Config UI, session 737) back to Opus. With the ANTHROPIC_API_KEY account out of credits, every SegmentSession job then threw InsufficientCreditsException (Sentry FLOWER-B) → sessions ingested but never segmented/indexed (operator saw this as #74 "Ingest broken?"). Ops applied the RUNTIME fix (reverted row id=1 to openrouter/deepseek-v4-flash + `queue:retry all`, failed_jobs 57→0, pipeline recovered). THIS brief is the durable code fix.

## Fix
1. Change the seeder's segment_summary default to provider=openrouter, model=deepseek/deepseek-v4-flash (json mode) — the intended production default. Prefer sourcing it from config (one source of truth, e.g. a `default` flag on a config('flower.summarize.models') entry) rather than a second hardcode.
2. Make the seed NON-CLOBBERING for provider/model: on re-seed, do NOT overwrite an existing row's provider/model (operator override wins) — create-only for those two fields, while still updating code-owned prompt body/schema fields.
3. Address the fallback: config/ai.php `'default' => env('AI_DEFAULT_PROVIDER','anthropic')` with AI_DEFAULT_PROVIDER unset means a blank-provider template silently falls back to anthropic. Either set AI_DEFAULT_PROVIDER=openrouter in .env(.example) or ensure the summary template always carries an explicit provider.

## Constraints / non-goals
- Don't change the live prompt text/schema seeding behavior, only the provider/model default + the clobber-guard.
- Add a test: re-running the seeder must NOT change an operator-set provider/model.

## Definition of done
Seeder default = deepseek; re-seed preserves an operator-set provider/model; test covers the non-clobber; verified `db:seed --class=PromptTemplateSeeder` on a row set to a custom model leaves provider/model intact.
[3] plan_proposed flower-ops: ## Objective
Make the segment_summary summarizer default to DeepSeek (OpenRouter/json) and stop the seeder from silently reverting an operator-chosen provider/model on re-seed.

## Problem (incident 2026-07-03, root cause of feedback #74)
`database/seeders/PromptTemplateSeeder.php` (L28-29) hardcodes the segment_summary default as provider=anthropic, model=claude-opus-4-8, via updateOrCreate keyed on 'segment_summary.default'. So ANY re-seed overwrites the live prompt_templates row (id=1) back to Opus. On 2026-07-03 15:41 a re-seed (likely during DB backup/restore work, commit fa5465d) clobbered the operator's deliberate deepseek/deepseek-v4-flash selection (set 2026-06-29 via Config UI, session 737) back to Opus. With the ANTHROPIC_API_KEY account out of credits, every SegmentSession job then threw InsufficientCreditsException (Sentry FLOWER-B) → sessions ingested but never segmented/indexed (operator saw this as #74 "Ingest broken?"). Ops applied the RUNTIME fix (reverted row id=1 to openrouter/deepseek-v4-flash + `queue:retry all`, failed_jobs 57→0, pipeline recovered). THIS brief is the durable code fix.

## Fix
1. Change the seeder's segment_summary default to provider=openrouter, model=deepseek/deepseek-v4-flash (json mode) — the intended production default. Prefer sourcing it from config (one source of truth, e.g. a `default` flag on a config('flower.summarize.models') entry) rather than a second hardcode.
2. Make the seed NON-CLOBBERING for provider/model: on re-seed, do NOT overwrite an existing row's provider/model (operator override wins) — create-only for those two fields, while still updating code-owned prompt body/schema fields.
3. Address the fallback: config/ai.php `'default' => env('AI_DEFAULT_PROVIDER','anthropic')` with AI_DEFAULT_PROVIDER unset means a blank-provider template silently falls back to anthropic. Either set AI_DEFAULT_PROVIDER=openrouter in .env(.example) or ensure the summary template always carries an explicit provider.

## Constraints / non-goals
- Don't change the live prompt text/schema seeding behavior, only the provider/model default + the clobber-guard.
- Add a test: re-running the seeder must NOT change an operator-set provider/model.

## Definition of done
Seeder default = deepseek; re-seed preserves an operator-set provider/model; test covers the non-clobber; verified `db:seed --class=PromptTemplateSeeder` on a row set to a custom model leaves provider/model intact.
[4] status_change flower-ops: (no body)

Recommended linked context:
{
    "todos": [],
    "scratchpads": []
}

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: #162` 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. merged 1d ago

    Merged to MAIN as 6cd3745 (branch flower/162-seeder-deepseek-default, worker commit 741ab22). Suite green on MAIN: 772/770 (2 skips, 5151 assertions). No re-seed was run, so the operator's live prompt_templates row id=1 (openrouter/deepseek-v4-flash) is untouched — the fix guards FUTURE re-seeds from clobbering it. Also hardened AiSegmentSummarizer (+21 lines, explicit-provider fallback): that's job code, so a Horizon reload will pick it up, but current summarizer behavior is already correct (reads the live deepseek row), so no urgent reload.

    agent · flower-orchestrator
  2. link added 1d ago
    agent · system:commit-trailer
  3. participant joined 1d ago
    system · system:commit-trailer
  4. note added 1d ago

    Done — seeder fix shipped on branch flower/162-seeder-deepseek-default (commit 741ab22). What changed: 1. config/flower.php — flagged the DeepSeek entry `default => true` in summarize.models (single source of truth for the production summary default). 2. AiSegmentSummarizer::defaultSummaryModel() — new static helper resolving provider/model from the flagged config entry (fallback: first entry → hardcoded deepseek/deepseek-v4-flash). 3. database/seeders/PromptTemplateSeeder.php — segment_summary now seeds NON-CLOBBERING: firstOrNew, sets provider/model from the config default ONLY when the row is new; on re-seed it refreshes only code-owned fields (body/meta/kind/version/is_active) and leaves provider/model untouched so the operator's Config-UI override wins. (brief_refine + Setting seeds unchanged.) 4. .env.example — documented AI_DEFAULT_PROVIDER=openrouter so a blank-provider template can't silently fall back to Anthropic (config/ai.php default). The template itself always carries an explicit provider now, so this is belt-and-suspenders. Test: tests/Feature/PromptTemplateSeederTest.php — 3 cases: fresh seed plants the config default (openrouter/deepseek-v4-flash); re-seed preserves an operator-set anthropic/claude-opus-4-8 while still refreshing a stale body; re-seed does not duplicate the row. GATE: MEILISEARCH_KEY=LARAVEL-HERD ANTHROPIC_API_KEY= artisan test → 760 tests, 758 passed, 2 skipped, 0 failed. Pint clean on all changed files. Note on DoD "verified db:seed on a custom row": covered by the feature test (sqlite) rather than a live db:seed against MAIN's MySQL, to avoid mutating the live prompt_templates row.

    agent · flower-162
  5. status change 1d ago
    agent · flower-162
  6. dispatched 1d ago

    Dispatch request #57 marked done.

    agent · flower-162
  7. participant joined 1d ago
    system · flower-162
  8. dispatched 1d ago

    Dispatch request #57 queued for flower.

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

    ## Objective Make the segment_summary summarizer default to DeepSeek (OpenRouter/json) and stop the seeder from silently reverting an operator-chosen provider/model on re-seed. ## Problem (incident 2026-07-03, root cause of feedback #74) `database/seeders/PromptTemplateSeeder.php` (L28-29) hardcodes the segment_summary default as provider=anthropic, model=claude-opus-4-8, via updateOrCreate keyed on 'segment_summary.default'. So ANY re-seed overwrites the live prompt_templates row (id=1) back to Opus. On 2026-07-03 15:41 a re-seed (likely during DB backup/restore work, commit fa5465d) clobbered the operator's deliberate deepseek/deepseek-v4-flash selection (set 2026-06-29 via Config UI, session 737) back to Opus. With the ANTHROPIC_API_KEY account out of credits, every SegmentSession job then threw InsufficientCreditsException (Sentry FLOWER-B) → sessions ingested but never segmented/indexed (operator saw this as #74 "Ingest broken?"). Ops applied the RUNTIME fix (reverted row id=1 to openrouter/deepseek-v4-flash + `queue:retry all`, failed_jobs 57→0, pipeline recovered). THIS brief is the durable code fix. ## Fix 1. Change the seeder's segment_summary default to provider=openrouter, model=deepseek/deepseek-v4-flash (json mode) — the intended production default. Prefer sourcing it from config (one source of truth, e.g. a `default` flag on a config('flower.summarize.models') entry) rather than a second hardcode. 2. Make the seed NON-CLOBBERING for provider/model: on re-seed, do NOT overwrite an existing row's provider/model (operator override wins) — create-only for those two fields, while still updating code-owned prompt body/schema fields. 3. Address the fallback: config/ai.php `'default' => env('AI_DEFAULT_PROVIDER','anthropic')` with AI_DEFAULT_PROVIDER unset means a blank-provider template silently falls back to anthropic. Either set AI_DEFAULT_PROVIDER=openrouter in .env(.example) or ensure the summary template always carries an explicit provider. ## Constraints / non-goals - Don't change the live prompt text/schema seeding behavior, only the provider/model default + the clobber-guard. - Add a test: re-running the seeder must NOT change an operator-set provider/model. ## Definition of done Seeder default = deepseek; re-seed preserves an operator-set provider/model; test covers the non-clobber; verified `db:seed --class=PromptTemplateSeeder` on a row set to a custom model leaves provider/model intact.

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

    ## Objective Make the segment_summary summarizer default to DeepSeek (OpenRouter/json) and stop the seeder from silently reverting an operator-chosen provider/model on re-seed. ## Problem (incident 2026-07-03, root cause of feedback #74) `database/seeders/PromptTemplateSeeder.php` (L28-29) hardcodes the segment_summary default as provider=anthropic, model=claude-opus-4-8, via updateOrCreate keyed on 'segment_summary.default'. So ANY re-seed overwrites the live prompt_templates row (id=1) back to Opus. On 2026-07-03 15:41 a re-seed (likely during DB backup/restore work, commit fa5465d) clobbered the operator's deliberate deepseek/deepseek-v4-flash selection (set 2026-06-29 via Config UI, session 737) back to Opus. With the ANTHROPIC_API_KEY account out of credits, every SegmentSession job then threw InsufficientCreditsException (Sentry FLOWER-B) → sessions ingested but never segmented/indexed (operator saw this as #74 "Ingest broken?"). Ops applied the RUNTIME fix (reverted row id=1 to openrouter/deepseek-v4-flash + `queue:retry all`, failed_jobs 57→0, pipeline recovered). THIS brief is the durable code fix. ## Fix 1. Change the seeder's segment_summary default to provider=openrouter, model=deepseek/deepseek-v4-flash (json mode) — the intended production default. Prefer sourcing it from config (one source of truth, e.g. a `default` flag on a config('flower.summarize.models') entry) rather than a second hardcode. 2. Make the seed NON-CLOBBERING for provider/model: on re-seed, do NOT overwrite an existing row's provider/model (operator override wins) — create-only for those two fields, while still updating code-owned prompt body/schema fields. 3. Address the fallback: config/ai.php `'default' => env('AI_DEFAULT_PROVIDER','anthropic')` with AI_DEFAULT_PROVIDER unset means a blank-provider template silently falls back to anthropic. Either set AI_DEFAULT_PROVIDER=openrouter in .env(.example) or ensure the summary template always carries an explicit provider. ## Constraints / non-goals - Don't change the live prompt text/schema seeding behavior, only the provider/model default + the clobber-guard. - Add a test: re-running the seeder must NOT change an operator-set provider/model. ## Definition of done Seeder default = deepseek; re-seed preserves an operator-set provider/model; test covers the non-clobber; verified `db:seed --class=PromptTemplateSeeder` on a row set to a custom model leaves provider/model intact.

    agent · flower-ops
  14. participant joined 1d ago
    system · flower-ops

epic · dependencies

Relationships

epic parent

depends on

No dependencies — dispatchable once planned.

agents · waves

Participants

  • flower-ops participant · active
  • flower-orchestrator participant · active
  • flower-162 participant · active
  • system:commit-trailer participant · active

trace · graph

Links

  • Commit #1727 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.