Skip to content

v1.2.0: Dex v2 — chat orchestration, proactive priority feed, wired executors & email design system - #3

Merged
STiFLeR7 merged 3 commits into
masterfrom
v1.2.0-planning
Jun 26, 2026
Merged

v1.2.0: Dex v2 — chat orchestration, proactive priority feed, wired executors & email design system#3
STiFLeR7 merged 3 commits into
masterfrom
v1.2.0-planning

Conversation

@STiFLeR7

Copy link
Copy Markdown
Owner

Summary

Promotes the v1.2.0-planning line into master. Because master currently sits behind the v1.1.0 release, this PR bundles both the v1.1.0 stabilization work and the v1.2.0 Dex-v2 increments. Net: 246 files, ~16.2k insertions / ~1.1k deletions across 9 commits.

Reviewers: if you prefer v1.1.0 and v1.2.0 as separate merges, say so and I'll split this into a v1.1.0→master PR first, then rebase this one.

What's included

v1.2.0 — Dex v2 (product-grade chat, proactive feed, email design system)

  • Chat orchestration foundation (14d04d1): transport-independent ChannelMessage + semantic ChannelRole, declarative ChannelRouter, and the Conversation → Planner → Validator → Executor pipeline. Governance (requires_owner / requires_approval) is stamped server-side from a trusted table, never inferred from the LLM. Thin Discord adapter (normalize → handle → render). Replaces the prior monkey-patched chat path.
  • Proactive Priority Feed: after each 2-hourly research run, high-importance new findings are routed via ChannelRole.PRIORITY_FEED onto the existing transactional outbox as an owner-tagged digest. Research stays Discord-agnostic; outbox discord delivery generalized to honor payload["channel_key"] (defaults to summaries — backward compatible).
  • Wired executors (b88b3c8): create_task, run_research (routed to the nexus agent runtime), and show_status now call real domain services via an injected session_factory/event_gateway; approval_request short-circuits at the Validator. Each side-effecting action emits a SYSTEM status card; every branch is fail-soft.
  • Email design system (6369129): design-first, Jinja2 + table-based HTML. base.html master layout + 9 component partials, 12 operational + 4 conversational templates, 4 design docs, sample_context.json, and rendered previews. Gmail/Outlook(VML)/Apple Mail compatible, dark-mode, mobile-first. No EmailService changes, no service wiring — pure assets.
  • Planning docs (988b793): v1.2 charter, roadmap, evidence-backed tech-debt backlog.

v1.1.0 — Pilot operational validation & Nexus branding

  • 26fc0fd release commit; c4c4f3c Hermes H-4 pilot lifecycle (fail-fast init, configurable budgets, terminate/cancel, TIMED_OUT, resume); d6bd75d Hermes H-2 honesty fixes; b734c13 Track S default-secure sandbox; 2fd3ffc v1.1.0 planning charter.

Quality gates

  • Full suite: 241 passed (Dex-v2 added +16 E2E across channel harness, chat orchestration, wired actions, and priority feed).
  • ruff clean · mypy clean (69 source files).
  • Email system: all 16 templates verified to render via Jinja2 with realistic data (light/dark, desktop/mobile), zero unresolved tags. Adds no Python and imports no services.

Notes / non-goals

  • No business logic was attached to the email templates in this PR (design milestone).
  • A couple of operational follow-ups remain post-merge: restart the live server to pick up the wired executors, and optionally render the full 16 email previews.

🤖 Generated with Claude Code

Nexus Project added 3 commits June 26, 2026 12:56
Replace the monkey-patched Discord chat path with a transport-independent,
product-grade orchestration foundation, and add the proactive Priority Feed.

Channel harness (nexus/communication/channels.py)
- ChannelRole: semantic, platform-independent roles (CHAT, NOTIFICATION,
  PRIORITY_FEED, BRIEFING, APPROVAL, SYSTEM).
- ChannelMessage: transport-independent inbound message; every adapter
  normalizes its native event into this. Orchestration never sees the platform.
- ChannelRouter: declarative role <-> channel binding + per-role policy
  (respond-without-mention, post-only, mention-owner).

Chat pipeline (nexus/communication/chat/)
- Conversation -> Planner -> ChatAction -> Validator -> Executor.
- Typed ChatAction contract; governance flags (requires_owner/requires_approval)
  are stamped server-side from a trusted table, never inferred from the LLM.
- Validator enforces owner/schema/approval gates; Executor performs side effects
  via injected services and emits a SYSTEM status card.
- Per-conversation memory passed to the planner (fixes incoherent follow-ups).

Thin Discord adapter (nexus/communication/discord/bot.py)
- normalize -> ChatService.handle -> render. No LLM/email/DB logic in the adapter.

Proactive Priority Feed (nexus/intelligence/feed.py)
- After each research run, high-importance new findings are routed via
  ChannelRole.PRIORITY_FEED onto the transactional outbox as an owner-tagged,
  influencer-style digest. Research stays Discord-agnostic.
- Outbox discord delivery generalized to honor payload['channel_key']
  (defaults to 'summaries' — backward compatible) so one outbox serves every
  channel role.
- Composed into the existing 2-hourly research job; config toggle + threshold.

Tests: +17 E2E (channel harness, chat orchestration, priority feed).
Gate: 236 passed, ruff clean, mypy clean (69 files).
The remaining chat actions now call real domain services instead of
returning 'not wired up yet'. The Executor gains an injected session_factory
and event_gateway (provided at startup in api.py) and opens a session per
action, mirroring the /task_create slash command path — no duplicated logic.

