Skip to content

feat(briefing): add deterministic Morning Brief v1 - #15

Merged
chadsm-sys merged 2 commits into
mainfrom
feature/morning-brief-v1
Jul 11, 2026
Merged

feat(briefing): add deterministic Morning Brief v1#15
chadsm-sys merged 2 commits into
mainfrom
feature/morning-brief-v1

Conversation

@chadsm-sys

Copy link
Copy Markdown
Owner

Status

SCOPED PASS / REPOSITORY WARN

Draft only. Do not merge yet.

Summary

Adds the canonical deterministic, fixture-backed, local, read-only Hermes Morning Brief v1.

  • Renders the 10-section executive brief in Markdown.
  • Emits a stable machine-readable JSON representation.
  • Uses normalized JSON snapshots and performs no live collection.
  • Includes synthetic fixtures for healthy, busy, failure, everything blocked, no overnight work, contradictory evidence, stale evidence, and unknown state.
  • Includes generated Markdown and JSON examples.
  • Does not contact DGX Spark 1, DGX Spark 2, or the live Hermes runtime.

Focused diff

This PR contains one focused commit and 14 Morning Brief files only:

  • renderer: scripts/morning_brief_v1.py
  • tests: tests/test_morning_brief_v1.py
  • fixtures: tests/fixtures/morning_brief/
  • docs/examples: docs/morning-brief-v1*

No main-branch mutation, runtime change, scheduling, notifications, networking, or production configuration changes.

Scoped validation — PASS

Morning Brief tests:       17 passed in 0.10s
Ruff format (changed .py): 3 files already formatted
Ruff lint (changed .py):   All checks passed
Ty (changed production/generator .py): All checks passed
Git diff check:            PASS
Generated Markdown cmp:    PASS
Generated JSON cmp:        PASS

Deterministic artifact hashes exactly match the committed examples:

Markdown SHA-256: 1bd4ba94868fc3dc1435a1fc3ca471e064da023da74de1503b2ccf0c1541a6e3
JSON SHA-256:     47335b193533cce79b6fb96ff5192d33c3e06336b575d1286eb7eb36aca5780f

Secret scan before commit:

gitleaks: no leaks found

Repository-wide validation — WARN

The following blockers are pre-existing, unrelated, and explicitly out of scope for this PR:

  1. ruff format --check . reports legacy formatting drift, including .plans/streaming-support.md.
  2. pytest -q fails during collection because optional acp dependencies are unavailable (ModuleNotFoundError: No module named 'acp').
  3. ty check panics in existing tools/checkpoint_manager.py with execute: too many cycle iterations; ty identifies this as a checker bug (version 0.0.21).
  4. Repository-wide Ruff lint passes but reports an existing invalid # noqa directive warning at run_agent.py:94.

No attempt was made to repair optional dependencies, legacy formatting drift, the ty panic, or the existing lint warning.

Safety boundaries

  • Fixture-backed and local only
  • Read-only renderer
  • No DGX Spark contact
  • No live Hermes runtime contact or modification
  • No launchd/systemd/networking/job changes
  • No notifications
  • No main modification
  • No request to merge yet

Review gate

Review the scoped implementation and separate v1.1 design packet before considering merge. v1.1 is design-only and is not implemented in this PR.

@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown

🔎 Lint report: feature/morning-brief-v1 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10615 on HEAD, 10616 on base (✅ -1)

🆕 New issues (2):

Rule Count
invalid-assignment 1
unresolved-import 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`
tests/test_morning_brief_v1.py:8: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`

✅ Fixed issues (2):

Rule Count
unresolved-attribute 2
First entries
run_agent.py:2920: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`

Unchanged: 5559 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@chadsm-sys
chadsm-sys marked this pull request as ready for review July 11, 2026 19:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89340d02fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

def _time_key(value: Any) -> str:
text = _text(value, "")
try:
return datetime.fromisoformat(text.replace("Z", "+00:00")).isoformat()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize completion times before sorting wins

When two completion_time values use different offsets, _time_key returns strings that preserve their local offsets, so the reverse sort compares wall-clock text rather than instants. For example, 2026-07-11T09:00:00+00:00 sorts ahead of 2026-07-11T05:30:00-04:00 even though the latter is 30 minutes newer, violating the documented “wins newest first” contract for snapshots aggregated from sources in different time zones.

Useful? React with 👍 / 👎.

Comment on lines +479 to +480
"- **Ready to merge:** "
+ (", ".join(report["github"]["ready_to_merge"]) or "None"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize GitHub lists before joining

If a JSON snapshot has a missing/non-string entry such as null in github.ready_to_merge, validation only checks that the field is a list, and this join raises TypeError. That escapes the invalid-input handler as a traceback/exit 1 instead of rendering UNKNOWN or returning the stable status 2, so a single bad scalar in one GitHub list breaks the default brief.

Useful? React with 👍 / 👎.

@chadsm-sys
chadsm-sys merged commit 51bb388 into main Jul 11, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant