Skip to content

Fix cross-group scheduled tasks getting wrong chat_jid#5

Closed
gavrielc wants to merge 1 commit intomainfrom
claude/fix-scheduled-task-jid-jTs3Y
Closed

Fix cross-group scheduled tasks getting wrong chat_jid#5
gavrielc wants to merge 1 commit intomainfrom
claude/fix-scheduled-task-jid-jTs3Y

Conversation

@gavrielc
Copy link
Copy Markdown
Collaborator

@gavrielc gavrielc commented Feb 1, 2026

When the main group scheduled a task for a target_group, the chatJid was
incorrectly using the main group's JID because the container passed its
own JID in the IPC message. Now the host process looks up the correct
JID for the target group from registeredGroups instead of trusting the
IPC payload.

https://claude.ai/code/session_01LEiLiUcbVeWQ4HXxj6p3pJ

When the main group scheduled a task for a target_group, the chatJid was
incorrectly using the main group's JID because the container passed its
own JID in the IPC message. Now the host process looks up the correct
JID for the target group from registeredGroups instead of trusting the
IPC payload.

https://claude.ai/code/session_01LEiLiUcbVeWQ4HXxj6p3pJ
@gavrielc
Copy link
Copy Markdown
Collaborator Author

gavrielc commented Feb 1, 2026

Conflicts with PR #3's IPC authorization changes. The fix concept is still valid (looking up target JID from registeredGroups instead of trusting IPC payload), but needs to be re-applied to the new code structure.

@gavrielc gavrielc closed this Feb 1, 2026
gavrielc added a commit that referenced this pull request Feb 1, 2026
…alidation

- PR #10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR #5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR #8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
deverman pushed a commit to deverman/nanoclawswift that referenced this pull request Feb 2, 2026
…alidation

- PR qwibitai#10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR qwibitai#5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR qwibitai#8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rlin1027 referenced this pull request in Rlin1027/NanoGemClaw Feb 6, 2026
Extended ContainerInput with mediaPath field:
- container-runner.ts: Added mediaPath to ContainerInput interface
- agent-runner/index.ts: Added mediaPath to internal ContainerInput
- index.ts: Pass mediaPath through runAgent -> runContainerAgent

Media handling flow:
1. User sends image via Telegram
2. extractMediaInfo() detects media type
3. downloadMedia() saves to groups/{folder}/media/
4. mediaPath passed to container as /workspace/group/media/{filename}
5. Agent can now analyze images using Gemini's vision capabilities

This enables image analysis without additional configuration.
@TomGranot TomGranot deleted the claude/fix-scheduled-task-jid-jTs3Y branch February 12, 2026 15:51
gavrielc added a commit that referenced this pull request Feb 17, 2026
…dently

- Remove post-apply base update from apply.ts (base is stable, only
  changes on core updates)
- Re-author Discord skill modify files against clean core (no Telegram
  dependency — Discord and Telegram are independent skills)
- Remove Docker contamination from both Telegram and Discord skill
  packages (restore Apple Container runtime from clean core)
- Update architecture docs: principle #5 and Section 1 reflect stable
  base correctly
- Update skills-system-status.md to reflect Phase 2 completion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tunmaker pushed a commit to tunmaker/nanoclaw that referenced this pull request Feb 24, 2026
…alidation

- PR qwibitai#10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR qwibitai#5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR qwibitai#8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
withhonor007 pushed a commit to withhonor007/nanoclaw-slack that referenced this pull request Feb 25, 2026
commit 452a9f8363c151bf440d405de195614307b3ca4f
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:43:52 2026 +0000

    restore

commit 55dbe9d4a57884ec5065ef6ba41704c2aac9f462
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:38:56 2026 +0000

    feat(skill/slack): include groups/main CLAUDE.md in package modifies with Slack formatting guidance

commit 846c6dbd6aca5ee57fda83c94f5afd1c5f7bf69d
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:26:22 2026 +0000

    docs(contributing): document nanorepo package-based skill format alongside instruction-based format

commit 1e024930d9dc93955939dc2581da860a050fc74c
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:25:53 2026 +0000

    fix(skill-pr): revert src/container-runner.ts to main baseline; ANTHROPIC_BASE_URL fix moved to fix/anthropic-base-url-passthrough branch

commit b651b3f0ac459afadde5d302e55074587f0dec38
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:24:46 2026 +0000

    feat(slack): downgrade skill version from 1.0.0 to 0.1.2 for pre-release alignment

commit ce81959f2e2b8adb2d32ade429b1f334086836f6
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 16:04:52 2026 +0000

    docs(slack): 更新技术债务文档至 v1.4,重新分类债务项并调整优先级

    - 版本号 1.3 → 1.4,更新日期 2026-02-25
    - 全局优先级"中等"改为"见各项优先级"
    - 新增"Part I: 核心代码架构债务"分类标题,明确债务项需修改 `src/` 主代码库
    - 债务项 #1 新增"优先级:中等 — 第二通道集成前必须解决"标签
    - 开发决策声明中"Part I 项"替代"所有债务项",限定范围更精确
    - 修正"Post-Application Revision"措

