14 KiB
Service and module map
This is an ownership map, not an API dump. Read the owning implementation and tests before changing behavior.
Lifecycle and account ownership
| Module | Owns | Important constraints |
|---|---|---|
src/bootstrap.ts |
Dependency composition and startup wiring | Keep business policy in services; preserve initialization order and test seams. |
src/main-loop.ts |
Shared discovery/screening/dispatch workers and legacy loop | Loops are abortable; queue transitions and shutdown must remain recoverable. |
services/reddit-account-runtime.ts |
Immutable account runtime/factory/manager lifecycle | Same-account operations serialize; session refresh replaces one runtime. |
services/reddit-user-messenger.ts |
Account selection for explicit API/MCP messages | Prefer the newest existing conversation owner; otherwise choose the authenticated running account with the fewest hourly sends. |
services/reddit-account-runtime-builder.ts |
Concrete account dependency graph and account loop | Account-specific browser, Matrix, repos, limiter, automation, chat, and media live here. |
services/account-runtime-event-wiring.ts |
Per-account chat-to-realtime event bridge | Every account runtime publishes reply, media, and sync events into the shared dashboard/push stream; sync IDs remain account-scoped. |
services/reddit-accounts.ts |
Account import/activation orchestration | Verification must bind Reddit cookies and Matrix identity before activation. |
services/account-auth-context.ts |
Current verified identity snapshot | Account work pauses unless both sides authenticate. |
services/session-bound-runtime.ts |
Legacy auth-bound background lifecycle | Prevents background work while logged out. |
Discovery, preparation, and delivery
| Module | Owns | Important constraints |
|---|---|---|
services/monitor.ts |
Subreddit ordering, post/comment candidate fetching, reaction/age/gender/seller screening, rejection summaries | Comment reactions fail closed at the confidence gate and, when configured, the expressed-gender gate; cheap checks run first; preserve exact rejection/deferred counts; listing 404 disables the subreddit. |
reddit/api.ts |
Reddit JSON calls, post/comment parsing, seller/profile evidence, username resolution, error types | All reads must use the coordinator; redact error metadata. |
reddit/request-coordinator.ts |
Process-wide Reddit request spacing and cooldown | Space failed requests too; 429 cooldown is global. |
services/processor.ts |
Source-specific AI preparation and outbound safety | Returns prepared or explicit skip; performs no remote chat send. |
services/comment-targeted-opener.ts |
Deterministic commenter/source attribution validation | Requires comment grounding; rejects source-image ownership/appearance claims and image requests before a commenter opener can be prepared. |
services/physique-targeting.ts |
Pure optional score-range decision for image candidates | Disabled means pass; enabled ranges reject unknown and out-of-range scores before opener generation. |
services/strategy-selector.ts |
Weighted explore/exploit selection and experiment metadata | Separate image/chat strategy sections; respect mature response window and sample floor. |
services/recipient-deduplicator.ts |
Global recipient history plus live reservation | Case-insensitive; release failures, commit successes, recover stale claims. |
utils/rate-limiter.ts |
Per-account send spacing/hour limits/jitter | Increment only for confirmed sends; reply priority may use the same limiter. |
database/candidate-queue-repository.ts |
Durable candidate state machine, leases, retries, prepared-message replacement, counts, and manual clearing | Mutations require an eligible state or expected worker lease; recover expired/interrupted work; reject active comments admitted under a superseded eligibility policy; operator edits clear AI attribution; manual removals preserve sending leases and terminal audit rows. |
Account growth
Comment-based growth exists so a new account accumulates the age/karma history Reddit requires before it will accept chat invitations. It is account-scoped rather than part of the shared outreach funnel, it is the lowest-priority work an account runtime performs, and it deliberately keeps running while the account is held out of outbound messaging — building that history is what lifts the hold.
| Module | Owns | Important constraints |
|---|---|---|
services/account-growth.ts |
Per-account discovery, generation, posting, verification, and trust updates | Auto-posts without operator review, so both screening stages fail closed; due retries and existing queue work run before discovery; an interrupted post is never retried. |
services/growth-pacer.ts |
Adaptive allowance ladder, the operator limit override, promote/demote/pause decisions, quiet hours, spacing | Pure and clock-injected. Pause beats demote beats promote; an operator limit replaces the earned allowance but never the pause; jitter is derived from the previous post so the gate cannot flap. |
services/growth-thread-screening.ts |
Pure thread eligibility (age window, comment count, locked/stickied/NSFW) | A comment on a dead or saturated thread wastes a scarce daily allowance. |
services/growth-comment-safety.ts |
Deterministic pre-publication gate on generated comment text | Rejects links, contact solicitation, user tags, filler, and any text revealing the generator. Independent of prompt wording. |
reddit/comment-client.ts |
Comment submission and comment-state lookups for one account | Classifies Reddit's error codes into retry/abandon/disable/re-auth/stop; runs inside the account's own browser session and shares the request coordinator. |
database/growth-repository.ts |
Growth settings, per-account community list, durable comment records | One comment per thread across every account; mutations require the expected worker lease; queue clearing deletes only unposted discovered/retryable rows. |
services/account-browsing-simulation.ts |
Durable pacing, eligibility, post/comment weighting, selection, and optional vote dispatch | Runs below comment growth; votes require the per-account opt-in plus running mode outside dry-run, and uncertain writes are never retried. |
database/browsing-simulation-repository.ts |
Per-account browsing policy, cross-account selection checks, and minimal decision audit | Stores identity/permalink, safe reasons, and durable vote state without copying Reddit content; browsing never feeds comment trust. |
Verification is the safety mechanism that matters most. Posted comments are swept at roughly 15 minutes, 2 hours, and 24 hours using one batched info.json request, and a single signed-out probe on the second sweep decides whether the comment is publicly visible at all. Two consecutive removals, or one invisible comment, hard-pauses the account until an operator clears it; a failed probe never pauses anything.
Conversation, chat, and media
| Module | Owns | Important constraints |
|---|---|---|
services/chat/service.ts |
Matrix conversation sync, cache updates, starts/replies, scoped cooldowns | Room-creation limits pause new outreach without blocking existing-room replies; Matrix acceptance and UI visibility are distinct. |
services/chat/matrix/client.ts |
Matrix HTTP protocol and error classification | Authentication/rate-limit errors need typed handling. |
services/chat/cache.ts |
Account-scoped cached conversations and sync state | SQLite is durable; do not share caches across accounts. |
services/chat/matrix/username-resolver.ts |
Matrix/Reddit identity mapping | Preserve unresolved internal IDs without leaking them in operator text. |
services/chat/matrix/token-refresher.ts |
Explicit refresh-unavailable behavior | New credentials come from verified extension dumps, not token sniffing. |
services/recipient-account-status.ts |
Periodic cached-conversation recipient profile checks | Only definitive Reddit results replace durable state; checks are authentication-bound and must not block the reply loop. |
services/conversation-automation.ts |
Reply-first policy, cached-history deterministic risk screening, claims, retries, send-time refresh, handoffs, turn budgets | Snapshot policy; apply the shared risk decision before actionability and send; claim before send; supersede stale queued work; reconcile pending claims; fail closed. |
services/conversation-state.ts |
Pure conversation parsing/state/safety helpers | Conversation text is untrusted data; keep prompt boundaries explicit. |
services/conversation-risk.ts |
Shared deterministic seller, funnel, contact-platform, payment, and scam decision | Live, revalidation, automatic history, and forced-sweep paths must not diverge. |
services/seller-sweep.ts |
Operator-forced deterministic and batched-AI seller screening | Use complete cached inbound text; deterministic off-platform outcomes remain terminal; unchanged clean AI screens use the durable watermark. |
services/conversation-boundaries.ts |
Sequence-aware media requests, refusals, and full-stop detection | Short ambiguous replies become boundaries only in the matching request context. |
services/outbound-message-safety.ts |
Final no-proximity/no-meeting rule | This is defense in depth beyond prompts. |
services/conversation-outcome*.ts |
Response outcome classification/recording | Keep analytics attribution account/message scoped. |
services/response-checker.ts |
Inbox/performance response checks and successful examples | Non-overlapping; do not confuse chat sync with outcome maturity. |
services/media.ts |
Download, verify, index, and list private media occurrences while reusing asset files | Preserve account ownership, retryable download failures, and authenticated serving. |
services/media-sync.ts |
Periodic authenticated media sync and operator-visible completion status | Stop while auth is unavailable and on runtime shutdown; do not report partial work as success. |
services/media-library.ts |
Shared operator uploads, image validation/re-encoding, classification state, and private files | Require consent confirmation; received media never enters this store. |
services/media-library-exchange.ts |
Inbound request detection, progressive selection, reservation, and image-first exchange | Never offer proactively; exact tags do not substitute; no asset reuse per conversation. |
services/image-replacement.ts |
Green-screen detection, perspective fitting, compositing, and private preview generation | Sources come from the consent-controlled library; targets resolve from authoritative conversation data; generation never sends. |
database/media-library-repository.ts |
Shared asset metadata and durable account/conversation send audit | Reserve before remote send; uncertain sends stay consumed. |
Persistence
| Module | Owns |
|---|---|
database/client.ts |
Database open settings and ordered migrations. |
database/repositories.ts |
Posts, messages, successes, activity, outbox, states, claims, outcomes, users, recipient history. |
database/account-repositories.ts |
Verified account records, conversations, sync cursors, and media content. |
database/ai-usage-repository.ts |
Model request/cost/reliability records. |
database/legacy-content-import.ts |
One-time ownership of legacy file-backed chat/media data. |
config/persistence.ts |
Secret-free application configuration in SQLite. |
Repositories should expose domain operations rather than raw SQL to callers. Multi-step state transitions belong in SQLite transactions when partial completion would break invariants.
Web and agent surfaces
| Module | Owns |
|---|---|
web/server.ts |
Express lifecycle, middleware order, route registration, static dashboard/media. |
web/auth.ts |
Dashboard session and bearer-token authorization. |
web/context.ts |
Narrow route dependency container. |
web/routes/*.ts |
Focused endpoint families. |
web/api-catalog.ts |
Operation metadata, OpenAPI, and capability discovery. |
web/agent-job-manager.ts |
Bounded async sync jobs and job status. |
web/events/* |
Typed event publication, replay, subscriptions, and Express SSE. |
web/log-broadcaster.ts |
Recent logs plus legacy/typed stream adapters. |
mcp/api-client.ts, mcp/server.ts |
HTTP-backed stdio MCP tools. |
Authorization is semantic, not just authentication: read and control agent tokens intentionally cannot import sessions, send messages, activate accounts, mutate legacy config, or use debug routes.
Frontend
| Area | Owns |
|---|---|
apps/dashboard/src/app/ |
Shell, routing, providers, auth status, notifications, realtime repair. |
apps/dashboard/src/api/ |
HTTP client, schema parsing, query keys/hooks. |
apps/dashboard/src/features/ |
Route-level feature slices. |
apps/dashboard/src/components/ |
Reusable domain-aware UI elements. |
packages/api-contracts/ |
Shared strict transport schemas and inferred types. |
Utility boundaries
utils/logger.ts: Winston creation, child context, and attachable sinks. No productionconsole.log.utils/retry.ts: bounded retry behavior for operations that are safe to repeat.utils/image.ts: download/MIME/size helpers.utils/gender-tag.ts: deterministic self-declared tag parsing.utils/fetch-with-timeout.ts: abortable HTTP timeout wrapper.utils/json-safe.ts: safe serialization for log/event data.
When a module starts owning two independent reasons to change, extract a narrow collaborator and inject it. Do not solve size alone by moving methods into a generic utility file.
Learning responsibilities are deliberately split: conversation-attribution.ts reconciles authorship, conversation-learning-extractor.ts derives credit and decisions, conversation-learning-redactor.ts enforces data minimisation, conversation-learning-provider.ts retrieves bounded examples, and conversation-learning-evaluator.ts runs offline hard gates. SQLite ownership stays in the event and learning repositories. ChatService only calls the narrow observer interface after authoritative synchronization.