Context
#11477 / PR #11480 added priority-based level filtering to logger.mjs + made the CLI default to logLevel: 'info'. That delivered the substrate prerequisite, but the per-item ✨ Created/📦 Moved/✅ Updated events remained at logger.info(...) level. Operator empirical 2026-05-16T18:35Z: post-#11480-merge npm run ai:sync-github-workflow STILL emits thousands of per-item INFO lines because the CLI default surfaces info-level output.
The original #11477 prescription was correct in intent (move per-item events to DEBUG) but couldn't land before PR #11480 added the logger filtering substrate. Now the filtering exists; the per-item downgrade can land.
Problem
CLI sync run with logLevel: 'info' (the default) produces ~35k+ lines on a clean-slate corpus (8.5k issues × per-item create logs + 2.8k PRs + 165 discussions + 166 release-notes × per-item create/move/update). Same operator-stated concern as the original #11477 ticket: "very intense ... would crush your context window."
Architectural Reality
Logger filtering is now real (post-#11480-merge). The level taxonomy:
error always prints (always-on, fail-loud)
warn — anomalies + recoverable errors ('⚠️ Could not sync...' etc.)
info — phase headers + final summaries ('📥 Fetching issues...', '✨ Synced N modified...')
debug — per-item events + GraphQL pagination details
Per-item events are operationally verbose-trace details — they belong at debug. Operators who want to see them opt-in via npm run ai:sync-github-workflow -- --verbose (already wired by PR #11480) or via NEO_LOG_LEVEL=debug.
The Fix
Downgrade in 4 syncer files:
ai/services/github-workflow/sync/IssueSyncer.mjs:
'✨ Created #N: path' → logger.debug
'📦 Moved #N: oldPath → newPath' → logger.debug
'✅ Updated #N: path' → logger.debug
'🗑️ Removed dropped issue #N: ...' → logger.debug
ai/services/github-workflow/sync/PullRequestSyncer.mjs:
'✨ Synced...' (per-item) → logger.debug
'📦 Moved PR #N: ...' → logger.debug
ai/services/github-workflow/sync/DiscussionSyncer.mjs:
'📦 Moved Discussion #N: ...' → logger.debug
'✅ Synced discussion #N' → logger.debug
ai/services/github-workflow/sync/ReleaseNotesSyncer.mjs:
'✅ Synced release notes for ${tagName}' → logger.debug
KEEP at INFO (operator visibility): phase headers (📥 Fetching ..., 🔄 Reconciling ...), final per-syncer summary ('✨ Synced N modified pull requests to disk.', '📦 Archived N closed issue(s)').
Acceptance Criteria
Out of Scope
- Adding batch-summary INFO checkpoints (e.g., every N items processed) — original #11477 AC #4. Defer to a separate ticket if operators want progress signal between phase headers. The per-item DEBUG path provides per-item visibility on demand; phase headers + final summaries provide the bounded INFO progress narrative.
- Sibling KB/Memory-Core/Neural-Link loggers — same pattern may exist; separate sweep ticket if friction surfaces.
- Logger refactor (output sinks, file logging, structured JSON) — narrow scope to level reassignment.
Avoided Traps
- Adding
--quiet flag: rejected — NEO_LOG_LEVEL=warn npm run ai:sync-github-workflow already achieves this via the env binding PR #11480 added.
- Removing per-item logs entirely: rejected — operators occasionally need per-item visibility for debugging stuck syncs; preserve via
--verbose opt-in.
- Batch-summary checkpoints in this PR: deferred to keep scope tight; can land as a separate enhancement if INFO-level progress signal feels too sparse post-this-fix.
Related
- Direct parent: #11477 / PR #11480 (logger filtering substrate — landed; this ticket completes the prescription's other half)
- Empirical anchor: operator's 2026-05-16T18:35Z empirical paste post-#11480-merge showing per-item INFO logs still flooding
- Authority chain: my original #11477 prescription (
info → debug) was correct in intent but couldn't land without #11477's logger filtering substrate first; @neo-gpt's V-B-A correction made it land in two stages instead of one
Origin Session ID: 0064efde-455e-4ecd-a26f-574381b3766a
Retrieval Hint: query_raw_memories(query="syncer per-item Created Moved Updated INFO downgrade DEBUG #11477 follow-up log volume")
Context
#11477 / PR #11480 added priority-based level filtering to
logger.mjs+ made the CLI default tologLevel: 'info'. That delivered the substrate prerequisite, but the per-item✨ Created/📦 Moved/✅ Updatedevents remained atlogger.info(...)level. Operator empirical 2026-05-16T18:35Z: post-#11480-mergenpm run ai:sync-github-workflowSTILL emits thousands of per-item INFO lines because the CLI default surfaces info-level output.The original #11477 prescription was correct in intent (move per-item events to DEBUG) but couldn't land before PR #11480 added the logger filtering substrate. Now the filtering exists; the per-item downgrade can land.
Problem
CLI sync run with
logLevel: 'info'(the default) produces ~35k+ lines on a clean-slate corpus (8.5k issues × per-item create logs + 2.8k PRs + 165 discussions + 166 release-notes × per-item create/move/update). Same operator-stated concern as the original #11477 ticket: "very intense ... would crush your context window."Architectural Reality
Logger filtering is now real (post-#11480-merge). The level taxonomy:
erroralways prints (always-on, fail-loud)warn— anomalies + recoverable errors ('⚠️ Could not sync...'etc.)info— phase headers + final summaries ('📥 Fetching issues...','✨ Synced N modified...')debug— per-item events + GraphQL pagination detailsPer-item events are operationally verbose-trace details — they belong at
debug. Operators who want to see them opt-in vianpm run ai:sync-github-workflow -- --verbose(already wired by PR #11480) or viaNEO_LOG_LEVEL=debug.The Fix
Downgrade in 4 syncer files:
ai/services/github-workflow/sync/IssueSyncer.mjs:'✨ Created #N: path'→logger.debug'📦 Moved #N: oldPath → newPath'→logger.debug'✅ Updated #N: path'→logger.debug'🗑️ Removed dropped issue #N: ...'→logger.debugai/services/github-workflow/sync/PullRequestSyncer.mjs:'✨ Synced...'(per-item) →logger.debug'📦 Moved PR #N: ...'→logger.debugai/services/github-workflow/sync/DiscussionSyncer.mjs:'📦 Moved Discussion #N: ...'→logger.debug'✅ Synced discussion #N'→logger.debugai/services/github-workflow/sync/ReleaseNotesSyncer.mjs:'✅ Synced release notes for ${tagName}'→logger.debugKEEP at INFO (operator visibility): phase headers (
📥 Fetching ...,🔄 Reconciling ...), final per-syncer summary ('✨ Synced N modified pull requests to disk.','📦 Archived N closed issue(s)').Acceptance Criteria
logger.debuginstead oflogger.info.logger.info.warn/errorlevels untouched.npm run ai:sync-github-workflowproduces ~O(phases + per-syncer-summaries) info lines instead of ~O(items); operator can scroll output without losing phase progression.npm run ai:sync-github-workflow -- --verbosecontinues to emit per-item events (now at debug level vialogLevel: 'debug'set by the CLI flag).Out of Scope
Avoided Traps
--quietflag: rejected —NEO_LOG_LEVEL=warn npm run ai:sync-github-workflowalready achieves this via the env binding PR #11480 added.--verboseopt-in.Related
info → debug) was correct in intent but couldn't land without #11477's logger filtering substrate first; @neo-gpt's V-B-A correction made it land in two stages instead of oneOrigin Session ID: 0064efde-455e-4ecd-a26f-574381b3766a
Retrieval Hint:
query_raw_memories(query="syncer per-item Created Moved Updated INFO downgrade DEBUG #11477 follow-up log volume")