docs: add unified logger epic planning and task breakdown#36
docs: add unified logger epic planning and task breakdown#36ericelliott wants to merge 4 commits intomainfrom
Conversation
Create comprehensive task epic for unified event-driven logging framework covering client/server implementation, security, schema validation, and testing infrastructure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive planning documentation for a unified event-driven logging framework that will work across both client and server environments. The epic outlines the architecture for a telemetry system with security, privacy, and resilience features.
- Creates detailed task breakdown for unified logger implementation with 9 major task areas
- Documents requirements for client/server logging, security/privacy, transport, and schema validation
- Adds epic reference to project plan tracking file
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tasks/unified-logger-epic.md | New epic document detailing 9 task areas with requirements for unified logging framework |
| plan.md | Added reference to new unified logger epic in project plan |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
tasks/unified-logger-epic.md
Outdated
| **Requirements**: | ||
| - Given browser is online, should flush batched events immediately in background | ||
| - Given browser is offline, should buffer events to localStorage without data loss | ||
| - Given browser reconnects after offline period, should auto-flush pooled buffers |
There was a problem hiding this comment.
Corrected spelling of 'pooled' to 'pooled' (likely meant 'queued').
| - Given browser reconnects after offline period, should auto-flush pooled buffers | |
| - Given browser reconnects after offline period, should auto-flush queued buffers |
Updated requirements and refined logging behavior for both client and server. Modified event handling and transport logic, including consent checks and error handling.
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
tasks/unified-logger-epic.md
Outdated
| sampler = takeEveryglobal default sampler # Feature Request: Unified Event Driven Logger for AIDD (`aidd/logger`) | ||
|
|
There was a problem hiding this comment.
Malformed line with missing space and concatenated text. Should be 'sampler = takeEvery // global default sampler' followed by a new line before the heading.
| sampler = takeEveryglobal default sampler # Feature Request: Unified Event Driven Logger for AIDD (`aidd/logger`) | |
| sampler = takeEvery // global default sampler |
Feature Request: Unified Event Driven Logger for AIDD (aidd/logger)
tasks/unified-logger-epic.md
Outdated
| sanitizer // optional override | ||
| serializer // optional override | ||
| context // key map of contextual fields | ||
| props // additional structured dat |
There was a problem hiding this comment.
Incomplete word 'dat' should be 'data'.
| props // additional structured dat | |
| props // additional structured data |
tasks/unified-logger-epic.md
Outdated
| serializer // optional override | ||
| context // key map of contextual fields | ||
| props // additional structured dat | ||
| createdAt? // Time of server injestion |
There was a problem hiding this comment.
Misspelled 'injestion' should be 'ingestion'.
| createdAt? // Time of server injestion | |
| createdAt? // Time of server ingestion |
tasks/unified-logger-epic.md
Outdated
|
|
||
| Security (Server side) | ||
|
|
||
| POST $eventsRoute[enevtId] |
There was a problem hiding this comment.
Misspelled 'enevtId' should be 'eventId'.
| POST $eventsRoute[enevtId] | |
| POST $eventsRoute[eventId] |
tasks/unified-logger-epic.md
Outdated
|
|
||
| ## Core design | ||
|
|
||
| ```sudo |
There was a problem hiding this comment.
Code fence language identifier 'sudo' should likely be 'js' or 'javascript' for JavaScript code blocks, or 'pseudocode' if representing pseudo-code.
| ```sudo | |
| ```pseudocode |
tasks/unified-logger-epic.md
Outdated
|
|
||
| ## Server API | ||
|
|
||
| ```sudo |
There was a problem hiding this comment.
Multiple code fence language identifiers use 'sudo' which appears to be a typo. Should be 'js', 'javascript', or 'pseudocode' depending on the intended usage.
| ```sudo | |
| ```js |
- Update task-creator.mdc to require Interfaces section in epics - Add comprehensive SudoLang interfaces to unified logger epic - Define all types: Event, LogPayload, EnrichedEvent, LoggerOptions, etc. - Align all requirements with defined interfaces - Include framework interfaces (Dispatch, Events$) marked as out-of-scope Interfaces take precedence - requirements verified for consistency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| - Given client online and flushIntervalMs elapsed, should flush on timer | ||
| - Given POST to /api/events/[id] fails, should log error to console and ignore (fire-and-forget) | ||
| - Given batch to flush, should POST to /api/events/[eventId] with Content-Type application/json | ||
| - Given multiple events to flush, should batch into single POST body with events array |
There was a problem hiding this comment.
Bug: Batching Conflicts with URL Design
The client transport requirements for flushing events are contradictory. The design specifies POSTing to an endpoint with a single event ID in the URL path, but also requires batching multiple events into a single request body. This creates an ambiguous URL structure for batched requests and conflicts with the server's idempotency handling, which expects individual event IDs.
…-logger-011CUQeqSLSHdpHuNSGMSAFK
|
@cursor please review again |
|
Cloud Agent has finished! You can now access it through Cursor. Learn more about Cursor Agents |
|
Cursor Agent can help with this pull request. Just |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - Given request method is not POST, should reject with 405 Method Not Allowed | ||
| - Given Content-Type is not application/json, should reject with 415 Unsupported Media Type | ||
| - Given request origin not in allowedOrigins, should reject with 403 Forbidden | ||
| - Given request referer origin does not match origin header, should reject with 400 Bad Request |
There was a problem hiding this comment.
The requirement mentions checking "referer origin" but the correct HTTP header name is "Referer" (note the misspelling in the HTTP standard is intentional). However, the requirement says "request referer origin does not match origin header" which seems like a security check. Consider clarifying what this check is validating - typically you'd check that the Origin header matches allowed origins, or that Referer matches the request origin, but checking "referer origin does not match origin header" is unclear. This might need to be: "Given request Referer header origin does not match Origin header, should reject with 400 Bad Request" or simply removed if covered by the allowedOrigins check on line 219.
| - Given request referer origin does not match origin header, should reject with 400 Bad Request |
|
|
||
| // Configuration | ||
| LoggerOptions { | ||
| endpoint?: string // POST target (client: '/api/events', server: 'console') |
There was a problem hiding this comment.
Inconsistent endpoint definition. Line 58 defines the client endpoint as '/api/events' but the Client Transport Layer (line 201, 207) and Server Event Endpoint (line 214) sections describe the endpoint as /api/events/[id] or /api/events/[eventId]. The endpoint should be consistently defined. Based on the idempotent delivery design mentioned in line 201, the endpoint in LoggerOptions should likely be '/api/events' as a base, with the implementation appending /${eventId} when making requests.
| endpoint?: string // POST target (client: '/api/events', server: 'console') | |
| endpoint?: string // POST base path (e.g., '/api/events'); implementation appends '/${eventId}' for idempotent delivery (client), or 'console' for server |
| **Status**: 📋 PLANNED | ||
| **File**: [`tasks/unified-logger-epic.md`](./tasks/unified-logger-epic.md) | ||
| **Goal**: Create event-driven logging framework for unified telemetry across client and server | ||
| **Tasks**: 9 tasks (core infrastructure, client implementation, server implementation, event configuration, security/privacy, transport, schema validation, testing, documentation) |
There was a problem hiding this comment.
Incorrect task count and incomplete task list. The summary states "9 tasks" but the epic contains 10 task sections. Additionally, the task list omits "Server Event Endpoint" (which is distinct from the Client Transport Layer). Update to: "10 tasks (core infrastructure, client implementation, server implementation, event configuration, security/privacy, client transport, server endpoint, schema validation, testing, documentation)".
| **Tasks**: 9 tasks (core infrastructure, client implementation, server implementation, event configuration, security/privacy, transport, schema validation, testing, documentation) | |
| **Tasks**: 10 tasks (core infrastructure, client implementation, server implementation, event configuration, security/privacy, client transport, server endpoint, schema validation, testing, documentation) |
|
|
||
| EventConfig { | ||
| shouldLog?: boolean // default: true | ||
| sampler?: RxJSOperator // rxjs pipeable operator |
There was a problem hiding this comment.
Inconsistent capitalization of "RxJS". The library name "RxJS" should be consistently capitalized. Line 83 uses lowercase "rxjs pipeable operator" and line 249 uses lowercase "rxjs". These should be "RxJS pipeable operator" and "RxJS" respectively to match the official library name capitalization used in the type name "RxJSOperator".
| sampler?: RxJSOperator // rxjs pipeable operator | |
| sampler?: RxJSOperator // RxJS pipeable operator |
| **Requirements**: | ||
| - Given tests need storage isolation, should provide mock StorageAdapter | ||
| - Given tests need dispatch spy, should provide vi.fn mock for Dispatch | ||
| - Given tests need events$ stub, should provide Subject from rxjs for controllable event emission |
There was a problem hiding this comment.
Inconsistent capitalization of "RxJS". The library name should be "RxJS" (not "rxjs") to match the official library name capitalization used elsewhere in the document (e.g., "RxJSOperator" type name).
| - Given tests need events$ stub, should provide Subject from rxjs for controllable event emission | |
| - Given tests need events$ stub, should provide Subject from RxJS for controllable event emission |
| LoggerOptions { | ||
| endpoint?: string // POST target (client: '/api/events', server: 'console') | ||
| payloadSanitizer?: Sanitizer // (any) => any | ||
| headerSanitizer?: (headers: Record<string, string>) => Record<string, string> | ||
| serializer?: Serializer // (any) => string (default: JSON.stringify) | ||
| batchSizeMin?: number // default 10 | ||
| batchSizeMax?: number // default 50 events OR 64KB bytes, whichever first | ||
| flushIntervalMs?: number // timer for auto-flush when online | ||
| maxLocalBytes?: number // cap for localStorage pool | ||
| maxByteLength?: number // max request body size (server) | ||
| skewWindow?: number // acceptable timestamp skew (default: 24h in ms) | ||
| futureSkewWindow?: number // acceptable future timestamp skew (default: 1h5m in ms) | ||
| consentProvider?: () => { analytics: boolean } | ||
| getIds?: () => { | ||
| sessionId?: ID | ||
| userPseudoId?: string | ||
| requestId?: ID | ||
| } | ||
| clock?: () => Timestamp // default: Date.now | ||
| level?: LogLevel // default: 'info' | ||
| sampler?: RxJSOperator // default: takeEvery (pass-through) | ||
| events?: Record<string, EventConfig> // per-event overrides | ||
| } |
There was a problem hiding this comment.
Missing interface definition. The Server Event Endpoint requirement (line 219) references allowedOrigins for origin validation, but this configuration option is not defined in the LoggerOptions interface. Add allowedOrigins?: string[] to the LoggerOptions interface to align with this requirement, or clarify how allowed origins are configured.
| sampler?: RxJSOperator // rxjs pipeable operator | ||
| sanitizer?: Sanitizer // (payload) => payload | ||
| serializer?: Serializer // (payload) => string | ||
| level?: LogLevel // default: 'info' |
There was a problem hiding this comment.
Missing interface definition. The Schema Validation requirement (line 238) mentions that developers can "register EventConfig with schema", but the EventConfig interface (lines 81-87) does not include a schema field. Add schema?: object or a more specific JSON schema type to the EventConfig interface to align with this requirement.
| level?: LogLevel // default: 'info' | |
| level?: LogLevel // default: 'info' | |
| schema?: object // optional JSON schema for validation |
Create comprehensive task epic for unified event-driven logging framework covering client/server implementation, security, schema validation, and testing infrastructure.
🤖 Generated with Claude Code
Note
Introduces a comprehensive Unified Logger epic with interfaces and requirements, adds an Interfaces section and constraints to the epic template, and updates plan.md entries.
tasks/unified-logger-epic.mddefining a unified client/server logging framework.ai/rules/task-creator.mdc):plan.md):tasks/unified-logger-epic.mdwith goals and task areas.Written by Cursor Bugbot for commit ac5c280. This will update automatically on new commits. Configure here.