commit 6ce563117813ade0b9474ead36c0d7e172993bc0
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 15:41:55 2026 +0000

    docs(slack): 移除技术债务文档,已通过 Path C 实现解决

    - 删除 slack-technical-debt-zh.md(413 行)
    - 债务项 #1-qwibitai#4(*_ONLY 标志、路由增强、IPC 扩展、配置统一)已通过 skill-first Path C 实现(getChatName + IPC auto-resolve + resolveChannelName)
    - 债务项 qwibitai#5(核心文件修改)已在 W6 审计中确认为通用基础设施改进,无需回退
    - 文档版本 1.3,最后更新 2026-02-25,标记为"中等优先级"

commit a14d55f7885370673d095b0a376c7ab3cff68b58
Author: brand <gialovcompotrds@gmail.com>
Date:   Wed Feb 25 15:34:25 2026 +0000

    docs(slack): 更新用户指南术语和结构,新增 API 恢复章节

    - 标题改为"用户指南"(原"用户手册")
    - 统一术语:App→应用、Token→令牌、Main Channel→主频道、故障排查→故障排除、运维与监控→操作与监控
    - 新增第 10 节"API 恢复与弹性",说明 AI API 宕机时的失败消息丢弃和恢复后处理新消息机制
    - 概述部分新增自动 API 恢复功能说明
    - 前置条件表格标题"条件"改为"要求"
    - 简化描
atakankarsli added a commit to atakankarsli/nanoclaw that referenced this pull request Feb 27, 2026
…nts-a-k

feat: heartbeat, model routing, and agent behavior improvements
blaykeelder1-commits pushed a commit to blaykeelder1-commits/nanoclaw that referenced this pull request Mar 2, 2026
- qwibitai#5: Add 10s minimum cooldown between container spawns per group
  to prevent rapid credit burn from burst messages
- qwibitai#8: WhatsApp queue flush now stops on first failure instead of
  losing remaining messages (peek-then-shift pattern)
- qwibitai#10: Cap WhatsApp outgoing queue at 100 messages to prevent
  memory leak during extended disconnects
- qwibitai#14: Advance scheduled task next_run BEFORE enqueueing to prevent
  60s scheduler poll from double-firing the same task

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dptts added a commit to dptts/nanoclaw that referenced this pull request Mar 7, 2026
Prevents agents from receiving notifications for their own actions
on Forgejo (comments, PRs, self-assignments, etc.).

Changes:
- Filter out payload.sender from all recipients in determineRecipients()
- Skip noisy webhook events: closed, labeled, unlabeled, deleted
- Add 4 comprehensive tests for self-notification filtering

This solves the issue where agents were getting spammed with
notifications for every action they performed.

Fixes qwibitai#5

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
akasha-scheuermann pushed a commit to rscheuermann/nanoclaw that referenced this pull request Mar 14, 2026
…alidation

- PR qwibitai#10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR qwibitai#5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR qwibitai#8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bebekim pushed a commit to bebekim/goodclaw that referenced this pull request Mar 14, 2026
…alidation

- PR qwibitai#10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR qwibitai#5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR qwibitai#8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
kvasa pushed a commit to kvasa/nanoclaw that referenced this pull request Mar 15, 2026
…itai#8, qwibitai#11 + tests)

Security:
- Fix command injection in stopContainer(): use execFileSync/execFile with
  argument arrays instead of exec() with shell string interpolation.
  Renamed stopContainer() to stopContainerArgs() returning [bin, ...args].

Robustness:
- Fix cursor race condition (index.ts): saveState(chatJid) now does atomic
  read-modify-write of only that group's cursor, preventing cross-group
  cursor clobber when concurrent groups save/rollback simultaneously.
- Cap outgoing message queues in WhatsApp and Slack channels at 1000
  entries to prevent OOM when connection stays down.
- Add double-resolve guard in container-runner Promise (safeResolve()).
- Cache loadSenderAllowlist() result with 5s TTL to avoid synchronous
  file I/O on every incoming message.

Tests:
- mount-security.test.ts: 32 new tests for validateMount, validateAdditionalMounts,
  loadMountAllowlist (previously zero coverage on security-critical module).
- reaction-tracker.test.ts: 11 new tests covering race conditions between
  finalize() and transition timer.
- cursor-isolation.test.ts: 6 regression tests verifying per-group cursor isolation.
- Updated container-runtime.test.ts and sender-allowlist.test.ts for new APIs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Quirds pushed a commit to thankyourobot/tyr-aios that referenced this pull request Mar 24, 2026
…ge to both files

