diff --git a/.gitignore b/.gitignore index 731bba787..d65d3a09e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,10 @@ dist-ssr # Test output / debug captures .output.txt *.output.txt +**/typecheck_output.txt + +# Git bundles (use git remote/clone, not committed bundles) +*.bundle # iOS / Xcode RaveniOS/RaveniOS.xcodeproj/xcuserdata/ diff --git a/Archived Repomixes/WovenWeb Legacy Examples/repomix-output.xml b/Archived Repomixes/WovenWeb Legacy Examples/repomix-output.xml deleted file mode 100644 index 1cb3f080d..000000000 --- a/Archived Repomixes/WovenWeb Legacy Examples/repomix-output.xml +++ /dev/null @@ -1,542774 +0,0 @@ -This file is a merged representation of a subset of the codebase, containing specifically included files, combined into a single document by Repomix. -The content has been processed where empty lines have been removed, line numbers have been added. - - -This section contains a summary of this file. - - -This file contains a packed representation of a subset of the repository's contents that is considered the most important context. -It is designed to be easily consumable by AI systems for analysis, code review, -or other automated processes. - - - -The content is organized as follows: -1. This summary section -2. Repository information -3. Directory structure -4. Repository files (if enabled) -5. Multiple file entries, each consisting of: - - File path as an attribute - - Full contents of the file - - - -- This file should be treated as read-only. Any changes should be made to the - original repository files, not this packed version. -- When processing this file, use the file path to distinguish - between different files in the repository. -- Be aware that this file may contain sensitive information. Handle it with - the same level of security as you would the original repository. - - - -- Some files may have been excluded based on .gitignore rules and Repomix's configuration -- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files -- Only files matching these patterns are included: ../WovenWebApp, ../WovenWebApp/__tests__, ../WovenWebApp/.claude, ../WovenWebApp/.codeviz, ../WovenWebApp/.github, ../WovenWebApp/.sessions, ../WovenWebApp/analysis, ../WovenWebApp/app, ../WovenWebApp/app/api, ../WovenWebApp/app/chat, ../WovenWebApp/app/components, ../WovenWebApp/app/debug-auth, ../WovenWebApp/app/dev-tools, ../WovenWebApp/app/glossary, ../WovenWebApp/app/math-brain, ../WovenWebApp/app/mbrain-wip, ../WovenWebApp/app/privacy-policy, ../WovenWebApp/app/safe, ../WovenWebApp/app/styles, ../WovenWebApp/app/test-env, ../WovenWebApp/app/error.tsx, ../WovenWebApp/app/favicon.ico, ../WovenWebApp/app/globals.css, ../WovenWebApp/app/layout.tsx, ../WovenWebApp/app/not-found.tsx, ../WovenWebApp/app/page.tsx, ../WovenWebApp/app/types.d.ts, ../WovenWebApp/art, ../WovenWebApp/astrologyAPIv3, ../WovenWebApp/audit, ../WovenWebApp/components, ../WovenWebApp/config, ../WovenWebApp/coverage, ../WovenWebApp/data, ../WovenWebApp/Developers Notes, ../WovenWebApp/docs, ../WovenWebApp/e2e, ../WovenWebApp/Error Reports, ../WovenWebApp/examples, ../WovenWebApp/For ChatbotMerge, ../WovenWebApp/hooks, ../WovenWebApp/legacy, ../WovenWebApp/lib, ../WovenWebApp/netlify, ../WovenWebApp/offshoot, ../WovenWebApp/packages, ../WovenWebApp/pages, ../WovenWebApp/Persona, ../WovenWebApp/playwright-report, ../WovenWebApp/poetic-brain, ../WovenWebApp/public, ../WovenWebApp/reports, ../WovenWebApp/scripts, ../WovenWebApp/specs, ../WovenWebApp/src, ../WovenWebApp/test, ../WovenWebApp/tests, ../WovenWebApp/types, ../WovenWebApp/utils, ../WovenWebApp/velocity-artifacts, ../WovenWebApp/velocity-tracker-template, ../WovenWebApp/vendor, ../WovenWebApp/web, ../WovenWebApp/.env.example, ../WovenWebApp/.eslintignore, ../WovenWebApp/.eslintrc.json, ../WovenWebApp/.gitignore, ../WovenWebApp/.netlify-dev.pid, ../WovenWebApp/.nvmrc, ../WovenWebApp/.server.pid, ../WovenWebApp/.tmp_delete_old_branches.log, ../WovenWebApp/ANALYSIS_API_VALIDATION_AND_FORM_FLOW.md, ../WovenWebApp/analyze-branches.sh, ../WovenWebApp/ASPECTS_LEGEND_QUICK_REF.md, ../WovenWebApp/AstroBrain.md, ../WovenWebApp/Balance Meter.md, ../WovenWebApp/benchmark-payload-maryland-control.json, ../WovenWebApp/benchmark-payload-neutral-date.json, ../WovenWebApp/benchmark-payload.json, ../WovenWebApp/benchmark-result-2018-10-10.json, ../WovenWebApp/benchmark-result-maryland-control.json, ../WovenWebApp/benchmark-result-neutral-date.json, ../WovenWebApp/CHANGELOG.md, ../WovenWebApp/check-env.js, ../WovenWebApp/cleanup-deps.sh, ../WovenWebApp/copilot-setup-steps.yml, ../WovenWebApp/corpus_provenance.json, ../WovenWebApp/corpus_registry.yml, ../WovenWebApp/debug_output_2.txt, ../WovenWebApp/debug_output_3.txt, ../WovenWebApp/debug_output_4.txt, ../WovenWebApp/debug_output.txt, ../WovenWebApp/debug_relocation_2.txt, ../WovenWebApp/debug_relocation_final_2.txt, ../WovenWebApp/debug_relocation_final_3.txt, ../WovenWebApp/debug_relocation_final_4.txt, ../WovenWebApp/debug_relocation_final_5.txt, ../WovenWebApp/debug_relocation_final_6.txt, ../WovenWebApp/debug_relocation_final_7.txt, ../WovenWebApp/debug_relocation_final_8.txt, ../WovenWebApp/debug_relocation_final_9.txt, ../WovenWebApp/debug_relocation_final_10.txt, ../WovenWebApp/debug_relocation_final.txt, ../WovenWebApp/debug_relocation.txt, ../WovenWebApp/debug_repro_fix.txt, ../WovenWebApp/debug_repro.txt, ../WovenWebApp/debug-hooks.js, ../WovenWebApp/delete-branches-batch.sh, ../WovenWebApp/delete-branches-commands.sh, ../WovenWebApp/delete-old-branches.sh, ../WovenWebApp/DELIVERABLES_COPILOT_REVIEW.md, ../WovenWebApp/fast-branch-analysis.py, ../WovenWebApp/health-check.js, ../WovenWebApp/HealthAutoExport-2025-08-04-2025-09-03 2.json, ../WovenWebApp/HOUSES_LEGEND_IMPLEMENTATION.md, ../WovenWebApp/hurricane-michael-benchmark-result.json, ../WovenWebApp/IMPLEMENTATION_RELATIONAL_METADATA.md, ../WovenWebApp/jest.config.js, ../WovenWebApp/jest.setup.js, ../WovenWebApp/LICENSE.txt, ../WovenWebApp/MANDATE_1_DELIVERY_SUMMARY.md, ../WovenWebApp/MANDATE_2_INDEX.md, ../WovenWebApp/MANDATE_2_PLAN_SUMMARY.md, ../WovenWebApp/MANDATE_2_PLANNING_COMPLETE.md, ../WovenWebApp/netlify-local-setup.patch, ../WovenWebApp/netlify.toml, ../WovenWebApp/next-env.d.ts, ../WovenWebApp/next.config.mjs, ../WovenWebApp/old-branches-report.txt, ../WovenWebApp/openapi.json, ../WovenWebApp/package-lock.json, ../WovenWebApp/package.json, ../WovenWebApp/playwright.config.ts, ../WovenWebApp/Poetic Brain Integration Guide.md, ../WovenWebApp/postcss.config.js, ../WovenWebApp/RAVEN_MODULES_REFERENCE.md, ../WovenWebApp/README.md, ../WovenWebApp/Readme.txt, ../WovenWebApp/REFACTOR_AUDIT_REPORT.md, ../WovenWebApp/RELATIONAL_CONTEXT_NEGATIVE_CONSTRAINTS.md, ../WovenWebApp/RELATIONAL_METADATA_COMPLETE.md, ../WovenWebApp/RELATIONAL_METADATA_QUICK_REF.md, ../WovenWebApp/RELATIONAL_METADATA_SYSTEM.md, ../WovenWebApp/Relocation and Directional Bias.md, ../WovenWebApp/server.log, ../WovenWebApp/SESSION_COMPLETE.md, ../WovenWebApp/setup-next-prod.patch, ../WovenWebApp/solar-return-response.json, ../WovenWebApp/StateOfMind-2025-08-04-2025-09-03.csv, ../WovenWebApp/tailwind.config.js, ../WovenWebApp/tailwind.offshoot.config.js, ../WovenWebApp/test_output.txt, ../WovenWebApp/test-dan-bias.js, ../WovenWebApp/test-dan-simple.sh, ../WovenWebApp/test-dan.sh, ../WovenWebApp/test-fallback-mode.ts, ../WovenWebApp/test-golden-standard.sh, ../WovenWebApp/test-kerykeion-mapper.ts, ../WovenWebApp/test-loop-fix.ts, ../WovenWebApp/test-natal-parser.ts, ../WovenWebApp/test-oct8-5pm-2025.json, ../WovenWebApp/test-oct8-2025.json, ../WovenWebApp/test-poetic-brain-fixes.ts, ../WovenWebApp/test-report.json, ../WovenWebApp/test-report.sh, ../WovenWebApp/test-solar-return.sh, ../WovenWebApp/test-srp-integration.js, ../WovenWebApp/test-srp.js, ../WovenWebApp/test-alex-fracture.js, ../WovenWebApp/test-translocation-parser.ts, ../WovenWebApp/test-upload-flow-simple.sh, ../WovenWebApp/test-upload-flow.sh, ../WovenWebApp/The Poetic Brain (Raven Calder)High-Level OverviewThis document.md, ../WovenWebApp/tmp-benchmark.log, ../WovenWebApp/tsconfig.json, ../WovenWebApp/tsconfig.tsbuildinfo, ../WovenWebApp/Velocity Tracker and AI Collaboration Guide.md, ../WovenWebApp/velocity-log.jsonl, ../WovenWebApp/verify-copilot-setup.js, ../WovenWebApp/vitest.config.ts, ../WovenWebApp/WOVEN_MAP_V6_COMPLETE_ARCHITECTURE.md, ../WovenWebApp/WovenWeb Codemap & GuardrailsAuthoritative System Flow – Pure.md, ../WovenWebApp/WovenWebApp – Architecture Overview.md, ../WovenWebApp/WovenWebApp – Architecture OverviewPure Next.js Edition.md, ../WovenWebApp/WovenWebApp.code-workspace -- Files matching patterns in .gitignore are excluded -- Files matching default ignore patterns are excluded -- Empty lines have been removed from all files -- Line numbers have been added to the beginning of each line -- Files are sorted by Git change count (files with more changes are at the bottom) - - - - - -../ - WovenWebApp/ - __tests__/ - api/ - astrologer.test.ts - astrology-mathbrain-route.test.ts - balance-tooltips.test.ts - export/ - trimPayloadForPoeticBrain.test.ts - lib/ - tooltip-context.test.ts - mandate-2/ - phase-1-balance-tooltips.test.ts - mbti/ - inferMbtiFromChart.test.ts - poetics/ - mandate.test.ts - narrative-builder.test.ts - narrative-integration.test.ts - synastry-mandate.test.ts - api-natal-aspects-refactor.test.js - astroseek-guard.test.ts - balance-export-regression.test.ts - balance-meter-orb-fix.test.js - basic.test.ts - canonical-scaling.test.js - ci-gate-golden-case.test.ts - dashboard-calibrated-values.test.ts - export-parity.test.ts - golden-standard.test.ts - persona-hybrid.test.ts - pipeline-order.test.ts - poetic-brain-adapter.test.ts - raven-geometry.test.ts - raven-upload-summary.test.ts - relocation-houses.test.js - rendering-sanity.test.ts - report-integrity-validator.test.ts - seismograph-diagnostics-example.test.js - seismograph-saturation-fix.test.js - srp-feature-flag.test.ts - srp-guards.test.ts - srp-integration.test.ts - synastry-bias-field.test.js - .claude/ - settings.local 2.json - settings.local 3.json - .codeviz/ - Woven Web/ - Woven-Web.md - Woven-Web.png - .git/ - gk/ - config - hooks/ - applypatch-msg.sample - commit-msg.sample - fsmonitor-watchman.sample - post-update.sample - pre-applypatch.sample - pre-commit.sample - pre-merge-commit.sample - pre-push.sample - pre-rebase.sample - pre-receive.sample - prepare-commit-msg.sample - push-to-checkout.sample - sendemail-validate.sample - update.sample - info/ - exclude - logs/ - refs/ - heads/ - main - remotes/ - origin/ - HEAD - HEAD - objects/ - pack/ - pack-5de8d643620e03c30ba22a971fbbb3564d150e47.idx - pack-5de8d643620e03c30ba22a971fbbb3564d150e47.pack - pack-5de8d643620e03c30ba22a971fbbb3564d150e47.rev - refs/ - heads/ - main - remotes/ - origin/ - HEAD - config - description - FETCH_HEAD - HEAD - index - packed-refs - .github/ - ISSUE_TEMPLATE/ - copilot-task.yml - workflows/ - corpus-excerpt.yml - delete-old-branches.yml - doc-organizer.yml - jules_pr_review.yml - playwright.yml - velocity.yml - copilot-instructions.md - .sessions/ - store.json - analysis/ - Wheel Charts/ - 1973-07-24_Symbolic_Weather_Dashboard_2018-10-10_to_2018-10-10_Mirror+SymbolicWeather.json - 1973-07-24_Symbolic_Weather_Dashboard_2025-12-05_to_2025-12-13_Mirror+SymbolicWeather.json - 1990-06-14_Symbolic_Weather_Dashboard_2025-12-09_to_2025-12-09_Mirror+SymbolicWeather.json - 2006-01-03_carrie_1975-08-21_Symbolic_Weather_Dashboard_2025-12-09_to_2025-12-09_Mirror+SymbolicWeather.json - abby and carrie.json - Dan and Alex.json - HealthAutoExport-2025-11-28-2025-12-12.json - How to Read Wheel Charts.md - Research notebook findings.md - Weather_Dashboard_dan-cross-alex_2025-12-05_to_2025-12-13_Mirror+SymbolicWeather.json - Weather_Dashboard_dan-cross-alex_2025-12-08_to_2025-12-13_Mirror+SymbolicWeather.json - app/ - api/ - advice-ladder-tree/ - route.ts - api-health/ - route.ts - astrology-health/ - route.ts - astrology-mathbrain/ - route.ts - auth-config/ - route.ts - chart/ - [id]/ - route.ts - city-search/ - route.ts - daily-integration/ - route.ts - debug-env/ - route.ts - health/ - route.ts - poetic-brain/ - route.ts - provider-health/ - route.ts - raven/ - route.ts - resolve-city/ - route.ts - symbolic-weather/ - route.ts - usage/ - route.ts - user-profiles/ - route.ts - chat/ - ChatClientPage.tsx - page.tsx - components/ - SymbolicSeismograph.tsx - debug-auth/ - DebugAuthClient.tsx - page.tsx - dev-tools/ - auth-status-ab123/ - page.tsx - glossary/ - page.tsx - math-brain/ - components/ - DirectionalBiasTest.tsx - DownloadControls.tsx - PersonForm.tsx - ProfileManager.tsx - README.md - SnapshotButton.tsx - SnapshotDisplay.tsx - TransitControls.tsx - hooks/ - useChartExport.ts - useGeolocation.ts - useSnapshot.ts - useUserProfiles.ts - utils/ - formatting.ts - snapshot.ts - validation.ts - AuthProvider.tsx - page.test.tsx - page.tsx - types.ts - mbrain-wip/ - page.tsx - privacy-policy/ - page.tsx - safe/ - page.tsx - styles/ - archival-mode.css - test-env/ - components/ - DownloadButton.tsx - OutputPanel.tsx - ScenarioSelector.tsx - SummaryCards.tsx - Tooltip.tsx - UploadDropzone.tsx - lib/ - types.ts - validators.ts - page.tsx - TestEnvClient.tsx - error.tsx - favicon.ico - globals.css - layout.tsx - not-found.tsx - page.tsx - types.d.ts - art/ - math brain.png - Raven Calder.png - woven map image.png - astrologyAPIv3/ - best-astrology-api-postman.json - audit/ - uncanny.ts - components/ - chat/ - Header.tsx - Sidebar.tsx - types.ts - dev/ - AuthStatusPill.tsx - feedback/ - AdviceLadderTree.tsx - DailyIntegrationLayer.tsx - EnhancedMirrorNarrativeSummary.tsx - GranularValidation.tsx - SessionScores.tsx - SSTFeedback.tsx - TherapeuticIntegrationStep.tsx - WovenMapFeedbackLoop.tsx - WrapUpCard.tsx - math-brain/ - CityAutocomplete.tsx - DateTimePicker.tsx - index.ts - QuickStartWizard.tsx - mathbrain/ - AccelerometerScatter.tsx - BalanceMeterSummary.tsx - EnhancedDailyClimateCard.tsx - PatternRecognitionSummary.tsx - UnifiedSymbolicDashboard.tsx - WeatherPlots.tsx - WeatherProvenance.tsx - onboarding/ - ArchetypeSelector.tsx - HookCardReveal.tsx - ui/ - PlainModeToggle.tsx - StickyProgress.tsx - BalanceMeterPopover.tsx - ChatClient.tsx - ErrorBoundary.tsx - Glossary.tsx - HealthDataUpload.tsx - HitRateDisplay.tsx - HomeHero.tsx - MirrorResponseActions.tsx - PingFeedback.tsx - PoeticCard.tsx - PoeticSnapshotCard.tsx - ReadingSummaryCard.tsx - RequireAuth.tsx - SavedChartsDropdown.tsx - SessionWrapUpModal.tsx - UsageMeter.tsx - VelocityWidget.js - WrapUpCard.tsx - config/ - raven_calder_config.8.6.25.yaml - raven_calder_config.schema.json - spec.json - coverage/ - app/ - api/ - chat/ - index.html - route.ts.html - raven/ - index.html - route.ts.html - math-brain/ - hooks/ - index.html - utils/ - formatting.ts.html - index.html - config/ - index.html - spec.json.html - lib/ - api/ - astrologer.ts.html - index.html - aspects/ - index.html - orbs.ts.html - balance/ - amplifiers.js.html - assertions.js.html - constants.js.html - index.html - scale-bridge.js.html - scale.js.html - export/ - index.html - weatherLog.ts.html - guard/ - index.html - no-context.ts.html - mathbrain/ - adapter.ts.html - index.html - raven/ - guards.ts.html - index.html - intent.ts.html - normalize.ts.html - parser.ts.html - provenance.ts.html - render.ts.html - reportSummary.ts.html - sst.ts.html - reporting/ - canonical-scaling.js.html - index.html - metric-labels.js.html - relational.ts.html - schemas/ - day.ts.html - index.html - ui/ - format.ts.html - index.html - sanitize.ts.html - voice/ - guard.ts.html - index.html - labels.ts.html - blueprint-narrator.ts.html - index.html - natural-followup-flow.ts.html - persona.ts.html - reflection-narrator.ts.html - usage-tracker.ts.html - weather-lexicon-adapter.ts.html - weather-narrator.ts.html - weatherDataTransforms.js.html - poetic-brain/ - src/ - index.html - index.ts.html - src/ - validation/ - index.html - lexical-guard.ts.html - contract-linter.ts.html - frontstage-renderer.ts.html - index.html - pdf-sanitizer.ts.html - schema-rule-patch.ts.html - seismograph.js.html - base.css - block-navigation.js - clover.xml - coverage-final.json - favicon.png - index.html - prettify.css - prettify.js - sort-arrow-sprite.png - sorter.js - data/ - srp/ - light-ledger.json - shadow-ledger.json - raven_store.json - Developers Notes/ - Architecture/ - poetic_brain_code_map.md - Archive/ - Enhanced_Diagnostic_Matrix 8.16.25.txt - README.md - Core/ - Temporary Reference/ - Three-Lane Resonance (Sept 26 – Oct 3, 2025) Symbolic Weather × Physiology × Narrative.png - README.md - Implementation/ - README.md - Lessons Learned/ - AuthOstuff.md - poetic_brain_auth_fix_dec2025.md - README.md - Poetic Brain/ - README.md - Poetic Brain Ideas/ - SST Integrity Rule.md - DH Cross rosebud-entry-2025-10-03_16-00-15.txt - poetic_brain_auth_fix_dec2025.md - README.md - docs/ - archive/ - 01-PoeticBrain-Corpus/ - Developers Notes/ - Archive/ - RAVEN_DATA_TEMPLATE_REVISED.md - RavenCalder_Corpus_Complete_9.25.25.md - Auth/ - Auth0-RavenCalder-Settings.md - Poetic Brain/ - DIAGNOSTIC_INTEGRITY_INTEGRATION.md - Emotional symbolic interpretation Impact Protocol 8.28.25.md - How Raven Speaks v2.md - IMPLEMENTATION_SPEC_MIRROR_REPORTS.md - LADDER_TREE_PROTOCOL_V10.25.md - POETIC_CODEX_CARD_SPEC.md - Poetic-Brain-Session-Flow-Bug-Report.md - Polarity → Astrology Anchors.md - PRIVACY_CONSTRAINT_DAN_ALEX.md - PROTOCOL_UPDATE_SUMMARY_V10.2.md - QUEUE_ANALYSIS_FILTERS_GUIDE.md - RAVEN_OUTPUT_PROTOCOL_SUMMARY.md - RAVEN_OUTPUT_PROTOCOL.md - RAVEN_PROTOCOL_V10.2_UNIFIED.md - RAVEN-PERSONA-SPEC.md - READING_FLOW_DOCUMENTATION.md - REPORT_JSON_STRUCTURE.md - Woven Map Probabilistic Field Lexicon 8.28.25 copy.md - Poetic Brain Ideas/ - POETIC_BRAIN_ARCHITECTURE_OVERHAUL_OCT_2025.md - What Raven Calder Does with the Readouts.md - Raven Calder Output Protocol Handbook.md - docs/ - CLEAR_MIRROR_VOICE.md - How Raven Speaks v2 (1).md - POETIC_BRAIN_INTEGRATION.md - POETIC_BRAIN_V1_SNAPSHOT.md - POETIC_BRAIN_VALIDATION.md - RAVEN_PROTOCOL_BUG_HUNT_REPORT.md - lib/ - raven/ - the chat structure in code.md - Persona/ - Communcation Rules - Four Report Types_Integrated 10.1.25.md - POETIC_INDEX_CARD_IMAGE_PROTOCOL.md - Raven CLEAR MIRROR _ SHAREABLE MIRROR CORRESPONDENCE LEXICON - Gemini Export November 30, 2025 at 4_57_27 PM CST.csv - SST, Shadow and Sidereal.md - poetic-brain/ - perplexity_usage.md - The Symbolic Resonance Protocol.md - Sample Output/ - Mirror_Directive_dan-alex_2025-11-04_to_2025-11-08 (1).md - specs/ - symbolic-weather-directive/ - glossary.md - spec.md - tests-acceptance.md - test-results/ - export-flows-Chart-Export--25b41-rt-natal-mirror-as-markdown-chromium/ - error-context.md - export-flows-Chart-Export--25b41-rt-natal-mirror-as-markdown-firefox/ - error-context.md - export-flows-Chart-Export--25b41-rt-natal-mirror-as-markdown-webkit/ - error-context.md - CLEAR_MIRROR_PDF_IMPLEMENTATION.md - CLEAR_MIRROR_RAVEN_POPULATION_GUIDE.md - CLEAR_MIRROR_SESSION_DIAGNOSTICS.md - CLEAR_MIRROR_UNIFIED_SCHEMA.md - MATH_BRAIN_POETIC_BRAIN_BUG_HUNT_OCT19.md - POETIC_BRAIN_HANDOFF_FIX.md - POETIC_BRAIN_MIRROR_FLOW_FIX.md - POETIC_BRAIN_PERSONA_AUDIT.md - POETIC_BRAIN_SESSION_FLOW_ANALYSIS.md - POETIC_BRAIN_SESSION_UPLOAD_FIXES.md - POETIC_BRAIN_TONE_FIX_OCT19.md - QUICK_START_RAVEN_PROTOCOL.md - RAVEN_NARRATIVE_STRUCTURE_REQUIREMENTS.md - RAVEN_PROTOCOL_IMPLEMENTATION_COMPLETE.md - 02-AstroBrain-History/ - .github/ - instructions/ - ASTROLOGY_AGENT.md - analysis/ - balance_meter_saturation_debug_protocol.md - balance_meter_saturation_fix_2025-10-08.md - Developers Notes/ - API/ - Astrologer API and other issues.md - astrologerAPI.md - Core/ - BALANCE_METER_V5_COMPLETE.md - Implementation/ - MATH_BRAIN_COMPLIANCE.md - SEISMOGRAPH_GUIDE.md - Refractoring Mathbrain/ - plan to split up Math Brain.md - MATHBRAIN_REFACTORING_PLAN.md - docs/ - planning/ - Orignal Legacy Mathbrain Discussion and Backup.md - BALANCE_METER_README.md - SCATTER_PLOT_TERMINOLOGY_UPDATE.md - SEISMOGRAPH_DIAGNOSTICS.md - TRUE_ACCELEROMETER_VISUALIZATION_SPEC.md - lib/ - uncanny-scoring-spec.md - test-results/ - verify-refactor-Natal-Aspe-c9b7f-n-zero-Balance-Meter-values-chromium/ - error-context.md - verify-refactor-Natal-Aspe-c9b7f-n-zero-Balance-Meter-values-firefox/ - error-context.md - verify-refactor-Natal-Aspe-c9b7f-n-zero-Balance-Meter-values-webkit/ - error-context.md - BALANCE_METER_AUDIT_2025-10-05.md - DIRECTIONAL_BIAS_EPISTEMOLOGY.md - MAP_FIELD_EXPORT_CLARIFICATION.md - MAP_FIELD_IMPLEMENTATION_COMPLETE.md - SCATTER_PLOT_ARCHITECTURE.md - SCATTER_PLOT_VERIFICATION.md - V5_BALANCE_METER_CALIBRATION_COMPLETE.md - 03-Project-History/ - .github/ - agents/ - doc-organizer.agent.md - instructions/ - frontend.instructions.md - functions.instructions.md - copilot-instructions.md - app/ - November 2025/ - November 2025 plan.md - docs/ - planning/ - COMPOSITE_TRANSITS_BLOCKER_NOV12_2025.md - HOMEPAGE_PLANNING.md - DASHBOARD_FIX_QUICKSTART.md - PHASE_1_TASK_1.2_COMPLETE.md - PRIVACY_POLICY.md - PROJECT_OVERVIEW.md - QUICK_REFERENCE_CARD.md - READING_SESSION_LIFECYCLE.md - RECOGNITION_EVENT_2025-11-11.md - STC_EXPERIMENT_LOG.md - STC_EXPERIMENT_PLAN_2025-11-11.md - THREE_LAYER_PROTECTION.md - lib/ - srp/ - JSON_LOADER_COMPLETE.md - PHASE_1_COMPLETION_AUDIT.md - scripts/ - README-comparison.md - templates/ - sample_8.23.25.md - CHANGELOG.md - CURRENT_STATE_SUMMARY.md - DOCUMENTATION_INDEX_NOV12_2025.md - EXECUTIVE_SUMMARY_NOV6.md - FIELD_SCALE_FIX_2025_10_31.md - FILENAME_STRUCTURE_VERIFICATION.md - META_ANALYSIS_PIPELINE.md - OCT_31_2025_VS_OCT_10_2018_ANALYSIS.md - PHASE1_EXECUTION_TASKS.md - PHASE1_QUICK_START.md - QUICK_REFERENCE_START_HERE.md - README_STRATEGIC_DOCS.md - ROADMAP_PHASE0_TO_PHASE3.md - SECURITY_UX_HARDENING_NOV6.md - SESSION_NAVIGATION_MAP_NOV12_2025.md - SESSION_SUMMARY_NOV12_2025.md - SESSION_SUMMARY_NOV6.md - SESSION_SUMMARY_OCT_31_2025.md - SRP_REFINEMENT_1_COMPLETE.md - STRATEGIC_ROADMAP_NOV_2025.md - 04-Legacy-Architecture/ - Developers Notes/ - Archive/ - 20250918_Common Issues.md - 20250918_Notes for Dan the developer.md - Design Intent.md - Dynamic Content Generation Refactor.md - END-READING-IMPLEMENTATION.md - Fix Hybrid Beast.md - Impertives.md - IMPLEMENTATION_SUMMARY.md - Migration to React 9.15.25.md - PRECISION_MYSTICISM_NOTES.md - Raven Calder Suggestions.md - README_TAILWIND_PROD.md - REPORT_REQUIREMENTS.md - SCHEMA-PDF-INTEGRATION.md - Core/ - Four Report Types_Integrated 10.1.25.md - REPORT_STRUCTURE_VERIFICATION.md - TWO_MIND_ARCHITECTURE_COVENANT.md - UNIFIED_REPORT_STRUCTURE.md - Implementation/ - Developer Session Export Feature.md - CRITICAL_REPORT_FIXES_JAN_2025.md - REPORT_REQUIREMENTS_AUDIT_2025.md - docs/ - netlify-legacy/ - functions-changelog.md - CLEANUP_AND_BUG_HUNT_REPORT.md - EXPORT_FRAGMENTATION_FIX_COMPLETE.md - EXPORT_FRAGMENTATION_RECOVERY_REPORT.md - NETLIFY_LOCAL_DEV_GUIDE.md - OSR_DETECTOR_AND_EXPORT_FIXES.md - REFACTOR_UNIFIED_NATAL_ARCHITECTURE.md - SESSION_SUMMARY_EXPORT_FRAGMENTATION.md - TWO_FILE_ARCHITECTURE_IMPLEMENTATION.md - reports/ - compare-2018-10-10_vs_2025-10-06.md - lighthouse-summary.md - src/ - reporters/ - comparative_2025-09-07 (3).md - compare two days.md - test-results/ - export-flows-Chart-Export--170d2-chart-geometry-and-transits-chromium/ - error-context.md - export-flows-Chart-Export--170d2-chart-geometry-and-transits-firefox/ - error-context.md - export-flows-Chart-Export--170d2-chart-geometry-and-transits-webkit/ - error-context.md - export-flows-Chart-Export--706e7-ontstage-and-backstage-data-chromium/ - error-context.md - export-flows-Chart-Export--706e7-ontstage-and-backstage-data-firefox/ - error-context.md - export-flows-Chart-Export--706e7-ontstage-and-backstage-data-webkit/ - error-context.md - export-flows-Chart-Export--778ea-tal-data-for-Person-A-and-B-chromium/ - error-context.md - export-flows-Chart-Export--778ea-tal-data-for-Person-A-and-B-firefox/ - error-context.md - export-flows-Chart-Export--778ea-tal-data-for-Person-A-and-B-webkit/ - error-context.md - export-flows-Chart-Export--cb484-eter-report-with-provenance-chromium/ - error-context.md - export-flows-Chart-Export--cb484-eter-report-with-provenance-firefox/ - error-context.md - export-flows-Chart-Export--cb484-eter-report-with-provenance-webkit/ - error-context.md - math-brain-Math-Brain-Entr-f8c05-port-chart-data-as-markdown-chromium/ - error-context.md - math-brain-Math-Brain-Entr-f8c05-port-chart-data-as-markdown-firefox/ - error-context.md - math-brain-Math-Brain-Entr-f8c05-port-chart-data-as-markdown-webkit/ - error-context.md - math-brain-v2-Math-Brain-v-32c83-oad-v2-reports-successfully-chromium/ - error-context.md - math-brain-v2-Math-Brain-v-32c83-oad-v2-reports-successfully-firefox/ - error-context.md - math-brain-v2-Math-Brain-v-32c83-oad-v2-reports-successfully-webkit/ - error-context.md - regression-Regression-Test-07790-ry-integrity-across-exports-chromium/ - error-context.md - regression-Regression-Test-07790-ry-integrity-across-exports-firefox/ - error-context.md - regression-Regression-Test-07790-ry-integrity-across-exports-webkit/ - error-context.md - verify-refactor-Natal-Aspe-0e305--natal-aspects-in-Woven-Map-chromium/ - error-context.md - verify-refactor-Natal-Aspe-0e305--natal-aspects-in-Woven-Map-firefox/ - error-context.md - verify-refactor-Natal-Aspe-0e305--natal-aspects-in-Woven-Map-webkit/ - error-context.md - verify-refactor-Natal-Aspe-640bd--Dashboard-with-data-points-chromium/ - error-context.md - verify-refactor-Natal-Aspe-640bd--Dashboard-with-data-points-firefox/ - error-context.md - ARCHITECTURE_DOCS_INDEX.md - CORPUS_COMPLIANCE_REPORT.md - OLD_BRANCHES_REPORT.md - PHASE1_REFACTORING_ARCHITECTURE.md - REFACTORING_COMPLETION_SUMMARY.md - SESSION_COMPLETION_REPORT.md - SFD_REMOVAL_COMPLETION_REPORT.md - time-of-day-validation-report.md - TRANSLOCATION_ARCHITECTURE_GAP.md - V5_CALIBRATION_COMPLETION_REPORT.md - 05-Features-Epistemology/ - Developers Notes/ - Core/ - CONSOLIDATED_V5_DOCUMENTATION.md - MAGNITUDE_SCALE_FIX_2025.md - V5_IMPLEMENTATION_SUMMARY.md - Implementation/ - DREAM_PROTOCOL_REFERENCE.md - EPISTEMIC_RIGOR_IMPLEMENTATION_SUMMARY.md - EPISTEMIC_RIGOR_QUICK_REFERENCE.md - EPISTEMIC_RIGOR_SPECIFICATION.md - LINTER_SPECIFICATIONS.md - Relocated Houses Engine Integration.md - SAVED_CHARTS_IMPLEMENTATION.md - SMOKE_TESTS_GUIDE.md - Snapshot-Now-Feature.md - docs/ - bug-fixes/ - both-local-relocation-fix-2025-10-18.md - ACTOR_ROLE_OVERVIEW.md - BIAS_CHANNEL_CALIBRATION.md - JOURNAL_FEATURE.md - MAGNITUDE_AVG_FIX_2025-10-11.md - SINGLE_SOURCE_SCALING.md - SPEC_COMPLIANCE_STATUS.md - STC_PROTOCOL.md - UNIFIED_DASHBOARD_IMPLEMENTATION_COMPARISON.md - lib/ - srp/ - FEATURE_FLAG_COMPLETE.md - IMPLEMENTATION_SUMMARY.md - SEPARATION_PROTOCOL.md - specs/ - IMPLEMENTATION_SUMMARY.md - API_LIMITATION_RELOCATION_HOUSES.md - CONSOLIDATION_IMPLEMENTATION_COMPLETE.md - EPISTEMIC_ALIGNMENT_COMPLETE.md - GOLDEN_STANDARD_VALIDATION_CHECKLIST.md - IMPLEMENTATION_GUIDE_PRIVACY_GUARD_NOV12.md - IMPLEMENTATION_SUMMARY.md - OCT_19_IMPLEMENTATION_SUMMARY.md - RELOCATION_SHIM_REDUNDANCY.md - RESONANCE_VALIDATION_UX_FIX.md - SINGLE_SOURCE_OF_TRUTH_IMPLEMENTATION.md - SINGLE_SOURCE_SERVES_GOLDEN_STANDARD.md - TRANSLOCATION_VS_RELOCATION.md - UI_BUTTONS_IMPLEMENTATION_COMPLETE.md - V5_TRANSLOCATION_IMPLEMENTATION_COMPLETE.md - 06-Velocity-Project/ - docs/ - VELOCITY_ANALYSIS.md - VELOCITY_PRODUCT_THESIS_2025-11-11.md - VELOCITY_RECOGNITION_ATTRIBUTION_2025-11-11.md - VELOCITY_TOOLKIT_README.md - VELOCITY_TRACKING_SETUP.md - velocity-forecast.md - velocity-whitepaper.md - VELOCITY_RETROSPECTIVE.md - 07-Testing-and-CI/ - docs/ - admin/ - debugging-empty-aspects.md - planning/ - PRECISION_MYSTICISM_NOTES.md - USER_FACING_MARKDOWN_DESIGN.md - debug-recognition.md - debug-signal.md - DIAGNOSTIC_QUICK_REFERENCE.md - DIAGNOSTIC_VISUAL_GUIDE.md - lib/ - srp/ - THE_CONSCIENCE_OF_THE_MACHINE.md - test-results/ - chat-auth-Chat-Auth-Gate-s-0f628-t-for-unauthenticated-users-chromium/ - error-context.md - chat-auth-Chat-Auth-Gate-s-0f628-t-for-unauthenticated-users-firefox/ - error-context.md - chat-auth-Chat-Auth-Gate-s-0f628-t-for-unauthenticated-users-webkit/ - error-context.md - chat-auth-Chat-Auth-Gate-s-73253-essing-chat-unauthenticated-chromium/ - error-context.md - chat-auth-Chat-Auth-Gate-s-73253-essing-chat-unauthenticated-firefox/ - error-context.md - chat-auth-Chat-Auth-Gate-s-73253-essing-chat-unauthenticated-webkit/ - error-context.md - math-brain-Math-Brain-Entr-65d59-play-birth-data-form-fields-chromium/ - error-context.md - math-brain-Math-Brain-Entr-65d59-play-birth-data-form-fields-firefox/ - error-context.md - math-brain-Math-Brain-Entr-65d59-play-birth-data-form-fields-webkit/ - error-context.md - math-brain-Math-Brain-Entr-a54b9-should-load-math-brain-page-chromium/ - error-context.md - math-brain-Math-Brain-Entr-a54b9-should-load-math-brain-page-firefox/ - error-context.md - math-brain-Math-Brain-Entr-a54b9-should-load-math-brain-page-webkit/ - error-context.md - math-brain-Math-Brain-Entr-af79c-it-solo-natal-chart-request-chromium/ - error-context.md - math-brain-Math-Brain-Entr-af79c-it-solo-natal-chart-request-firefox/ - error-context.md - math-brain-Math-Brain-Entr-af79c-it-solo-natal-chart-request-webkit/ - error-context.md - math-brain-v2-Math-Brain-v-3583a-l-v2-API-endpoint-correctly-chromium/ - error-context.md - math-brain-v2-Math-Brain-v-3583a-l-v2-API-endpoint-correctly-firefox/ - error-context.md - math-brain-v2-Math-Brain-v-3583a-l-v2-API-endpoint-correctly-webkit/ - error-context.md - DAN_BIAS_TEST_RESULTS.md - DECISION_CHECKLIST_NOV6.md - SFD_REMOVAL_FINAL_STATUS.md - TEST_STATUS_NOV12_2025.md - TEST_UPLOAD_FLOW.md - 08-Developer-Experience/ - Developers Notes/ - API/ - API_INTEGRATION_GUIDE.md - API_MASTER_REFERENCE.md - API_TIMEZONE_FIX_2025-11-10.md - Core/ - INTIMACY_TIER_LABELS_FIX_2025.md - Lessons Learned/ - AI_ASSISTANT_LIMITATIONS.md - AI_COPILOT_RENDER_STABILITY.md - BACKEND_DEVELOPMENT_GUIDE.md - BRANCH_PROTECTION_WORKFLOW.md - copilot_fix_recovery.md - CURRENT_SITUATION_SOLUTION.md - Dan's Learned Coder Lessons.md - ENHANCEMENT-SUMMARY.md - FORM_DATA_EXAMPLE.md - GIT_MERGE_CONFLICT_BEST_PRACTICES.md - Integrate_AuthO.md - Lessons Learned for Developer.md - Local Production Notes.md - MAIN_BRANCH_LOCKUP_GUIDE.md - MAINTENANCE_GUIDE.md - Next Actions.md - Overview.md - UI-RESTRUCTURE-SUMMARY.md - UI-Improvements/ - Core-Natal-Aspects-Redesign.md - REORGANIZATION_SUMMARY.md - ANALYSIS_DIRECTIVE_FIX_2025.md - ANALYSIS_DIRECTIVE_OVERHAUL_2025.md - SAVE_LOAD_FIX_2025.md - SESSION_CONTINUATION_FIXES_2025.md - SESSION_SUMMARY_JAN_2025.md - docs/ - PREFERRED_STRUCTURE_GUIDE.md - TERMINOLOGY_STYLE_GUIDE.md - UNIFIED_DASHBOARD_GUIDE.md - BRANCH_CLEANUP_README.md - DEVELOPMENT.md - Lessons Learned for Developer.md - QUICKSTART_DELETE_BRANCHES.md - 09-Legacy-API-and-Auth/ - INTEGRATION_ACTION_ITEMS.md - netlify-legacy/ - Snapshot-7-31-2025.html - planning/ - 3E68031B-9AB0-4BC6-8EDB-0D0A179EC777.png - velocity-product/ - README.md - an analysis of how symbolic weather looks.md - ARCHIVAL_MODE_DEPLOYMENT_SUMMARY.md - ARCHIVAL_MODE_INTEGRATION_GUIDE.md - ARCHIVAL_MODE_PDF_IMPLEMENTATION.md - ASPECTS_LEGEND.md - HOUSES_LEGEND.md - LESSONS_LEARNED_PERSON_B_RELOCATION.md - LEXICON_CONSISTENCY_SCAN_REPORT.md - MANDATE_1_COMPLETION_REPORT.md - MANDATE_2_ARCHITECTURE.md - MANDATE_2_IMPLEMENTATION_PLAN.md - MANDATE_2_INTEGRATION_PATTERN.md - MONETIZATION_STRATEGY.md - POETIC_BRAIN_AUTO_EXECUTION_FIX.md - README.md - SAVE_PROFILES_BEFORE_REPORT.md - TECHNICAL_REFERENCE_RELOCATION.md - TERMINOLOGY_FIX_SUMMARY.md - USER_PROFILE_DATABASE_IMPLEMENTATION.md - VALIDATION_HURRICANE_MICHAEL.md - velocity-forecast.md - e2e/ - api.spec.ts - chat-auth.spec.ts - export-flows.spec.ts - math-brain-v2.spec.ts - math-brain.spec.ts - mathbrain.spec.ts - README.md - regression.spec.ts - verify-refactor.spec.ts - Error Reports/ - edge-net-export-log.json - examples/ - epistemic-rigor-integration.js - math_brain_setup_Dan_Alex_20251012T062507.json - narrative-generation-demo.ts - schema-rule-patch-usage.ts - For ChatbotMerge/ - package.json - tsconfig.json - hooks/ - useAuth.ts - useFileUpload.ts - useRavenRequest.ts - useScrollAnchor.ts - useValidation.ts - legacy/ - .keep - lib/ - api/ - astrologer.ts - fetchWithRetry.ts - jules.ts - aspects/ - orbs.ts - astro/ - calculations.js - constants.js - auth/ - allowlist.ts - jwt.ts - balance/ - amplifiers.d.ts - amplifiers.js - amplifiers.ts - assertions.js - assertions.ts - constants.js - constants.ts - resonance-seismograph.ts - scale-bridge.js - scale.d.ts - scale.js - scale.ts - bigfive/ - inferBigFiveFromChart.ts - tensionSynthesis.ts - vocabularyShaper.ts - chat-pipeline/ - classification.ts - prompts.ts - uploads.ts - config/ - orb-profiles.js - export/ - filename-utils.js - mirrorSymbolicWeather.ts - trimPayloadForPoeticBrain.ts - weatherLog.ts - geo/ - us-states.ts - governance/ - schedule.ts - guard/ - no-context.ts - kerykeion/ - mapper.ts - schema.ts - math-brain/ - overflow-detail.ts - mathbrain/ - adapter.ts - mbti/ - inferMbtiFromChart.ts - woven_map_mbti_correspondence.json - pdf/ - archival-mode-generator.ts - clear-mirror-context-adapter.ts - clear-mirror-pdf.ts - seismograph-svg.ts - pipeline/ - mirrorRenderer.ts - plain-mode/ - context.tsx - dictionary.ts - index.ts - poetic-brain/ - runtime.ts - poetics/ - card-generator.ts - index.ts - mandate.ts - narrative-builder.ts - parser.ts - prompt-builder.ts - symbolToPoem.ts - synastry-calculator.ts - types.ts - prompts/ - clear-mirror-auto-execution.ts - raven/ - __tests__/ - sanitizeDirectiveForMode.test.ts - aspects-legend.ts - auto-execution.ts - balance-tooltip-types.ts - clear-mirror-parser.ts - context-gate.ts - geometry-extract.ts - guards.ts - helpers.ts - house-context.ts - houses-legend.ts - intent.ts - normalize.ts - parser.ts - persona-law.ts - personal-reading.ts - polarityCards.ts - prompt-architecture.ts - protocol.ts - provenance.ts - relational-metadata.ts - render.ts - reportPhases.ts - reportSummary.ts - sanitizeDirectiveForMode.ts - session-store.ts - sst-integrity.ts - sst.ts - styleSkins.ts - temporalBinding.ts - tooltip-context.ts - user-response.ts - validation-probes.ts - raven-client/ - types.ts - reporting/ - canonical-scaling.js - epistemic-integrity.js - math_brain_setup_A_Mary Hunt_20251031T002149.json - metric-labels.js - Mirror+SymbolicWeather_Weather_Dashboard_mary_2025-10-31_to_2025-10-31.json - README.md - relational.ts - transformation-trace.js - schemas/ - day.ts - server/ - .server.pid - astrology-mathbrain.js - chart-cache.js - srp/ - debug-blend-calc.ts - debug-mapper.ts - demo-payload.ts - example.ts - guards.ts - ledger.ts - loader.ts - mapper.ts - README.md - test-direct.js - test-loader-fallback.ts - test-mapper.js - types.ts - templates/ - clear-mirror-builder.ts - clear-mirror-template.ts - types/ - woven-map-blueprint.ts - ui/ - format.ts - sanitize.ts - validation/ - parseValidationPoints.ts - report-integrity-validator.ts - types.ts - validationUtils.ts - voice/ - guard.ts - labels.ts - periodLabel.ts - windsurf/ - testingPayloads.ts - actor-role-detector.test.ts - actor-role-detector.ts - auth.ts - blueprint-extraction.js - blueprint-narrator.ts - buildInfo.ts - climate-narrative.ts - climate-renderer.ts - devAuth.ts - download-readme-template.ts - fast-pdf-generator.js - field-lexicon.ts - followup-generator.ts - health-correlator.ts - health-data-types.ts - id.ts - lexicon.ts - llm.ts - mirror-narrative.ts - natural-followup-flow.ts - persona.ts - ping-tracker.ts - poetic-brain-adapter.ts - poetic-brain-schema.ts - prompts.ts - provenance.ts - raven-formatting.ts - raven-narrative.ts - reflection-narrator.ts - relocation-runtime.js - relocation.ts - report-parsing.ts - saved-charts.ts - session-bridge.ts - snapshot-utils.ts - symbolic-visuals.ts - taxonomy.ts - time-sampling.js - ui-strings.ts - ui-types.ts - unifiedDashboardTransforms.ts - usage-tracker.ts - weather-lexicon-adapter.ts - weather-narrator.ts - weatherDataTransforms.js - weatherDataTransforms.ts - weatherTransforms.ts - netlify/ - functions/ - api-health.js - astrology-health.js - astrology-mathbrain-test.js - astrology-mathbrain.ts - astrology.js - auth-config.ts - health.ts - poetic-brain.js - resolve-city.js - lib/ - function-helpers.ts - logger.js - offshoot/ - erp_pcs.html - offshoot.css - offshoot.min.css - packages/ - velocity-toolkit/ - bin/ - velocli.js - package.json - README.md - pages/ - api/ - velocity.js - Persona/ - archive/ - Raven Speaking.txt - Two Cases Studies in high negative directional bias.md - Advice Ladder Tree — Integration Protocol 9.3.25 copy.txt - Dream Protocol 7.13.25 copy.txt - Enhanced Diagnostic Matrix Woven Map Communication Protocol 8.28.25 copy.txt - Enhanced_Diagnostic_Matrix 8.16.25 copy.txt - Epistemological_Foundation_Dual_Anchor_Framework copy.md - Four Report Types_Integrated 10.1.25 copy.txt - MBTI INFERENCE v2.md - precision diagnostic Symbolic Analysis Guide 8.28.25 copy.txt - Raven Persona.txt - RavenCalder_Corpus_Complete_9.25.25 copy.md - README.md - Recursion Fields: Retrograde Signatures in The Woven Map 8.28.25 copy.txt - SST and Shadow.md - SST Template Guide 7.20.25 v3 copy.txt - Symbol-to-Poem Translation 8.28.25 copy.txt - The Poetic Codex 7.22.25 copy.txt - Vector & Core Pattern Architecture 9.8.25 copy.txt - playwright-report/ - index.html - poetic-brain/ - api/ - handler.ts - src/ - index.ts - test/ - generateSection.test.ts - processMirrorDirective.test.ts - processMirrorDirectiveSolo.test.ts - tests/ - processMirrorDirective.spec.ts - ravencalder-persona-excerpt.txt - README.md - tsconfig.json - public/ - art/ - math-brain.png - raven-calder.png - woven-map-image.png - vendor/ - auth0-spa-js.production.js - debug-dashboard.html - favicon.ico - logo.svg - reports/ - Mirror+SymbolicWeather_Weather_Dashboard_dan-alex_2025-11-15_to_2025-11-21.json - POETIC_BRAIN_REVIEW_NOV_2025.md - scripts/ - archive/ - debug-postMathBrain.js - diagnostic.js - quick-test.js - README.md - test-api-fixed.js - test-api-live.js - test-api-real.js - test-api-real.js.new - test-balance-meter-debug.js - test-consolidation.js - test-coords.js - test-health.js - test-improvements.js - test-relationship-validation.js - test-report-structure.js - test-transit-fallback.js - analyze-payload.js - append-recognition-provenance.js - audit-balance-meter-reads.js - auth-config-check.js - check-env-required.js - cleanup-legacy.js - compare-mathbrain-versions.js - debug_full_stack.js - debug-poetic-handoff.js - debug-signal.js - demo-followup.js - demo-natural-flow.js - fix-auth0.js - free-ports.sh - friction_output_real.txt - friction_output_v2.txt - friction_output_v3.txt - friction_output.txt - generate-persona-excerpts.js - ingest-raven.js - lexicon-lint.mjs - orchestrator.expected.js - probe-provenance.js - register-external-corpus.js - reproduce_transits_failure.js - smoke-auth0.js - smoke-golden-case.js - stc-experiment-log.js - test-api-response.js - test-bigfive-inference.js - test-enrich-fix.js - test-hurricane-michael-benchmark.js - test-hurricane-michael.js - test-journal.js - test-parent-child-friction.js - test-parent-child-real.ts - test-payload-trim.ts - test-relocation-v3.js - test-srp-hooks.js - test-srp-mapper.js - test-symbol-to-poem.ts - test-synastry-calculator.js - test-v3-payload.js - tinker-chat.js - validate-fieldmap-v5.js - velocity-artifacts.js - velocity-notifier.js - velocity-smart-analysis.js - velocity-survival-runner.js - velocity-survival.js - velocity-tracker-mcp.js - velocity-tracker.js - verify-v3-endpoints.js - specs/ - symbolic-weather-directive/ - fixtures/ - oct04-11.json - schemas/ - display-transform.schema.json - build.js - validate.js - README.md - src/ - feedback/ - advice-ladder-tree.js - daily-integration-layer.js - hook-stack-composer.js - sst-log-manager.js - formatter/ - aspect-mandate.js - create_markdown_reading_enhanced.js - create_markdown_reading.js - frontstage-preface.js - relational-flow.js - solo-mirror-template.js - math_brain/ - main.js - math-brain/ - utils/ - city-resolver.js - compression.js - readiness.js - time-and-coords.js - api-client.js - orchestrator.js - seismograph-core.js - seismograph-engine.js - validation.js - normalizers/ - astrology-normalizer.js - data-normalizer.js - parsers/ - seismograph-md.js - reporters/ - comparative-report.js - raw-math-composer.js - table-builders.js - woven-map-composer.js - schemas/ - HealthAutoExport-2025-08-08-2025-09-07.json - wm_json_appendix-1.0.json - wm_json_appendix-1.1.json - wm_json_appendix-1.2.json - wm_json_appendix-1.3.raven-wrapper.schema.json - services/ - astrologyMathBrain.ts - symbolic-weather/ - renderer.ts - types/ - wm-json-appendix.ts - utils/ - logger.js - sanitizeFilename.js - validation/ - lexical-guard.ts - balance-meter.js - contract-linter.ts - coords.ts - erp_pcs.css - frontstage-renderer.ts - input.css - pdf-sanitizer.ts - raven-lite-mapper.js - schema-rule-patch.ts - seismograph.js - wmchart-schema.ts - test/ - __mocks__/ - llm.ts - comparison-results/ - .gitignore - report-parsing/ - report-parsing.test.ts - windsurf/ - README.md - astrology-mathbrain.test.js - auth-redirect.test.ts - auth0-config-validator.js - balance-meter-relocated.spec.js - balance-properties.test.ts - bias-sanity-check.test.ts - both-local-relocation.test.js - canonical-scaling.test.ts - chat-guard.test.js - deployment-verification.js - dhcross-alex-synastry-oct2025.test.js - endpoint-health-check.js - epistemic-integrity.test.js - export-acceptance-relational.test.ts - export-consistency.test.ts - export-parity-relational.test.ts - filename-utils.test.js - generate-persona-excerpts.test.js - generateMirrorDirective.ts - ghost-exorcism.test.js - golden-standard-2018.test.ts - hurricane-michael-dhcross.test.js - lexical-guard.test.ts - mathbrain-adapter.test.ts - mirrorSymbolicWeather.provenance.test.ts - no-context-guard.test.ts - orb-profiles.spec.js - osr-detection.test.js - overflow-detail.test.ts - pdf-schema-integration.test.ts - person-b-relocation-fix.test.js - provenanceSnippet.test.ts - raven-direct-access.test.js - raven-guard.test.js - raven-report-upload.test.ts - run-all-smoke-tests.js - scaling.test.ts - schema-rule-patch.test.ts - setup.ts - smoke-osr-logic.js - smoke-tests.js - snapshot-fix-verification.test.js - snapshot-payload-validation.test.js - transformation-trace.test.js - triwheel-validation.test.ts - validate-bias-calibration.js - verify-bug-fix.js - vitest-setup.ts - voice-guard.test.ts - tests/ - business-logic/ - mathbrain-contract.spec.ts - poetic-bridge.spec.ts - resonance-boundaries.spec.ts - types/ - auth0-global.d.ts - html2pdf.d.ts - utils/ - create_summary_markdown.js - velocity-artifacts/ - velocity-badge.svg - velocity-dashboard.html - velocity-summary.json - velocity-tracker-template/ - .github/ - workflows/ - velocity.yml - docs/ - velocity-forecast.example.md - scripts/ - append-recognition-provenance.js - velocity-artifacts.js - velocity-notifier.js - velocity-tracker.js - velocity-artifacts/ - velocity-summary.example.json - package.json - README.md - vendor/ - auth0-spa-js.production.js - web/ - app/ - favicon.ico - globals.css - layout.tsx - page.tsx - public/ - file.svg - globe.svg - next.svg - vercel.svg - window.svg - .gitignore - .gitignore 2 - eslint.config.mjs - next.config.ts - package 2.json - package-lock 2.json - package.json - postcss.config 2.mjs - postcss.config.mjs - README.md - tsconfig 2.json - tsconfig.json - .env.example - .eslintignore - .eslintrc.json - .gitignore - .netlify-dev.pid - .nvmrc - .server.pid - ANALYSIS_API_VALIDATION_AND_FORM_FLOW.md - analyze-branches.sh - ASPECTS_LEGEND_QUICK_REF.md - AstroBrain.md - Balance Meter.md - benchmark-payload-maryland-control.json - benchmark-payload-neutral-date.json - benchmark-payload.json - benchmark-result-2018-10-10.json - benchmark-result-maryland-control.json - benchmark-result-neutral-date.json - CHANGELOG.md - check-env.js - cleanup-deps.sh - copilot-setup-steps.yml - corpus_provenance.json - corpus_registry.yml - debug_output_2.txt - debug_output_3.txt - debug_output_4.txt - debug_output.txt - debug_relocation_2.txt - debug_relocation_final_10.txt - debug_relocation_final_2.txt - debug_relocation_final_3.txt - debug_relocation_final_4.txt - debug_relocation_final_5.txt - debug_relocation_final_6.txt - debug_relocation_final_7.txt - debug_relocation_final_8.txt - debug_relocation_final_9.txt - debug_relocation_final.txt - debug_relocation.txt - debug_repro_fix.txt - debug_repro.txt - debug-hooks.js - delete-branches-batch.sh - delete-branches-commands.sh - delete-old-branches.sh - DELIVERABLES_COPILOT_REVIEW.md - fast-branch-analysis.py - health-check.js - HealthAutoExport-2025-08-04-2025-09-03 2.json - HOUSES_LEGEND_IMPLEMENTATION.md - hurricane-michael-benchmark-result.json - IMPLEMENTATION_RELATIONAL_METADATA.md - jest.config.js - jest.setup.js - LICENSE.txt - MANDATE_1_DELIVERY_SUMMARY.md - MANDATE_2_INDEX.md - MANDATE_2_PLAN_SUMMARY.md - MANDATE_2_PLANNING_COMPLETE.md - netlify-local-setup.patch - netlify.toml - next-env.d.ts - next.config.mjs - old-branches-report.txt - openapi.json - package.json - playwright.config.ts - Poetic Brain Integration Guide.md - postcss.config.js - RAVEN_MODULES_REFERENCE.md - README.md - Readme.txt - REFACTOR_AUDIT_REPORT.md - RELATIONAL_CONTEXT_NEGATIVE_CONSTRAINTS.md - RELATIONAL_METADATA_COMPLETE.md - RELATIONAL_METADATA_QUICK_REF.md - RELATIONAL_METADATA_SYSTEM.md - Relocation and Directional Bias.md - SESSION_COMPLETE.md - setup-next-prod.patch - solar-return-response.json - StateOfMind-2025-08-04-2025-09-03.csv - tailwind.config.js - tailwind.offshoot.config.js - test_output.txt - test-dan-bias.js - test-dan-simple.sh - test-dan.sh - test-fallback-mode.ts - test-golden-standard.sh - test-kerykeion-mapper.ts - test-loop-fix.ts - test-natal-parser.ts - test-oct8-2025.json - test-oct8-5pm-2025.json - test-poetic-brain-fixes.ts - test-report.json - test-report.sh - test-solar-return.sh - test-srp-integration.js - test-srp.js - test-alex-fracture.js - test-translocation-parser.ts - test-upload-flow-simple.sh - test-upload-flow.sh - The Poetic Brain (Raven Calder)High-Level OverviewThis document.md - tsconfig.json - tsconfig.tsbuildinfo - Velocity Tracker and AI Collaboration Guide.md - velocity-log.jsonl - verify-copilot-setup.js - vitest.config.ts - WOVEN_MAP_V6_COMPLETE_ARCHITECTURE.md - WovenWeb Codemap & GuardrailsAuthoritative System Flow – Pure.md - WovenWebApp – Architecture Overview.md - WovenWebApp – Architecture OverviewPure Next.js Edition.md - WovenWebApp.code-workspace - - - -This section contains the contents of the repository's files. - - - 1: /** - 2: * Test suite for the Astrologer API wrapper module - 3: * - 4: * Demonstrates integration with Balance Meter pipeline and validates - 5: * typed fetchers and normalization hooks. - 6: */ - 7: import { describe, it, expect, vi, beforeEach } from 'vitest'; - 8: import { - 9: AstrologerClient, - 10: AstrologerAPIError, - 11: normalizeAspect, - 12: normalizeAspects, - 13: aspectsToBalanceMeterDay, - 14: scaleBalanceMeterDay, - 15: createAstrologerClient, - 16: type SubjectModel, - 17: type AspectModel, - 18: type BalanceMeterDayInput, - 19: } from '@/lib/api/astrologer'; - 20: // Mock fetch for testing - 21: const mockFetch = vi.fn(); - 22: describe('Astrologer API Wrapper', () => { - 23: let client: AstrologerClient; - 24: const mockApiKey = 'test-api-key'; - 25: beforeEach(() => { - 26: vi.clearAllMocks(); - 27: vi.stubGlobal('fetch', mockFetch); - 28: client = new AstrologerClient({ apiKey: mockApiKey }); - 29: }); - 30: describe('Client Configuration', () => { - 31: it('should create client with default config', () => { - 32: const client = new AstrologerClient({ apiKey: mockApiKey }); - 33: expect(client).toBeInstanceOf(AstrologerClient); - 34: }); - 35: it('should create client from environment', () => { - 36: process.env.RAPIDAPI_KEY = mockApiKey; - 37: expect(createAstrologerClient()).toBeInstanceOf(AstrologerClient); - 38: delete process.env.RAPIDAPI_KEY; - 39: }); - 40: it('should throw if RAPIDAPI_KEY not set', () => { - 41: delete process.env.RAPIDAPI_KEY; - 42: expect(() => createAstrologerClient()).toThrow('RAPIDAPI_KEY environment variable is required'); - 43: }); - 44: }); - 45: describe('API Error Handling', () => { - 46: it.skip('should handle API errors gracefully', async () => { - 47: const mockResponse = { - 48: ok: false, - 49: status: 400, - 50: statusText: 'Bad Request', - 51: text: vi.fn().mockResolvedValue('Bad Request'), - 52: }; - 53: mockFetch.mockReturnValueOnce(Promise.resolve(mockResponse as any)); - 54: await expect(client.getBirthData({} as SubjectModel)) - 55: .rejects - 56: .toThrow(AstrologerAPIError); - 57: }); - 58: it('should retry on failure', async () => { - 59: mockFetch - 60: .mockResolvedValueOnce({ - 61: ok: false, - 62: status: 500, - 63: text: () => Promise.resolve('Server Error'), - 64: }) - 65: .mockResolvedValueOnce({ - 66: ok: true, - 67: json: () => Promise.resolve({ status: 'success', subject: {}, planets: [], houses: [] }), - 68: }); - 69: const result = await client.getBirthData({} as SubjectModel); - 70: expect(mockFetch).toHaveBeenCalledTimes(2); - 71: expect(result.status).toBe('success'); - 72: }); - 73: }); - 74: describe('Aspect Normalization', () => { - 75: const mockAspect: AspectModel = { - 76: p1_name: 'Sun', - 77: p2_name: 'Moon', - 78: aspect: 'trine', - 79: orbit: 2.5, - 80: diff: 120, - 81: p1_abs_pos: 45, - 82: p2_abs_pos: 165, - 83: aspect_degrees: 120, - 84: }; - 85: it('should normalize single aspect', () => { - 86: const normalized = normalizeAspect(mockAspect); - 87: expect(normalized).toEqual({ - 88: aspect: 'trine', - 89: orb: 2.5, - 90: transit_potency: 1.0, - 91: target_potency: 1.0, - 92: transit: 'Sun', - 93: target: 'Moon', - 94: }); - 95: }); - 96: it('should normalize aspect array', () => { - 97: const aspects = [mockAspect, mockAspect]; - 98: const normalized = normalizeAspects(aspects); - 99: expect(normalized).toHaveLength(2); -100: expect(normalized[0].aspect).toBe('trine'); -101: }); -102: }); -103: describe('Balance Meter Integration', () => { -104: const mockSubject: SubjectModel = { -105: name: 'Test Person', -106: year: 1990, -107: month: 5, -108: day: 15, -109: hour: 12, -110: minute: 0, -111: latitude: 40.7128, -112: longitude: -74.006, -113: timezone: 'America/New_York', -114: }; -115: const mockAspects: AspectModel[] = [ -116: { -117: p1_name: 'Sun', -118: p2_name: 'Mars', -119: aspect: 'square', -120: orbit: 1.2, -121: diff: 90, -122: p1_abs_pos: 45, -123: p2_abs_pos: 135, -124: aspect_degrees: 90, -125: }, -126: ]; -127: it('should convert aspects to Balance Meter day input', () => { -128: const dayInput = aspectsToBalanceMeterDay( -129: mockAspects, -130: '2024-01-01', -131: mockSubject, -132: ); -133: expect(dayInput).toEqual({ -134: date: '2024-01-01', -135: magnitude: 0.1, // 1 aspect / 10 -136: directional_bias: 0, -137: volatility: 0.05, // 1 aspect / 20 -138: aspects: expect.any(Array), -139: timezone: 'America/New_York', -140: }); -141: }); -142: it('should scale Balance Meter inputs using canonical functions', () => { -143: const dayInput: BalanceMeterDayInput = { -144: date: '2024-01-01', -145: magnitude: 0.5, -146: directional_bias: 0.2, -147: volatility: 0.3, -148: timezone: 'America/New_York', -149: }; -150: const scaled = scaleBalanceMeterDay(dayInput); -151: expect(scaled.magnitude).toHaveProperty('value'); -152: expect(scaled.directionalBias).toHaveProperty('value'); -153: // Values should be properly scaled and rounded -154: expect(typeof scaled.magnitude.value).toBe('number'); -155: expect(typeof scaled.directionalBias.value).toBe('number'); -156: }); -157: }); -158: describe('API Endpoints', () => { -159: const mockSubject: SubjectModel = { -160: name: 'Test Person', -161: year: 1990, -162: month: 5, -163: day: 15, -164: latitude: 40.7128, -165: longitude: -74.006, -166: }; -167: it('should call birth data endpoint', async () => { -168: const mockResponse = { -169: status: 'success', -170: subject: mockSubject, -171: planets: [], -172: houses: [], -173: }; -174: mockFetch.mockResolvedValueOnce({ -175: ok: true, -176: json: () => Promise.resolve(mockResponse), -177: }); -178: const result = await client.getBirthData(mockSubject); -179: expect(mockFetch).toHaveBeenCalledWith( -180: 'https://astrologer.p.rapidapi.com/api/v4/birth-data', -181: expect.objectContaining({ -182: method: 'POST', -183: headers: expect.objectContaining({ -184: 'X-RapidAPI-Key': mockApiKey, -185: 'X-RapidAPI-Host': 'astrologer.p.rapidapi.com', -186: }), -187: }) -188: ); -189: expect(result).toEqual(mockResponse); -190: }); -191: it('should call transit aspects data endpoint', async () => { -192: const mockResponse = { -193: status: 'success', -194: aspects: [], -195: }; -196: mockFetch.mockResolvedValueOnce({ -197: ok: true, -198: json: () => Promise.resolve(mockResponse), -199: }); -200: const transitDates = [{ year: 2024, month: 1, day: 1 }]; -201: const result = await client.getTransitAspectsData(mockSubject, transitDates); -202: expect(result).toHaveLength(1); -203: expect(result[0]).toEqual(mockResponse); -204: }); -205: it('should call relationship score endpoint', async () => { -206: const mockResponse = { -207: status: 'success', -208: score: 25, -209: qualitative_range: 'Good', -210: description: 'Compatible relationship', -211: }; -212: mockFetch.mockResolvedValueOnce({ -213: ok: true, -214: json: () => Promise.resolve(mockResponse), -215: }); -216: const subjectB: SubjectModel = { ...mockSubject, name: 'Partner' }; -217: const result = await client.getRelationshipScore(mockSubject, subjectB); -218: expect(result.score).toBe(25); -219: expect(result.qualitative_range).toBe('Good'); -220: }); -221: }); -222: }); - - - - 1: import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; - 2: import type { NextRequest } from 'next/server'; - 3: type LegacyMathBrainModule = { - 4: handler: ( - 5: event: any, - 6: context: any, - 7: ) => Promise<{ - 8: statusCode?: number; - 9: headers?: Record; - 10: body?: string; - 11: }>; - 12: }; - 13: type LegacyHandlerResult = Awaited>; - 14: const createRequest = (payload: unknown): NextRequest => - 15: new Request('https://example.com/api/astrology-mathbrain', { - 16: method: 'POST', - 17: headers: { 'content-type': 'application/json' }, - 18: body: JSON.stringify(payload), - 19: }) as NextRequest; - 20: describe('Astrology Math Brain API route', () => { - 21: let legacyMathBrain: LegacyMathBrainModule; - 22: let originalHandler: LegacyMathBrainModule['handler']; - 23: beforeEach(() => { - 24: vi.resetModules(); - 25: legacyMathBrain = require('../../lib/server/astrology-mathbrain.js') as LegacyMathBrainModule; - 26: originalHandler = legacyMathBrain.handler; - 27: }); - 28: afterEach(() => { - 29: legacyMathBrain.handler = originalHandler; - 30: }); - 31: const exercisePostRoute = async (mockResult: LegacyHandlerResult | { body?: object; statusCode?: number }) => { - 32: const handlerMock = vi.fn(async () => { - 33: const body = - 34: typeof mockResult.body === 'string' - 35: ? mockResult.body - 36: : JSON.stringify( - 37: 'body' in mockResult && mockResult.body !== undefined ? mockResult.body : { success: false }, - 38: ); - 39: return { - 40: statusCode: mockResult.statusCode ?? 500, - 41: headers: { 'content-type': 'application/json' }, - 42: body, - 43: }; - 44: }); - 45: legacyMathBrain.handler = handlerMock; - 46: const { POST } = await import('@/app/api/astrology-mathbrain/route'); - 47: const request = createRequest({ personA: { name: 'Demo' } }); - 48: const response = await POST(request); - 49: const payload = await response.json(); - 50: return { handlerMock, response, payload }; - 51: }; - 52: it('returns 422 when the legacy handler flags invalid birth data', async () => { - 53: const legacyResponse = { - 54: statusCode: 400, - 55: body: { - 56: success: false, - 57: code: 'NATAL_CHART_FETCH_FAILED', - 58: error: 'Legacy handler rejected birth data', - 59: detail: 'Birth data missing coordinates', - 60: }, - 61: }; - 62: const { handlerMock, response, payload } = await exercisePostRoute(legacyResponse); - 63: expect(handlerMock).toHaveBeenCalledOnce(); - 64: expect(response.status).toBe(422); - 65: expect(payload).toMatchObject({ - 66: success: false, - 67: code: 'BIRTH_DATA_INVALID', - 68: detail: 'Birth data missing coordinates', - 69: }); - 70: expect(payload.error).toContain('Birth data appears invalid or incomplete'); - 71: expect(payload.hint).toContain('Verify that the birth date, time'); - 72: }); - 73: it('returns 503 with hint when RapidAPI key is missing', async () => { - 74: const { response, payload } = await exercisePostRoute({ - 75: statusCode: 500, - 76: body: { - 77: success: false, - 78: code: 'RAPIDAPI_KEY_MISSING', - 79: error: 'Missing RAPIDAPI_KEY', - 80: }, - 81: }); - 82: expect(response.status).toBe(503); - 83: expect(payload).toMatchObject({ - 84: success: false, - 85: code: 'RAPIDAPI_KEY_MISSING', - 86: }); - 87: expect(payload.error).toContain('Math Brain is offline'); - 88: expect(payload.hint).toContain('Add RAPIDAPI_KEY'); - 89: }); - 90: it('returns 503 for RapidAPI subscription/auth failures', async () => { - 91: const { response, payload } = await exercisePostRoute({ - 92: statusCode: 401, - 93: body: { - 94: success: false, - 95: code: 'RAPIDAPI_SUBSCRIPTION', - 96: error: 'Subscription invalid', - 97: }, - 98: }); - 99: expect(response.status).toBe(503); -100: expect(payload).toMatchObject({ -101: success: false, -102: code: 'RAPIDAPI_AUTH_ERROR', -103: }); -104: expect(payload.error).toContain('RapidAPI rejected the request'); -105: }); -106: it('returns 503 for RapidAPI rate limiting', async () => { -107: const { response, payload } = await exercisePostRoute({ -108: statusCode: 429, -109: body: { -110: success: false, -111: error: 'Too Many Requests', -112: }, -113: }); -114: expect(response.status).toBe(503); -115: expect(payload).toMatchObject({ -116: success: false, -117: code: 'RAPIDAPI_RATE_LIMIT', -118: }); -119: expect(payload.error).toContain('RapidAPI rate limit reached'); -120: }); -121: it('returns 503 for upstream temporary failures', async () => { -122: const { response, payload } = await exercisePostRoute({ -123: statusCode: 502, -124: body: { -125: success: false, -126: code: 'UPSTREAM_TEMPORARY', -127: error: 'Upstream timeout', -128: }, -129: }); -130: expect(response.status).toBe(503); -131: expect(payload).toMatchObject({ -132: success: false, -133: code: 'UPSTREAM_TEMPORARY', -134: }); -135: expect(payload.error).toContain('Astrologer API is temporarily unavailable'); -136: }); -137: }); - - - - 1: /** - 2: * Balance Tooltips API Integration Tests - 3: * - 4: * Tests the `include_balance_tooltips` opt-in flag for the Math Brain API. - 5: * When enabled, the API returns scored aspects that explain the Balance Meter values. - 6: * - 7: * @see docs/MANDATE_2_IMPLEMENTATION_PLAN.md - 8: */ - 9: import { describe, it, expect, vi, beforeEach } from 'vitest'; - 10: // Mock the seismograph aggregate function to return predictable scored aspects - 11: const mockScoredAspects = [ - 12: { - 13: transit: { body: 'Saturn', retrograde: false }, - 14: natal: { body: 'Moon' }, - 15: type: 'square', - 16: orbDeg: 2.3, - 17: S: -0.85, - 18: }, - 19: { - 20: transit: { body: 'Jupiter', retrograde: false }, - 21: natal: { body: 'Venus' }, - 22: type: 'trine', - 23: orbDeg: 1.1, - 24: S: 0.72, - 25: }, - 26: { - 27: transit: { body: 'Mars', retrograde: true }, - 28: natal: { body: 'Sun' }, - 29: type: 'opposition', - 30: orbDeg: 3.5, - 31: S: -0.45, - 32: }, - 33: ]; - 34: describe('Balance Tooltips API Flag', () => { - 35: describe('include_balance_tooltips: false (default)', () => { - 36: it('should NOT include balance_tooltips in response by default', async () => { - 37: // Simulate a response without the flag - 38: const responseBody = { - 39: success: true, - 40: unified_output: { - 41: daily_entries: [ - 42: { - 43: date: '2025-01-15', - 44: symbolic_weather: { - 45: magnitude: 3.2, - 46: directional_bias: -1.5, - 47: }, - 48: }, - 49: ], - 50: }, - 51: // balance_tooltips should be undefined - 52: }; - 53: expect(responseBody).not.toHaveProperty('balance_tooltips'); - 54: }); - 55: it('should keep payload light when flag is not set', () => { - 56: const responseBody = { - 57: success: true, - 58: unified_output: { daily_entries: [] }, - 59: }; - 60: // Verify no extra data is included - 61: const keys = Object.keys(responseBody); - 62: expect(keys).not.toContain('balance_tooltips'); - 63: }); - 64: }); - 65: describe('include_balance_tooltips: true', () => { - 66: it('should include balance_tooltips array when flag is true', () => { - 67: // Simulate a response with the flag enabled - 68: const responseBody = { - 69: success: true, - 70: unified_output: { - 71: daily_entries: [ - 72: { - 73: date: '2025-01-15', - 74: symbolic_weather: { - 75: magnitude: 3.2, - 76: directional_bias: -1.5, - 77: _aggregateResult: { - 78: scored: mockScoredAspects, - 79: }, - 80: }, - 81: }, - 82: ], - 83: }, - 84: balance_tooltips: [ - 85: { - 86: date: '2025-01-15', - 87: scored_aspects: mockScoredAspects, - 88: }, - 89: ], - 90: }; - 91: expect(responseBody).toHaveProperty('balance_tooltips'); - 92: expect(responseBody.balance_tooltips).toHaveLength(1); - 93: expect(responseBody.balance_tooltips[0].date).toBe('2025-01-15'); - 94: expect(responseBody.balance_tooltips[0].scored_aspects).toHaveLength(3); - 95: }); - 96: it('should preserve scored aspect structure', () => { - 97: const scoredAspect = mockScoredAspects[0]; - 98: // Verify structure matches ScoredAspect type - 99: expect(scoredAspect).toHaveProperty('transit'); -100: expect(scoredAspect).toHaveProperty('natal'); -101: expect(scoredAspect).toHaveProperty('type'); -102: expect(scoredAspect).toHaveProperty('orbDeg'); -103: expect(scoredAspect).toHaveProperty('S'); -104: // Verify transit structure -105: expect(scoredAspect.transit).toHaveProperty('body'); -106: expect(scoredAspect.transit).toHaveProperty('retrograde'); -107: // Verify natal structure -108: expect(scoredAspect.natal).toHaveProperty('body'); -109: }); -110: it('should handle empty scored array gracefully', () => { -111: const responseBody = { -112: success: true, -113: balance_tooltips: [ -114: { -115: date: '2025-01-15', -116: scored_aspects: [], -117: }, -118: ], -119: }; -120: expect(responseBody.balance_tooltips[0].scored_aspects).toEqual([]); -121: }); -122: it('should handle missing _aggregateResult gracefully', () => { -123: // When _aggregateResult is missing, scored_aspects should be empty -124: const dailyEntry = { -125: date: '2025-01-15', -126: symbolic_weather: { -127: magnitude: 0, -128: directional_bias: 0, -129: // No _aggregateResult -130: }, -131: }; -132: const scoredAspects = (dailyEntry.symbolic_weather as any)?._aggregateResult?.scored || []; -133: expect(scoredAspects).toEqual([]); -134: }); -135: }); -136: describe('Scored Aspect Validation', () => { -137: it('should have valid score range (-1 to +1 typical, can exceed with boost)', () => { -138: for (const aspect of mockScoredAspects) { -139: // Scores typically range from -1 to +1, but can be higher with outer planet boost -140: expect(aspect.S).toBeGreaterThanOrEqual(-2); -141: expect(aspect.S).toBeLessThanOrEqual(2); -142: } -143: }); -144: it('should have valid aspect types', () => { -145: const validTypes = ['conjunction', 'opposition', 'square', 'trine', 'sextile', 'quincunx', 'semisextile']; -146: for (const aspect of mockScoredAspects) { -147: expect(validTypes).toContain(aspect.type); -148: } -149: }); -150: it('should have valid orb degrees (0-10 range)', () => { -151: for (const aspect of mockScoredAspects) { -152: expect(aspect.orbDeg).toBeGreaterThanOrEqual(0); -153: expect(aspect.orbDeg).toBeLessThanOrEqual(10); -154: } -155: }); -156: it('should identify hard aspects by negative score', () => { -157: const hardAspects = mockScoredAspects.filter(a => -158: ['square', 'opposition'].includes(a.type) -159: ); -160: for (const aspect of hardAspects) { -161: expect(aspect.S).toBeLessThan(0); -162: } -163: }); -164: it('should identify soft aspects by positive score', () => { -165: const softAspects = mockScoredAspects.filter(a => -166: ['trine', 'sextile'].includes(a.type) -167: ); -168: for (const aspect of softAspects) { -169: expect(aspect.S).toBeGreaterThan(0); -170: } -171: }); -172: }); -173: describe('Multi-day Response', () => { -174: it('should include tooltips for each day when flag is enabled', () => { -175: const responseBody = { -176: balance_tooltips: [ -177: { date: '2025-01-15', scored_aspects: mockScoredAspects }, -178: { date: '2025-01-16', scored_aspects: [mockScoredAspects[0]] }, -179: { date: '2025-01-17', scored_aspects: [] }, -180: ], -181: }; -182: expect(responseBody.balance_tooltips).toHaveLength(3); -183: expect(responseBody.balance_tooltips[0].scored_aspects).toHaveLength(3); -184: expect(responseBody.balance_tooltips[1].scored_aspects).toHaveLength(1); -185: expect(responseBody.balance_tooltips[2].scored_aspects).toHaveLength(0); -186: }); -187: it('should preserve date association', () => { -188: const responseBody = { -189: balance_tooltips: [ -190: { date: '2025-01-15', scored_aspects: mockScoredAspects }, -191: { date: '2025-01-16', scored_aspects: [] }, -192: ], -193: }; -194: // Each tooltip entry should have its date preserved -195: expect(responseBody.balance_tooltips[0].date).toBe('2025-01-15'); -196: expect(responseBody.balance_tooltips[1].date).toBe('2025-01-16'); -197: }); -198: }); -199: }); -200: describe('Balance Tooltip Data Shape', () => { -201: it('should match the expected TypeScript interface', () => { -202: // This test documents the expected shape for Phase 3 (tooltip-context.ts) -203: interface ScoredAspect { -204: transit: { body: string; retrograde: boolean }; -205: natal: { body: string }; -206: type: string; -207: orbDeg: number; -208: S: number; -209: _amplification?: { before: number; after: number; factor: number }; -210: } -211: interface BalanceTooltipEntry { -212: date: string; -213: scored_aspects: ScoredAspect[]; -214: } -215: const entry: BalanceTooltipEntry = { -216: date: '2025-01-15', -217: scored_aspects: mockScoredAspects, -218: }; -219: expect(entry.date).toBeDefined(); -220: expect(Array.isArray(entry.scored_aspects)).toBe(true); -221: }); -222: }); - - - - 1: /** - 2: * Test for trimPayloadForPoeticBrain - 3: * Verifies payload trimming reduces size while preserving essential data - 4: */ - 5: import { describe, it, expect } from 'vitest'; - 6: import { trimPayloadForPoeticBrain, estimatePayloadReduction } from '../../lib/export/trimPayloadForPoeticBrain'; - 7: describe('trimPayloadForPoeticBrain', () => { - 8: const samplePayload = { - 9: _format: 'mirror-symbolic-weather-v1', - 10: _version: '1.0', - 11: _poetic_brain_compatible: true, // Should be DROPPED - 12: _template_hint: 'solo_mirror', // Should be DROPPED - 13: _contains_transits: true, - 14: _contains_weather_data: true, - 15: _range_dates: ['2025-11-29', '2025-12-01'], - 16: _transit_days: 3, - 17: _natal_sections: 1, - 18: _required_sections: ['person_a'], - 19: generated_at: '2025-11-29T06:06:38.207Z', - 20: _natal_section: { - 21: mirror_source: 'integrated', - 22: note: 'Test', - 23: relationship_context: { - 24: type: 'PARTNER', - 25: intimacy_tier: 'P3', - 26: contact_state: 'ACTIVE', - 27: ex_estranged: false, - 28: scope: 'PARTNER', - 29: scope_label: 'Partner', - 30: }, - 31: }, - 32: person_a: { - 33: name: 'Dan', - 34: birth_data: { - 35: name: 'Dan', - 36: year: 1973, - 37: month: 7, - 38: day: 24, - 39: hour: 14, - 40: minute: 30, - 41: timezone: 'America/New_York', - 42: }, - 43: chart: { - 44: name: 'Dan', // Should be DROPPED - 45: year: 1973, // Should be DROPPED (duplicate) - 46: month: 7, // Should be DROPPED (duplicate) - 47: day: 24, // Should be DROPPED (duplicate) - 48: lng: -75.3, - 49: lat: 40.0167, - 50: tz_str: 'America/New_York', - 51: zodiac_type: 'Tropic', - 52: houses_system_identifier: 'P', - 53: houses_system_name: 'Placidus', - 54: house_cusps: [218.79, 247.49, 282.51, 320.31, 353.15, 18.77, 38.79, 67.49, 102.51, 140.31, 173.15, 198.77], - 55: sun: { - 56: name: 'Sun', // Should be DROPPED - 57: quality: 'Fixed', // Should be DROPPED - 58: element: 'Fire', // Should be DROPPED - 59: sign: 'Leo', - 60: sign_num: 4, - 61: position: 1.69, // Should be DROPPED - 62: abs_pos: 121.69, - 63: emoji: '♌️', // Should be DROPPED - 64: point_type: 'Planet', // Should be DROPPED - 65: house: 'Ninth_House', - 66: retrograde: false, - 67: }, - 68: moon: { - 69: name: 'Moon', - 70: quality: 'Fixed', - 71: element: 'Earth', - 72: sign: 'Tau', - 73: sign_num: 1, - 74: abs_pos: 54.35, - 75: emoji: '♉️', - 76: point_type: 'Planet', - 77: house: 'Seventh_House', - 78: retrograde: false, - 79: }, - 80: planets_names_list: ['Sun', 'Moon'], // Should be DROPPED - 81: transitsByDate: { - 82: '2025-11-29': { - 83: seismograph: { - 84: magnitude: 3.2, - 85: magnitude_label: 'Surge', - 86: magnitude_meta: null, - 87: magnitude_range: [0, 5], - 88: magnitude_method: 'adaptive_normalization_v4', // Should be DROPPED - 89: rawMagnitude: 3.23, // Should be DROPPED - 90: rawDirectionalBias: -4.56, // Should be DROPPED - 91: directional_bias: { - 92: value: -4.6, - 93: abs: 4.6, - 94: label: 'Maximum Inward', - 95: code: 'max_inward', - 96: direction: 'inward', - 97: meta: { // Should be DROPPED - 98: method: 'seismograph_signed_v4', - 99: epsilon: 0.05, -100: transform_pipeline: ['sign_resolution', 'no_clamp'], -101: }, -102: }, -103: volatility: 4.77, -104: volatility_label: 'Fragment Scatter', -105: }, -106: aspects: [ // Should be DROPPED -107: { p1: 'Sun', p2: 'Moon', aspect: 'sextile', orb: 2.3 }, -108: ], -109: hooks: ['some hook'], // Should be DROPPED -110: drivers: ['some driver'], // Should be DROPPED -111: }, -112: }, -113: }, -114: aspects: [ // Should be DROPPED -115: { p1_name: 'Sun', p2_name: 'Moon', aspect: 'sextile' }, -116: ], -117: }, -118: provenance: { -119: math_brain_version: '3.2.7', -120: ephemeris_source: 'AstroAPI-v3', -121: house_system: 'Placidus', -122: orbs_profile: 'default_v5', -123: timezone: 'America/Chicago', -124: relocation_applied: true, -125: relocation_mode: 'both_local', -126: persona_excerpt: 'This is a MASSIVE text dump of Raven persona...'.repeat(100), // Should be DROPPED -127: persona_excerpt_source: { source: 'corpus', file: 'test.txt' }, // Should be DROPPED -128: identity: { person_a: { source: 'test' } }, // Should be DROPPED -129: }, -130: daily_readings: [ -131: { -132: date: '2025-11-29', -133: magnitude: 3.2, -134: directional_bias: -4.6, -135: volatility: 4.77, -136: coherence: 0.23, -137: raw_magnitude: 3.23, // Should be DROPPED -138: raw_bias_signed: -4.56, // Should be DROPPED -139: aspects: [{ p1: 'Sun', p2: 'Moon' }], // Should be DROPPED -140: aspect_count: 1, // Should be DROPPED -141: overflow_detail: {}, // Should be DROPPED -142: }, -143: ], -144: }; -145: it('preserves essential metadata', () => { -146: const trimmed = trimPayloadForPoeticBrain(samplePayload); -147: expect(trimmed._format).toBe('mirror-symbolic-weather-v1'); -148: expect(trimmed._version).toBe('1.0'); -149: expect(trimmed._contains_transits).toBe(true); -150: expect(trimmed._range_dates).toEqual(['2025-11-29', '2025-12-01']); -151: expect(trimmed._transit_days).toBe(3); -152: expect(trimmed.generated_at).toBe('2025-11-29T06:06:38.207Z'); -153: }); -154: it('removes _poetic_brain_compatible and _template_hint', () => { -155: const trimmed = trimPayloadForPoeticBrain(samplePayload); -156: expect(trimmed._poetic_brain_compatible).toBeUndefined(); -157: expect(trimmed._template_hint).toBeUndefined(); -158: }); -159: it('keeps birth_data and essential chart info', () => { -160: const trimmed = trimPayloadForPoeticBrain(samplePayload); -161: expect(trimmed.person_a.name).toBe('Dan'); -162: expect(trimmed.person_a.birth_data).toBeDefined(); -163: expect(trimmed.person_a.birth_data.year).toBe(1973); -164: expect(trimmed.person_a.chart.lng).toBe(-75.3); -165: expect(trimmed.person_a.chart.lat).toBe(40.0167); -166: expect(trimmed.person_a.chart.house_cusps).toHaveLength(12); -167: }); -168: it('removes duplicate date fields from chart', () => { -169: const trimmed = trimPayloadForPoeticBrain(samplePayload); -170: expect(trimmed.person_a.chart.name).toBeUndefined(); -171: expect(trimmed.person_a.chart.year).toBeUndefined(); -172: expect(trimmed.person_a.chart.month).toBeUndefined(); -173: expect(trimmed.person_a.chart.day).toBeUndefined(); -174: }); -175: it('trims planet objects to essential fields', () => { -176: const trimmed = trimPayloadForPoeticBrain(samplePayload); -177: const sun = trimmed.person_a.chart.positions.sun; -178: expect(sun.abs_pos).toBe(121.69); -179: expect(sun.house).toBe('Ninth_House'); -180: expect(sun.retrograde).toBe(false); -181: expect(sun.sign).toBe('Leo'); -182: // Dropped fields -183: expect(sun.name).toBeUndefined(); -184: expect(sun.quality).toBeUndefined(); -185: expect(sun.element).toBeUndefined(); -186: expect(sun.emoji).toBeUndefined(); -187: expect(sun.point_type).toBeUndefined(); -188: expect(sun.position).toBeUndefined(); -189: }); -190: it('removes planets_names_list', () => { -191: const trimmed = trimPayloadForPoeticBrain(samplePayload); -192: expect(trimmed.person_a.chart.planets_names_list).toBeUndefined(); -193: }); -194: it('trims seismograph to final values only', () => { -195: const trimmed = trimPayloadForPoeticBrain(samplePayload); -196: const seismo = trimmed.person_a.chart.transitsByDate['2025-11-29'].seismograph; -197: expect(seismo.magnitude).toBe(3.2); -198: expect(seismo.directional_bias).toBe(-4.6); -199: expect(seismo.volatility).toBe(4.77); -200: expect(seismo.magnitude_label).toBe('Surge'); -201: expect(seismo.directional_bias_label).toBe('Maximum Inward'); -202: // Dropped meta/raw fields -203: expect(seismo.magnitude_meta).toBeUndefined(); -204: expect(seismo.magnitude_range).toBeUndefined(); -205: expect(seismo.magnitude_method).toBeUndefined(); -206: expect(seismo.rawMagnitude).toBeUndefined(); -207: expect(seismo.rawDirectionalBias).toBeUndefined(); -208: }); -209: it('removes aspects/hooks/drivers from transit days', () => { -210: const trimmed = trimPayloadForPoeticBrain(samplePayload); -211: const day = trimmed.person_a.chart.transitsByDate['2025-11-29']; -212: expect(day.aspects).toBeUndefined(); -213: expect(day.hooks).toBeUndefined(); -214: expect(day.drivers).toBeUndefined(); -215: }); -216: it('removes persona_excerpt from provenance (CRITICAL)', () => { -217: const trimmed = trimPayloadForPoeticBrain(samplePayload); -218: expect(trimmed.provenance.persona_excerpt).toBeUndefined(); -219: expect(trimmed.provenance.persona_excerpt_source).toBeUndefined(); -220: expect(trimmed.provenance.identity).toBeUndefined(); -221: // Keeps essential provenance -222: expect(trimmed.provenance.math_brain_version).toBe('3.2.7'); -223: expect(trimmed.provenance.house_system).toBe('Placidus'); -224: expect(trimmed.provenance.relocation_applied).toBe(true); -225: }); -226: it('trims daily_readings to final meter values', () => { -227: const trimmed = trimPayloadForPoeticBrain(samplePayload); -228: const reading = trimmed.daily_readings[0]; -229: expect(reading.date).toBe('2025-11-29'); -230: expect(reading.magnitude).toBe(3.2); -231: expect(reading.directional_bias).toBe(-4.6); -232: // Dropped fields -233: expect(reading.raw_magnitude).toBeUndefined(); -234: expect(reading.raw_bias_signed).toBeUndefined(); -235: expect(reading.aspects).toBeUndefined(); -236: expect(reading.aspect_count).toBeUndefined(); -237: expect(reading.overflow_detail).toBeUndefined(); -238: }); -239: it('preserves natal aspects array for Poetic Brain mandate generation', () => { -240: const trimmed = trimPayloadForPoeticBrain(samplePayload); -241: // Aspects are KEPT per spec: buildMandatesForChart needs them -242: expect(trimmed.person_a.aspects).toBeDefined(); -243: expect(Array.isArray(trimmed.person_a.aspects)).toBe(true); -244: }); -245: it('significantly reduces payload size', () => { -246: const trimmed = trimPayloadForPoeticBrain(samplePayload); -247: const stats = estimatePayloadReduction(samplePayload, trimmed); -248: // Expect at least 50% reduction due to persona_excerpt alone -249: expect(parseInt(stats.reductionPercent)).toBeGreaterThan(50); -250: // Verify stats are calculated correctly -251: expect(stats.originalSize).toBeGreaterThan(stats.trimmedSize); -252: expect(stats.reduction).toBeGreaterThan(0); -253: }); -254: it('handles null/undefined inputs gracefully', () => { -255: expect(trimPayloadForPoeticBrain(null)).toBeNull(); -256: expect(trimPayloadForPoeticBrain(undefined)).toBeUndefined(); -257: expect(trimPayloadForPoeticBrain({})).toEqual({}); -258: }); -259: it('handles API v3 format with chart.positions dictionary', () => { -260: // New format from API v3: positions in a nested dictionary with PascalCase keys -261: const apiV3Payload = { -262: _format: 'mirror-symbolic-weather-v1', -263: _version: '1.0', -264: generated_at: '2025-12-03T07:00:00.000Z', -265: person_a: { -266: name: 'Test', -267: birth_data: { year: 1980, month: 6, day: 15 }, -268: chart: { -269: positions: { -270: Sun: { sign: 'Gem', deg: 24.66, abs_pos: 84.66, house: 10, retro: false }, -271: Moon: { sign: 'Can', deg: 29.53, abs_pos: 119.53, house: 11, retro: false }, -272: Mercury: { sign: 'Can', deg: 19.09, abs_pos: 109.09, house: 11, retro: false }, -273: }, -274: angle_signs: { ascendant: 'Leo', mc: 'Tau' }, -275: cusps: [147.93, 170.43, 198.2, 231.36, 266.83, 299.63, 327.93, 350.43, 18.2, 51.36, 86.83, 119.63], -276: transitsByDate: {}, -277: }, -278: }, -279: provenance: { -280: math_brain_version: '3.3.0', -281: }, -282: }; -283: const trimmed = trimPayloadForPoeticBrain(apiV3Payload); -284: // Should preserve positions from the dictionary -285: expect(trimmed.person_a.chart.positions).toBeDefined(); -286: expect(Object.keys(trimmed.person_a.chart.positions).length).toBe(3); -287: expect(trimmed.person_a.chart.positions.Sun).toBeDefined(); -288: expect(trimmed.person_a.chart.positions.Sun.abs_pos).toBe(84.66); -289: expect(trimmed.person_a.chart.positions.Sun.sign).toBe('Gem'); -290: expect(trimmed.person_a.chart.positions.Sun.retrograde).toBe(false); // Normalized from 'retro' -291: // Should preserve angle_signs -292: expect(trimmed.person_a.chart.angle_signs).toEqual({ ascendant: 'Leo', mc: 'Tau' }); -293: // Should preserve cusps -294: expect(trimmed.person_a.chart.cusps).toHaveLength(12); -295: }); -296: }); - - - - 1: /** - 2: * Tooltip Context Builder Tests - 3: * - 4: * Tests for the Balance Meter tooltip content generation. - 5: * Verifies FRONTSTAGE voice rules (no astrological jargon). - 6: */ - 7: import { describe, it, expect } from 'vitest'; - 8: import { - 9: buildTooltipContent, - 10: buildTooltipForDate, - 11: buildLatestTooltip, - 12: formatTooltipAsText, - 13: formatTooltipAsHTML, - 14: getCompactSummary, - 15: type TooltipContent, - 16: } from '@/lib/raven/tooltip-context'; - 17: import type { ScoredAspect, BalanceTooltipEntry } from '@/lib/raven/balance-tooltip-types'; - 18: // Test fixtures - 19: const mockRestrictiveAspect: ScoredAspect = { - 20: transit: { body: 'Saturn', retrograde: false }, - 21: natal: { body: 'Moon' }, - 22: type: 'square', - 23: orbDeg: 2.3, - 24: S: -0.85, - 25: }; - 26: const mockHarmoniousAspect: ScoredAspect = { - 27: transit: { body: 'Jupiter', retrograde: false }, - 28: natal: { body: 'Venus' }, - 29: type: 'trine', - 30: orbDeg: 1.1, - 31: S: 0.72, - 32: }; - 33: const mockRetrogradeAspect: ScoredAspect = { - 34: transit: { body: 'Mercury', retrograde: true }, - 35: natal: { body: 'Sun' }, - 36: type: 'opposition', - 37: orbDeg: 3.5, - 38: S: -0.45, - 39: }; - 40: const mockNeutralAspect: ScoredAspect = { - 41: transit: { body: 'Venus', retrograde: false }, - 42: natal: { body: 'Mars' }, - 43: type: 'conjunction', - 44: orbDeg: 5.0, - 45: S: 0.05, - 46: }; - 47: describe('buildTooltipContent', () => { - 48: describe('empty/quiet cases', () => { - 49: it('should handle empty aspects array', () => { - 50: const result = buildTooltipContent([]); - 51: expect(result.headline).toBe('A relatively quiet field today'); - 52: expect(result.drivers).toHaveLength(0); - 53: expect(result.energyQuality).toBe('quiet'); - 54: expect(result.intensity).toBe('quiet'); - 55: }); - 56: it('should handle null/undefined aspects', () => { - 57: const result = buildTooltipContent(null as any); - 58: expect(result.headline).toBe('A relatively quiet field today'); - 59: expect(result.energyQuality).toBe('quiet'); - 60: }); - 61: }); - 62: describe('friction-dominant field', () => { - 63: it('should detect friction energy quality', () => { - 64: const result = buildTooltipContent([mockRestrictiveAspect]); - 65: expect(result.energyQuality).toBe('friction'); - 66: expect(result.drivers[0].direction).toBe('friction'); - 67: }); - 68: it('should generate appropriate headline for strong friction', () => { - 69: const result = buildTooltipContent([mockRestrictiveAspect]); - 70: expect(result.headline).toContain('friction'); - 71: expect(result.intensity).toBe('strong'); - 72: }); - 73: }); - 74: describe('flow-dominant field', () => { - 75: it('should detect flow energy quality', () => { - 76: const result = buildTooltipContent([mockHarmoniousAspect]); - 77: expect(result.energyQuality).toBe('flow'); - 78: expect(result.drivers[0].direction).toBe('flow'); - 79: }); - 80: it('should generate appropriate headline for flow', () => { - 81: const result = buildTooltipContent([mockHarmoniousAspect]); - 82: expect(result.headline).toContain('flow'); - 83: }); - 84: }); - 85: describe('mixed field', () => { - 86: it('should detect mixed energy quality', () => { - 87: const result = buildTooltipContent([ - 88: mockRestrictiveAspect, - 89: mockHarmoniousAspect, - 90: ]); - 91: expect(result.energyQuality).toBe('mixed'); - 92: }); - 93: it('should include both friction and flow drivers', () => { - 94: const result = buildTooltipContent([ - 95: mockRestrictiveAspect, - 96: mockHarmoniousAspect, - 97: ]); - 98: const directions = result.drivers.map((d: any) => d.direction); - 99: expect(directions).toContain('friction'); -100: expect(directions).toContain('flow'); -101: }); -102: }); -103: describe('retrograde handling', () => { -104: it('should add retrograde note when present', () => { -105: const result = buildTooltipContent([mockRetrogradeAspect]); -106: expect(result.retrogradeNote).toBeDefined(); -107: expect(result.retrogradeNote).toContain('inward'); -108: expect(result.retrogradeNote).toContain('reflective'); -109: }); -110: it('should include retrograde quality in driver description', () => { -111: const result = buildTooltipContent([mockRetrogradeAspect]); -112: expect(result.drivers[0].description).toContain('inward'); -113: }); -114: it('should not add retrograde note when none present', () => { -115: const result = buildTooltipContent([mockRestrictiveAspect]); -116: expect(result.retrogradeNote).toBeUndefined(); -117: }); -118: }); -119: describe('maxDrivers option', () => { -120: it('should limit drivers to maxDrivers', () => { -121: const manyAspects = [ -122: mockRestrictiveAspect, -123: mockHarmoniousAspect, -124: mockRetrogradeAspect, -125: mockNeutralAspect, -126: ]; -127: const result = buildTooltipContent(manyAspects, { maxDrivers: 2 }); -128: expect(result.drivers.length).toBeLessThanOrEqual(2); -129: }); -130: it('should default to 3 drivers', () => { -131: const manyAspects = [ -132: mockRestrictiveAspect, -133: mockHarmoniousAspect, -134: mockRetrogradeAspect, -135: mockNeutralAspect, -136: { ...mockRestrictiveAspect, S: -0.3 }, -137: ]; -138: const result = buildTooltipContent(manyAspects); -139: expect(result.drivers.length).toBeLessThanOrEqual(3); -140: }); -141: }); -142: describe('debug mode', () => { -143: it('should include debug data when requested', () => { -144: const result = buildTooltipContent([mockRestrictiveAspect], { includeDebug: true }); -145: expect(result._debug).toBeDefined(); -146: expect(result._debug?.totalAspects).toBe(1); -147: expect(result._debug?.restrictiveCount).toBe(1); -148: expect(result._debug?.harmoniousCount).toBe(0); -149: }); -150: it('should include top driver info in debug', () => { -151: const result = buildTooltipContent([mockRestrictiveAspect], { includeDebug: true }); -152: expect(result._debug?.topDriver).toBeDefined(); -153: expect(result._debug?.topDriver?.transit).toBe('Saturn'); -154: expect(result._debug?.topDriver?.natal).toBe('Moon'); -155: expect(result._debug?.topDriver?.aspect).toBe('square'); -156: }); -157: it('should not include debug data by default', () => { -158: const result = buildTooltipContent([mockRestrictiveAspect]); -159: expect(result._debug).toBeUndefined(); -160: }); -161: }); -162: describe('FRONTSTAGE VOICE RULES', () => { -163: it('should NOT contain planet names in headline', () => { -164: const result = buildTooltipContent([mockRestrictiveAspect]); -165: const headline = result.headline.toLowerCase(); -166: expect(headline).not.toContain('saturn'); -167: expect(headline).not.toContain('moon'); -168: expect(headline).not.toContain('jupiter'); -169: }); -170: it('should NOT contain aspect names in driver descriptions', () => { -171: const result = buildTooltipContent([ -172: mockRestrictiveAspect, -173: mockHarmoniousAspect, -174: ]); -175: result.drivers.forEach((driver: any) => { -176: const desc = driver.description.toLowerCase(); -177: expect(desc).not.toContain('square'); -178: expect(desc).not.toContain('trine'); -179: expect(desc).not.toContain('opposition'); -180: expect(desc).not.toContain('sextile'); -181: }); -182: }); -183: it('should NOT contain degrees or angles', () => { -184: const result = buildTooltipContent([mockRestrictiveAspect]); -185: const text = formatTooltipAsText(result).toLowerCase(); -186: expect(text).not.toMatch(/\d+°/); -187: expect(text).not.toContain('degree'); -188: }); -189: it('should use symbolic weather language', () => { -190: const result = buildTooltipContent([mockRestrictiveAspect]); -191: // Should use terms like friction, flow, field, etc. -192: const text = formatTooltipAsText(result).toLowerCase(); -193: const hasSymbolicLanguage = -194: text.includes('friction') || -195: text.includes('flow') || -196: text.includes('field') || -197: text.includes('force') || -198: text.includes('tension') || -199: text.includes('ease'); -200: expect(hasSymbolicLanguage).toBe(true); -201: }); -202: }); -203: }); -204: describe('buildTooltipForDate', () => { -205: const mockTooltips: BalanceTooltipEntry[] = [ -206: { date: '2025-01-15', scored_aspects: [mockRestrictiveAspect] }, -207: { date: '2025-01-16', scored_aspects: [mockHarmoniousAspect] }, -208: ]; -209: it('should find tooltip for specific date', () => { -210: const result = buildTooltipForDate(mockTooltips, '2025-01-15'); -211: expect(result).not.toBeNull(); -212: expect(result?.energyQuality).toBe('friction'); -213: }); -214: it('should return null for missing date', () => { -215: const result = buildTooltipForDate(mockTooltips, '2025-01-20'); -216: expect(result).toBeNull(); -217: }); -218: }); -219: describe('buildLatestTooltip', () => { -220: const mockTooltips: BalanceTooltipEntry[] = [ -221: { date: '2025-01-15', scored_aspects: [mockRestrictiveAspect] }, -222: { date: '2025-01-17', scored_aspects: [mockHarmoniousAspect] }, -223: { date: '2025-01-16', scored_aspects: [mockNeutralAspect] }, -224: ]; -225: it('should return tooltip for most recent date', () => { -226: const result = buildLatestTooltip(mockTooltips); -227: expect(result).not.toBeNull(); -228: // 2025-01-17 is the latest, which has harmoniousAspect -229: expect(result?.energyQuality).toBe('flow'); -230: }); -231: it('should return null for empty array', () => { -232: const result = buildLatestTooltip([]); -233: expect(result).toBeNull(); -234: }); -235: }); -236: describe('formatTooltipAsText', () => { -237: it('should format content as readable text', () => { -238: const content = buildTooltipContent([mockRestrictiveAspect]); -239: const text = formatTooltipAsText(content); -240: expect(text).toContain(content.headline); -241: expect(text).toContain(content.drivers[0].description); -242: }); -243: it('should include retrograde note when present', () => { -244: const content = buildTooltipContent([mockRetrogradeAspect]); -245: const text = formatTooltipAsText(content); -246: expect(text).toContain('Note:'); -247: }); -248: }); -249: describe('formatTooltipAsHTML', () => { -250: it('should generate valid HTML structure', () => { -251: const content = buildTooltipContent([mockRestrictiveAspect]); -252: const html = formatTooltipAsHTML(content); -253: expect(html).toContain('

'); -254: expect(html).toContain('