Chatagent Remediation Audit (WS-B/WS-C)
This document captures evidence-based audit notes used by the remediation plan.
If there is no concrete duplication/harm, we prefer no code movement and only
document the boundary.
Related acceptance boundary: docs/agent/chatagent-feature-checklist.md.
Appendix A — Schedule / stream duplication audit (WS-B)
Schedule cluster (current)
- Files:
internal/server/chatagent/scheduler.gointernal/server/chatagent/schedule.gointernal/server/chatagent/schedule_helpers.gointernal/server/chatagent/schedule_tool.gointernal/server/chatagent/scheduled_api.gointernal/server/chatagent/scheduled_run.gointernal/server/chatagent/scheduled_delivery.gointernal/server/chatagent/schedule_errors.go
Findings
- Create/update arg parsing:
parseCreateScheduleArgs(helpers) is used byScheduleTaskTool.Execute(tool). The validation path is already single-sourced viaValidateScheduleInput+ParseRunAt. - DB + scheduler coordination:
persistScheduledTaskrolls back DB state if scheduler registration fails; behavior is correct and covered by existing tests. No duplicate code found to consolidate safely without changing behavior. - Recommendation: No merge performed. The current split is functional (helpers vs tool registry vs scheduler lifecycle). Any refactor here should be driven by a failing test or measurable coupling issue.
Stream cluster (current)
- Files:
internal/server/chatagent/api_stream.gointernal/server/chatagent/event_stream.gointernal/server/chatagent/stream_coalescer.gointernal/server/chatagent/event_sink.gointernal/server/chatagent/progress.gointernal/server/chatagent/sink.go
Findings
- Streaming roles are distinct:
event_stream.goconvertspkg/agent/eventto productStreamEvent.api_stream.goowns HTTP SSE writing and run lifecycle management for RESTPOST …/messages.stream_coalescer.gobatches deltas; not duplicated elsewhere.event_sink.goprovides bounded buffering semantics (critical vs droppable).
- Observer filter duplication (REST/Web
/events): consolidated intochatagent.IsObserverStreamEventand used by bothinternal/server/chatagent_http_sessions.goandinternal/modules/web/chatagent_web_stream.go. - Recommendation: No merge performed beyond the shared observer filter. Further merging risks making the streaming path harder to reason about and test.
Appendix B — chatagent ↔ pkg/agent boundary audit (WS-C)
Current dependency shape
internal/server/chatagent is a product orchestration layer. It imports pkg/agent primitives (loop/harness/tools/session/permission) and binds them to:
- Flowbot persistence (
internal/store) - REST + Web SSE protocols
- Platform sinks (e.g. Slack streaming)
- Scheduled tasks and delivery context
- User permission configs stored as ConfigData
Import hotspots (non-test, approximate):
pkg/agent/msg,tools/coding,tool,hooks,permission,session,harness,ctxmgr,event,llm,subagent,env,sandbox; product tools underinternal/server/chatagent/tools/.
Findings
- No store leakage into
pkg/agent:internal/storeis only used insideinternal/server/chatagent(correct). - No obvious duplicated pure logic between
chatagentandpkg/agentthat should be moved today, based on a quick structural audit. Most logic inchatagentis product-specific (sessions, permissions storage, SSE protocol, scheduled task records). - The only boundary cleanup applied in this remediation is additive + product-layer:
chatagent.IsObserverStreamEventconsolidates duplicated filter logic between REST and Web/eventssubscribers (both are product endpoints).
Recommendation
- Keep WS-C as documentation-only for this iteration: write
internal/server/chatagent/AGENTS.mdand add cross-links inpkg/agent/AGENTS.mdandinternal/modules/web/AGENTS.md. - Only move code into
pkg/agentif a future change shows true duplication across multiple products (not just chatagent), and has tests demonstrating identical semantics.