fix(gateway): provider recipes, stdio takes allow-list override, proposal review CLI

- #2657: stdio MCP takesHoldersAllowList is operator-overridable via
  GBRAIN_MCP_TAKES_HOLDERS (comma-separated). Fail-closed ['world']
  default preserved; empty/garbage values never widen.
- #2689 (drift-guard half): pin every anthropic-recipe model id (chat +
  expansion + alias targets) to CANONICAL_PRICING so the allowlist can
  never rot ahead of / behind the canonical pricing table again. The
  Claude 5 allowlist entries and the honest MODEL_NOT_USABLE labeling
  for configured models already landed on master.
- #2790: calendar-to-brain recipe backfill + weekly cron now end a week
  AHEAD of today so the lookahead window ('knows who you're meeting
  tomorrow') actually has upcoming events to read; cron guide updated.
- #1467: take-proposal review surface — new src/core/takes-proposals.ts
  (list/accept/reject; accept promotes to the canonical takes fence
  under the per-page lock + DB mirror + promoted_row_num audit), wired
  as contract-first ops takes_proposals_list / takes_proposal_resolve
  (resolve is localOnly) and 'gbrain takes propose [--accept N|--reject N]'.
  propose_takes phase model now resolves models.propose_takes config
  (alias-aware) and threads the resolved id to the extractor + model_id
  column.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-07-21 14:37:55 -07:00
co-authored by Claude Fable 5
parent 0612b0daa8
commit 2d4f980a42
13 changed files with 645 additions and 13 deletions
+2 -1
View File
@@ -441,7 +441,8 @@ round-trip suite (CHECK admits unresolvable+NULL, still rejects partial+true and
unresolvable+true|false, pre-v80 NULL/NULL rows survive).
- `src/core/cycle/base-phase.ts` — abstract `BaseCyclePhase` class. Enforces `sourceScopeOpts(ctx)` threading at the type level; closes the source-isolation leak class structurally for every new phase. Inherits source-scope, budget meter, error envelope, progress reporter. propose_takes / grade_takes / calibration_profile all extend it.
- `src/core/cycle/propose-takes.ts` — LLM scans markdown prose, proposes gradeable claims to the `take_proposals` queue. Idempotency cache on `(source_id, page_slug, content_hash, prompt_version)` composite unique index. Fence-dedup: existing canonical takes passed to the extractor as context. Ships a stub prompt; tuned prompt arrives via the synthetic corpus build.
- `src/core/cycle/propose-takes.ts` — LLM scans markdown prose, proposes gradeable claims to the `take_proposals` queue. Idempotency cache on `(source_id, page_slug, content_hash, prompt_version)` composite unique index. Fence-dedup: existing canonical takes passed to the extractor as context. Model resolves explicit `opts.model` > `models.propose_takes` config (alias-aware) > gateway default; the resolved id reaches the extractor AND the `model_id` audit column.
- `src/core/takes-proposals.ts` — take-proposal review queue (#1467): `listTakeProposals` (source-scoped, holder allow-list fail-closed like `takes_list`) + `resolveTakeProposal` (accept promotes to the canonical markdown fence via `upsertTakeRow` under the per-page lock, mirrors to DB via `addTakesBatch`, records `promoted_row_num`; reject keeps the row as audit history; double-resolve throws). Surfaced as the `takes_proposals_list` / `takes_proposal_resolve` ops (resolve is `localOnly` — accept writes repo markdown) and `gbrain takes propose [--accept N | --reject N]`. Pinned by `test/takes-proposals-review.test.ts`.
- `src/core/cycle/grade-takes.ts` — walks unresolved takes older than 6 months, retrieves evidence, asks judge model, caches verdict. Auto-resolve DISABLED by default. Conservative thresholds: >=0.95 single OR >=0.85 ensemble 3/3 unanimous. `aggregateEnsemble` reuses the cross-modal substrate; fires on the borderline 0.6-0.95 band. Writes to `take_grade_cache`.
- `src/core/cycle/calibration-profile.ts` — aggregates resolved takes into 2-4 narrative pattern statements + active bias tags. Voice-gated via `gateVoice()`. Cold-brain skip when <5 resolved. Writes to `calibration_profiles` with audit columns (`voice_gate_passed`, `voice_gate_attempts`, `grade_completion`).
- `src/core/calibration/voice-gate.ts` — single `gateVoice()` function, mode parameter (`pattern_statement` | `nudge` | `forecast_blurb` | `dashboard_caption` | `morning_pulse`). 2 regens then template fallback from `src/core/calibration/templates.ts`. Haiku judge with mode-specific rubrics; all rubrics structurally forbid clinical/preachy voice.
+3 -2
View File
@@ -38,8 +38,9 @@ fixed. You wake up and the brain is smarter than when you went to sleep.
# Meeting sync — 10 AM, 4 PM, 9 PM on weekdays
0 10,16,21 * * 1-5 cd /path/to/meeting-sync && node meeting-sync.mjs >> /tmp/meeting-sync.log 2>&1
# Calendar sync — Sundays at 10 AM
0 10 * * 0 cd /path/to/calendar-sync && node calendar-sync.mjs --start $(date -v-7d +%Y-%m-%d) --end $(date +%Y-%m-%d)
# Calendar sync — Sundays at 10 AM. The +7d end keeps upcoming events in the
# brain — the lookahead window the daily briefing's meeting prep reads from.
0 10 * * 0 cd /path/to/calendar-sync && node calendar-sync.mjs --start $(date -v-7d +%Y-%m-%d) --end $(date -v+7d +%Y-%m-%d)
# Brain health — weekly Mondays at 6 AM
0 6 * * 1 gbrain doctor --json >> /tmp/gbrain-health.log 2>&1 && gbrain embed --stale