onboarding-patterns.md:
- Reorder pillars: Workspace Orientation moves from qwibitai#5 to qwibitai#3, before Access and Rhythms
- Add sequencing rationale at top of Five Pillars section
- Add operational notes nudge to Completing Onboarding

gap-analysis.md:
- Add operational notes nudge to Relationship to Onboarding: agent should write
  a brief ops note in projects/gap-analysis/ before closing onboarding so future
  sessions don't need to re-read the reference file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
luisherranz pushed a commit to luisherranz/nanoclaw that referenced this pull request Mar 31, 2026
Critical bugs:
- Bug qwibitai#4: Remove sequence from content hash to prevent duplicates on
  repeated PreCompact calls. Hash is now sha256(session_id:role:content).
- Bug qwibitai#5: storeMessages() now returns count of newly inserted messages.
  PreCompact only creates leaf summaries for newly inserted messages,
  preventing re-summarization of already-stored content.

Should-fix:
- #1/qwibitai#10: Add dbInitialized flag to skip redundant schema setup on
  repeated initLcmDatabase() calls (fast path for MCP tool calls).
- qwibitai#6: Depth-capped condensation now attempts API summarization first,
  falls back to truncated concatenation with 10K token cap instead of
  unbounded blob.
- qwibitai#7: Skip API call entirely when neither ANTHROPIC_API_KEY nor
  ANTHROPIC_AUTH_TOKEN is set, go straight to deterministic fallback.

Nice-to-have:
- qwibitai#3: Remove duplicate LcmMessage/LcmSummary from src/types.ts.
  Single source of truth is container/agent-runner/src/lcm-store.ts.
@Nate-Vish Nate-Vish mentioned this pull request Mar 31, 2026
5 tasks
morrowgarrett added a commit to morrowgarrett/nanoclaw that referenced this pull request Apr 1, 2026
…ation

qwibitai#5 Warm container: Already supported via 30min IDLE_TIMEOUT + IPC piping.
   Docker startup is only 0.4s; Claude Code init is the real bottleneck.
   Full elimination requires embedded SDK (future).

qwibitai#6 Frozen memory snapshot + prompt caching:
- Query memU once at container start for relevant context
- Inject as immutable system prompt prefix
- Enables Anthropic's automatic prefix caching (50-75% token savings)
- Memory context frozen for session duration (no mid-turn re-queries)

qwibitai#7 Smart model routing: Skipped — Agent SDK doesn't expose model selection
   in query options. Would require SDK changes or CLI wrapper.

qwibitai#8 FTS5 session search:
- Added FTS5 virtual table on messages for full-text cross-session search
- Auto-synced via INSERT/DELETE triggers
- searchMessages() function for keyword-based message recall
- Complements memU's semantic search with fast keyword search

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quirds added a commit to thankyourobot/tyr-aios that referenced this pull request Apr 8, 2026
Adversarial review surfaced 10+ issues with the junction table migration
and maintenance features. Resolved the ones that matter most for
pre-production deploy:

Schema cleanup:
- Collapsed all 7 LCM migrations into base schema (DBs will be wiped
  before production, no upgrade path needed)
- Dropped dead JSON columns (source_message_ids, parent_summary_ids,
  child_summary_ids) that were write-only after junction table refactor
- Removed legacy session_id→conversation_id rename
- Removed lcm_schema_version and migration framework entirely

API cleanup:
- StoreSummaryInput now takes sourceMessageIds/childSummaryIds as arrays
  (was: JSON-stringified strings)
- Removed silent try/catch on JSON parse failures
- Removed the range-based fallback in lcm-subagent read_source
  (junction tables are authoritative)
- Renamed getCoveredLeafIds → getCoveredSummaryIds (name was a lie:
  returned any covered summary, not just leaves)

Dead code removal:
- Deleted lcm-transcript-repair.ts entirely (was wired at wrong point
  in architecture: applied to stored messages, but our pipeline never
  re-sends those to an API, so it was fixing a problem we don't have)
- Removed unused repairToolPairing import in lcm-helpers.ts

Safety & correctness:
- Pruning safety floors: minRetainedConversations (default 1) and
  maxDeleteFraction (default 0.5), with force=true override
- Integrity check qwibitai#3 (leaf lineage) bumped from warning to error
  since getMessagesForSummary has no fallback path
- Integrity check qwibitai#4 (condensed lineage) same treatment
- Integrity check qwibitai#5 (orphans) rewrote N+1 query loop as a single
  JOIN query using the junction table index

DR script (aios-infra):
- Extended dr-test.sh with LCM integrity checks: summarization stall
  detection, orphan leaf/condensed summary detection, schema verification

125 tests passing, tsc clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
niels-emmer added a commit to niels-emmer/nanoclaw that referenced this pull request Apr 9, 2026
- Read HTTP Content-Type header from audio download response instead of
  hardcoding audio/ogg; falls back to Matrix event info.mimetype
- Map MIME type to correct file extension for OpenAI Whisper (webm, ogg,
  wav, flac, mp3, mp4) — fixes 400 errors from Chrome-based Element Web
  which sends audio/webm;codecs=opus
- Add HTTP response status check before attempting transcription
- Docs: add issues qwibitai#5 (container image loss) and qwibitai#6 (voice transcription
  MIME mismatch) to DEBUG_CHECKLIST.md with diagnosis commands
