From 11020e8f000a474aabb922d9daa205c59813351c Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 13 Sep 2026 22:45:43 +0200 Subject: [PATCH] Publish FI briefs to origin or fail the day FI-WP-0004 grants origin publication. Local commit without push no longer posts fi_daily_brief (that cleared due while losing the file). Prompt/context refuse re-announcing cataloged models and invented sizes. Assistant: grok Assistant-Session: 01a09c6a-1cfc-75b1-a78d-c13eaf22241d --- docs/legacy-runtime-inventory.md | 9 ++- rein_aharness/approaches.py | 2 + rein_aharness/fi_research_brief.py | 70 ++++++++++++++++++--- tests/test_fi_research_brief.py | 97 +++++++++++++++++++++--------- 4 files changed, 136 insertions(+), 42 deletions(-) diff --git a/docs/legacy-runtime-inventory.md b/docs/legacy-runtime-inventory.md index 9d3f50e..a1b4a06 100644 --- a/docs/legacy-runtime-inventory.md +++ b/docs/legacy-runtime-inventory.md @@ -59,14 +59,13 @@ constraint rather than a grant-bearing path. | Inputs | FI sources allowlist, daily playbook, reserve status, two fixed research baselines/plans, recent briefs, and recent git log | | Model/credential lane | HTTP `LLM_CONNECT_URL`; model from `FI_RESEARCH_BRIEF_MODEL`, then Binky-named `BRIEF_DAILY_MODEL` / `MAIL_TRIAGE_MODEL`; provider credential remains behind llm-connect | | Output | `briefs/YYYY/MM/YYYY-MM-DD.md`; model JSON is rendered deterministically | -| Repository mutation | Stages only the brief path and creates one local commit | -| Publication | Local commit only. The former `FI_RESEARCH_BRIEF_PUSH` path was removed 2026-09-04; publication requires a separate owner/grant. | -| Completion | Best-effort State Hub `fi_daily_brief` with path/date/candidate count; `fi_brief_status` uses it to clear due state | +| Repository mutation | Stages the brief path, one local commit, then `git push origin` | +| Publication | Origin publication is a **FI-owned grant** (FI-WP-0004, 2026-09-13). The 2026-09-04 local-only commit was losing durable memory. | +| Completion | State Hub `fi_daily_brief` only after `pushed=true` + `origin_sha`. Push failure posts `executor_run` and leaves `due=true`. | | Failure/retry | Normal generation/commit failure reopens; an existing daily path succeeds idempotently | | Current rollback material | Disable/pause the Activity Core definition. FI documents a disabled 07:35 host timer as break-glass, but its installer still enables that timer and must not be invoked casually | -Publication, if still needed, must become a separately named and granted -capability with remote-ref and result evidence. +Origin publication is the named grant: FI-WP-0004-T04 in freedom-intelligence. The Binky-named fallback model environment variables must not survive in an FI owned declaration. diff --git a/rein_aharness/approaches.py b/rein_aharness/approaches.py index 71d9a4f..251036c 100644 --- a/rein_aharness/approaches.py +++ b/rein_aharness/approaches.py @@ -313,6 +313,8 @@ def _run_fi(target: Path, *, report_to_hub: bool, commit: bool) -> ApproachResul "path": r.path, "wrote": r.wrote, "committed": r.committed, + "pushed": r.pushed, + "origin_sha": r.origin_sha, "skipped_existing": r.skipped_existing, "collection_candidates": r.collection_candidates, "head_after": r.head_after, diff --git a/rein_aharness/fi_research_brief.py b/rein_aharness/fi_research_brief.py index 4b5f290..619d240 100644 --- a/rein_aharness/fi_research_brief.py +++ b/rein_aharness/fi_research_brief.py @@ -2,7 +2,8 @@ activity-core owns *when* (Temporal schedule + fi_brief_status). This rein command owns *execution*: draft brief from playbook context, -commit under freedom-intelligence, post fi_daily_brief for idempotence. +commit under freedom-intelligence, **push to origin**, then post +fi_daily_brief. A local-only commit is a failed day (FI-WP-0004). No Claude Code / host coding agent — llm-connect only. """ @@ -53,6 +54,8 @@ class FiResearchBriefResult: model_meta: dict[str, Any] = field(default_factory=dict) skipped_existing: bool = False collection_candidates: int = 0 + pushed: bool = False + origin_sha: str = "" def _berlin_today() -> date: @@ -93,6 +96,17 @@ def collect_context(repo: Path, day: date) -> str: f"{_truncate(last.read_text(encoding='utf-8', errors='replace'), 3500)}\n" ) + catalog = repo / "inventory" / "catalog" + if catalog.is_dir(): + lines = [ + "## Catalog (DO NOT re-announce these as new releases; " + "DO NOT invent sizes that contradict these entries)\n" + ] + for p in sorted(catalog.glob("*.yaml")): + text = p.read_text(encoding="utf-8", errors="replace") + lines.append(f"### {p.name}\n{_truncate(text, 900)}\n") + chunks.append("\n".join(lines)) + try: log = _git(repo, "log", f"-{_MAX_GIT_LOG}", "--oneline") chunks.append(f"## Recent git log\n{log}\n") @@ -114,6 +128,12 @@ Rules: - Cover axes when there is signal: A frontier/commercial, B open/local, C training/FT, D harness/fleet. - Flag collection candidates only when license/size/rationale are clear. +- NEVER re-announce a model that already has a catalog YAML as a "new release". +- NEVER invent parameter counts or file sizes. If the card is not in context, + write "unknown — verify card" rather than guessing. DeepSeek-V4-Flash-0731 + is a ~304B / ~13B-active MIT MoE (~167 GiB), NOT a 12B dense model. +- Every non-empty axis row needs a primary URL in "sources". +- Scan axes C (training) and D (harness) even if the result is an empty array. - Prefer primary sources; mark unverified claims as "unverified". - "No material delta" is allowed **only** when you have considered the prior brief + allowlist + reserve status and still find nothing. Even then: @@ -317,12 +337,12 @@ def _truncate(text: str, n: int) -> str: return text[: n - 20] + "\n…(truncated)…\n" -def _git(repo: Path, *args: str) -> str: +def _git(repo: Path, *args: str, timeout: int = 60) -> str: result = subprocess.run( ["git", "-C", str(repo), *args], capture_output=True, text=True, - timeout=60, + timeout=timeout, ) if result.returncode != 0: raise FiResearchBriefError( @@ -331,6 +351,15 @@ def _git(repo: Path, *args: str) -> str: return result.stdout.strip() +def _publish_origin(repo: Path) -> str: + """Push HEAD to origin. FI-owned grant: origin is the durable brief store.""" + branch = _git(repo, "rev-parse", "--abbrev-ref", "HEAD") + if not branch or branch == "HEAD": + branch = "main" + _git(repo, "push", "-u", "origin", f"HEAD:{branch}", timeout=120) + return _git(repo, "rev-parse", "HEAD") + + def run_fi_research_brief( target_repo: Path, *, @@ -357,6 +386,7 @@ def run_fi_research_brief( result.head_after = _git(repo, "rev-parse", "HEAD") except FiResearchBriefError: pass + _finalize_publish(result, repo, commit=commit) _hub(result, report_to_hub, repo) return result @@ -448,22 +478,41 @@ def run_fi_research_brief( model_meta=meta, collection_candidates=n_cands, ) + _finalize_publish(result, repo, commit=commit) _hub(result, report_to_hub, repo) return result +def _finalize_publish( + result: FiResearchBriefResult, repo: Path, *, commit: bool +) -> None: + """Origin push is required for a successful brief day when we commit.""" + if not commit or not result.ok: + return + try: + sha = _publish_origin(repo) + result.pushed = True + result.origin_sha = sha + result.head_after = sha + except FiResearchBriefError as exc: + result.ok = False + result.reason = f"origin publish failed: {exc}"[:300] + + def _hub(result: FiResearchBriefResult, report_to_hub: bool, repo: Path) -> None: if not report_to_hub: return - if result.ok: - # Idempotence for activity-core fi_brief_status resolver + # fi_daily_brief clears activity-core due. Only fire it when origin has + # the brief (FI-WP-0004). Local commit without push is a failed day. + published = result.ok and result.pushed + if published: event_type = "fi_daily_brief" summary = ( f"FI daily brief {result.date}" + ( - " (already present)" + " (already present, pushed)" if result.skipped_existing - else f" wrote={result.wrote} committed={result.committed}" + else f" wrote={result.wrote} committed={result.committed} pushed={result.pushed}" ) ) detail = { @@ -473,18 +522,23 @@ def _hub(result: FiResearchBriefResult, report_to_hub: bool, repo: Path) -> None "collection_candidates": result.collection_candidates, "wrote": result.wrote, "committed": result.committed, + "pushed": result.pushed, + "origin_sha": result.origin_sha, "skipped_existing": result.skipped_existing, "executor": "rein-aharness", } else: event_type = "executor_run" - summary = f"FI daily research brief failed: {result.reason}" + summary = f"FI daily research brief failed: {result.reason or 'not published to origin'}" detail = { "repo": "freedom-intelligence", "ok": False, "date": result.date, "reason": result.reason, "model_meta": result.model_meta, + "wrote": result.wrote, + "committed": result.committed, + "pushed": result.pushed, "executor": "rein-aharness", } hub.post_progress_event(summary=summary, event_type=event_type, detail=detail) diff --git a/tests/test_fi_research_brief.py b/tests/test_fi_research_brief.py index 0db0a8a..bba1a53 100644 --- a/tests/test_fi_research_brief.py +++ b/tests/test_fi_research_brief.py @@ -8,10 +8,14 @@ from pathlib import Path from rein_aharness import fi_research_brief +def _git(cwd: Path, *args: str) -> None: + subprocess.run(["git", "-C", str(cwd), *args], check=True, capture_output=True) + + def _repo(tmp_path: Path) -> Path: repo = tmp_path / "freedom-intelligence" repo.mkdir() - subprocess.run(["git", "init", "-q"], cwd=repo, check=True) + subprocess.run(["git", "init", "-q", "-b", "main"], cwd=repo, check=True) (repo / "README.md").write_text("baseline\n", encoding="utf-8") subprocess.run(["git", "add", "."], cwd=repo, check=True) subprocess.run( @@ -31,37 +35,72 @@ def _repo(tmp_path: Path) -> Path: return repo -def test_fi_brief_never_pushes_even_when_legacy_env_requests_it( - tmp_path: Path, - monkeypatch, -) -> None: - repo = _repo(tmp_path) - monkeypatch.setenv("FI_RESEARCH_BRIEF_PUSH", "1") - original_git = fi_research_brief._git - calls: list[tuple[str, ...]] = [] +def _with_origin(tmp_path: Path, repo: Path) -> Path: + remote = tmp_path / "origin.git" + subprocess.run(["git", "init", "--bare", "-q", "-b", "main", str(remote)], check=True) + _git(repo, "remote", "add", "origin", str(remote)) + _git(repo, "push", "-u", "origin", "HEAD:main") + return remote - def observed_git(target: Path, *args: str) -> str: - calls.append(args) - return original_git(target, *args) - monkeypatch.setattr(fi_research_brief, "_git", observed_git) - result = fi_research_brief.run_fi_research_brief( - repo, - day=date(2026, 9, 4), - report_to_hub=False, - complete_fn=lambda _prompt: json.dumps( - { - "headline_deltas": ["No material delta after allowlist review."], - "axis_a": [], - "axis_b": [], - "axis_c": [], - "axis_d": [], - "collection_candidates": [], - "lab_implications": ["Recheck tomorrow."], - } - ), +def _complete(_prompt: str) -> str: + return json.dumps( + { + "headline_deltas": ["No material delta after allowlist review."], + "axis_a": [], + "axis_b": [], + "axis_c": [], + "axis_d": [], + "collection_candidates": [], + "lab_implications": ["Recheck tomorrow."], + } ) + +def test_fi_brief_pushes_to_origin_and_records_sha(tmp_path: Path) -> None: + repo = _repo(tmp_path) + _with_origin(tmp_path, repo) + result = fi_research_brief.run_fi_research_brief( + repo, + day=date(2026, 9, 13), + report_to_hub=False, + complete_fn=_complete, + ) assert result.ok is True assert result.committed is True - assert not any(args and args[0] == "push" for args in calls) + assert result.pushed is True + assert result.origin_sha + remote_head = subprocess.run( + ["git", "-C", str(tmp_path / "origin.git"), "rev-parse", "HEAD"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + assert remote_head == result.origin_sha + brief = repo / "briefs" / "2026" / "09" / "2026-09-13.md" + assert brief.is_file() + + +def test_fi_brief_push_failure_is_not_a_completed_day( + tmp_path: Path, monkeypatch +) -> None: + repo = _repo(tmp_path) + posted: list[dict] = [] + + def fake_post(**kwargs): + posted.append(kwargs) + + monkeypatch.setattr(fi_research_brief.hub, "post_progress_event", fake_post) + result = fi_research_brief.run_fi_research_brief( + repo, + day=date(2026, 9, 13), + report_to_hub=True, + complete_fn=_complete, + ) + assert result.ok is False + assert result.committed is True + assert result.pushed is False + assert "origin publish failed" in result.reason + assert posted + assert posted[-1]["event_type"] == "executor_run" + assert posted[-1]["detail"]["pushed"] is False