- create_task: TaskService.create_task -> change_status(QUEUED); emits
  lifecycle events via the gateway. Owner-gated.
- run_research: creates and queues a research task routed to the 'nexus'
  agent runtime (topic preserved as description) — responsive and async.
  Owner-gated.
- show_status: live counts from the DB (health, open tasks, pending
  approvals, 24h research findings). Open to all.
- approval_request: unchanged — short-circuits at the Validator
  (requires_approval) before reaching the executor.

Each side-effecting action emits a SYSTEM status card routed to #console via
the channel harness, and every branch is fail-soft (missing config or a
service error returns an honest reply + failed card, never crashes).

Architecture held: thin adapter, governance stamped server-side in the
planner's trusted table, validator schema gates unchanged.

Tests: +5 E2E (real DB session factory, scripted LLM, no service mocks):
owner create_task persists+queues; non-owner denied persists nothing;
missing title schema-fails; run_research queues a nexus-runtime task;
show_status reflects seeded counts.
Gate: 241 passed, ruff clean, mypy clean (69 files).
Design-first milestone. Establishes the email visual identity of Nexus v2 as a
reusable, production-quality, Jinja2 + table-based HTML system. No business
logic, no service wiring, no EmailService changes — pure design assets.

Foundation
- base.html master layout: 600px table shell, mso ghost tables, inline-CSS-first
  (the <style> block carries only dark-mode + responsive media queries),
  hidden preheader, accent + content blocks.
- 9 component partials as Jinja2 macros: header, footer, section (+panel,
  code_block), metric_card (+metric_row), badge, status_chip, divider (+spacer),
  button (+VML button_row), timeline, table (data_table, kv_grid, progress).

Email types (extend base.html, one accent each)
- 12 operational: morning_digest, operational_intelligence, research_report,
  todo_digest, reminder, approval_required, execution_completed,
  execution_failed, security_alert, scheduler_report, weekly_review,
  monthly_executive.
- 4 conversational (Q&A family): qa_transcript, conversation_summary,
  action_items, decision_summary (remaining formats documented as presets).

Documentation
- EMAIL_DESIGN_SYSTEM.md — philosophy, architecture, semantic + subsystem colour
  system, type scale, spacing/radius/elevation, icon strategy, placeholder
  schema, future-extension strategy (Discord/Slack/Teams/web/PDF).
- EMAIL_STYLE_GUIDE.md — voice & tone, colour/writing rules, accent-per-type,
  55 subject-line patterns, accessibility checklist.
- EMAIL_COMPONENT_LIBRARY.md — per-component signatures, params, examples,
  variants, higher-order patterns, Q&A family mapping.
- EMAIL_TEMPLATE_GUIDELINES.md — authoring model, client-compatibility matrix,
  responsive + dark-mode rules, charts approach, per-type specifications,
  rendering instructions, design-only integration seam, QA checklist.

Verification & extras
- sample_context.json: concrete placeholder payloads (the data schema).
- previews/: 3 rendered HTML examples.
- All 16 templates verified to render via Jinja2 with realistic data, light/dark
  and desktop/mobile, with zero unresolved tags.

Compatibility: Gmail, Outlook (Word/VML), Apple Mail; dark mode; mobile-first
responsive; no external images, web fonts, or JS.
@STiFLeR7
STiFLeR7 merged commit 9d96be5 into master Jun 26, 2026
1 check passed
@STiFLeR7
STiFLeR7 deleted the v1.2.0-planning branch June 26, 2026 08:06

@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: 6369129e3e

ℹ️ 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".


async with get_session(self.session_factory) as session:
memory_service = MemoryService(session)
task_service = TaskService(session, memory_service, self.event_gateway)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Publish chat task events after commit

When ChatService is built in api.py, self.event_gateway is the live gateway with WorkflowOrchestrator subscribers. Passing it into TaskService here makes change_status(...QUEUED) synchronously publish TASK_UPDATED before this get_session block commits the newly created task; the orchestrator opens its own DB session for the approval request and cannot see the uncommitted task, so chat-created tasks can be reported as queued while no approval/execution is created. Defer publishing until after the transaction commits or route this through the DB outbox.

Useful? React with 👍 / 👎.

Comment on lines +226 to +227
channel_name = getattr(message.channel, "name", None)
in_chat_channel = self.router.respond_without_mention(channel_name)

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 Handle configured channel IDs for chat routing

When Discord channels are configured by ID (which get_channel_by_config supports), this reverse lookup uses the channel name while ChannelRouter stored the configured ID string, so in_chat_channel is false. In that deployment, messages in the configured CHAT channel without an @ mention never reach ChatService, and the no-mention chat channel only works for name-based configs. Use message.channel.id as well or map both IDs and names.

Useful? React with 👍 / 👎.

Comment thread nexus/config.py
Comment on lines +273 to +274
if _to and not yaml_data["email"].get("to_address"):
yaml_data["email"]["to_address"] = _to

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 Let NOTIFY_EMAIL_TO override YAML recipients

If config/settings.yaml already defines email.to_address, NOTIFY_EMAIL_TO is ignored because this guard only assigns when the YAML value is empty, even though the surrounding env mapping treats deployment env as overriding YAML and the comment says an explicit recipient wins. In deployments changing the recipient via env, operational/chat emails continue going to the stale YAML address.

Useful? React with 👍 / 👎.

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