- Docs: add Linux systemd commands to Service Management section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
luisherranz pushed a commit to luisherranz/nanoclaw that referenced this pull request Apr 10, 2026
Critical bugs:
- Bug qwibitai#4: Remove sequence from content hash to prevent duplicates on
  repeated PreCompact calls. Hash is now sha256(session_id:role:content).
- Bug qwibitai#5: storeMessages() now returns count of newly inserted messages.
  PreCompact only creates leaf summaries for newly inserted messages,
  preventing re-summarization of already-stored content.

Should-fix:
- #1/qwibitai#10: Add dbInitialized flag to skip redundant schema setup on
  repeated initLcmDatabase() calls (fast path for MCP tool calls).
- qwibitai#6: Depth-capped condensation now attempts API summarization first,
  falls back to truncated concatenation with 10K token cap instead of
  unbounded blob.
- qwibitai#7: Skip API call entirely when neither ANTHROPIC_API_KEY nor
  ANTHROPIC_AUTH_TOKEN is set, go straight to deterministic fallback.

Nice-to-have:
- qwibitai#3: Remove duplicate LcmMessage/LcmSummary from src/types.ts.
  Single source of truth is container/agent-runner/src/lcm-store.ts.
chocoSprite added a commit to chocoSprite/nanoclaw that referenced this pull request Apr 12, 2026
router.ts (62줄)에서 4개 함수(escapeXml/formatMessages/stripInternalTags/
formatOutbound)를 신규 src/formatting.ts로 분리. 신호:

- 해당 함수들의 테스트 파일 이름이 이미 formatting.test.ts였음 (의도된
  구조와 현재 구조의 mismatch 명시 표시)
- index.ts:84의 "Re-export for backwards compatibility during refactor"
  hack 본인이 임시 표시 남김 (이제 제거 가능)
- routeOutbound는 dead code (호출 0건) 발견하여 함께 삭제

router.ts 62→8줄 (findChannel만 남음). index.ts/session-commands.ts/
db.test.ts/formatting.test.ts import 경로 갱신. 408/408 통과.
project_final_review.md qwibitai#5 완료.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
foxsky added a commit to foxsky/nanoclaw that referenced this pull request Apr 12, 2026
…index

Three parallel review agents (reuse, quality, efficiency) flagged
actionable items on Phase 2:

