fix(migrate-v2): reset auto-created messaging_group policy on re-run
If 1b-db is re-run after the v2 service has already started (e.g.
recovering from an earlier failure), the messaging_group it would
otherwise create may already exist — auto-created by the runtime router
on the first inbound message, with the router's default
unknown_sender_policy ('request_approval'), not the migration's intent
('public'). The previous reuse path skipped creation but never updated
the policy, so re-runs left the bot hanging every message waiting for
an approver that wasn't seeded yet.
When reusing an existing row that has zero wired agent_groups (signal
of a router auto-create), reset the policy to 'public'. Once any wiring
exists, the user has had a chance to tighten via the skill — leave it.
Also adds a CHANGELOG entry covering this and the two sibling fixes
(Discord DM resolution, symlink skip in copyTree).
This commit is contained in:
committed by
exe.dev user
parent
7dbedad9bd
commit
3b5e5a24f4
@@ -7,6 +7,7 @@ For detailed release notes, see the [full changelog on the documentation site](h
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
- **v1 → v2 migration.** Run `bash migrate-v2.sh` from the v2 checkout. Finds your v1 install (sibling directory or `NANOCLAW_V1_PATH`), merges `.env`, seeds the v2 DB from `registered_groups`, copies group folders (`CLAUDE.md` → `CLAUDE.local.md`), copies session data with conversation continuity, ports scheduled tasks, interactively selects and installs channels (clack multiselect), copies container skills, builds the agent container, and offers a service switchover to test. Hands off to Claude (`/migrate-from-v1`) for owner seeding, access policy, CLAUDE.md cleanup, and fork customization porting. See [docs/migration-dev.md](docs/migration-dev.md) and [docs/v1-to-v2-changes.md](docs/v1-to-v2-changes.md).
|
- **v1 → v2 migration.** Run `bash migrate-v2.sh` from the v2 checkout. Finds your v1 install (sibling directory or `NANOCLAW_V1_PATH`), merges `.env`, seeds the v2 DB from `registered_groups`, copies group folders (`CLAUDE.md` → `CLAUDE.local.md`), copies session data with conversation continuity, ports scheduled tasks, interactively selects and installs channels (clack multiselect), copies container skills, builds the agent container, and offers a service switchover to test. Hands off to Claude (`/migrate-from-v1`) for owner seeding, access policy, CLAUDE.md cleanup, and fork customization porting. See [docs/migration-dev.md](docs/migration-dev.md) and [docs/v1-to-v2-changes.md](docs/v1-to-v2-changes.md).
|
||||||
|
- **Migration fixes.** `1b-db` now resolves Discord DMs as `discord:@me:<id>` (previously skipped any v1 chat that wasn't a guild channel — a blocker for personal-bot installs). `1c-groups` skips symlinks instead of following them (a single broken `.claude-shared.md → /app/CLAUDE.md` no longer aborts the whole copy). When `1b-db` reuses an auto-created `messaging_group` with no wired agents, its `unknown_sender_policy` is now reconciled to the migration's `public` default.
|
||||||
|
|
||||||
## [2.0.0] - 2026-04-22
|
## [2.0.0] - 2026-04-22
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ import {
|
|||||||
createMessagingGroup,
|
createMessagingGroup,
|
||||||
createMessagingGroupAgent,
|
createMessagingGroupAgent,
|
||||||
getMessagingGroupAgentByPair,
|
getMessagingGroupAgentByPair,
|
||||||
|
getMessagingGroupAgents,
|
||||||
getMessagingGroupByPlatform,
|
getMessagingGroupByPlatform,
|
||||||
|
updateMessagingGroup,
|
||||||
} from '../../src/db/messaging-groups.js';
|
} from '../../src/db/messaging-groups.js';
|
||||||
import { runMigrations } from '../../src/db/migrations/index.js';
|
import { runMigrations } from '../../src/db/migrations/index.js';
|
||||||
import { readEnvFile } from '../../src/env.js';
|
import { readEnvFile } from '../../src/env.js';
|
||||||
@@ -147,7 +149,15 @@ async function main(): Promise<void> {
|
|||||||
ag = getAgentGroupByFolder(g.folder)!;
|
ag = getAgentGroupByFolder(g.folder)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// messaging_group — one per (channel_type, platform_id)
|
// messaging_group — one per (channel_type, platform_id).
|
||||||
|
//
|
||||||
|
// If the row already exists *and* has zero wired agent_groups, it
|
||||||
|
// was almost certainly auto-created by the runtime router on an
|
||||||
|
// inbound message (which uses 'request_approval' or similar — not
|
||||||
|
// the migration's 'public'). Reset its policy to match what the
|
||||||
|
// migration would have set if it had created the row first. Once
|
||||||
|
// any wiring exists, the user has had a chance to tighten the
|
||||||
|
// policy via the skill — leave it alone.
|
||||||
let mg = getMessagingGroupByPlatform(channelType, platformId);
|
let mg = getMessagingGroupByPlatform(channelType, platformId);
|
||||||
if (!mg) {
|
if (!mg) {
|
||||||
createMessagingGroup({
|
createMessagingGroup({
|
||||||
@@ -160,6 +170,12 @@ async function main(): Promise<void> {
|
|||||||
created_at: createdAt,
|
created_at: createdAt,
|
||||||
});
|
});
|
||||||
mg = getMessagingGroupByPlatform(channelType, platformId)!;
|
mg = getMessagingGroupByPlatform(channelType, platformId)!;
|
||||||
|
} else if (
|
||||||
|
mg.unknown_sender_policy !== 'public' &&
|
||||||
|
getMessagingGroupAgents(mg.id).length === 0
|
||||||
|
) {
|
||||||
|
updateMessagingGroup(mg.id, { unknown_sender_policy: 'public' });
|
||||||
|
mg = getMessagingGroupByPlatform(channelType, platformId)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// messaging_group_agents — wire them
|
// messaging_group_agents — wire them
|
||||||
|
|||||||
Reference in New Issue
Block a user