chore: rolling promotion dev -> main - #1146
namastex888 wants to merge 3404 commits into
Conversation
feat(events): real-time stream command with LISTEN/NOTIFY + StreamTable
Root cause: three interrelated issues caused CI-only failures: 1. mock.restore() in afterAll clears all process-global mock.module registrations, breaking whichever test file runs second 2. mockClear() only clears call counts but not mockImplementation() overrides set by other test files' nested describe blocks 3. Concurrent delivery afterEach set queryMock via dynamic import without session_id in result events Fix: - Add resetAllMocks() to _sdk-mocks.ts that does mockReset() + mockImplementation() for every shared mock function - Use resetAllMocks() in both test files' beforeEach blocks - Remove mock.restore() from both files' afterAll - Use shared queryMock directly instead of dynamic imports
fix(test): prevent cross-file mock leak in SDK executor tests
bunx tauri fails to resolve the package, and older npm-based Tauri CLI has a broken bundle_dmg.sh that uses AppleScript (fails without Finder permissions). cargo tauri uses the native bundler — matches khal-os's proven approach.
Audit all 80+ wishes against dev codebase. 17 had stale statuses: SHIPPED (14): - unified-omni-bridge (PRs #1063, #1065) - fix-omni-bridge-hardening (PR #1065) - unified-executor-layer (PR #1062) - auto-orchestrate, fix-depends-parser, parallel-execution - task-projects, test-pg-ram-isolation, task-auto-close-on-merge - worktree-out-of-repo, docs-overhaul, genie-hacks-community-docs - multi-agent-session-isolation, session-auto-create OBSOLETE (3): - genie-omni-marriage (superseded by smaller wishes) - fix-session-uuid-resume (replaced by --continue by name) - qa-dev-to-main (time-bound QA from March 20)
chore: wish housekeeping — mark 14 shipped, 3 obsolete
…build @khal-os/sdk leaks server-only imports (WorkOS AuthKit for Next.js) into the client bundle. Tauri/Vite builds fail because these modules are not resolvable in a non-Next.js context. Externalize them since the desktop app does not use WorkOS auth.
Tauri's bundle_dmg.sh was failing silently. khal-os builds DMG successfully with the same Tauri version (2.10.3) by including macOS minimumSystemVersion, icon references, and category in the bundle config. Aligning genie's tauri.conf.json to match.
Tauri's bundle_dmg.sh fails on macOS 26.3 due to a relative path bug in the bundler (current_dir mismatch when invoking the script). The .app builds fine — only the DMG packaging step breaks. Split make tauri into: - make tauri-app: builds .app via cargo tauri build --bundles app - make tauri-dmg: packages .app into .dmg via hdiutil create - make tauri: runs both (the full pipeline) hdiutil is native macOS, no dependencies, no AppleScript permissions, works in CI headless environments.
Add waitForExecutorReady() that uses PG LISTEN/NOTIFY on the genie_executor_state channel to detect when an executor reaches 'running' or 'idle' state, with polling fallback every 2s. - spawn-command.ts: new waitForExecutorReady() with _pgDeps injection - executor-registry.ts: emit executor.ready audit event on running - protocol-router.ts: try PG readiness before falling back to tmux - Graceful degradation: falls back to tmux scraping when PG unavailable - Mark daily-metrics-agent wish as SHIPPED
Stage .app + /Applications symlink into a temp dir before creating the DMG so users see the standard macOS drag-to-install layout.
…vents feat: add PG-based readiness detection for spawned agents
chore: rolling promotion dev -> main
Replace execFile('omni', ...) subprocess fork (~230ms/reply) with
in-process NATS publish via setNatsPublish() hook injected by the
bridge. Adds NatsPublishFn type to IExecutor interface, mirroring
the existing setSafePgCall pattern.
Fixes unified-executor-layer Groups 2 + migration numbering:
- Remove child_process import from claude-sdk.ts
- handleDoneTool now publishes to omni.reply.<inst>.<chat> directly
- Bridge wires nc.publish into executor after NATS connect
- Rename 026_events_trace_id.sql → 028 to resolve numbering conflict
fix: restore NATS reply path + resolve migration numbering
chore: rolling promotion dev -> main
Agents spawned via the omni bridge now receive a system prompt teaching them how to use omni CLI verbs (say, speak, imagine, react, history, done) to respond in WhatsApp conversations. The prompt is injected on every delivery when OMNI_INSTANCE is present in the executor env, ensuring it persists even across SDK resume boundaries.
…lexity Moves turn-based prompt assembly into a standalone helper function, bringing _processDelivery back under the cognitive complexity limit.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
The preceding auto-version bump used the legacy workflow marker that suppresses CI, leaving the rolling PR stale. This empty commit carries no such marker and exists solely to fire fresh push and pull_request events so the rollup reflects the proven green state from d8bf000 (all 4 runs SUCCESS). Follow-up resolves automatically once PR #1124 merges to main — the auto-version marker fix from #1140 will then take effect on main and this paper cut stops recurring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request increments the version of the genie plugin and its related packages from 4.260413.4 to 4.260413.5 across several configuration files, including marketplace.json and the project package.json files. I have no feedback to provide.
- releases_24h: 1 (v4.260413.4) - merged_prs_7d: 12 - avg_merge_time_h: 10.4 - ship_rate_pct: 100% - git metrics: 185 commits, 28 releases, +44.7K LoC (7d)
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.genie/agents/metrics-updater/daily-stats.jsonl:
- Line 33: collect-stats.sh is using unqualified timestamps with git log (e.g.,
--after="YYYY-MM-DD 00:00:00") which causes timezone boundary misses; update the
script so the start and end timestamps are emitted in ISO8601 UTC (append Z) and
used for git log arguments (replace the current --after/--before strings with
values produced via date -u '+%Y-%m-%dT%H:%M:%SZ' or equivalent); ensure both
the --after and --before (or --since/--until) invocations in collect-stats.sh
use these UTC-qualified timestamps so commits on the day boundary are correctly
counted.
In @.genie/agents/metrics-updater/runs.jsonl:
- Line 30: The run record is missing required top-level fields and has two
metrics misplaced: add a top-level "status" string (e.g., "success" | "failed" |
"no_changes"), a top-level boolean "velocity_md_updated", and a top-level
"steps" array containing per-step timing objects (start, end, name/duration) to
match the documented step breakdown; also move "daily_stats_count" and
"charts_generated" out of "metrics" into top-level fields, and ensure the
updated record includes the same "metrics" object keys that remain nested
unchanged.
In @.genie/agents/metrics-updater/state.json:
- Around line 4-9: The state.json contains an undocumented "last_metrics"
object; either remove this dead field from
.genie/agents/metrics-updater/state.json or add it to the documented schema and
ensure the updater writes it. To fix: if you choose removal, delete
"last_metrics" from the file and any tests/fixtures expecting it; if you choose
to document it, add a "last_metrics" section to AGENT.md (around the schema
block) describing its keys and update the metrics-updater code path that
persists state (the function that writes state:
saveState/persistState/writeState in the metrics-updater module) to populate
"last_metrics" whenever the other documented fields are written. Ensure both
code and docs are kept in sync.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 07aab703-c236-479d-922b-e00f72987ad3
⛔ Files ignored due to path filters (5)
.genie/assets/commits-30d.svgis excluded by!**/*.svg.genie/assets/loc-30d.svgis excluded by!**/*.svg.genie/assets/releases-30d.svgis excluded by!**/*.svgREADME.mdis excluded by!*.mdVELOCITY.mdis excluded by!*.md
📒 Files selected for processing (7)
.claude-plugin/marketplace.json.genie/agents/metrics-updater/daily-stats.jsonl.genie/agents/metrics-updater/runs.jsonl.genie/agents/metrics-updater/state.jsonpackage.jsonplugins/genie/.claude-plugin/plugin.jsonplugins/genie/package.json
| {"date":"2026-04-11","commits":12,"loc_added":81,"loc_removed":38,"releases":3,"contributors":["Claude","Felipe Rosa","genie","github-actions[bot]"]} | ||
| {"date":"2026-04-12","commits":14,"loc_added":2754,"loc_removed":3653,"releases":1,"contributors":["Claude","Felipe Rosa","Test","genie","github-actions[bot]"]} | ||
| {"date":"2026-04-13","commits":14,"loc_added":668,"loc_removed":70,"releases":0,"contributors":["Claude","Felipe Rosa","genie","github-actions[bot]"]} | ||
| {"date":"2026-04-14","commits":0,"loc_added":0,"loc_removed":0,"releases":0,"contributors":[]} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check git commits on 2026-04-14 to verify if zero is accurate
git log --all --since="2026-04-14T00:00:00Z" --until="2026-04-14T23:59:59Z" --oneline | wc -l
# Check the collect-stats.sh logic for date handling
cat .genie/agents/metrics-updater/tools/collect-stats.sh | grep -A 10 "since\|until\|date"Repository: automagik-dev/genie
Length of output: 2612
Fix date boundary handling in collect-stats.sh causing missing commits.
The record shows zero commits for 2026-04-14, but git log confirms 1 commit exists on that date. The issue is in collect-stats.sh's date logic: it uses unqualified timestamps (--after="YYYY-MM-DD 00:00:00") which can cause timezone-related boundary mismatches in git log. The date comparison needs explicit UTC timezone qualification (e.g., --after="2026-04-14T00:00:00Z") to match the actual commit timestamps.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.genie/agents/metrics-updater/daily-stats.jsonl at line 33, collect-stats.sh
is using unqualified timestamps with git log (e.g., --after="YYYY-MM-DD
00:00:00") which causes timezone boundary misses; update the script so the start
and end timestamps are emitted in ISO8601 UTC (append Z) and used for git log
arguments (replace the current --after/--before strings with values produced via
date -u '+%Y-%m-%dT%H:%M:%SZ' or equivalent); ensure both the --after and
--before (or --since/--until) invocations in collect-stats.sh use these
UTC-qualified timestamps so commits on the day boundary are correctly counted.
| {"timestamp": "2026-04-12T19:41:00Z", "duration_ms": 817, "status": "success", "dry_run": true, "daily_stats_count": 31, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [{"name": "collect_stats", "duration_ms": 110}, {"name": "backfill_check", "duration_ms": 22}, {"name": "generate_charts", "duration_ms": 68}, {"name": "generate_velocity", "duration_ms": 372}, {"name": "generate_readme", "duration_ms": 73}, {"name": "commit_push", "duration_ms": 20}]} | ||
| {"timestamp":"2026-04-13T00:00:00.000Z","duration_ms":45000,"api_calls":2,"tools_generated":0,"errors":[],"status":"success","fallback":false,"metrics":{"releases_24h":0,"merged_prs_7d":9,"avg_merge_time_h":1.4,"ship_rate_pct":100}} | ||
| {"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1264, "status": "success", "dry_run": true, "daily_stats_count": 33, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [{"name": "collect_stats", "duration_ms": 216}, {"name": "backfill_check", "duration_ms": 47}, {"name": "generate_charts", "duration_ms": 158}, {"name": "generate_velocity", "duration_ms": 359}, {"name": "generate_readme", "duration_ms": 159}, {"name": "commit_push", "duration_ms": 33}]} | ||
| {"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1576, "api_calls": 2, "tools_generated": 3, "errors": [], "metrics": {"releases_24h": 1, "merged_prs_7d": 12, "avg_merge_time_h": 10.4, "ship_rate_pct": 100, "git_commits_7d": 185, "git_releases_7d": 28, "git_loc_net_7d": 44700, "git_contributors_7d": 6, "daily_stats_count": 33, "charts_generated": 3}} |
There was a problem hiding this comment.
Missing required fields in run record.
Line 30 is missing several required fields according to the documented schema (AGENT.md:105-125):
status(required to indicate "success", "failed", "no_changes", etc.)velocity_md_updated(required boolean)steps(required array with step timing breakdown)
Additionally, daily_stats_count and charts_generated are embedded in the metrics object instead of being top-level fields, inconsistent with line 29 and the documented schema.
This schema violation makes it unclear whether the run succeeded and breaks tooling that parses this log file according to the documented format.
📋 Expected schema structure
According to AGENT.md:105-125, each line should be:
-{"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1576, "api_calls": 2, "tools_generated": 3, "errors": [], "metrics": {"releases_24h": 1, "merged_prs_7d": 12, "avg_merge_time_h": 10.4, "ship_rate_pct": 100, "git_commits_7d": 185, "git_releases_7d": 28, "git_loc_net_7d": 44700, "git_contributors_7d": 6, "daily_stats_count": 33, "charts_generated": 3}}
+{"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1576, "status": "success", "dry_run": false, "daily_stats_count": 33, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [...], "metrics": {"releases_24h": 1, "merged_prs_7d": 12, "avg_merge_time_h": 10.4, "ship_rate_pct": 100, "git_commits_7d": 185, "git_releases_7d": 28, "git_loc_net_7d": 44700, "git_contributors_7d": 6}}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.genie/agents/metrics-updater/runs.jsonl at line 30, The run record is
missing required top-level fields and has two metrics misplaced: add a top-level
"status" string (e.g., "success" | "failed" | "no_changes"), a top-level boolean
"velocity_md_updated", and a top-level "steps" array containing per-step timing
objects (start, end, name/duration) to match the documented step breakdown; also
move "daily_stats_count" and "charts_generated" out of "metrics" into top-level
fields, and ensure the updated record includes the same "metrics" object keys
that remain nested unchanged.
The .genie/snapshot.sql.gz dump was committed on 2026-04-01 and shipped in
every npm release since. Root cause: db-backup wrote pg_dump output inside
the repo tree, .gitignore did not exclude it, and package.json has no
files allow-list — so npm publish packed the 44 MB dump containing live
service credentials.
Changes:
- getSnapshotPath() now resolves to \${GENIE_HOME}/backups/<repo>/ instead
of <repo>/.genie/, so dumps can never land in the working tree
- assertOutsideRepo() guard refuses any snapshot path inside the repo
- Remove .genie/snapshot.sql.gz from working tree + index (history purge
tracked separately in the wish)
- .gitignore: add .genie/incidents/, .genie/snapshot.sql*, *.sql.gz,
*.dump, *.pgdump
- Tests updated to verify backups land outside the repo
- Wish plan drafted at .genie/wishes/security-key-leak-remediation/
Credential rotation verified independently (18/18 dead via API probes).
History rewrite, npm deprecate, and publish hardening tracked in the wish
Groups C and D.
Follow-up to previous commit — the three files below should have landed there but a pathspec error aborted the initial git add. - getSnapshotPath() now resolves under GENIE_HOME/backups/<repo>/, never inside the repo tree - assertOutsideRepo() refuses any snapshot path inside the repo - backup() creates the snapshot dir from the resolved path (not from a hard-coded <repo>/.genie) - Tests: snapshot path is outside repo; <repo>/.genie/snapshot.sql.gz is never created - .gitignore: block .genie/incidents/, .genie/snapshot.sql*, *.sql.gz, *.dump, *.pgdump
…nternal state Root cause of the 2026-04-14 .genie/snapshot.sql.gz leak was not just the committed dump — it was the lack of a files allow-list in package.json, so npm publish packed the full working tree minus .gitignore. This commit fixes the publish surface permanently: - package.json: files allow-list limits the tarball to dist/, skills/, plugins/genie/, scripts/postinstall-tmux.js, scripts/tmux/, src/db/migrations/, templates/, README.md, LICENSE. - .npmignore: defense-in-depth — explicit deny for *.sql.gz, *.dump, .env*, .genie/, .claude/, src/ (except migrations), tests, CI config, secrets/ — so even if files is accidentally removed, the worst patterns are still blocked. Result: tarball drops from 52.5 MB / 757 files to 2.3 MB / 141 files. Zero .genie/, .env, dump, or internal state leaks into the published package. Verified via `npm pack --dry-run`.
Scans every published tarball of @automagik/genie for the leaked .genie/snapshot.sql.gz, splits affected versions by the 72-hour unpublish window, runs npm unpublish on the self-service group, and generates a force-unpublish email for npm support covering the rest. Ground truth from direct tarball scan (not date correlation): - 92 versions contain the blob (4.260402.2 through 4.260414.1) - First clean version: 4.260414.2 Usage: bash scripts/incident-2026-04-14/npm-cleanup.sh # dry-run bash scripts/incident-2026-04-14/npm-cleanup.sh --execute # unpublish bash scripts/incident-2026-04-14/npm-cleanup.sh --rescan # refresh cache Path is scoped under scripts/incident-2026-04-14/ so the directory can be removed cleanly after npm support finishes the force-unpublish. The script is not in the package files allow-list so it will not ship.
npm unpublish exits 0 even when unauthenticated (PUT returns 404 but
the CLI still prints "- pkg@ver" and reports success). The first run
against the registry silently did nothing, making it look like 12
versions were removed when in fact they were still live.
Two fixes:
- abort up front if `npm whoami` fails
- re-query the registry after each unpublish and only report "removed"
when the version is actually gone; failures are collected for the
support-email fallback
The previous version redirected unpublish stdout/stderr to /dev/null,
which hid npm's web-auth OTP URL from the user — every unpublish was
silently failing with EOTP while the script reported failures without
context.
Changes:
- pass npm unpublish output straight through to the terminal so
OTP prompts and web-auth URLs are visible
- respect NPM_OTP env var when set (for TOTP-based batches)
- hint the user toward `npm token create` for non-interactive runs
|
Closing — superseded by #1149. |
Rolling Promotion PR
Auto-maintained rolling promotion PR from
devtomain.Process:
ready-to-mergeadded when all checks pass