A generative polyrhythmic MIDI composition engine. Two independent metric layers evolve simultaneously, coordinated by cross-layer intelligence and a conductor system. Music emerges through emergent coherence — 100+ independent observers nudge a shared signal field, and complex feedback loops resolve contradictions into musicality.
- Getting Started
- Architecture Overview
- Subsystem Map
- Signal & Feedback Topology
- Conductor Intelligence
- Cross-Layer Coordination
- Composers & Music Generation
- Diagnostic & Telemetry
- Configuration & Profiles
- Build Pipeline
- Custom ESLint Rules
- Output Files
- Music21 & Priors
- Documentation Index
- Node.js (CommonJS)
- Python 3 (for Music21 priors scripts only)
npm installnpm run mainThis single command runs the full 15-stage pipeline: global generation, boot-order verification, tuning invariant checks, feedback graph validation, linting, type-checking, composition, trace summary, health check, dependency graph, conductor map, cross-layer map, golden fingerprint, narrative digest, and feedback graph visualization. Composition files land in output/, metrics in metrics/, logs in log/.
Pass --seed N to make composition deterministic (seeded PRNG via mulberry32 replaces Math.random):
npm run main -- --seed 42tonal(^6.4.2) — Music theory library — scales, chords, intervals, note math@tonaljs/rhythm-pattern(^1.0.0) — Rhythm pattern generation
TypeScript (^5.9.3), ESLint (^9.0.0), and related tooling are dev dependencies. Type-checking is via tsc --noEmit over JSDoc-annotated JavaScript.
Polychron does not hardcode musical structure — it steers it. The system generates compositions through a three-layer nervous system:
Conductor — 42 intelligence modules cast multiplicative bias votes for density, tension, and flicker. Products are dampened, normalized, and committed to state. 11 hypermeta self-calibrating controllers auto-tune constants that previously required manual adjustment; a meta-controller watchdog detects and resolves inter-controller conflicts. signalReader is the ONE read API for all consumers.
v getSignals() / signalReader.*() ^ explainabilityBus (diagnostic only)
Cross-Layer — 44 modules coordinate L1-L2 via absoluteTimeGrid (shared temporal memory), negotiationEngine (trust-weighted conflict arbiter), entropyRegulator (meta-conductor entropy steering), adaptiveTrustScores (per-module EMA weights 0.4-1.8), and explainabilityBus (ring buffer of typed diagnostics).
v modified playProb/stutterProb ^ NOTES_EMITTED, STUTTER_APPLIED
Play Loop — section, phrase, measure, beat, div, subdiv, subsubdiv. processBeat orchestrates cross-layer, emits notes, records. coherenceMonitor feeds closed-loop density feedback back to the conductor.
Every beat follows this sequence:
- Conductor update —
globalConductorUpdatecollects intelligence module votes, computes composite intensity, applies dampening (conductorDampening) and normalization (pipelineNormalizer), commits resolved signals toconductorState. - Signal bridge —
conductorSignalBridgecaches a beat-delayed snapshot. Cross-layer modules read through this bridge, never directly from the conductor. This firewall prevents microscopic layer interplay from polluting macroscopic composition trajectories. - Play loop —
processBeatorchestrates a 14-stage topological pipeline: binaural mapping, intent curves, entropy regulation, phase lock, rest sync, cadence probing, negotiation, probability adjust, note emission, and beat recording. - Negotiation —
negotiationEngineappliesadaptiveTrustScoresweights (0.4–1.8) to cross-layer module recommendations, forcing consensus through compromise. - Emission — Notes are picked via the assigned composer, stutter effects apply, MIDI/CSV events push to the buffer.
- Closing the loop —
crossLayerBeatRecordcaptures output,coherenceMonitorcompares actual vs intended density and feeds a dampened bias correction back to the conductor for the next beat.
For a deep-dive, see ARCHITECTURE.md.
Three firewalls keep the system musical instead of chaotic:
- Top-down steering only — The conductor sets the climate. Cross-layer orchestrates the weather. The play loop experiences it. Cross-layer modules cannot write to the conductor; they modify
playProb/stutterProblocally and emit diagnostics toexplainabilityBus. Conversely, conductor modules cannot mutate cross-layer state (ESLint-enforced). - Network dampening — Every feedback loop must register with
feedbackRegistry. The closed-loop controller mechanism prevents phase misalignment and thermal loads from causing resonance. - Temporal decoupling — Modules communicate via
absoluteTimeGridchannels (post()/query()/findClosest()by millisecond time), not direct calls.
src/index.js requires subsystems in this exact, dependency-driven order:
utils - conductor - rhythm - time - composers - fx - crossLayer - writer - play
Each subsystem's index.js loads helpers first, then the manager/orchestrator last.
Core infrastructure consumed by every other subsystem.
validator— Stamped validation —requireFinite,optionalFinite,requireDefined,assertRange, etc.clamps— Numeric clamping utilitiesrandoms— Deterministic random sources (noMath.random— ESLint-enforced)midiData— MIDI constants, note names, velocity tablesinstrumentation— Runtime instrumentation and timingmodeQualityMap— Canonical mode-to-quality map shared by priors modulespriorsHelpers—resolvePhase,resolveWeightOrDefault,weightedAdjustmentmoduleLifecycle— Scoped-reset registry (create(ownerName)- reset by scope:all/section/phrase)beatCache— Deduplication —create(fn)ensures at most one evaluation per beatfeedbackRegistry— Coordinates closed-loop controllers to prevent catastrophic resonanceclosedLoopController— Base controller abstraction for feedback-enrolled moduleseventCatalog— Canonical event type constantssystemSnapshot— Serializable state capture for diagnosticsformatTime— Time formatting utilitiestrustSystems— Canonical trust system name constants — eliminates hardcoded trust strings across the codebase.names(9 scored systems),heatMapSystems(13 heat-map systems),assertKnownTrustSystem(),assertKnownHeatMapSystem()init— Bootstrap initialization side-effects
The brain of the system. 42 modules register with conductorIntelligence, contributing 30 density biases, 20 tension biases, 14 flicker modifiers, 29 recorders, and 56 state providers. Organized into specialized domains:
Top-level orchestration:
conductorIntelligence— Central registry —registerDensityBias,registerTensionBias,registerFlickerModifier,registerRecorder,registerStateProvider,registerModuleglobalConductor— Orchestrates system-wide coherence — motif density, stutter, play probabilitiesglobalConductorUpdate— Per-beat collection of all registered bias productsconductorState— Committed signal state snapshotconductorDampening— Progressive deviation dampening — regime-aware gravity + dimensionality-aware strength + centroid controller (density/tension only) + flicker range elasticity (3x accelerated) + meta-telemetry with watchdog feeddynamismEngine/dynamismPulse— Dynamic energy tracking and pulse detectionPhraseArcManager/phraseArcProfiler— Phrase-level arc shaping (attack/sustain/release)textureBlender— Blends texture signals across layersconfig— Central tunable constants — sections, phrases, divisions, weight distributionssectionMemory— Cross-section narrative memory (snapshot before reset, seed 30% carryover)analysisHelpers— Shared analysis utilities
Subdomain modules:
dynamics/(8) — Climax prediction, density waves, dynamic range, energy momentum, velocity shapeharmonic/(17) — Cadence advising, consonance/dissonance, harmonic density, field tracking, pitch-class gravity, tension resolution, tonal anchor distancemelodic/(15) — Ambitus migration, counterpoint motion, interval balance, melodic contour, register migration, tessiture pressure, thematic recall, voice-leading efficiencyrhythmic/(15) — Accent patterns, attack density, onset regularity, rhythmic complexity, syncopation density, temporal proportionstexture/(20) — Articulation profiling, layer coherence, motivic density, orchestration weight, repetition fatigue, rest density, structural form, textural gradients, voice densitysignal/(17 +output/) — Pipeline infrastructure — see Diagnostic & Telemetry. IncludesmetaControllerRegistry— queryable topology manifest of all 11 hypermeta self-calibrating controllers (axis, file, interactors, snapshot API)journey/(5) — Harmonic journey planning — key/mode selection across sectionsprofiles/(15) — Conductor config profiles (default, minimal, atmospheric, explosive, restrained, rhythmic drive) + merging/validation/tuning
RhythmManager— Subsystem manager — pattern lifecycle coordinationrhythmRegistry— Pattern and strategy registrationpatterns/getRhythm/setRhythm— Pattern resolution and assignmentmakeOnsets— Onset generation from patternsrhythmModulator— Real-time pattern modulationphaseLockedRhythmGenerator— Phase-aware rhythm generation for cross-layer synccrossModulateRhythms— Cross-layer rhythm modulationrhythmPriors/rhythmPriorsData— Musicological rhythm probability tablesrhythmHistoryTracker— Pattern usage historyrhythmConfig/rhythmValues/patternLength— Configuration and constants
Subdirectories:
drums/(6 files) —drumMap,drummer,drumTextureCoupler,playDrumsfeedback/(7 files) —conductorRegulationListener,emissionFeedbackListener,feedbackAccumulator,fXFeedbackListener,journeyRhythmCoupler,stutterFeedbackListener
absoluteTimeGrid— Shared temporal memory —post()to channels,query()/findClosest()by msabsoluteTimeWindow— Sliding window over absolute time for recent-history queriesLayerManager— Manages L1/L2 layer registration and timingmidiTiming— MIDI tick/time conversiongetPolyrhythm/polyrhythmPairs— Polyrhythm ratio computationgetMeterPair— Selects meter pairs for sectionstempoFeelEngine— Tempo humanization and feelfractalArcGenerator— Fractal-based structural arc generationsetUnitTiming— Per-unit timing computationtimeStream/timeGridHelpers— Time streaming and grid utilities
Eleven specialized composers, each implementing a distinct compositional strategy:
ScaleComposer— Scale-degree-based melodic generationModeComposer— Modal composition with mode-specific voice leadingBluesComposer— Blues scale patterns with blue-note inflectionsChromaticComposer— Chromatic passage and passing-tone generationPentatonicComposer— Pentatonic scale patternsQuartalComposer— Quartal/quintal harmony constructionHarmonicRhythmComposer— Harmonic rhythm-aware note selectionMelodicDevelopmentComposer— Motivic development and transformationModalInterchangeComposer— Borrowed chords from parallel modesTensionReleaseComposer— Tension/release arc-driven compositionMeasureComposer— Measure-level note pool management
Subdirectories:
chord/(12 files) —ChordComposer,ChordManager,ProgressionGenerator, harmonic priorsfactory/(7 files) —FactoryManager— selects and blends composers per phrase, phase-based family affinitymotif/(18 files) —MotifComposer,motifManager, motif transforms, chain, validationprofiles/(18 files) — Per-composer tuning profiles +profileRegistry+runtimeProfileAdapterutils/(4 files) — Scale degree transposition, normalizationvoice/(17 files) —VoiceLeadingComposer,VoiceManager, voice-leading scoring and priors
setBalanceAndFX— Layer balance, panning, and FX routingsetBinaural— Binaural beat mapping
Subdirectories:
noise/(7 files) —noiseManager, simplex/FBM/worley noise engines, configurationstutter/(13 files) —StutterManager, stutter fade/pan/FX strategies, stutter config, stutter profiler
Coordinates the two independent metric layers through trust-weighted negotiation.
Top-level infrastructure:
crossLayerRegistry—register(name, module, scopes)— lifecycle management for cross-layer modulescrossLayerLifecycleManager— OrchestratesresetAll/resetSection/resetPhraseacross registered modulesconductorSignalBridge— Beat-delayed signal cache — the firewall between conductor and cross-layerexplainabilityBus— Ring buffer of typed diagnostic events for telemetrycrossLayerEmissionGateway— Attributed MIDI buffer write gateway — all cross-layerpush()calls route throughemit(sourceModule, buffer, event), providing per-module emission counts and a centralized boundary guard
Subdomain modules:
dynamics/(6) —articulationComplement,crossLayerDynamicEnvelope,dynamicRoleSwap,restSynchronizer,texturalMirror,velocityInterferenceharmony/(10) —cadenceAlignment,convergenceHarmonicTrigger,harmonicIntervalGuard,motifEcho,motifIdentityMemory,phaseAwareCadenceWindow,pitchMemoryRecall,registerCollisionAvoider,spectralComplementarity,verticalIntervalMonitorrhythm/(9) —convergenceDetector,emergentDownbeat,feedbackOscillator,grooveTransfer,polyrhythmicPhasePredictor,rhythmicComplementEngine,rhythmicPhaseLock,stutterContagion,temporalGravitystructure/(10) —adaptiveTrustScores,beatInterleavedProcessor,contextualTrust,crossLayerClimaxEngine,crossLayerSilhouette,entropyMetrics,entropyRegulator,interactionHeatMap,negotiationEngine,sectionIntentCurves
grandFinale— Final CSV/MIDI file writingtraceDrain— JSONL trace output (metrics/trace.jsonl) when--traceis enabledlogUnit— Structured per-unit logging
The top-level composition engine.
main— Entry point — section/phrase/measure orchestration, journey planning, lifecycle managementfullBootstrap/mainBootstrap— Global validation, registry population assertions,VALIDATED_GLOBALS+ADVISORY_GLOBALS(graduated: critical globals throw on missing, advisory globals warn only — annotate with/** @boot-advisory */inglobals.d.ts)layerPass— Extracted layer pass loop — conductor updates batched once per measureprocessBeat— Per-beat pipeline — 14-stage topological sequenceevents— Beat event dispatchingplayNotes/playNotesEmitPick/playNotesComputeUnit— Note emission pipelineemitPickCrossLayerRecord/emitPickTextureEmit— Post-emission cross-layer recording and texture emissioncrossLayerBeatRecord— Post-beat outcome recording with trust payoffsbeatPipelineDescriptor— Pipeline stage metadatachannelCoherence— Channel-level coherence trackingmicroUnitAttenuator— Sub-beat attenuation for subdivisions
Each pipeline collects multiplicative bias votes from registered modules:
- Density (30 biases) — Controls note output probability
- Tension (20 biases) — Shapes harmonic tension and resolution
- Flicker (14 modifiers) — Drives rhythmic variation and stutter
All three are dampened + normalized.
Biases are multiplied together (not summed), dampened by conductorDampening (regime-aware gravity + centroid correction + flicker range elasticity), normalized by pipelineNormalizer (adaptive soft-envelope), and decorrelated by pipelineCouplingManager (self-calibrating targets + adaptive coherent relaxation + gain budget management).
Eight closed-loop feedback systems maintain compositional coherence:
- Density correction (
coherenceMonitor) — Compares actual vs intended note output; feeds dampened bias (0.60–1.30) into density product. Phase-aware bell gain peaks mid-phrase. - Entropy steering (
entropyRegulator) — Steers cross-layer systems toward a section-position-driven entropy target. Scale clamp [0.3, 2.0]. - Condition hints (
profileAdaptation) — Detects sustained low-density / high-tension / flat-flicker streaks; advisory hints forconductorConfig. Streak trigger at 6 beats. - Trust governance (
adaptiveTrustScores) — EMA-based weights (0.4–1.8) per cross-layer module. 9 scored systems (canonical names intrustSystems.names):stutterContagion,phaseLock,cadenceAlignment,feedbackOscillator,coherenceMonitor,convergence,entropyRegulator,restSynchronizer,roleSwap. - Decorrelation (
pipelineCouplingManager) — Self-tuning decorrelation for 15 dimension pairs. Self-calibrating targets, adaptive gain, regime-aware. - Regime-reactive damping (
regimeReactiveDamping) — Suppresses density/tension/flicker volatility when regime is exploring. 64-beat rolling regime share tracking with squared penalty. - Pipeline tension homeostasis (
pipelineBalancer) — Closed-loop controller nudging tension product toward neutral (1.0) when divergence exceeds deadband. Attribution-driven gain. - Dynamic architecture (
dynamicArchitectPlanner) — Macro-level dynamic curve planning from intensity snapshots. Shapes tension arc across sections.
All controllers are enrolled with feedbackRegistry to prevent catastrophic resonance.
11 meta-controllers auto-tune parameters that previously required manual adjustment between runs (queryable via metaControllerRegistry.getAll() / getById() / getByAxis() / getInteractors()):
- Self-Calibrating Coupling Targets (
pipelineCouplingManager) — Per-pair rolling |r| EMA. Intractable correlations relax targets upward; easily resolved pairs tighten toward baseline. Product-feedback guard freezes tightening when density product drops below 0.75. - Regime Distribution Equilibrator (
regimeReactiveDamping) — 64-beat rolling histogram vs target budget {exploring:35%, coherent:35%, evolving:20%}. Strength 0.25 with squared penalty when exploring exceeds 60%. Tension pin relief valve relaxes ceiling on sustained saturation. - Pipeline Product Centroid Controller (
conductorDampening) — 20-beat product EMA per pipeline. Corrective multiplier (±25%) counteracts chronic drift from 1.0. Density and tension only — flicker axis excluded to avoid fighting elasticity controller. - Flicker Range Elasticity Controller (
conductorDampening) — 32-beat rolling flicker range. 3x accelerated adjustment rate (0.015/beat). Compressed range reduces dampening base; excessive range increases it. - Trust Starvation Auto-Nourishment (
adaptiveTrustScores) — Per-system trust velocity EMA (50-beat horizon). Injects synthetic payoff when velocity stagnates for 100+ beats. Hysteresis: disengages only when velocity exceeds 3x threshold for 50 beats. Nourishment strength decays 10% per application (floor 0.05). - Adaptive Coherent Relaxation (
pipelineCouplingManager) — Derives coherent-regime coupling relaxation from rolling regime share instead of static constant. - Entropy PI Controller (
systemDynamicsProfiler) — Integral term + adaptive alpha + anti-windup (Ki=0.05, clamp ±3.0). Freezes integral accumulation when P and I terms have opposite signs. - Progressive Strength Auto-Scaling (
conductorDampening) — Derives dampening strength from active contributor count instead of hardcoded pipeline-specific multipliers. - Coupling Gain Budget Manager (
pipelineCouplingManager) — Per-axis budget cap (0.24, flicker 0.36) prevents coupling manager from dominating any single pipeline. Product-feedback guard on density axis. - Meta-Observation Telemetry (
conductorDampening) — Per-beat snapshots of meta-controller state emitted toexplainabilityBusand fed to the meta-controller watchdog. - Meta-Controller Interaction Watchdog (
conductorMetaWatchdog) — Runs every 50 beats, detects opposing correction patterns between controllers on the same axis. Attenuates the weaker controller by 50% when conflict exceeds 30/50 beats. Self-heals when conflict resolves.
For constant values, interaction partners, and cross-constant invariants, see TUNING_MAP.md.
systemDynamicsProfiler classifies the system's 6D phase-space trajectory (density, tension, flicker, entropy, trust, phase) into regimes with 5-beat hysteresis:
exploring— High variance, low coherence — the system is searchingcoherent— Stable, well-correlated signals — everything is working togetherevolving— Gradual directional change — musical developmentdrifting— Slowly losing coherence — needs nudgingoscillating— Periodic instability — feedback loop interferencefragmented— Multiple signals pulling in different directionsstagnant— Flat signals — musical stasis
Regime classification drives dampening strength, decorrelation aggressiveness, and profile adaptation behavior. The regime distribution equilibrator tracks a 64-beat rolling histogram and auto-modulates bias directions (strength 0.25, squared penalty above 60% exploring) to prevent any single regime from dominating. A tension pin relief valve relaxes the tension ceiling when sustained saturation is detected.
Every conductor intelligence module self-registers at load time via conductorIntelligence:
conductorIntelligence.registerDensityBias('myModule', () => bias, lo, hi);
conductorIntelligence.registerRecorder('myModule', (ctx) => { /* side-effect */ });
conductorIntelligence.registerStateProvider('myModule', () => ({ field: value }));
conductorIntelligence.registerModule('myModule', { reset() { /* ... */ } }, ['all', 'section']);- Module votes (multiplicative biases)
conductorIntelligencecollects productsconductorDampeninglimits deviation (regime-aware, centroid-corrected density/tension, flicker-elastic)pipelineNormalizersmooths (adaptive envelope)pipelineCouplingManagerdecorrelates (self-calibrating targets, gain budget, product-feedback guard)pipelineBalancerself-regulates (attribution-driven, deadband 0.25)conductorStatecommits final signalssignalReaderexposes to consumers
- Dynamics (8) — Energy, climax, dynamic range, velocity, density waves
- Harmonic (17) — Cadence, consonance, harmonic fields, pitch gravity, tension resolution
- Melodic (15) — Contour, intervals, register, tessiture, counterpoint, thematic recall
- Rhythmic (15) — Accent, onset, syncopation, complexity, symmetry, temporal proportions
- Texture (20) — Articulation, layer coherence, motivic density, rest density, structural form
Signal(17 + 11 meta-controllers) — Pipeline health, dynamics profiling, coupling, normalization, coherence, self-calibrating hypermeta controllers, interaction watchdog- Journey (5) — Harmonic journey planning — key/mode selection, harmonic rhythm
adaptiveTrustScores maintains EMA-based trust scores for 8 cross-layer modules:
stutterContagion— Cross-layer stutter coordination effectivenessphaseLock— Phase synchronization accuracycadenceAlignment— Cadence resolution successfeedbackOscillator— Feedback stabilitycoherenceMonitor— Density correction accuracyconvergence— Layer convergence qualityentropyRegulator— Entropy tracking accuracyrestSynchronizer— Meaningful shared rest successroleSwap— Dynamic role-swap effectiveness
All trust system names are canonical constants defined in trustSystems.names (9 systems) and trustSystems.heatMapSystems (13 heat-map systems). Use trustSystems.assertKnownTrustSystem(name) to validate at runtime.
Trust formula: score = score * 0.9 + payoff * 0.1 (EMA). Weight: 1 + score * 0.75, clamped to [0.4, 1.8]. Trust ceilinged at 0.75. Trust starvation auto-nourishment injects synthetic payoffs when per-system velocity stagnates for 100+ beats; hysteresis prevents premature disengagement (3x threshold for 50 beats). Nourishment strength decays 10% per application (floor 0.05) to prevent trust inflation. negotiationEngine consumes these weights to gate which systems get influence.
Convention: All trust system names are defined as canonical constants in
trustSystems(seesrc/utils/trustSystems.js). Never hardcode trust system name strings — usetrustSystems.names.STUTTER_CONTAGION,trustSystems.heatMapSystems.SPECTRAL_COMPLEMENT, etc. Boot validation asserts completeness at startup.
negotiationEngine is the conflict arbiter. It receives intent from multiple cross-layer modules and produces final playProb and stutterProb for each layer per beat. Trust weights scale each module's influence. Play scale clamped to [0.4, 1.8] — matching trust weight range by design.
Shared temporal memory for inter-module communication:
post(channel, time, data)— write to a named channel at absolute ms timequery(channel, startMs, endMs)— read events in a time rangefindClosest(channel, targetMs)— nearest event lookup
Modules never call each other directly; they post to and query from the grid.
FactoryManager selects and blends composers per phrase based on:
- Phase-based family affinity (exploratory phases favor wider selection)
- Active conductor profile (profiles can bias toward specific composer families)
- Harmonic context (key, mode, chord progression)
Two composers are selected per phrase — one for L1, one for L2 — allowing contrapuntal independence.
The motif subsystem (18 files) provides motivic identity and development:
Motif— immutable motif data structuremotifChain— tracks motif history for thematic continuitymotifTransforms— inversion, retrograde, augmentation, diminution, transpositionmotifTransformAdvisor— context-aware transform selectionplayMotifs— motif application during note emission
VoiceLeadingComposer and VoiceManager ensure smooth melodic transitions:
voiceLeadingScorers— multi-criteria scoring (interval size, direction, common tones)voiceLeadingPriors— musicological voice-leading probability tablesregisterBiasing— register-aware note selection
ChordComposer and ChordManager handle harmonic generation:
ProgressionGenerator— generates chord progressions from journey contextpivotChordBridge— smooth modulation between sections via pivot chordsharmonicPriors— musicological chord transition probabilities
signalHealthAnalyzer— Per-beat pipeline health grades:healthy/strained/stressed/criticalcoherenceVerdicts— Auto-diagnoses findings (critical/warning/info) from health, dynamics, attribution, trust, couplingsignalTelemetry— Signal pipeline telemetry recording
systemDynamicsProfiler— 6D phase-space regime classification (see Regime Detection)phaseSpaceMath— Welford's z-score normalization, derivative metricsnarrativeTrajectory— Tracks compositional narrative arc over timestructuralNarrativeAdvisor— Structural form advice based on trajectory
metrics/system-manifest.json(JSON) — Machine-readable diagnostic snapshot — config, journey, registries, contributions, healthmetrics/capability-matrix.md(Markdown) — Human-readable summary of system capabilities and module registrationsmetrics/trace.jsonl(JSONL) — Per-beat trace data (when--traceenabled) — full pipeline state per beatmetrics/trace-summary.json(JSON) — Statistical summary of trace (regimes, signals, coupling, trust, stage timing)metrics/dependency-graph.json(JSON) — Machine-readable global dependency graphmetrics/conductor-map.json+conductor-map.md— Per-module conductor intelligence mapmetrics/golden-fingerprint.json+fingerprint-comparison.json— Statistical regression detectionmetrics/narrative-digest.md(Markdown) — Prose narrative of the composition run
Use system-manifest.json as the primary diagnostic source.
When --trace is passed to main.js, traceDrain writes a JSONL entry per beat containing:
- Conductor signals (density, tension, flicker)
- Cross-layer module decisions
- Trust scores and payoffs
- Negotiation outcomes
- Note emission details (including embedded per-beat
notesarray with pitch, velocity, channel) - Pipeline health grades
scripts/trace-summary.js processes the trace into a statistical summary after composition, including per-stage timing aggregates (min/max/avg) when stage profiling data is present.
Trace Replay: npm run replay launches scripts/trace-replay.js for post-hoc trace analysis:
npm run replay -- --timeline # Beat-by-beat timeline (default)
npm run replay -- --stats # Per-section/phrase aggregates
npm run replay -- --section 2 # Filter to section 2
npm run replay -- --layer 1 # Filter to layer 1
npm run replay -- --search regime=sparse # Search for specific values
npm run replay -- --json # Output as JSON to metrics/trace-replay.jsonscripts/golden-fingerprint.js computes a 7-dimension statistical fingerprint of each composition run (note count, pitch entropy, density variance, tension arc, trust convergence, regime distribution, coupling means). Each run is compared against the previous to detect regression:
- STABLE — 0 dimensions drifted
- EVOLVED — 1–2 dimensions shifted (normal musical variation)
- DRIFTED — 3+ dimensions shifted (potential regression)
A drift explainer (metrics/fingerprint-drift-explainer.json) is auto-generated alongside the comparison, providing per-dimension causal analysis: note count correlations, pitch entropy interpretation, density variance significance, tension arc reshaping, trust module shifts, and regime balance changes.
scripts/narrative-digest.js generates a prose story of the composition: what the system did, why, and how it felt about it (trust scores, regime transitions, signal landscape).
scripts/generate-conductor-map.js auto-generates a per-module map showing signal reads, bias registrations, domains, scopes, and end-of-run bias values.
scripts/generate-crosslayer-map.js auto-generates a map of all cross-layer modules showing:
- Registry scopes (all/section/phrase)
- ATG channel usage per module
- Inter-module interactions and dependencies
- Output:
metrics/crosslayer-map.json+metrics/crosslayer-map.md
scripts/visualize-feedback-graph.js generates an interactive HTML/SVG visualization (metrics/feedback-graph.html) of the feedback topology from metrics/feedback_graph.json. Features:
- Circle-layout graph with color-coded edges by latency (immediate/beat/phrase/section)
- Hover tooltips with mechanism details
- Node colors by subsystem, firewall legend, invariant status badge
npm run dashboard launches a zero-dependency WebSocket server that streams trace data in real time to a browser dashboard at http://localhost:3377. Run it alongside npm run main in another terminal.
explainabilityBus maintains a ring buffer of typed diagnostic events emitted by cross-layer modules. Used for post-hoc analysis of why specific musical decisions were made.
Central hub of tunable constants, annotated with sensitivity tiers:
-
@tier-1— Feedback loop constants (documented in TUNING_MAP.md). Changing these shifts emergent behavior across multiple subsystems. -
@tier-2— Musical texture constants. Changes affect timbral quality, rhythmic feel, and harmonic character. -
@tier-3— Structural defaults and cosmetic settings. Safe to experiment with freely. -
SECTIONS— Section count range {min: 3, max: 5} -
PHRASES_PER_SECTION— Phrases per section {min: 1, max: 3} -
BPM— Tempo (default: 72) -
PPQ— Pulses per quarter note (30000) -
TUNING_FREQ— Tuning frequency (432 Hz) -
DIVISIONS/SUBDIVS/SUBSUBDIVS— Beat subdivision weight distributions -
BINAURAL— Binaural beat configuration -
TENSION_SMOOTHING— Tension EMA factor (0.25) -
FLICKER_SMOOTHING— Flicker EMA factor (0.30)
Six named profiles shape the conductor's behavior:
default— Balanced, general-purposeminimal— Sparse, restrainedatmospheric— Ambient, texture-focusedexplosive— High energy, denserestrained— Conservative, steadyrhythmicDrive— Rhythm-forward, percussive
Profiles are defined in src/conductor/profiles/ and resolved by conductorConfig with merge/validation/tuning-override support.
sectionMemory provides cross-section narrative continuity:
snapshot()— captures density/tension/flicker/energy/trend before section resetseed()— blends previous density into new section at 30% carryovergetPrevious()— retrieves previous section snapshotreset()— clears memory
npm run main executes this sequence:
node scripts/generate-globals-dts.js— RegeneratesVALIDATED_GLOBALS+ADVISORY_GLOBALSfromglobals.d.tsnode scripts/verify-boot-order.js— Validates subsystem require order, intra-subsystem dependency ordering, and cross-subsystem dependency orderingnode scripts/check-tuning-invariants.js— Validates cross-constant invariants from TUNING_MAP.mdnode scripts/validate-feedback-graph.js— Cross-validatesmetrics/feedback_graph.jsonloop declarations against source-codefeedbackRegistry.registerLoop()/closedLoopControllercalls. Outputsmetrics/feedback-graph-validation.jsonnpm run lint— ESLint with 16 custom rules (auto-fix)npm run tc— TypeScript type-check viatsc --noEmitnode src/play/main.js --trace— Runs composition (16GB heap, trace enabled)node scripts/trace-summary.js— Summarizes trace outputnode scripts/check-manifest-health.js— Validates system manifest health and coupling tail risk (regime-scaled thresholds)node scripts/generate-dependency-graph.js— Builds machine-readable dependency graphnode scripts/generate-conductor-map.js— Auto-generates conductor intelligence mapnode scripts/generate-crosslayer-map.js— Auto-generates cross-layer intelligence mapnode scripts/golden-fingerprint.js— Statistical regression detection (7-dimension fingerprint + drift explainer)node scripts/narrative-digest.js— Generates prose narrative of composition runnode scripts/visualize-feedback-graph.js— Generates interactive feedback graph visualization
All steps log to log/ via scripts/run-with-log.js.
npm run dashboard— Launch real-time composition dashboard (WebSocket on:3377)npm run replay— Trace replay analysis (--timeline,--stats,--section N,--layer L,--search K=V,--json)npm run snapshot <name>— Save currentmetrics/as a named snapshot for A/B comparisonnpm run compare <name>— Compare currentmetrics/against a named snapshot (verdict: SIMILAR/DIFFERENT/DIVERGENT)npm run diff <name>— Structural composition diff against a named snapshot (section/harmonic/tension/regime/pitch changes)npm run music21-data— Run Music21 priors export scriptsnpm run lint:raw— ESLint without log wrappernpm run tc— TypeScript check onlynpm run deps:check— Check for unused dependenciesnpm run deps:audit— Security audit + dep check
16 project-specific rules in scripts/eslint-rules/:
case-conventions— Enforce PascalCase for classes, camelCase for everything elseno-conductor-registration-from-crosslayer— Prevent cross-layer modules from registering with conductorno-console-acceptable-warning— Restrictconsole.warnto'Acceptable warning: ...'formatno-direct-conductor-state-from-crosslayer— Prevent cross-layer modules from readingconductorStatedirectly (must useconductorSignalBridge)no-direct-crosslayer-write-from-conductor— Prevent conductor modules from mutating cross-layer state (read-only access allowed)no-direct-signal-read— BanconductorIntelligence.getSignalSnapshot()— usesignalReaderno-math-random— BanMath.random()— use project random sourcesno-non-ascii— Ban non-ASCII characters in sourceno-requires-outside-index— Restrictrequire()toindex.jsfilesno-silent-early-return— Ban silent early returns — fail fastno-typeof-validated-global— Bantypeofchecks on boot-validated globalsno-unregistered-feedback-loop— Require feedback loop registration withfeedbackRegistry(closedLoopController auto-registers)no-unstamped-validator— Require module name stamp onvalidator.create()no-useless-expose-dependencies-comments— Ban/* expose-dependencies */commentsonly-error-throws— Requirethrow new Error(...)— no throwing strings/objectsvalidator-name-matches-filename— Require validator stamp to match filename
output/output1.csv— Layer 1 MIDI event data (CSV)output/output1.mid— Layer 1 MIDI fileoutput/output2.csv— Layer 2 MIDI event data (CSV)output/output2.mid— Layer 2 MIDI file
metrics/system-manifest.json— Full diagnostic manifest (config, journey, registries, attribution, verdicts)metrics/capability-matrix.md— Human-readable capability summarymetrics/trace.jsonl— Per-beat trace data (when--traceenabled)metrics/trace-summary.json— Statistical summary of trace data (regimes, signals, coupling, trust, stage timing)metrics/boot-order.json— Boot order with per-file global providers, intra-subsystem violations, and cross-subsystem violationsmetrics/tuning-invariants.json— Cross-constant invariant validation results
metrics/dependency-graph.json— Machine-readable global dependency graph (nodes, edges, fan-in/fan-out)metrics/conductor-map.json— Per-module registry of signals, biases, domains, scopesmetrics/conductor-map.md— Human-readable conductor intelligence mapmetrics/golden-fingerprint.json— 7-dimension statistical fingerprint of current runmetrics/golden-fingerprint.prev.json— Previous run fingerprint (for comparison)metrics/fingerprint-comparison.json— Dimension-by-dimension drift analysis (STABLE/EVOLVED/DRIFTED)metrics/fingerprint-drift-explainer.json— Per-dimension causal drift analysismetrics/crosslayer-map.json+crosslayer-map.md— Cross-layer intelligence map (modules, scopes, ATG channels)metrics/feedback-graph.html— Interactive SVG feedback topology visualizationmetrics/feedback-graph-validation.json— Feedback graph cross-validation results (loop counts, source-vs-JSON concordance, passes/failures/warnings)metrics/narrative-digest.md— Prose narrative of the composition runmetrics/run-comparison.json— A/B profile comparison results (whennpm run compareis used)metrics/composition-diff.json+composition-diff.md— Structural composition diff (whennpm run diffis used)metrics/trace-replay.json— Trace replay output (whennpm run replay -- --jsonis used)
scripts/music21/ contains Python scripts for musicological analysis via the Music21 library. Run via npm run music21-data.
export_harmonic_priors.py— Chord transition probability tablesexport_melodic_priors.py— Melodic interval probability tablesexport_rhythm_priors.py— Rhythmic pattern probability tablesexport_voice_leading_priors.py— Voice-leading preference tables
All scripts share export_utils.py and output data consumed by corresponding *PriorsData.js files in src/.
Two globals from src/utils/ are used across all priors modules:
modeQualityMap— canonical mode-to-quality map (never duplicate)priorsHelpers—resolvePhase(opts),resolveWeightOrDefault(table, key, fallback),weightedAdjustment(weight, scale)
- README.md — This document — comprehensive project overview
- .github/copilot-instructions.md — Concise coding rules guide for AI assistants and contributors
- ARCHITECTURE.md — Beat lifecycle deep-dive — signal flow from conductor to emission
- TUNING_MAP.md — Feedback loop constants, interaction partners, cross-constant invariants
- metrics/conductor-map.md — Auto-generated conductor intelligence map (per-run)
- metrics/crosslayer-map.md — Auto-generated cross-layer intelligence map (per-run)
- metrics/narrative-digest.md — Auto-generated prose narrative (per-run)
- metrics/feedback_graph.json — Feedback loop topology (source of truth for visualization)