Phase 1: collaboration board substrate (Issue sync, debate cycle, consensus) - #7
Merged
Merged
Conversation
added 5 commits
July 1, 2026 13:24
…sue-number linking Extends feature_backlog dedup beyond exact-title match so Claude's and Gemini's independently-worded proposals for the same idea collapse into one entry (verified: '[Gemini] FinBERT integration for sentiment' vs 'FinBERT sentiment upgrade' now dedupe correctly, unrelated proposals stay distinct). New agent_track_record table (bumped in mark_proposal_done) backs the Phase 1 consensus formula. New github_issue_number column + lookup, for the upcoming Issue-sync work.
New github_sync.py (reuses community.py's existing GitHub REST client)
mirrors every feature_backlog proposal to a GitHub Issue — labels: FSI
level (parsed from the description), category, risk tier, and which
agent proposed it. New risk_rules.py classifies high/medium/low via
keyword + file-path matching (auth/payment/secret/schema-touching
proposals are always high, never auto-mergeable later regardless of
consensus).
Both fred_rnd.py and gemini_rnd.py now pass proposed_by explicitly
("claude"/"gemini") at insertion time — previously neither agent set
this, and Gemini's cycle identified its own proposals via a "[Gemini] "
title-string-prefix hack instead. That hack is gone; proposal selection
now filters on the real proposed_by column.
Verified end-to-end against the live repo: created a real Issue, confirmed
labels/body/hidden proposal-id marker, confirmed the issue-number lookup
round-trips correctly, then cleaned up the test artifacts.
New debate.py::run_debate_cycle() — each agent reviews the OTHER agent's
open proposal Issues (never its own) and posts a stance (agree/disagree/
escalate) + confidence + rationale as a comment, gated by a hidden
<!--fredai:stance:{agent}--> marker so an issue is never reviewed twice.
compute_consensus() combines the reviewer's self-reported confidence with
both agents' historical accuracy (memory_store.get_track_record — 0.7
cold-start default until 5+ samples exist): "disagree" heavily discounts
the score, "escalate" forces it to zero (future auto-merge gate treats
that as always requiring a human, regardless of risk tier).
Wired into main.py's scheduler as job_agent_debate (6h interval, jittered
like the other cross-agent jobs).
Verified against the live repo: created a real Claude-authored test
proposal, ran the cycle, got a genuine Gemini review (agree, 0.90
confidence, real rationale) posted as an issue comment with the correct
consensus score and label; ran again and confirmed it correctly skipped
re-reviewing. Cleaned up test artifacts after.
…-board-substrate # Conflicts: # memory_store.py
essentialbit
added a commit
that referenced
this pull request
Jul 1, 2026
…oposal (#20) Found live, right after PR #7 merged: Gemini's interactive session hit this within its first hour. insert_feature_proposal()'s dedup correctly resolved a near-duplicate proposal to an *existing* row's id, but sync_proposal_to_issue() had no idea — it always created a brand new GitHub Issue regardless, so the same feature_backlog row ended up mirrored to two separate Issues (confirmed: #9 and #14 both carried the same <!--fredai:proposal_id=5--> marker; #11 and #16 the same for proposal_id=7). New memory_store.get_proposal(id) lets sync_proposal_to_issue check for an already-linked github_issue_number before creating anything, returning the existing issue number instead. Verified: simulated the exact scenario (insert, sync, insert a near-duplicate that dedupes to the same id, sync again) and confirmed the second sync returns the same issue number instead of creating a new one. Co-authored-by: Saifodius <penny-suing-henna@duck.com>
essentialbit
added a commit
that referenced
this pull request
Jul 2, 2026
Replaces the dashboard globe's 4 hardcoded decorative "geopolitical flight path" arcs (always the same 4 hubs -> NY, no real data behind them at all) with real per-story HQ-to-exchange arcs from Phase 1's story_arcs data (PR #52, already merged), colored by each story's actual sentiment score instead of a fixed rainbow palette. Capped to the 40 most recent stories to keep the globe high-signal per the new MISSION.md guiding principle #7 (minimalist, high-signal UI) -- uncapped would mean 100+ overlapping arcs on a 24h+ window, which reads as cluttered, not sophisticated. Conservative interpretation note: #48's Phase 2 spec bundles both arcs AND hotspot clustering. Splitting these — this PR is arcs only (the higher-value, more contained piece); hotspot clustering is a natural Phase 2b follow-up rather than risking a larger, harder-to-review PR. Verified with a real functional test: launched the live app, confirmed /api/news/globe-data still returns real story_arcs (165 for a 24h window), confirmed the dashboard page serves with the new code intact, and checked the extracted inline JS with `node --check` (exit 0, no syntax errors) since a headless browser wasn't available to click through it directly. Co-authored-by: Saifodius <penny-suing-henna@duck.com>
This was referenced Jul 5, 2026
essentialbit
added a commit
that referenced
this pull request
Jul 7, 2026
…108) (#118) Fred's L3 backtest loop was real (111 signal_outcomes rows, 4h/24h/72h checkpoints genuinely filling) but measured one thing: aggregate direction hit-rate, with no way to tell which signal source actually earns its keep, and no baseline -- a 55% hit rate means nothing without knowing what a naive momentum guess would have scored on the same data. - signal_outcomes gains two additive columns (source default 'aggregate', baseline_direction) -- legacy rows untouched, verified byte-for-byte parity against pre-migration accuracy math (73 rows / 29 correct, unchanged) - log_scan_outcomes now also logs one row per independent source that actually has data for an asset this cycle: news_sentiment (direct news_items query, not the blended fallback), insider (SEC Form 4, most recent filing), short_interest (ratio TREND not a static threshold -- rising=bearish/falling=bullish, needs 2 stored readings), technical (SMA20/50 cross). Sources without live data are skipped, not fabricated as neutral (Principle #7). Baseline = naive prior-move momentum from the already-fetched quotes dict, no new fetches. - get_backtest_accuracy v2: per-source accuracy + baseline delta + proving_value flag (delta<=0 at n>=20). get_underperforming_sources() surfaces flags for human review -- no auto-removal. - New GET /api/backtest/source-health route; Track Record panel shows baseline delta per checkpoint and a compact underperforming-sources note when any exist. Real bug caught by the functional test (not a hypothetical): insider signal_type is sec_client.py's raw code name (open_market_purchase/open_market_sale), not a bullish/bearish label -- was flowing through unmapped until the test asserted valid directions against live Form 4 data and failed. Fixed with an explicit mapping. Verified: 24/24 assertions against a copy of the live DB -- exact regression match on legacy accuracy math, deterministic scorer math on synthetic rows (75% signal vs 25% baseline = +50pt; a 25-sample losing source correctly flagged), and a real end-to-end scan cycle against live trending/quotes/news/insider/short-interest data. Co-authored-by: Saifodius <penny-suing-henna@duck.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 8, 2026
Closed
Closed
Merged
Closed
This was referenced Jul 9, 2026
Closed
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the Claude/Gemini collaboration board (Phase 0 — PR-gated pushes, branch protection, safe on-device sync — already merged). GitHub Issues are now the system of record for proposals; Claude and Gemini debate them and produce a weighted consensus score.
memory_store.py): proposal insertion now catches near-duplicates via Jaccard word-overlap on top of exact-title matching — verified Gemini's differently-worded restatement of a Claude proposal collapses into one entry.agent_track_recordtable +github_issue_numbercolumn, bumped automatically inmark_proposal_done.risk_rules.py: keyword/file-path classifier (auth/payment/secret/schema-touching proposals are alwayshighrisk — never eligible for future auto-merge regardless of consensus).github_sync.py: mirrors every proposal to a GitHub Issue (labels: FSI level, category, risk, proposed-by) — reusescommunity.py's existing GitHub client, no new one.fred_rnd.pyandgemini_rnd.pynow setproposed_byexplicitly at insertion time — Gemini's old"[Gemini] "title-prefix hack for self-identification is gone, replaced by the real column.debate.py: the actual debate — each agent reviews the other agent's open proposal Issues, posts a stance (agree/disagree/escalate) + confidence + rationale, gated against re-reviewing via a hidden HTML marker.compute_consensus()weighs stance confidence against each agent's historical accuracy (agent_track_record, 0.7 cold-start default); disagree heavily discounts, escalate forces the score to zero.main.py's scheduler asjob_agent_debate(6h, jittered like the other cross-agent jobs).Test plan (all done against the live repo, artifacts cleaned up after)
sync_proposal_to_issue: created a real Issue, confirmed labels/body/hidden proposal-id marker, confirmed round-trip lookuprun_debate_cycle: created a Claude-authored test proposal, got a genuine Gemini review posted with correct consensus score; ran again and confirmed it skipped re-reviewing