1. TYPE SAFETY (Agent 1 qwibitai#5, Agent 2 qwibitai#4): The pending_approval response
   field was not declared in UpdateResult, and new AdminResult fields
   (offer_register, merged, source_archived, notes_added) were only
   returned via 'as any' casts. Fixed:
   - UpdateResult extended with pending_approval: { request_id,
     target_chat_jid, message, parent_board_id }
   - AdminResult extended with offer_register, merged, source_archived,
     notes_added (used by merge_project and handle_subtask_approval)
   - All 4 'as any' casts in the Phase 2 code removed
   - Also cleaned up `parentBoard?.group_jid ?? null` dead fallback
     (the null case was already made unreachable by the earlier
     fail-fast guard)

2. UNUSED INDEX (Agent 3 qwibitai#6): idx_subtask_requests_status on
   (status, target_board_id) was never queried — the dominant query
   is the PK lookup on request_id (O(1)). Removed the index and the
   drift-guard test that asserted its existence. Added a comment
   explaining the decision so a future scan-by-pending query can
   reinstate it.

Deferred (acceptable at current scale):
- subtask_requests grows unbounded: zero boards have opted into
  approval mode, so no current users. Revisit when adoption warrants.
- N+1 insert in approve loop: typical batches < 10 subtasks,
  better-sqlite3 caches prepared statements.
- decision field conflates handle_subtask_approval + process_minutes_
  decision: matches existing codebase pattern.
- Reject/approve notification duplication: only 2 sites with small
  variation, helper extraction would save ~2 lines.

236 engine / 365 skill tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dm-j pushed a commit to dm-j/nanoclaw that referenced this pull request Apr 13, 2026
…alidation

- PR qwibitai#10: Add sentinel markers for robust JSON parsing between container
  and host. Fallback to last-line parsing for backwards compatibility.

- PR qwibitai#5: Look up target JID from registeredGroups instead of trusting
  IPC payload, fixing cross-group scheduled tasks getting wrong chat_jid.

- PR qwibitai#8: Add lightweight schedule validation in container MCP that
  returns errors to agents (cron syntax, positive interval, valid ISO
  timestamp). Also defensive validation on host side.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
alanz added a commit to alanz/nanoclaw that referenced this pull request Apr 18, 2026
…g fixes

Three divergences resolved against the current implementation:

- Incremental reset archives (#1/qwibitai#2): ArchiveAndStartThrowawayOnReset now
  binds a prior_archives lookup, derives latest_prior_at, and passes it as
  messages_since on the new archive (null = full transcript). Added
  NonOverlappingArchivesPerSession invariant to assert no message timestamp
  sits inside the range of two non-placeholder archives for the same session.
  All other creation sites set messages_since: null.

- Path format (qwibitai#4): all example archive paths now include the {HHmm} time
  component that the code has always written.

- ThrowawaySession status (qwibitai#5): creation sites changed from status: queued
  (undeclared) to status: running, matching the code where runContainerAgent
  is called immediately with no queued step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gavrielc added a commit that referenced this pull request Apr 18, 2026
PR #5 review flagged three behavior changes that shouldn't have slipped
in. This commit reverts each to match the pre-refactor behavior exactly.

1. User upsert ordering. Split the router hook into two setters:
   setSenderResolver (runs before agent resolution) and setAccessGate
   (runs after). Restores the pre-PR sequence where the users row is
   upserted even if the message is dropped by wiring or trigger rules.

2. dropped_messages audit. Moved src/modules/permissions/db/dropped-messages.ts
   back to src/db/dropped-messages.ts. The table is core audit infra, not
   permissions-specific. Router re-writes rows for no_agent_wired and
   no_trigger_match; the access gate writes rows for policy refusals.

3. Permissionless container fallback. Dropped. poll-loop restores the
   original deny-all check when NANOCLAW_ADMIN_USER_IDS is empty.

Module contract doc updated with the two-hook shape.

Validation: host build clean, 137/137 host tests, 17/17 container
tests, typecheck clean, service boots to "NanoClaw running" with
permissions module registering both hooks and clean SIGTERM shutdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gavrielc added a commit that referenced this pull request Apr 18, 2026
PR #5 moved src/db/users.ts and src/db/user-roles.ts into the permissions
module. The channels branch's telegram adapter still imported from the
old paths — update to src/modules/permissions/db/*.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gavrielc added a commit that referenced this pull request Apr 18, 2026
…optional

Promotes approvals to the default tier with a public API (requestApproval +
registerApprovalHandler) that other modules consume. Self-modification
(install_packages / request_rebuild / add_mcp_server) moves into a new
optional module that registers delivery actions + matching approval handlers
via the new API.

## Approvals (default tier)

- Adds `src/modules/approvals/primitive.ts` exporting `requestApproval`,
  `registerApprovalHandler`, `notifyAgent`. Absorbs `pickApprover` /
  `pickApprovalDelivery` / `channelTypeOf` from the deleted `src/access.ts`.
- Rewrites `response-handler.ts` to dispatch to registered approval handlers
  on approve (action-keyed Map). Reject path is centralized.
- Drops the three self-mod-specific delivery-action registrations from
  `approvals/index.ts`; they belong to self-mod now.
- `onecli-approvals.ts` now imports picks from the primitive instead of
  `src/access.ts`.

## Self-mod (optional tier)

- New `src/modules/self-mod/` with request handlers (validate input + call
  requestApproval) and apply handlers (orchestration on approve).
- `apply.ts` owns updateContainerConfig + buildAgentGroupImage + killContainer
  calls. Self-mod depends on approvals (via registerApprovalHandler +
  requestApproval + notifyAgent) and on core (container-runner, container-config).
- Registers 3 delivery actions + 3 approval handlers at import time.

## Other changes

- `src/access.ts` and `src/access.test.ts` deleted. Tests split across
  `src/modules/approvals/picks.test.ts` (approver selection) and
  `src/modules/permissions/permissions.test.ts` (access + roles + DM).
- `src/modules/index.ts` barrel: approvals loads before self-mod so
  registerApprovalHandler is bound when self-mod registers at import time.

## Validation

- `pnpm run build` clean
- `pnpm test` — 137 host tests pass
- `bun test` in container/agent-runner — 17 tests pass
- Service starts; boot log shows `OneCLI approval handler started`,
  `NanoClaw running`; clean SIGTERM shutdown

Resolves the transitional tier violation flagged in PR #5 where core
imported from the permissions optional module via `src/access.ts`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 20, 2026
…ASR upgrade

Urgent insertion after Phase 05 Plan 05-03 Task 5 live verification surfaced
3 unfixable-in-wave defects: qwibitai#4 retry-args, qwibitai#5 attempt_no hardcoded, qwibitai#6
persona handoff broken after amd_result=human. See 05-03-TASK5-DEFECTS.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
charlie17 added a commit to charlie17/nanoclaw that referenced this pull request Apr 21, 2026
…e3 stdlib

Trigger qwibitai#5 of midnight-reset showed task status=success but sessions row NOT deleted. Same defect class as fix 4: container base node:22-slim has no sqlite3 CLI, so `sqlite3 ... DELETE ...` silently failed with command-not-found. Session row persisted; D3 D-gate failed.

Fix: rewrite DELETE as python3 heredoc using sqlite3 stdlib. touch _close and the final JSON emission are unchanged (bash builtins, no CLI deps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 21, 2026
…t per (phone, date) for distinct idempotency_keys

- Add 5 tests in defect qwibitai#5 describe block:
  1. two distinct keys → attempt_no 1 and 2 (RED: UNIQUE constraint fails)
  2. same idempotency_key → duplicate:true, one row (regression guard, passes at RED)
  3. three distinct keys → attempt_no 1, 2, 3 (RED: UNIQUE constraint on 2nd insert)
  4. same phone, different dates → both attempt_no=1 (regression, passes at RED)
  5. MAX+1 over gap (seeded 1,2,5 → new=6) (RED: UNIQUE on hardcoded 1)
- 3/5 fail RED with SqliteError UNIQUE; 2/5 pass as regression guards
- Tests use fresh_db + mock fetch pattern from existing test file
- Test 5 proves COALESCE(MAX+1) semantics NOT COUNT-based (gaps preserved per RESEARCH §9)
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 21, 2026
… via db.transaction + SELECT MAX+1

Replace hardcoded attempt_no=1 at voice-start-case-2-call.ts:211 with
better-sqlite3 db.transaction() wrapping SELECT COALESCE(MAX(attempt_no), 0) + 1
+ INSERT. Mirrors project idiom at voice-case-2-retry.ts:155-184.

- Two distinct idempotency_keys for same (target_phone, calendar_date) now
  both INSERT successfully with attempt_no 1 and 2 (enables lunch + dinner
  same day at same restaurant)
- D-7 duplicate-check flow at lines 163-197 preserved — identical key still
  short-circuits to {ok:true, duplicate:true} without INSERT and without
  incrementing attempt_no
- COALESCE(MAX+1) accepts gaps per RESEARCH §9 (PK unique, ordinal audit-only)
- Code comment cites RESEARCH §8 Pitfall 4 invariant: tool runs in fresh
  MCP request handler, no enclosing transaction
- Tests 1-5 green (19 total in this file); full voice-case-2-retry regression
  suite green (no drift on shared voice_case_2_attempts table)
- Root build clean; voice-bridge build clean
- deferred-items.md: pre-existing src/channels/gmail.test.ts buildQuery
  failure noted (unrelated to this plan, verified on pristine base)

Closes defect qwibitai#5 (DEFECTS.md §5, Plan 05.1 RESEARCH §5).
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 21, 2026
…allocation

SUMMARY.md for Plan 05.1-04:
- Defect qwibitai#5 closed; voice_start_case_2_call supports same-day multi-booking
- TDD RED (0a695ec) + GREEN (2e9d2c8), no REFACTOR
- 5 new tests + 14 pre-existing = 19/19 pass in voice-start-case-2-call.test.ts
- voice-case-2-retry.test.ts (14/14) regression-clean on shared voice_case_2_attempts table
- Root + voice-bridge builds green
- Deferred: pre-existing src/channels/gmail.test.ts buildQuery failure (verified pre-existing on pristine base, out of scope)

STATE.md and ROADMAP.md intentionally NOT updated (parallel executor — orchestrator owns those writes).
@alecburrett alecburrett mentioned this pull request Apr 23, 2026
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 24, 2026
- 7/8 PASS: qwibitai#2 setTimeout, qwibitai#3 idle_timeout_ms, qwibitai#4 CASE6B_PERSONA gone, qwibitai#5 tsc strict, qwibitai#6 Plan-XX refs (13 ≤ 30), qwibitai#7 suite green + D-6 byte-identical, qwibitai#8 finding file
- 1 PARTIAL: #1 LOC delta — CONTEXT baseline 7021 measure shows -274 (LOC INCREASED), but git pre-plan baseline (7529) shows +234 reduction (78% of 300 target). CONTEXT baseline was captured pre-Phase-05.2-final-merge; cross-check is the honest measurement.
- D-6 evidence: accept.test.ts:285-311 byte-identical pre/post phase
- §201 invariant tests green (audio-guard + ghost-scan + amd-classifier 3/3 files / 25 tests)
- Plan 05.2-03 D-8 invariant test green (sideband-wait-for-speech 4/4)
- silence-monitor.ts: 227 LOC VAD ladder → 49 LOC hard-safety stub (-176 LOC, biggest delta)
- persona.ts: -86 LOC (CASE6B_PERSONA deleted, dead exports retired)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ravingfan-blip pushed a commit to ravingfan-blip/nanoclaw that referenced this pull request Apr 24, 2026
INVARIANTS — replace the now-stale "Testing-mode 7-day expiry" note
with a Production-mode token-refresh note that points at SESSION_HANDOFF
for the manual re-auth procedure (only needed if tokens are revoked).

REGRESSION_TESTS — add Section D with a status table for the v1 stable
run on 2026-04-24, marking each of the 14 test items PASS / NOT RUN
with notes. Clarify test qwibitai#5 to make explicit that the only thing
between the user and a sent email is Jarvis's persona discipline (the
OAuth grant technically permits send).

LESSONS — fill in the previously placeholder file with six engineering
lessons captured during the v1 build: pre-installing MCP servers in the
Dockerfile to dodge the SDK startup timeout; the WhatsApp self-chat
fromMe trap that hides owner messages from feedback filters; the
unreliable self-presence loopback that strands the typing indicator;
the double-prefix gotcha when both the persona and the channel add the
prefix; the gongrzhe Gmail MCP scope hardcoding; and the GCP
Production-publish trick that removes the weekly refresh-token
rotation. Also promote the "examples of bad outputs" from placeholders
to concrete cases observed or anticipated.

STABLE_BASELINE — promote the baseline to "STABLE on main", point at
the merge commit 9d71efe and the tag jarvis-stable-2026-04-24,
list the runtime artifacts that exist outside git (OAuth credentials,
SQLite registration, persona file), and rewrite the rollback
instructions for a post-merge world (revert / reset, force-push,
SQLite delete, container rebuild).

SESSION_HANDOFF — replace "None yet — docs-only scaffold" with the
actual stable behaviours validated on 2026-04-24, and replace the
now-obsolete "Permanent fix: publish to Production" instructions with
a "Rolling back to Testing mode" note for the inverse direction.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
carstenf pushed a commit to carstenf/nanoclaw that referenced this pull request Apr 25, 2026
…4 warnings

Plan-checker revision round 2 fixes for Phase 05.6:

BLOCKER #1 — REQ-DIR-17 real NanoClaw-side gateway (Plan 06-01):
- Added Task 4 to Plan 06-01: ships src/voice-mid-call-gateway.ts +
  src/voice-mid-call-gateway.test.ts. Module exports checkMidCallMutation,
  registerActiveCall, deregisterActiveCall, isCallActive. Active-call
  set lifecycle bound to voice_triggers_init (register on entry) and
  voice-finalize-call-cost (deregister on completion).
- Modified ToolRegistry in src/mcp-tools/index.ts to be metadata-aware:
  register(name, handler, meta) accepts { mutating: true } and the
  invoke() dispatch path calls checkMidCallMutation BEFORE the handler
  runs. Mutating tools registered with { mutating: true } at registration
  time. 11 mutating tools enumerated.
- Updated must_haves.truths in Plan 06-01 to reflect 3-tier defense
  (agent prompt + dispatch gateway + handler-boundary sentinel) and the
  active-call set lifecycle.
- Updated success_criteria + frontmatter (files_modified, artifacts,
  key_links) to add the new gateway module + its integration points.

BLOCKER qwibitai#2 — FAIL-recovery wording (Plan 06-02 + 06-03):
- Plan 06-02 <objective> now contains an explicit FAIL-recovery policy:
  diagnose, land fix in separate plan/hot-patch (NOT in 05.6 plans),
  re-run synthetic smoke, re-execute failed step from beginning,
  three-strike escalation to ASK FOR CHAT. Policy applied to Task 2
  (synth FAIL), Task 4 (inbound FAIL), Task 6 (outbound FAIL). §201
  BREACH does NOT follow generic recovery — audit-level investigation
  required.
- Plan 06-03 Task 3 already had `git revert HEAD` recovery; now also
  notes the runtime-ENV revert window REOPENS after revert.

WARNING qwibitai#3 — Runtime-revert truth qualification (Plan 06-03):
- must_haves.truth qualified to "Step 1→Step 2 ONLY; after Step 2 the
  emergency revert path becomes `git revert <Step-2-cleanup-SHA>` per
  D-30." Same qualification added to <objective>, the Step 1 commit
  message, the Step 2 commit message, success_criteria, and the
  briefing template.

WARNING qwibitai#4 — Wrong WireGuard IP (Plan 06-02 + 06-03):
- Replaced hardcoded http://10.0.0.2:3201/ with http://127.0.0.1:3201/
  in: Plan 06-02 Task 1 step 2 (.env append + curl /health verification);
  Plan 06-03 Task 2 step 7 (.env.example update); the briefing template
  in Plan 06-03 Task 5; verification + acceptance_criteria across both
  plans. NanoClaw + voice-bridge are co-located on Lenovo1 per
  /opt/server-docs/MASTER.md + project_nanoclaw_infra memory — local
  loopback. 10.0.0.x is the WireGuard subnet, not a NanoClaw transport
  address. Both plans now also instruct: if container deploy changes
  the host, ASK Carsten for the lenovo1-internal address — do NOT
  guess; do NOT use 10.0.0.x.

WARNING qwibitai#5 — §201 audio-leak jq query (Plan 06-02):
- Aligned the jq selector with tracing-contract.md: contract specifies
  `delta` is STRIPPED and replaced with `delta_bytes` integer. Task 4
  step 4 now (a) verifies every response.audio.delta event has
  delta_bytes integer (redaction integrity), AND (b) asserts no
  response.audio.delta event retains a non-empty .delta payload (BREACH
  on any leak). Same query applied in Task 6 step 3 for the outbound
  trace.

WARNING qwibitai#6 — Du/Sie negative check missing (Plan 06-02):
- Task 4 step 6 (inbound, Du-axis) and Task 6 step 3.d (outbound,
  Sie-axis) now BOTH run a negative check: PLACEHOLDER_LEAK=$(jq -r
  '...instructions...' | grep -c '{{[a-z_]\+}}'); test
  "$PLACEHOLDER_LEAK" -eq 0 — BREACH on any unsubstituted {{...}}
  token. Positive Du/Sie token check stays as before; negative
  placeholder-leak check added on top.

Files modified:
- .planning/phases/05.6-container-agent-integration-cutover/05.6-01-PLAN.md
- .planning/phases/05.6-container-agent-integration-cutover/05.6-02-PLAN.md
- .planning/phases/05.6-container-agent-integration-cutover/05.6-03-PLAN.md

Phase scope unchanged — fixes are corrective, not additive scope. The
new src/voice-mid-call-gateway.ts file is NEW SOURCE CODE that the
executor (later /gsd-execute-phase) writes; the planner only updates
the PLAN.md task spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jmcstone added a commit to jmcstone/nanoclaw that referenced this pull request Apr 25, 2026
… + lode rename

MCP server key rename (agent-runner/src/index.ts):
- mcpServers['inbox'] → mcpServers['messages'] so the agent-runner registers
  the mailroom HTTP server under the 'messages' key. The SDK prepends
  'mcp__messages__' to every bare tool name the server returns (after the
  companion mailroom commit strips the old 'mcp__inbox__' prefix from
  descriptors). Net result: Madison sees 'mcp__messages__query' etc. —
  no more double-prefix bug.
- allowedTools wildcard updated: 'mcp__inbox__*' → 'mcp__messages__*'
- Log message updated: "inbox MCP: enabled" → "messages MCP: enabled"

mcp-tool-discovery.ts + test:
- computeGroupMcpHash() pushes 'messages' (not 'inbox') into the server names
  set for the telegram_inbox group, keeping session-hash invalidation accurate.
- Test assertions updated: serverNames.toContain('messages').

Lode docs (lode/architecture/madison-pipeline.md):
- Mermaid edge label updated: 'mcp__inbox__*' → 'mcp__messages__*'

lode/lessons.md:
- New lesson: "Name things by what they ARE, not where they live" — documents
  the inbox-vs-messages naming mistake and the labels:["INBOX"] filter pattern
  as the canonical narrow-inbox view.

Madison persona (~/containers/data/NanoClaw/groups/telegram_inbox/CLAUDE.md,
outside repo — Write directly):
- Global find/replace: 43 occurrences of mcp__inbox__ → mcp__messages__
- New paragraph after filter documentation: explains "full store vs current
  Inbox view" and the labels:["INBOX"] cross-source filter pattern
- Example qwibitai#5 updated to show labels:["INBOX"] alongside read:false as the
  canonical "unread in my current inbox view" pattern

All 334 nanoclaw tests pass. tsc --noEmit: zero errors.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
manarde added a commit to manarde/nanoclaw that referenced this pull request Apr 27, 2026
…ibitai#5 — P1)

Previously shutdown() drained the queue and disconnected channels then
process.exit(0)'d, leaving any in-flight host_mcp_query `claude -p`
children running. Their per-child exit handler in src/ipc.ts therefore
never fired:

- Request descriptor (data/ipc/<group>/host-mcp-requests/<id>.json) and
  host-only .mcp-config.json files persist as orphans across restart.
- Worse: an orphaned claude can still write a reply via
  host-mcp-reply-server AFTER the daemon restarts. The user sees
  late/duplicate messages, and if registered_groups changed during
  the gap the reply could land in the wrong chat.

Fix: in shutdown(), iterate hostMcpActiveChildren and kill each child
with SIGTERM, wait 2s, then SIGKILL the survivors. Mirrors the
per-request kill timing in src/ipc.ts. Best-effort — errors from
.kill() are swallowed and the loop doesn't block shutdown indefinitely.

Note: integration-level verification only; per spec, no unit test added
since simulating the SIGTERM/SIGINT path in isolation requires
significant new infrastructure.

Also includes prettier auto-format leftover from the FIX 4 commit.

Ref: docs/plans/2026-04-24-001-feat-host-mcp-proxy-plan.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants