diff --git a/.github/workflows/backend-quality-gate.yml b/.github/workflows/backend-quality-gate.yml index f82c5f3f..5f0a3ca0 100644 --- a/.github/workflows/backend-quality-gate.yml +++ b/.github/workflows/backend-quality-gate.yml @@ -63,6 +63,7 @@ jobs: python scripts/run_quality_gate.py \ --profile quick --skip-yoga-logic --skip-frontend-runtime \ 2>&1 | tee artifacts/quick-quality-gate.log + python scripts/commercial_privacy_artifact_scan.py --json python -m build - name: Upload quick quality gate diagnostics diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ca5930f..aa940886 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,8 @@ jobs: run: | mkdir -p artifacts python scripts/run_quality_gate.py --profile quick --skip-yoga-logic --skip-frontend-runtime 2>&1 | tee artifacts/quick-quality-gate.log + - name: Run commercial privacy artifact gate + run: python scripts/commercial_privacy_artifact_scan.py --json - name: Upload quick quality gate diagnostics if: always() uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore index a1818814..aba631e4 100644 --- a/.gitignore +++ b/.gitignore @@ -43,5 +43,9 @@ frontend/pnpm-workspace.yaml /benchmarks/vedastro_nuget_probe/bin/ /benchmarks/vedastro_nuget_probe/obj/ +# Local ephemeris/runtime data downloaded outside the repo artifact contract +/hip_main.dat +/hip_main.dat.download + # Local isolated feature worktrees .worktrees/ diff --git a/docs/research/open_source_integration_priority_table_2026_07_03.md b/docs/research/open_source_integration_priority_table_2026_07_03.md index 1b898025..c4b79e02 100644 --- a/docs/research/open_source_integration_priority_table_2026_07_03.md +++ b/docs/research/open_source_integration_priority_table_2026_07_03.md @@ -27,7 +27,7 @@ | 优先级 | 开源对象(仓内真实文件) | 当前状态 | 接哪里 | 用来干什么 | 许可证风险 | 预计几小时落地 | |---|---|---|---|---|---|---| -| P0 | `references/open_source_sources/panchanga_api/README.md` `references/open_source_sources/panchanga_api/MCP.md` `references/open_source_sources/panchanga_api/SKILL.md` | 半接 | `scripts/prashna.py` `scripts/remedies.py` `scripts/jyotish_api_server.py` `scripts/unified_consultation_orchestrator.py` `jyotish-app/main.js` | 把“时间问事 / Muhurta / Panchanga / Remedies”压到统一入口,复用你刚接好的 `prashna` 与 `audited_remedies` 主链 | 低。镜像内 README 指向 MIT;当前仓内有 `LICENSE` | 4-8h | +| 已接/参考 | `references/open_source_sources/panchanga_api/README.md` `references/open_source_sources/panchanga_api/MCP.md` `references/open_source_sources/panchanga_api/SKILL.md` | 已接入主链;外部镜像仅参考 | `scripts/prashna.py` `scripts/remedies.py` `scripts/jyotish_api_server.py` `scripts/unified_consultation_orchestrator.py` `jyotish-app/main.js` | 现有主链已覆盖 Prashna / Muhurta / Panchanga / Remedies;只保留镜像的方法学参考 | 不可直接复用。镜像 `LICENSE` 为 `All rights reserved`,不得复制实现 | 不新增接线;仅做外部数值证据与显示合同 | | P0 | `scripts/vedastro_service_adapter.py` `scripts/vedastro_official_mcp_bridge.py` `scripts/diagnose_vedastro_mode.py` | 半接 | `scripts/jyotish_api_server.py` `mcp_server.py` `scripts/unified_consultation_orchestrator.py` | 让 official layer 真正默认参与,而不是只做桥接存在证明;同时把 runtime truth 里的 `official/full/partial/fallback` 说清楚 | 低。这里主要是官方 API/桥接,不是复制外部 GPL 代码 | 3-6h | | P0 | `references/oracle/artifacts/pyjhora_*` `references/oracle/artifacts/pending_packets/*pyjhora*.json` `scripts/generate_pyjhora_oracle_artifact_manifest.py` | 已接(黑盒证据层) | `scripts/external_oracle_sanity_closure.py` `scripts/oracle_benchmark_inventory.py` `scripts/historical_event_backtest.py` `README.md` | 保留 PyJHora 作为黑盒对照、历史事件回测、数值 sanity,不碰源码复制 | 中高。AGPL 风险不在“调用输出”,而在“复制代码/常量/实现” | 1-3h 做下一轮批量证据清点;8-16h 做更完整事件包 | | P1 | `references/open_source_sources/jyotishganit/README.md` `references/open_source_sources/jyotishganit/LICENSE` `references/open_source_sources/jyotishganit/jyotishganit/*` | 已接(部分) | `scripts/bhava_bala.py` `scripts/shadbala.py` `scripts/shadbala_advanced.py` `scripts/trimshamsa_d30.py` `scripts/constants/mit_imported_constants.py` `scripts/jyotish_engine.py` | 继续把 MIT 安全算法/常量吸收到本地精度层,尤其是 `Bhava Bala`、`Sputa Drishti`、部分 divisional / constants 对齐 | 低。MIT,且本仓已有显式标注“基于 jyotishganit” | 2-6h 做一轮定点补强;10-20h 做系统 sweep | diff --git a/docs/research/panchanga_local_jyotishganit_comparison_2026_07_21.md b/docs/research/panchanga_local_jyotishganit_comparison_2026_07_21.md new file mode 100644 index 00000000..65b4f1c7 --- /dev/null +++ b/docs/research/panchanga_local_jyotishganit_comparison_2026_07_21.md @@ -0,0 +1,29 @@ +# Panchanga local ↔ jyotishganit comparison — TEMCQ-061 + +Date: 2026-07-21 + +This packet closes the first local comparison step for the Panchanga schema ticket without writing a new Panchanga algorithm. + +## Result + +- Local method: `scripts/muhurta.py::calc_panchanga` +- Case: Steve Jobs +- Compared fields: `vaara`, `tithi`, `nakshatra`, `yoga`, `karana` +- Result: 4 exact matches + 1 naming alias +- Truth upgrade: 0 + +## Field comparison + +| Field | Local | jyotishganit | Status | +|---|---|---|---| +| vaara | Thursday | Thursday | within_tolerance | +| tithi | Shukla Tritiya | Shukla Tritiya | within_tolerance | +| nakshatra | Uttara Bhadrapada | Uttara Bhadrapada | within_tolerance | +| yoga | Shubha | Shubha | within_tolerance | +| karana | Garija | Gara | alias_match | + +`Gara` and `Garija` are recorded as a naming alias, not a formula mismatch. + +## Boundary + +This is still `research_observation_only`. It does not upgrade Panchanga to global truth because VedAstro and PyJHora/JHora five-field normalized packets are not pinned for this same comparison, and sunrise-relative semantics still need multi-case closure. diff --git a/docs/research/panchanga_temcq_061_schema_packet_2026_07_21.md b/docs/research/panchanga_temcq_061_schema_packet_2026_07_21.md new file mode 100644 index 00000000..9d30054c --- /dev/null +++ b/docs/research/panchanga_temcq_061_schema_packet_2026_07_21.md @@ -0,0 +1,26 @@ +# Panchanga TEMCQ-061 schema packet — 2026-07-21 + +## Result + +- Status: `schema_mapping_required` +- Normalized fields ready: `0` +- Truth upgrades: `0` + +## Observed jyotishganit raw + +- Vaara: Thursday +- Tithi: Shukla Tritiya +- Nakshatra: Uttara Bhadrapada +- Yoga: Shubha +- Karana: Gara + +## Blockers + +- Local archived high-rigor raw lacks a normalized Panchanga field. +- PyJHora/JHora normalized Panchanga raw is not archived. +- VedAstro shared Panchanga endpoint/method is not pinned. +- Naming and calculation conventions must be fixed before field comparison. + +## Boundary + +This is schema mapping only. It does not prove Panchanga parity or production timing readiness. diff --git a/docs/research/three_engine_bav_sav_field_closure_packet_2026_07_21.md b/docs/research/three_engine_bav_sav_field_closure_packet_2026_07_21.md new file mode 100644 index 00000000..a3e0d9fc --- /dev/null +++ b/docs/research/three_engine_bav_sav_field_closure_packet_2026_07_21.md @@ -0,0 +1,20 @@ +# Three-engine BAV/SAV field closure packet — 2026-07-21 + +## Result + +- Rows: `8` +- Local / PyJHora-JHora / jyotishganit agreement: `5/8` +- Multi-engine variants: `3/8` +- Truth upgrades: `0` + +## Required evidence before upgrade + +- Public worked BAV/SAV table +- Contributor set +- Lagna inclusion policy +- Shodhana state +- Rashi order / orientation + +## Boundary + +This packet reuses existing arbitration/probe output. It does not implement or copy a new Ashtakavarga algorithm and does not upgrade formula truth. diff --git a/docs/research/three_engine_d2_field_closure_packet_2026_07_21.md b/docs/research/three_engine_d2_field_closure_packet_2026_07_21.md new file mode 100644 index 00000000..343062cb --- /dev/null +++ b/docs/research/three_engine_d2_field_closure_packet_2026_07_21.md @@ -0,0 +1,26 @@ +# Three-engine D2 field closure packet — 2026-07-21 + +## Result + +- Rows: `7` +- Local / PyJHora-JHora / jyotishganit agreement: `7/7` +- VedAstro differing endpoint result: `7/7` +- Truth upgrades: `0` + +## Interpretation + +For the Steve Jobs public same-case D2 rows, local, PyJHora/JHora and +jyotishganit agree on seven planet signs. VedAstro differs on all seven rows. + +This is therefore classified as: + +`partial_consensus_vedastro_endpoint_blocked` + +The remaining blocker is not local formula evidence. It is VedAstro hosted +endpoint/method semantics: same ayanamsa, node mode, varga and timezone contract +must be pinned before these rows can become global truth. + +## Boundary + +This packet supports local/PyJHora/jyotishganit D2 confidence only. It does not +upgrade global oracle truth or commercial production tuning. diff --git a/docs/research/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.md b/docs/research/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.md new file mode 100644 index 00000000..fcb71536 --- /dev/null +++ b/docs/research/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.md @@ -0,0 +1,18 @@ +# Three-engine D4/D9/D10 field closure packet — 2026-07-21 + +## Result + +- Rows: `3` +- Local / PyJHora-JHora / jyotishganit agreement: `3/3` +- VedAstro differing endpoint result: `3/3` +- Truth upgrades: `0` + +## Classification + +D4, D9 and D10 each have one Moon.sign mismatch row. In all three rows, local, PyJHora/JHora and jyotishganit agree; VedAstro differs. + +Status: `partial_consensus_vedastro_endpoint_blocked` + +## Boundary + +This packet supports partial same-case confidence for these three varga rows only. It does not upgrade global oracle truth or commercial production tuning. diff --git a/docs/research/three_engine_field_status_batch_2026_07_21.md b/docs/research/three_engine_field_status_batch_2026_07_21.md new file mode 100644 index 00000000..8b27cf8e --- /dev/null +++ b/docs/research/three_engine_field_status_batch_2026_07_21.md @@ -0,0 +1,18 @@ +# Three-engine field status batch — 2026-07-21 + +## Result + +- Existing TEMCQ rows classified: `18` +- New Panchanga ticket placeholder: `TEMCQ-061` +- Truth upgrades: `0` + +## Classification + +- `10` D2/D4/D9/D10 rows are ready for endpoint/method semantics checks. +- `8` BAV/SAV rows are ready for public worked-example comparison. +- Panchanga has jyotishganit raw but no existing mismatch ticket, so it is queued separately. + +## Boundary + +This is a closure-status packet only. It does not mark any field as numeric +truth, formula parity, or production timing evidence. diff --git a/docs/research/three_engine_jyotishganit_bridge_applied_2026_07_21.md b/docs/research/three_engine_jyotishganit_bridge_applied_2026_07_21.md new file mode 100644 index 00000000..624f261d --- /dev/null +++ b/docs/research/three_engine_jyotishganit_bridge_applied_2026_07_21.md @@ -0,0 +1,27 @@ +# Three-engine jyotishganit bridge applied — 2026-07-21 + +## Status + +- Claim status: `observation_only` +- Truth upgrades: `0` +- Source selected hash: `4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4` + +## Applied rows + +- Existing TEMCQ tickets mapped: `18` +- No existing ticket: `1` + +Mapped groups: + +- D2/D4/D9/D10 sign rows → existing `endpoint_or_varga_semantics` tickets. +- BAV/SAV rows → existing `ashtakavarga_table_or_contributor_variant` tickets. +- Panchanga → no old mismatch ticket; create a separate closure row before comparison. + +## Boundary + +This packet only proves that jyotishganit selected raw can be routed into the +existing closure queue. It does not prove formula truth, timing readiness, or +commercial production tuning. + +Shadbala remains an explicit gap because the current jyotishganit probe does not +expose `shadbala` or `strengths` in selected raw. diff --git a/docs/superpowers/plans/2026-07-21-ai-jyotish-consultation-workbench-alignment.md b/docs/superpowers/plans/2026-07-21-ai-jyotish-consultation-workbench-alignment.md new file mode 100644 index 00000000..cceaf323 --- /dev/null +++ b/docs/superpowers/plans/2026-07-21-ai-jyotish-consultation-workbench-alignment.md @@ -0,0 +1,311 @@ +# AI Jyotish consultation workbench alignment + +Date: 2026-07-21 + +Commercial repo: `/Users/wuyongnaren/Documents/Jyotisha-commercial` + +Research truth source: `/Users/wuyongnaren/Documents/印度占星` + +Current commercial branch observed: `codex/fix-chat-session-deletion` + +## Product target + +Upgrade the commercial Jyotish website from a form/report/chat surface into an AI astrology consultation workbench: + +- guided topics when users do not know what to ask; +- strict workflow routing for career, marriage, wealth, timing, rectification and general readings; +- visible evidence chain, parameter freeze, confidence and claim boundary; +- follow-up prompts after every answer; +- privacy-safe commercial runtime without writing user birth data or private cases into public artifacts. + +This is not a UI-only optimization. UI work is downstream of runtime identity, evidence gates and workflow routing. + +## Current architecture observed + +### Frontend + +- Main page: `frontend/src/app/page.tsx` +- Global styles: `frontend/src/app/globals.css` +- Sidebar/session UI: + - `frontend/src/components/app-sidebar.tsx` + - `frontend/src/components/sidebar-session-row.tsx` +- Message rendering: + - `frontend/src/components/chat-message-row.tsx` + - `frontend/src/components/chat-message-content.tsx` +- Birth-time journey UI: + - `frontend/src/components/birth-time-intake.tsx` + - `frontend/src/components/birth-time-guide-turn.tsx` + - `frontend/src/components/birth-time-choice-question.tsx` + - `frontend/src/components/birth-time-candidate-result.tsx` + - `frontend/src/components/birth-time-evidence-draft-card.tsx` + +### API routes + +- Chat/consultation: `frontend/src/app/api/consult/route.ts` +- Health check: `frontend/src/app/api/health/route.ts` +- Daily star language: `frontend/src/app/api/daily-starlanguage/route.ts` +- Chart profiles: `frontend/src/app/api/chart-profiles/route.ts` +- Birth-time guide: `frontend/src/app/api/birth-time-guide/route.ts` +- Birth-time journey: `frontend/src/app/api/birth-time-journey/route.ts` +- Birth rectification: `frontend/src/app/api/birth-rectification/route.ts` + +### Workflow and safety layer + +- Workflow projection: `frontend/src/lib/consultation-workflow-request.ts` +- Entrypoint question resolver: `frontend/src/lib/consultation-entrypoint.ts` +- Safety guard: `frontend/src/lib/consult-safety.ts` +- Timing boundary guard: `frontend/src/lib/timing-output-guard.ts` +- Agent reply and streaming: + - `frontend/src/lib/agent-reply.ts` + - `frontend/src/lib/stream-text-response.ts` + +### Existing tests already relevant + +- `frontend/tests/consultation-workflow-contract.test.ts` +- `frontend/tests/consultation-workflow-request.test.ts` +- `frontend/tests/starter-questions.test.ts` +- `frontend/tests/chat-stream-layout.test.ts` +- `frontend/tests/birth-time-mobile-scroll-contract.test.ts` +- `frontend/tests/birth-time-journey-*.test.ts` +- `frontend/tests/timing-output-guard.test.ts` +- `frontend/tests/jyotish-api-reachability-contract.test.ts` + +## Gap summary + +| Layer | Current state | Gap | +|---|---|---| +| Truth source identity | `/api/health` reports web/env/model/Jyotish API status and git commit | Does not expose research truth source path, research commit, evidence packet count, oracle summary or claim gate status | +| Guided topics | Starter questions and private entrypoints exist | Topics are not yet generated from profile completeness + question intent + strict workflow evidence requirements | +| Strict workflow routing | `consultation-workflow-request.ts` maps broad themes | Timing currently maps to career; missing explicit route taxonomy for rectification, health, annual/monthly timing, Prashna, compatibility | +| Evidence display | Birth-time evidence components exist | No general consultation evidence panel/audit table for D1/D9/D10/Dasha/Narayana/Transit/Shadbala/AV/Jaimini/UL/DK/A10 | +| Parameter freeze | Some backend headers expose workflow status | UI does not consistently show Ayanamsa, node mode, timezone, coordinates, birth-time precision and calculation source | +| Claim boundary | Timing guard exists | Need runtime gate that prevents blocked/partial/oracle-missing claims from rendering as definitive predictions | +| Layout maturity | Chat shell exists | Composer can visually drift/overlay content; workbench should reserve bottom space and use stable scroll container | +| Privacy | Commercial repo has Supabase/business flow | Need explicit artifact filter and CI guard to prevent private birth data/events from entering public fixtures | + +## P0 implementation plan + +### P0-1 — Runtime identity and capability status + +Goal: the site must show what capability source it is using. + +Files: + +- Add `frontend/src/lib/truth-source-runtime-identity.ts` +- Add or extend `frontend/src/app/api/health/route.ts` +- Add `frontend/tests/truth-source-runtime-identity.test.ts` +- Add `frontend/tests/health-deployment.test.ts` assertions + +Contract: + +```json +{ + "truthSource": { + "path": "/Users/wuyongnaren/Documents/印度占星", + "commit": "...", + "skillVersion": "...", + "evidencePacketCount": 120, + "oracleSummary": { + "ready": [], + "partial": [], + "blocked": [] + }, + "claimGateStatus": "partial_or_blocked_present" + } +} +``` + +Rules: + +- Do not read private user artifacts. +- Do not require the production container to mount the local research repo; if absent, report `not_mounted`, not `ok`. +- Do not claim synced when git/packet metadata cannot be read. + +### P0-2 — Workbench shell layout fix + +Goal: stop the composer from floating over forms/content and make the page feel like a stable consultation tool. + +Files: + +- `frontend/src/app/page.tsx` +- `frontend/src/app/globals.css` +- `frontend/tests/chat-stream-layout.test.ts` +- `frontend/tests/birth-time-mobile-scroll-contract.test.ts` + +Contract: + +- One scroll container for conversation/workbench content. +- Composer pinned inside the main column, not viewport-floating across sidebar. +- Content bottom padding equals composer height. +- Onboarding/profile forms cannot appear underneath the composer. + +### P0-3 — Guided topic cards + +Goal: when user lacks a question, show 3-5 useful consultation cards with evidence preview. + +Files: + +- Add `frontend/src/lib/guided-jyotish-topics.ts` +- Extend `frontend/src/lib/consultation-entrypoint.ts` +- Extend `frontend/src/app/page.tsx` +- Extend `frontend/tests/starter-questions.test.ts` + +Initial topics: + +- Career phase and next leverage point +- Relationship pattern and partnership timing boundary +- Wealth structure and risk point +- Current year/month broad timing window +- Birth-time confidence check + +Each topic must carry: + +- `theme` +- `visibleQuestion` +- `strictWorkflowRoute` +- `evidencePreview` +- `confidenceCap` +- `claimBoundary` + +### P0-4 — Strict workflow route contract + +Goal: every user question must route to an explicit Jyotish workflow before the agent speaks. + +Files: + +- Extend `frontend/src/lib/consultation-workflow-request.ts` +- Extend `frontend/src/app/api/consult/route.ts` +- Extend `frontend/tests/consultation-workflow-contract.test.ts` +- Extend `frontend/tests/consultation-workflow-request.test.ts` + +Routes: + +- `career`: D1, D10, 10th house/lord, A10, AmK, Vimshottari, Narayana, transit +- `marriage`: D1, D9, 7th house/lord, Venus/Jupiter, DK, UL, A7, Vimshottari, Narayana, transit +- `wealth`: D1, D2, D11, 2nd/11th/9th/5th, wealth yogas, AV, Dasha +- `timing`: Dasha + Narayana + transit + varga; day/month remains candidate unless holdout passes +- `rectification`: D1 boundary, D9/D10/D12/D60 sensitivity, event backtest, candidate not truth +- `prashna`: question time/place/timezone/ayanamsa/node mode; observation only until oracle packets close +- `general`: broad multi-domain reading with clear missing layers + +### P0-5 — Claim gate display + +Goal: users can still receive dates/windows, but the UI must not package exploratory candidates as verified prediction. + +Files: + +- `frontend/src/lib/timing-output-guard.ts` +- `frontend/src/components/chat-message-content.tsx` +- Add `frontend/src/components/claim-boundary-badge.tsx` +- Tests: + - `frontend/tests/timing-output-guard.test.ts` + - `frontend/tests/consultation-workflow-contract.test.ts` + +Statuses: + +- `verified_window` +- `candidate_day_window` +- `exploratory_unvalidated` +- `observation_only` +- `blocked_until_oracle` +- `blocked_until_human_labels` + +## P1 implementation plan + +### P1-1 — Evidence panel / Technique Audit Table + +Files: + +- Add `frontend/src/components/evidence-audit-panel.tsx` +- Extend `frontend/src/components/chat-message-content.tsx` +- Add `frontend/tests/evidence-audit-panel.test.ts` + +Rows: + +- D1 +- D9 / D10 / D2 / D11 as applicable +- Vimshottari Dasha +- Narayana Dasha +- Transit / Gochara +- Shadbala +- Ashtakavarga +- Jaimini: DK, AmK, UL, A7, A10 +- Functional Benefic/Malefic +- MEVG / Global Web Evidence +- Real Case Calibration + +### P1-2 — Report export + +Files: + +- Add `frontend/src/lib/consultation-report-export.ts` +- Add export button in message/report view +- Add `frontend/tests/consultation-report-export.test.ts` + +Export must include: + +- frozen parameters; +- conclusion; +- evidence table; +- conflict points; +- claim boundary; +- follow-up questions. + +### P1-3 — Privacy artifact filter + +Files: + +- Add `scripts/commercial_privacy_artifact_scan.py` +- Add `tests/test_commercial_privacy_artifact_scan.py` +- Wire into commercial CI. + +Rules: + +- Reject real user names, exact birth data, private location/event text in fixtures. +- Allow public-person examples only with source tag. +- Mark imported research oracle packets as non-user artifacts. + +## P2 implementation plan + +### P2-1 — Visual polish after P0/P1 + +Files: + +- `frontend/src/app/page.tsx` +- `frontend/src/app/globals.css` +- `frontend/src/components/app-sidebar.tsx` + +Direction: + +- Keep original warm color palette. +- Use commercial site layout language, but make the homepage cards smaller, lower, and easier to click. +- Do not put birth-time rectification as an oversized floating block. + +### P2-2 — Commercial sync discipline + +Files: + +- Add `docs/research_sync_contract.md` +- Add `frontend/tests/research-truth-source-contract.test.ts` + +Rules: + +- Commercial repo consumes mature research contracts. +- Commercial repo does not copy private WorkBuddy fragments. +- WorkBuddy backups remain `historical_fragment_only`. + +## First landing sequence + +1. Implement P0-1 runtime identity endpoint and test. +2. Implement P0-2 layout contract to fix composer drift. +3. Implement P0-3 guided topics as deterministic cards. +4. Implement P0-4 strict workflow route taxonomy. +5. Implement P0-5 claim boundary badge. +6. Run focused frontend tests. +7. Only then start P1 evidence panel. + +## Current blocker / caution + +`/private/tmp/jyotisha-optimize` from the pasted request does not exist on this machine. The active commercial candidate is `/Users/wuyongnaren/Documents/Jyotisha-commercial`. + +The commercial worktree currently has untracked `hip_main.dat` and `hip_main.dat.download`. They look like local ephemeris/runtime assets and should not be committed unless explicitly reviewed. diff --git a/frontend/src/app/api/birth-time-candidate-completion/route.ts b/frontend/src/app/api/birth-time-candidate-completion/route.ts index 4452fe57..b8b0d8cd 100644 --- a/frontend/src/app/api/birth-time-candidate-completion/route.ts +++ b/frontend/src/app/api/birth-time-candidate-completion/route.ts @@ -1,9 +1,5 @@ import { NextResponse } from "next/server"; import { z } from "zod"; -import { candidateWorkingTime } from "@/lib/birth-time-candidate-completion"; -import { createAdminSupabaseClient } from "@/lib/supabase/admin"; -import { isSupabaseConfigurationError } from "@/lib/supabase/config"; -import { createServerSupabaseClient } from "@/lib/supabase/server"; export const runtime = "nodejs"; @@ -13,57 +9,12 @@ const requestSchema = z.object({ time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/), }).strict(); +/** Compatibility endpoint for stale clients; unconfirmed candidates never write profiles. */ export async function POST(request: Request) { - try { - const supabase = await createServerSupabaseClient(); - const { data: { user }, error: authError } = await supabase.auth.getUser(); - if (authError || !user) { - return NextResponse.json({ error: "请先登录" }, { status: 401 }); - } - - const parsed = requestSchema.safeParse(await request.json().catch(() => null)); - if (!parsed.success) { - return NextResponse.json({ error: "候选时间格式不正确" }, { status: 400 }); - } - - const admin = createAdminSupabaseClient(); - const { data: stored, error: caseError } = await admin - .from("birth_time_rectification_cases") - .select("id,user_id,journey_protocol,status,candidate_result_id,candidate_result,turn_state") - .eq("id", parsed.data.caseId) - .eq("user_id", user.id) - .maybeSingle(); - const time = candidateWorkingTime(stored, { ...parsed.data, userId: user.id }); - if (caseError || !time) { - return NextResponse.json( - { error: "候选结果已变化", message: "请使用当前评估结果继续。" }, - { status: 409 }, - ); - } - - const { data: profile, error: profileError } = await admin - .from("profiles") - .update({ - active_birth_time: time, - birth_time_status: "candidate", - updated_at: new Date().toISOString(), - }) - .eq("id", user.id) - .eq("rectification_case_id", parsed.data.caseId) - .select("id") - .maybeSingle(); - if (profileError || !profile) { - return NextResponse.json( - { error: "候选时间暂时无法保存", message: "当前评估结果仍已保留,请稍后重试。" }, - { status: 503 }, - ); - } - - return NextResponse.json({ ok: true, activeTime: time, birthTimeStatus: "candidate" }); - } catch (error) { - if (isSupabaseConfigurationError(error)) { - return NextResponse.json({ error: "Supabase 尚未配置" }, { status: 503 }); - } - return NextResponse.json({ error: "候选时间暂时无法保存" }, { status: 500 }); - } + const parsed = requestSchema.safeParse(await request.json().catch(() => null)); + if (!parsed.success) return NextResponse.json({ error: "候选时间格式不正确" }, { status: 400 }); + return NextResponse.json( + { error: "候选时间不能直接采用", message: "候选范围已保留;请补充资料,或在高置信结果出现后通过正式确认继续。" }, + { status: 409 }, + ); } diff --git a/frontend/src/app/api/health/route.ts b/frontend/src/app/api/health/route.ts index 25927299..21e4ae97 100644 --- a/frontend/src/app/api/health/route.ts +++ b/frontend/src/app/api/health/route.ts @@ -4,6 +4,8 @@ import { conversationalRectificationDeploymentShaFromEnvironment, } from "../../../lib/conversational-rectification/creation-policy.ts"; +import { getTruthSourceRuntimeIdentity } from "@/lib/truth-source-runtime-identity"; + type Check = { status: "ok" | "degraded" | "blocked"; message?: string; @@ -61,12 +63,17 @@ export async function GET() { const rectificationV3MigrationsReady = process.env.RECTIFICATION_V3_MIGRATIONS_READY?.trim().toLowerCase() === "true"; const creationPolicy = conversationalRectificationCreationPolicyFromEnvironment(); + const truthSourceIdentity = getTruthSourceRuntimeIdentity(); const checks = { web: { status: "ok" } satisfies Check, supabasePublicConfig: envCheck(["NEXT_PUBLIC_SUPABASE_URL", "NEXT_PUBLIC_SUPABASE_ANON_KEY"]), supabaseServiceRole: envCheck(["SUPABASE_SERVICE_ROLE_KEY"]), modelProvider: anyEnvCheck(["LLM_MODELS_JSON", "OPENAI_API_KEY", "LLM_API_KEY", "DEEPSEEK_API_KEY"]), jyotishApi: await jyotishApiCheck(), + researchTruthSource: { + status: truthSourceIdentity.status, + message: truthSourceIdentity.mountStatus === "mounted" ? undefined : truthSourceIdentity.mountStatus, + } satisfies Check, }; const status = aggregate(checks); const rectificationV3Ready = status === "ok" @@ -88,6 +95,7 @@ export async function GET() { readyForNewCases: rectificationV3Ready, }, }, + truthSource: truthSourceIdentity, checks, }, { status: status === "ok" ? 200 : 503 }, diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 6bc2d95a..411caf56 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -84,6 +84,7 @@ --space-12: 48px; --space-16: 64px; --space-24: 96px; + --composer-reserve: 148px; --ease-out: cubic-bezier(.22, 1, .36, 1); --sidebar-background: var(--color-sidebar); --sidebar-solid: var(--color-sidebar-solid); @@ -150,6 +151,17 @@ button:disabled { cursor: default; opacity: .45; } .message-markdown { color: var(--color-ink); font-size: 17px; line-height: 1.65; } .message-markdown > *:first-child { margin-top: 0; } .message-markdown > *:last-child { margin-bottom: 0; } +.claim-boundary-badge { width: fit-content; margin: 0 0 var(--space-2); padding: 4px 9px; border: 1px solid color-mix(in srgb, var(--color-action) 24%, transparent); border-radius: 999px; background: var(--color-action-soft); color: var(--color-action-hover); font-size: 12px; line-height: 1.45; } +.evidence-audit-panel { margin: 0 0 var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: color-mix(in srgb, var(--color-canvas-soft) 68%, transparent); } +.evidence-audit-panel summary { cursor: pointer; padding: var(--space-2) var(--space-3); color: var(--color-ink-secondary); font-size: 13px; } +.evidence-audit-table { display: grid; gap: 1px; padding: 0 var(--space-3) var(--space-3); } +.evidence-audit-row { display: grid; grid-template-columns: minmax(120px, 1fr) auto minmax(160px, 1.2fr); gap: var(--space-3); align-items: center; padding: var(--space-2) 0; border-top: 1px solid color-mix(in srgb, var(--color-border) 64%, transparent); font-size: 12px; } +.evidence-audit-row b { color: var(--color-action-hover); font-weight: 600; } +.evidence-audit-row small { color: var(--color-ink-tertiary); line-height: 1.45; } +.raw-evidence-receipt { margin: 0 var(--space-3) var(--space-3); border-top: 1px solid color-mix(in srgb, var(--color-border) 64%, transparent); padding-top: var(--space-2); } +.raw-evidence-receipt summary { padding: var(--space-1) 0; color: var(--color-ink-tertiary); font-size: 12px; } +.raw-evidence-receipt pre { max-height: 180px; overflow: auto; margin: var(--space-2) 0 0; padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-canvas); color: var(--color-ink-secondary); font-size: 11px; line-height: 1.5; } +.report-download-button { margin-top: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); color: var(--color-ink-secondary); cursor: pointer; padding: 7px 10px; font-size: 12px; } .message-markdown p { margin: 0 0 14px; } .message-markdown ul, .message-markdown ol { margin: 10px 0 16px; padding-left: 24px; } .message-markdown li { margin: 6px 0; } @@ -331,7 +343,7 @@ button:disabled { cursor: default; opacity: .45; } .status-loading { background: var(--color-action); } .credit-button { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 11px; cursor: pointer; font-size: 13px; font-variant-numeric: tabular-nums; transition: background-color 120ms ease-out, transform 120ms ease-out; min-width: 64px; border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); color: var(--color-ink-secondary); font-weight: 500; } -.conversation { min-width: 0; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; background: var(--color-canvas); } +.conversation { min-width: 0; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; padding-bottom: var(--composer-reserve); background: var(--color-canvas); } .conversation.is-empty { display: grid; place-items: center; padding: var(--space-8); } .welcome { width: min(820px, 100%); padding: var(--space-10) 0 var(--space-16); } .welcome > .onboarding-message:first-child { padding-bottom: var(--space-8); } @@ -535,6 +547,13 @@ button:disabled { cursor: default; opacity: .45; } .product-entrypoint-action .starter-arrow { width: 15px; height: 15px; color: currentColor; } .starter-loading { color: var(--color-ink-secondary); margin-left: 0; padding: var(--space-5); border-radius: var(--radius-lg); background: var(--color-canvas-muted); font-size: 14px; } .starter-note { margin: 10px 0 0; color: var(--color-ink-secondary); line-height: 1.5; grid-column: 1 / -1; font-size: 13px; } +.parameter-freeze-panel { display: grid; grid-column: 1 / -1; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); } +.parameter-freeze-panel > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); color: var(--color-ink-secondary); font-size: var(--type-caption); } +.parameter-freeze-panel b { color: var(--color-ink); font-size: var(--type-title-sm); } +.parameter-freeze-panel dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: var(--space-2); margin: 0; } +.parameter-freeze-panel dl > div { min-width: 0; padding: var(--space-2); border-radius: var(--radius-md); background: var(--color-canvas-soft); } +.parameter-freeze-panel dt { color: var(--color-ink-tertiary); font-size: 11px; } +.parameter-freeze-panel dd { overflow: hidden; margin: 2px 0 0; color: var(--color-ink); text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .message-list { margin: 0 auto; width: min(900px, 100%); padding: var(--space-8) var(--space-8) var(--space-16); } .message { display: flex; animation: message-enter 160ms var(--ease-out) both; padding: var(--space-2) 0; } @@ -554,7 +573,7 @@ button:disabled { cursor: default; opacity: .45; } .thinking i { width: 5px; height: 5px; border-radius: 50%; animation: pulse 850ms ease-in-out infinite alternate; background: var(--color-action); } .error-message { margin: 12px 0 0; padding: 12px 14px; border-left: 3px solid var(--color-danger); background: var(--color-danger-muted); color: var(--color-danger); font-size: 13px; line-height: 1.6; border-color: var(--color-danger); border-radius: 0 var(--radius-md) var(--radius-md) 0; } -.composer-wrap { z-index: 2; min-width: 0; border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent); padding: var(--space-3) var(--space-6) var(--space-4); background: var(--color-frosted); backdrop-filter: saturate(130%) blur(20px); } +.composer-wrap { position: sticky; bottom: 0; z-index: 2; min-width: 0; border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent); padding: var(--space-3) var(--space-6) var(--space-4); background: var(--color-frosted); backdrop-filter: saturate(130%) blur(20px); } .composer-suggestions { width: min(680px, 100%); margin: 0 auto 9px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; touch-action: pan-x; -webkit-overflow-scrolling: touch; display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--space-2); margin-bottom: var(--space-3); overflow: visible; } .composer-suggestions button { flex: 0 0 clamp(176px, 56vw, 230px); overflow: hidden; border: 1px solid var(--color-border); color: var(--color-ink-secondary); cursor: pointer; scroll-snap-align: start; text-overflow: ellipsis; white-space: nowrap; transition: border-color 120ms ease-out, color 120ms ease-out, transform 120ms ease-out; width: 100%; min-width: 0; min-height: 44px; padding: 0 var(--space-2); border-color: var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas-soft); font-size: var(--type-caption); } .composer { width: min(760px, 100%); display: flex; align-items: flex-end; gap: 10px; margin: 0 auto; border: 1px solid var(--color-border); transition: border-color 140ms ease-out; min-height: 60px; padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-color: var(--color-border-strong); border-radius: var(--radius-lg); background: var(--color-canvas); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-border) 42%, transparent); } diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 6cecd198..ad4a6eba 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -16,6 +16,7 @@ import { ConversationalBirthTimeRectification } from "@/components/conversationa import { ChatMessageContent } from "@/components/chat-message-content"; import { AgentAvatar, ChatMessageRow } from "@/components/chat-message-row"; import { ModelSelector } from "@/components/model-selector"; +import { ParameterFreezePanel, type ParameterFreezeRow } from "@/components/parameter-freeze-panel"; import { Button } from "@/components/ui/button"; import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; import { Textarea } from "@/components/ui/textarea"; @@ -64,9 +65,11 @@ import { isGuidedBirthTimePreview, previewRectificationJourney, } from "@/lib/birth-time-guided-preview"; +import { defaultGuidedJyotishTopics } from "@/lib/guided-jyotish-topics"; import { keepFocusWithin } from "@/lib/focus-trap"; import { chatMessageViews, type ChatMessage } from "@/lib/chat-message-view"; import { persistExistingChatSession } from "@/lib/chat-session-persistence"; +import { consultationReportMarkdown } from "@/lib/consultation-report-export"; import { OnboardingAuthenticationError, type OnboardingContent, @@ -196,11 +199,7 @@ type PendingConsultation = { const undoWindowMs = 2_500; const china = chinaLocations.country; -const themes: Array<{ id: Exclude; label: string; prompt: string }> = [ - { id: "career", label: "事业", prompt: "未来一年,事业和收入该关注什么?" }, - { id: "marriage", label: "关系", prompt: "我的关系模式是什么?" }, - { id: "timing", label: "时运", prompt: "未来哪些阶段值得把握?" }, -]; +const themes = defaultGuidedJyotishTopics; const rectificationCardLabels = { start: "开始生时校正", @@ -852,7 +851,6 @@ export default function Home() { preview: process.env.NODE_ENV === "development" && uiPreview.current, onJourney: setBirthTimeJourney, onReady: completeGuidedBirthTime, - onCandidateComplete: completeCandidateBirthTime, onEditBirthTimeDetails: editDeclaredBirthTimeDetails, }); @@ -993,6 +991,16 @@ export default function Home() { const profileComplete = isProfileComplete(profile); const birthTimeDisplay = birthTimeDisplayState(profile); + const profileBirthPlace = selectedBirthPlace(profile); + const parameterFreezeRows: ParameterFreezeRow[] = profileComplete && profileBirthPlace ? [ + { label: "出生时间", value: `${profile.date} ${profile.time || "未定"}` }, + { label: "出生地点", value: profileBirthPlace.label }, + { label: "经纬度", value: `${profileBirthPlace.lat.toFixed(4)}, ${profileBirthPlace.lon.toFixed(4)}` }, + { label: "时区", value: `UTC+${profileBirthPlace.tz}` }, + { label: "Ayanamsa", value: "Lahiri / Sidereal" }, + { label: "Node mode", value: "True Node" }, + { label: "出生时间精度", value: birthTimeDisplay?.kind === "candidate" ? "候选时间" : birthTimeDisplay?.kind === "confirmed" ? "已确认" : "待校正" }, + ] : []; const dailyStarlanguage = dailyStarlanguageCard ?? (profileComplete ? buildDailyStarlanguageCard(profile) : null); const onboardingPending = profileComplete && !onboarding && !onboardingError; const currentOnboardingMessage = onboardingJustCompleted @@ -1436,11 +1444,15 @@ export default function Home() { message_count: session.messages.length, messages: session.messages.map((message) => ({ role: message.role, text: message.text })), }; + const reportMarkdown = consultationReportMarkdown({ title: session.title, messages: session.messages }); const transcript = [ `Jyotisha 对话:${session.title}`, "", ...session.messages.map((message) => `${message.role === "user" ? "我" : "Jyotisha"}:${message.text}`), "", + "---- Markdown 报告 ----", + reportMarkdown, + "", "---- JSON 分享包 ----", JSON.stringify(sharePayload, null, 2), ].join("\n"); @@ -1807,21 +1819,6 @@ export default function Home() { setOnboardingJustCompleted(false); } - function completeCandidateBirthTime(result: JourneyClientResponse, time: string) { - const candidateProfile: Profile = { - ...profileDraft, - time, - birthTimeStatus: "candidate", - rectificationCaseId: result.caseId, - }; - setProfile(candidateProfile); - setProfileDraft(candidateProfile); - setBirthTimeJourney(null); - setPresetMessageLength(0); - setStartGreeting(createStartGreeting(candidateProfile.name)); - setOnboardingJustCompleted(false); - } - async function retryBirthTimeAssessment() { if (!account || profileSaving) return; setProfileSaving(true); @@ -2535,6 +2532,15 @@ export default function Home() { } if (!response.body) throw new Error("浏览器未收到可读取的回答流"); const techniqueTruth = response.headers.get("x-jyotish-technique-truth") ?? "unknown"; + const workflowReceipt = { + route: response.headers.get("x-jyotish-workflow-route") ?? "unknown", + status: response.headers.get("x-jyotish-workflow-status") ?? "unknown", + preciseTiming: response.headers.get("x-jyotish-precise-timing") ?? "unknown", + missingLayers: (response.headers.get("x-jyotish-missing-layers") ?? "none") + .split(",") + .map((item) => item.trim()) + .filter((item) => item && item !== "none"), + }; const reader = response.body.getReader(); const decoder = new TextDecoder(); @@ -2565,7 +2571,7 @@ export default function Home() { title: currentSession.messages.length === 0 ? resolveSessionTitle(question, reply.title) : userSession.title, - messages: [...userSession.messages, { role: "assistant", text: reply.text, suggestions: reply.suggestions, techniqueTruth }], + messages: [...userSession.messages, { role: "assistant", text: reply.text, suggestions: reply.suggestions, techniqueTruth, workflowReceipt }], updatedAt: timestamp(), }; updateSession(sessionId, () => completedSession); @@ -2622,16 +2628,16 @@ export default function Home() { await persistSession(interruptedSession); setRequestError({ sessionId, - message: "回答中途断开,已保留生成内容;本次已开始生成并计费。", + message: "回答中途断开,已保留生成内容;请复制现有内容或继续追问,系统正在以账户记录为准同步点数。", }); } catch (persistError) { setRequestError({ sessionId, - message: `${persistError instanceof Error ? persistError.message : "云端同步失败"} 已计费的部分回答仍保留在当前页面,请复制保存。`, + message: `${persistError instanceof Error ? persistError.message : "云端同步失败"} 部分回答仍保留在当前页面,请复制保存后继续追问。`, }); } if (activeSessionIdRef.current === sessionId) { - setComposerNotice("回答中途断开,已保留现有内容,本次已计费。"); + setComposerNotice("回答中途断开,已保留现有内容;请继续追问或复制保存。"); } } return Boolean(partialReply); @@ -2977,6 +2983,7 @@ export default function Home() {
正在准备三个入门问题…
) : (
+ {parameterFreezeRows.length > 0 && }
); diff --git a/frontend/src/components/birth-time-candidate-result.tsx b/frontend/src/components/birth-time-candidate-result.tsx index eed98691..d1509616 100644 --- a/frontend/src/components/birth-time-candidate-result.tsx +++ b/frontend/src/components/birth-time-candidate-result.tsx @@ -145,20 +145,10 @@ function TerminalAction({ controller, error, path }: { readonly error: string; readonly path: NonNullable>; }) { - if (path.kind === "complete_with_candidate") { - return ( -
- 评估已完成,下一步 -

点击后将使用 {path.time} 作为当前排盘时间并进入对话;原始填报和本次候选结果仍会保留

- - {error ?

{error}

: null} -
- ); - } return (
+ 尚未达到采用条件 +

候选范围已保留,但当前证据不足以将具体分钟写入当前排盘时间。补充经历后可重新评估。

{error ?

{error}

: null} 会建立新的记录,当前结果仍会保留。 diff --git a/frontend/src/components/chat-message-row.tsx b/frontend/src/components/chat-message-row.tsx index 5abd93c3..149b714e 100644 --- a/frontend/src/components/chat-message-row.tsx +++ b/frontend/src/components/chat-message-row.tsx @@ -1,5 +1,8 @@ import { ChatMessageContent } from "@/components/chat-message-content"; +import { ClaimBoundaryBadge } from "@/components/claim-boundary-badge"; +import { EvidenceAuditPanel } from "@/components/evidence-audit-panel"; import type { ChatMessageView } from "@/lib/chat-message-view"; +import { consultationReportMarkdown, downloadMarkdownReport } from "@/lib/consultation-report-export"; export function AgentAvatar() { return
diff --git a/frontend/src/components/claim-boundary-badge.tsx b/frontend/src/components/claim-boundary-badge.tsx new file mode 100644 index 00000000..e9dd5b28 --- /dev/null +++ b/frontend/src/components/claim-boundary-badge.tsx @@ -0,0 +1,13 @@ +const boundaryCopy: Record = { + unknown: "证据边界未知", + partial: "部分证据闭环", + observation_only: "仅观察", + blocked: "证据阻塞", + reference_only: "仅参考", +}; + +export function ClaimBoundaryBadge({ status }: { readonly status?: string }) { + const normalized = status?.trim() || "unknown"; + const label = boundaryCopy[normalized] ?? `证据状态:${normalized}`; + return

{label} · 不把未闭环内容包装成确定预测。

; +} diff --git a/frontend/src/components/evidence-audit-panel.tsx b/frontend/src/components/evidence-audit-panel.tsx new file mode 100644 index 00000000..abb9e626 --- /dev/null +++ b/frontend/src/components/evidence-audit-panel.tsx @@ -0,0 +1,64 @@ +type AuditRow = { + label: string; + status: "required" | "partial" | "blocked"; + boundary: string; +}; + +type WorkflowReceipt = { + route: string; + status: string; + preciseTiming: string; + missingLayers: readonly string[]; +}; + +const defaultAuditRows: AuditRow[] = [ + { label: "D1 / Natal", status: "required", boundary: "基础命盘层" }, + { label: "Varga: D9 / D10 / D2 / D11", status: "required", boundary: "按问题域调用,不混用" }, + { label: "Vimshottari Dasha", status: "required", boundary: "阶段证据之一" }, + { label: "Narayana Dasha", status: "required", boundary: "应期/校时必须交叉" }, + { label: "Transit / Gochara", status: "partial", boundary: "精确日/月仍需 holdout" }, + { label: "Shadbala / Ashtakavarga", status: "partial", boundary: "组件 parity 未全闭环" }, + { label: "Functional Benefic/Malefic", status: "required", boundary: "不能只看自然吉凶" }, + { label: "MEVG / Real Case Calibration", status: "blocked", boundary: "外部校准不足时降级" }, +]; + +function workflowRows(receipt?: WorkflowReceipt): AuditRow[] { + if (!receipt) return defaultAuditRows; + return [ + { label: `Workflow route: ${receipt.route}`, status: receipt.status === "blocked" ? "blocked" : "required", boundary: "后端实际路由" }, + { label: `Precise timing: ${receipt.preciseTiming}`, status: receipt.preciseTiming === "allowed" ? "partial" : "blocked", boundary: "精确应期 claim gate" }, + { + label: "Missing route layers", + status: receipt.missingLayers.length ? "blocked" : "required", + boundary: receipt.missingLayers.length ? receipt.missingLayers.join(" / ") : "none", + }, + ...defaultAuditRows, + ]; +} + +export function EvidenceAuditPanel({ claimStatus, workflowReceipt }: { readonly claimStatus?: string; readonly workflowReceipt?: WorkflowReceipt }) { + const rows = workflowRows(workflowReceipt); + const rawReceipt = { + techniqueTruth: claimStatus || "unknown", + workflowReceipt: workflowReceipt ?? null, + privacyBoundary: "no_birth_data_or_private_case_raw", + }; + return ( +
+ 证据链摘要 · {claimStatus || "unknown"} +
+ {rows.map((row) => ( +
+ {row.label} + {row.status} + {row.boundary} +
+ ))} +
+
+ 查看非敏感 raw receipt +
{JSON.stringify(rawReceipt, null, 2)}
+
+
+ ); +} diff --git a/frontend/src/components/parameter-freeze-panel.tsx b/frontend/src/components/parameter-freeze-panel.tsx new file mode 100644 index 00000000..7069b0d9 --- /dev/null +++ b/frontend/src/components/parameter-freeze-panel.tsx @@ -0,0 +1,23 @@ +export type ParameterFreezeRow = { + label: string; + value: string; +}; + +export function ParameterFreezePanel({ rows }: { readonly rows: readonly ParameterFreezeRow[] }) { + return ( +
+
+ 当前排盘参数 + 这些参数会随咨询一起送入证据链。 +
+
+ {rows.map((row) => ( +
+
{row.label}
+
{row.value}
+
+ ))} +
+
+ ); +} diff --git a/frontend/src/hooks/use-birth-time-guided-journey.ts b/frontend/src/hooks/use-birth-time-guided-journey.ts index 1917a2f7..7d005fa8 100644 --- a/frontend/src/hooks/use-birth-time-guided-journey.ts +++ b/frontend/src/hooks/use-birth-time-guided-journey.ts @@ -3,7 +3,6 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { answerDynamicBirthTimeChoice, - confirmDynamicBirthTimeCandidate, confirmBirthTimeEvidenceDraft, draftBirthTimeEvidence, finishBirthTimeRectification, @@ -15,7 +14,6 @@ import { } from "@/lib/birth-time-journey-client"; import type { JourneyClientResponse } from "@/lib/birth-time-journey-client"; import { - completeGuidedBirthTimeCandidate, confirmGuidedBirthTimeCandidate, reviseBirthTimeEvidenceDraft, saveGuidedBirthTimeCandidate, @@ -38,7 +36,6 @@ type GuidedJourneyInput = { readonly preview: boolean; readonly onJourney: (journey: JourneyClientResponse) => void; readonly onReady: (journey: JourneyClientResponse) => void; - readonly onCandidateComplete: (journey: JourneyClientResponse, time: string) => void; readonly onEditBirthTimeDetails: () => void; }; @@ -54,7 +51,6 @@ export type BirthTimeGuidedController = { readonly resume: () => void; readonly editBirthTimeDetails: () => void; readonly acknowledgeReady: () => void; - readonly completeCandidate: (time: string) => void; readonly retryScoring: () => void; readonly saveCandidate: (resultId: string) => void; readonly confirmCandidate: (resultId: string, time: string) => void; @@ -71,7 +67,7 @@ function previewAction(turn: JourneyClientResponse, command: DynamicPreviewComma } export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeGuidedController { - const { journey, onJourney, onReady, onCandidateComplete, onEditBirthTimeDetails, preview } = input; + const { journey, onJourney, onReady, onEditBirthTimeDetails, preview } = input; const latest = useRef(journey); const busy = useRef(false); const [actionRegistry] = useState(() => createStableActionIdentityRegistry()); @@ -186,27 +182,6 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG const acknowledgeReady = () => { if (journey?.nextAction.kind === "ready") onReady(journey); }; - const completeCandidate = (time: string) => { - const turn = journey; - const resultId = turn?.candidateResult?.resultId; - const winner = turn?.candidateResult?.winningSegment; - if (!turn || !resultId || winner?.representativeTime !== time) return; - if (turn.journeyProtocol === "dynamic-choice-v2") return; - const release = claimMutation(busy); - if (release === null) return; - setPending(true); - setError(""); - const completion = preview - ? Promise.resolve() - : completeGuidedBirthTimeCandidate({ caseId: turn.caseId, resultId, time }); - void completion - .then(() => onCandidateComplete(turn, time)) - .catch((caught) => setError(birthTimeUserError(caught))) - .finally(() => { - release(); - setPending(false); - }); - }; const retryScoring = () => { const turn = journey; if (preview && turn?.journeyProtocol === "dynamic-choice-v2" @@ -228,10 +203,8 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG (actionId) => saveGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId }), )); const confirmCandidate = (resultId: string, time: string) => operate((turn) => preview ? Promise.resolve(turn) : stableAction( - turn, turn.journeyProtocol === "dynamic-choice-v2" ? "confirm_dynamic_candidate" : "confirm_guided_candidate", [resultId, time], - (actionId) => turn.journeyProtocol === "dynamic-choice-v2" - ? confirmDynamicBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time }) - : confirmGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time }), + turn, "confirm_guided_candidate", [resultId, time], + (actionId) => confirmGuidedBirthTimeCandidate({ caseId: turn.caseId, actionId, turnVersion: turn.turnVersion, resultId, time }), )); const selectOption = (optionId: string) => operate((turn) => { if (turn.journeyProtocol !== "dynamic-choice-v2" @@ -281,7 +254,6 @@ export function useBirthTimeGuidedJourney(input: GuidedJourneyInput): BirthTimeG resume, editBirthTimeDetails: onEditBirthTimeDetails, acknowledgeReady, - completeCandidate, retryScoring, saveCandidate, confirmCandidate, diff --git a/frontend/src/lib/agent-reply.ts b/frontend/src/lib/agent-reply.ts index 74a4d589..3dfd3351 100644 --- a/frontend/src/lib/agent-reply.ts +++ b/frontend/src/lib/agent-reply.ts @@ -1,8 +1,9 @@ -export type ReplyTheme = "career" | "marriage" | "timing" | "general"; +export type ReplyTheme = "career" | "marriage" | "wealth" | "timing" | "general"; const fallbackSuggestions: Record = { career: ["我更适合怎样的职业路径?", "未来一年事业上要避开什么?", "我该如何发挥自己的优势?"], marriage: ["我在关系里容易重复什么模式?", "怎样的伴侣更适合我?", "未来一年关系上要注意什么?"], + wealth: ["我的财富增长方式是什么?", "接下来财务上要避开什么?", "我该如何稳定提升收入?"], timing: ["接下来最值得把握的阶段是什么?", "哪些时期更适合主动行动?", "我现在应该优先准备什么?"], general: ["未来一年,事业和收入该关注什么?", "我的关系模式是什么?", "未来哪些阶段值得把握?"], }; diff --git a/frontend/src/lib/birth-time-candidate-completion.ts b/frontend/src/lib/birth-time-candidate-completion.ts index c05b974a..50af9a20 100644 --- a/frontend/src/lib/birth-time-candidate-completion.ts +++ b/frontend/src/lib/birth-time-candidate-completion.ts @@ -5,38 +5,10 @@ type CandidateCompletionRequest = { readonly time: string; }; -function record(value: unknown): Record | null { - return value !== null && typeof value === "object" - ? value as Record - : null; -} - +/** Direct adoption was superseded by versioned high-confidence confirmation. */ export function candidateWorkingTime( - stored: unknown, - request: CandidateCompletionRequest, + _stored: unknown, + _request: CandidateCompletionRequest, ): string | null { - const assessment = record(stored); - const candidate = record(assessment?.candidate_result); - const winner = record(candidate?.winningSegment); - const turn = record(assessment?.turn_state); - const action = record(turn?.nextAction); - const actionKind = action?.kind; - const terminal = actionKind === "present_low_result" - || actionKind === "present_medium_result" - || actionKind === "candidate_saved"; - const terminalStatusMatches = actionKind === "present_low_result" - ? assessment?.status === "rectifying" - : (actionKind === "present_medium_result" || actionKind === "candidate_saved") - && assessment?.status === "candidate"; - - return assessment?.id === request.caseId - && assessment?.user_id === request.userId - && assessment?.journey_protocol === "legacy-guided-v1" - && terminalStatusMatches - && assessment.candidate_result_id === request.resultId - && action?.resultId === request.resultId - && terminal - && winner?.representativeTime === request.time - ? request.time - : null; + return null; } diff --git a/frontend/src/lib/birth-time-guided-client.ts b/frontend/src/lib/birth-time-guided-client.ts index 89bd035c..48261848 100644 --- a/frontend/src/lib/birth-time-guided-client.ts +++ b/frontend/src/lib/birth-time-guided-client.ts @@ -16,7 +16,6 @@ type DraftRevision = GuidedMutation & { }; type CandidateSave = GuidedMutation & { readonly resultId: string }; type CandidateConfirmation = CandidateSave & { readonly time: string }; -type CandidateCompletion = Pick & { readonly time: string }; const errorPayloadSchema = z.object({ message: z.string().optional(), @@ -69,22 +68,3 @@ export function confirmGuidedBirthTimeCandidate( ) { return send({ type: "confirm_guided_candidate", ...input }); } - -export async function completeGuidedBirthTimeCandidate( - input: CandidateCompletion, -) { - const { response, payload } = await postJson({ - url: "/api/birth-time-candidate-completion", - body: JSON.stringify(input), - retryLostResponse: false, - }); - if (!response.ok) { - const parsed = errorPayloadSchema.safeParse(payload); - throw new GuidedBirthTimeRequestError( - response.status, - parsed.success - ? parsed.data.message ?? parsed.data.error ?? "候选时间暂时无法保存" - : "候选时间暂时无法保存", - ); - } -} diff --git a/frontend/src/lib/birth-time-intake-model.ts b/frontend/src/lib/birth-time-intake-model.ts index dd585359..56e56fce 100644 --- a/frontend/src/lib/birth-time-intake-model.ts +++ b/frontend/src/lib/birth-time-intake-model.ts @@ -203,7 +203,7 @@ export function isDeclaredBirthProfileComplete( export function isBirthTimeReadyForConsultation(draft: BirthTimeDraft) { return isBirthClockTime(draft.time) - && (draft.birthTimeStatus === "candidate" || draft.birthTimeStatus === "confirmed"); + && draft.birthTimeStatus === "confirmed"; } const declaredBirthInputKeys = [ diff --git a/frontend/src/lib/chat-message-view.ts b/frontend/src/lib/chat-message-view.ts index 35825f56..e7f0d9ad 100644 --- a/frontend/src/lib/chat-message-view.ts +++ b/frontend/src/lib/chat-message-view.ts @@ -3,6 +3,12 @@ export type ChatMessage = { readonly text: string; readonly suggestions?: readonly string[]; readonly techniqueTruth?: string; + readonly workflowReceipt?: { + readonly route: string; + readonly status: string; + readonly preciseTiming: string; + readonly missingLayers: readonly string[]; + }; }; export type ChatMessageView = ChatMessage & { diff --git a/frontend/src/lib/consultation-report-export.ts b/frontend/src/lib/consultation-report-export.ts new file mode 100644 index 00000000..7d12ad72 --- /dev/null +++ b/frontend/src/lib/consultation-report-export.ts @@ -0,0 +1,37 @@ +import type { ChatMessage } from "./chat-message-view"; + +export function consultationReportMarkdown(input: { + title: string; + messages: readonly ChatMessage[]; +}) { + const latestAssistant = [...input.messages].reverse().find((message) => message.role === "assistant"); + const evidence = latestAssistant?.workflowReceipt; + return [ + `# ${input.title}`, + "", + "## 最新回答", + latestAssistant?.text || "暂无回答。", + "", + "## Claim boundary", + `technique_truth: ${latestAssistant?.techniqueTruth || "unknown"}`, + evidence ? `workflow_route: ${evidence.route}` : "workflow_route: unknown", + evidence ? `workflow_status: ${evidence.status}` : "workflow_status: unknown", + evidence ? `precise_timing: ${evidence.preciseTiming}` : "precise_timing: unknown", + evidence ? `missing_layers: ${evidence.missingLayers.join(" / ") || "none"}` : "missing_layers: unknown", + "", + "## Boundary", + "本报告保留证据边界;未闭环内容不得包装成确定预测。", + ].join("\n"); +} + +export function downloadMarkdownReport(title: string, markdown: string) { + const blob = new Blob([markdown], { type: "text/markdown;charset=utf-8" }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = `${title.replace(/[\\/:*?"<>|]+/g, "-")}.md`; + document.body.append(anchor); + anchor.click(); + anchor.remove(); + URL.revokeObjectURL(url); +} diff --git a/frontend/src/lib/consultation-workflow-request.ts b/frontend/src/lib/consultation-workflow-request.ts index 1f4d08d8..0fe7b16e 100644 --- a/frontend/src/lib/consultation-workflow-request.ts +++ b/frontend/src/lib/consultation-workflow-request.ts @@ -2,15 +2,64 @@ export const consultationThemeValues = ["career", "marriage", "wealth", "timing" export type ConsultationTheme = typeof consultationThemeValues[number]; +export type ConsultationWorkflowRoute = + | "career" + | "marriage" + | "wealth" + | "timing" + | "rectification" + | "prashna" + | "general"; + +type WorkflowProjection = { + question: string; + themes: readonly ("career" | "marriage" | "wealth")[]; + strictWorkflowRoute: ConsultationWorkflowRoute; + requiredLayers: readonly string[]; + claimBoundary: string; +}; + +const routeRequirements: Record & { prefix?: string }> = { + career: { + themes: ["career"], + strictWorkflowRoute: "career", + requiredLayers: ["D1", "D10", "10th house/lord", "A10", "AmK", "Vimshottari", "Narayana", "Transit"], + claimBoundary: "career_direction_and_broad_timing_only", + }, + marriage: { + themes: ["marriage"], + strictWorkflowRoute: "marriage", + requiredLayers: ["D1", "D9", "7th house/lord", "Venus/Jupiter", "DK", "UL", "A7", "Vimshottari", "Narayana", "Transit"], + claimBoundary: "relationship_pattern_and_broad_window_only", + }, + wealth: { + themes: ["wealth"], + strictWorkflowRoute: "wealth", + requiredLayers: ["D1", "D2", "D11", "2nd/11th/9th/5th houses", "Wealth Yogas", "Ashtakavarga", "Dasha"], + claimBoundary: "wealth_structure_not_financial_advice", + }, + timing: { + themes: ["career"], + strictWorkflowRoute: "timing", + requiredLayers: ["Vimshottari", "Narayana", "Transit", "Varga", "negative holdout gate"], + claimBoundary: "candidate_day_month_window_only_until_holdout_passes", + prefix: "应期与阶段问题:", + }, + general: { + themes: ["career", "marriage", "wealth"], + strictWorkflowRoute: "general", + requiredLayers: ["D1", "D9", "D10", "D2", "Dasha", "Narayana", "Transit", "Functional Benefic/Malefic"], + claimBoundary: "multi_domain_summary_with_missing_layers_disclosed", + }, +}; + export function projectConsultationWorkflowRequest(question: string, theme: ConsultationTheme) { - switch (theme) { - case "career": - case "marriage": - case "wealth": - return { question, themes: [theme] } as const; - case "timing": - return { question: `应期与阶段问题:${question}`, themes: ["career"] } as const; - case "general": - return { question, themes: ["career", "marriage", "wealth"] } as const; - } + const requirement = routeRequirements[theme]; + return { + question: `${requirement.prefix ?? ""}${question}`, + themes: requirement.themes, + strictWorkflowRoute: requirement.strictWorkflowRoute, + requiredLayers: requirement.requiredLayers, + claimBoundary: requirement.claimBoundary, + } satisfies WorkflowProjection; } diff --git a/frontend/src/lib/guided-jyotish-topics.ts b/frontend/src/lib/guided-jyotish-topics.ts new file mode 100644 index 00000000..cde6ee58 --- /dev/null +++ b/frontend/src/lib/guided-jyotish-topics.ts @@ -0,0 +1,50 @@ +import type { ConsultationTheme } from "./consultation-workflow-request"; + +export type GuidedJyotishTopic = { + id: ConsultationTheme; + label: string; + prompt: string; + strictWorkflowRoute: string; + evidencePreview: string[]; + confidenceCap: "low" | "medium"; + claimBoundary: string; +}; + +export const defaultGuidedJyotishTopics: GuidedJyotishTopic[] = [ + { + id: "career", + label: "事业", + prompt: "未来一年,事业和收入该关注什么?", + strictWorkflowRoute: "career", + evidencePreview: ["D1", "D10", "A10", "Vimshottari", "Narayana", "Transit"], + confidenceCap: "medium", + claimBoundary: "输出职业结构与阶段判断;具体日/月只作为候选窗口。", + }, + { + id: "marriage", + label: "关系", + prompt: "我的关系模式是什么?", + strictWorkflowRoute: "marriage", + evidencePreview: ["D1", "D9", "7宫", "DK", "UL", "Vimshottari", "Narayana"], + confidenceCap: "medium", + claimBoundary: "输出关系模式与宽窗口;不承诺某日必然发生事件。", + }, + { + id: "wealth", + label: "财富", + prompt: "我的财富增长方式和风险点是什么?", + strictWorkflowRoute: "wealth", + evidencePreview: ["D1", "D2", "D11", "2/11宫", "财富 Yoga", "Ashtakavarga"], + confidenceCap: "medium", + claimBoundary: "输出财富结构和风险类型;不替代投资建议。", + }, + { + id: "timing", + label: "时运", + prompt: "未来哪些阶段值得把握?", + strictWorkflowRoute: "timing", + evidencePreview: ["Dasha", "Narayana", "Transit", "Varga"], + confidenceCap: "low", + claimBoundary: "精确月/日仍是探索性候选,未通过独立 holdout 前不升级。", + }, +]; diff --git a/frontend/src/lib/onboarding-client.ts b/frontend/src/lib/onboarding-client.ts index 7f1a8c76..47116f9f 100644 --- a/frontend/src/lib/onboarding-client.ts +++ b/frontend/src/lib/onboarding-client.ts @@ -77,7 +77,7 @@ type OnboardingProfileFingerprintInput = { }; export type OnboardingSuggestion = { - readonly theme: "career" | "marriage" | "timing"; + readonly theme: ConsultationTheme; readonly text: string; }; @@ -268,3 +268,4 @@ export async function requestOnboardingWithRecovery( throw lastError ?? new OnboardingRequestError("pending"); } +import type { ConsultationTheme } from "./consultation-workflow-request"; diff --git a/frontend/src/lib/truth-source-runtime-identity.ts b/frontend/src/lib/truth-source-runtime-identity.ts new file mode 100644 index 00000000..3297b130 --- /dev/null +++ b/frontend/src/lib/truth-source-runtime-identity.ts @@ -0,0 +1,82 @@ +import { existsSync, readFileSync } from "node:fs"; +import { join } from "node:path"; + +type OracleSummary = { + ready: string[]; + partial: string[]; + blocked: string[]; +}; + +export type TruthSourceRuntimeIdentity = { + status: "ok" | "blocked"; + path: string; + mountStatus: "mounted" | "not_mounted"; + commit: string; + skillVersion: string; + evidencePacketCount: number | null; + oracleSummary: OracleSummary; + claimGateStatus: "ready" | "partial_or_blocked_present" | "not_mounted"; +}; + +export const DEFAULT_RESEARCH_TRUTH_SOURCE_PATH = "/Users/wuyongnaren/Documents/印度占星"; + +function readJson(path: string): unknown { + return JSON.parse(readFileSync(path, "utf8")); +} + +function readEvidencePacketCount(researchPath: string): number | null { + const indexPath = join(researchPath, "references/oracle/evidence_packet_index_2026_07_19.json"); + if (!existsSync(indexPath)) return null; + const data = readJson(indexPath) as { summary?: { packet_count?: unknown } }; + return typeof data.summary?.packet_count === "number" ? data.summary.packet_count : null; +} + +function readSkillVersion(researchPath: string): string { + const skillPath = join(researchPath, "SKILL.md"); + if (!existsSync(skillPath)) return "unknown"; + const source = readFileSync(skillPath, "utf8"); + const version = source.match(/(?:version|Version)[::]\s*([^\n]+)/); + return version?.[1]?.trim() || "present_unversioned"; +} + +function readCommit(researchPath: string): string { + const headPath = join(researchPath, ".git/HEAD"); + if (!existsSync(headPath)) return "unknown"; + const head = readFileSync(headPath, "utf8").trim(); + if (!head.startsWith("ref: ")) return head.slice(0, 40); + const refPath = join(researchPath, ".git", head.slice(5)); + if (!existsSync(refPath)) return "unknown"; + return readFileSync(refPath, "utf8").trim().slice(0, 40); +} + +export function getTruthSourceRuntimeIdentity( + researchPath = process.env.JYOTISH_RESEARCH_TRUTH_SOURCE_PATH ?? DEFAULT_RESEARCH_TRUTH_SOURCE_PATH, +): TruthSourceRuntimeIdentity { + if (!existsSync(researchPath)) { + return { + status: "blocked", + path: researchPath, + mountStatus: "not_mounted", + commit: "unknown", + skillVersion: "unknown", + evidencePacketCount: null, + oracleSummary: { ready: [], partial: [], blocked: ["research_truth_source_not_mounted"] }, + claimGateStatus: "not_mounted", + }; + } + + const evidencePacketCount = readEvidencePacketCount(researchPath); + const blocked = evidencePacketCount === null ? ["evidence_packet_index_missing"] : []; + const partial = ["commercial_runtime_identity_only"]; + + return { + status: blocked.length ? "blocked" : "ok", + path: researchPath, + mountStatus: "mounted", + commit: readCommit(researchPath), + skillVersion: readSkillVersion(researchPath), + evidencePacketCount, + oracleSummary: { ready: [], partial, blocked }, + claimGateStatus: blocked.length ? "partial_or_blocked_present" : "partial_or_blocked_present", + }; +} diff --git a/frontend/tests/birth-time-candidate-completion.test.ts b/frontend/tests/birth-time-candidate-completion.test.ts index d860f59c..a5674e72 100644 --- a/frontend/tests/birth-time-candidate-completion.test.ts +++ b/frontend/tests/birth-time-candidate-completion.test.ts @@ -2,216 +2,11 @@ import assert from "node:assert/strict"; import test from "node:test"; import { candidateWorkingTime } from "../src/lib/birth-time-candidate-completion.ts"; -const terminalCase = { - id: "5425f9e7-3d45-491d-aab3-24cfd4261d51", - user_id: "07e583fc-90b9-4fcb-a9d3-8de654eeac9a", - journey_protocol: "legacy-guided-v1", - status: "candidate", - candidate_result_id: "d9133ba2-afcf-56da-b40b-ace3d7124a7d", - candidate_result: { - confidence: "medium", - winningSegment: { representativeTime: "04:53" }, - }, - turn_state: { - nextAction: { - kind: "present_medium_result", - resultId: "d9133ba2-afcf-56da-b40b-ace3d7124a7d", - }, - }, -}; - -const lowTerminalCase = { - ...terminalCase, - status: "rectifying", - candidate_result: { - ...terminalCase.candidate_result, - confidence: "low", - }, - turn_state: { - ...terminalCase.turn_state, - nextAction: { - kind: "present_low_result", - resultId: terminalCase.candidate_result_id, - }, - }, -}; - -const completionRequest = { - userId: terminalCase.user_id, - caseId: terminalCase.id, - resultId: terminalCase.candidate_result_id, - time: "04:53", -} as const; - -test("candidate completion only accepts the persisted terminal representative time", () => { - assert.equal(candidateWorkingTime(terminalCase, { - ...completionRequest, - }), "04:53"); - - assert.equal(candidateWorkingTime(terminalCase, { - ...completionRequest, - time: "04:54", +test("unconfirmed candidate results cannot directly become the active consultation time", () => { + assert.equal(candidateWorkingTime({}, { + userId: "07e583fc-90b9-4fcb-a9d3-8de654eeac9a", + caseId: "5425f9e7-3d45-491d-aab3-24cfd4261d51", + resultId: "d9133ba2-afcf-56da-b40b-ace3d7124a7d", + time: "04:53", }), null); }); - -test("accepts a matching low-confidence result from the rectifying state", () => { - assert.equal(candidateWorkingTime(lowTerminalCase, { - ...completionRequest, - }), "04:53"); -}); - -test("accepts a persisted candidate-saved compatibility action", () => { - assert.equal(candidateWorkingTime({ - ...terminalCase, - turn_state: { - nextAction: { - kind: "candidate_saved", - resultId: terminalCase.candidate_result_id, - }, - }, - }, completionRequest), "04:53"); -}); - -test("does not accept a medium terminal action from the rectifying state", () => { - assert.equal(candidateWorkingTime({ - ...lowTerminalCase, - turn_state: { - ...lowTerminalCase.turn_state, - nextAction: { - kind: "present_medium_result", - resultId: terminalCase.candidate_result_id, - }, - }, - }, { - ...completionRequest, - }), null); -}); - -test("non-terminal cases cannot be adopted for consultation", () => { - assert.equal(candidateWorkingTime({ - ...terminalCase, - turn_state: { nextAction: { kind: "ask_dynamic_choice" } }, - }, { - ...completionRequest, - }), null); -}); - -test("legacy candidate completion rejects dynamic-choice-v2 cases", () => { - assert.equal(candidateWorkingTime({ - ...terminalCase, - journey_protocol: "dynamic-choice-v2", - }, completionRequest), null); -}); - -test("legacy candidate completion requires an explicit legacy protocol", () => { - assert.equal(candidateWorkingTime({ ...terminalCase, journey_protocol: undefined }, completionRequest), null); -}); - -const rejectedCompletions = [ - { - name: "case owned by another user", - stored: { ...terminalCase, user_id: "f6cf99a5-9af7-4980-93ea-0298ee1dc95e" }, - request: completionRequest, - }, - { - name: "request from another user", - stored: terminalCase, - request: { ...completionRequest, userId: "f6cf99a5-9af7-4980-93ea-0298ee1dc95e" }, - }, - { - name: "missing case owner", - stored: { ...terminalCase, user_id: null }, - request: completionRequest, - }, - { - name: "empty case owner", - stored: { ...terminalCase, user_id: "" }, - request: completionRequest, - }, - { - name: "wrong case ID", - stored: terminalCase, - request: { ...completionRequest, caseId: "c84052ca-bcea-40a8-a32a-56980bbf7b22" }, - }, - { - name: "wrong persisted result ID", - stored: { ...terminalCase, candidate_result_id: "a3e41512-9fa0-4866-a187-e3b3aa07aee0" }, - request: completionRequest, - }, - { - name: "wrong action result ID", - stored: { - ...terminalCase, - turn_state: { - nextAction: { - ...terminalCase.turn_state.nextAction, - resultId: "a3e41512-9fa0-4866-a187-e3b3aa07aee0", - }, - }, - }, - request: completionRequest, - }, - { - name: "wrong requested result ID", - stored: terminalCase, - request: { ...completionRequest, resultId: "a3e41512-9fa0-4866-a187-e3b3aa07aee0" }, - }, - { - name: "missing winning segment", - stored: { ...terminalCase, candidate_result: { confidence: "medium" } }, - request: completionRequest, - }, - { - name: "missing representative time", - stored: { - ...terminalCase, - candidate_result: { confidence: "medium", winningSegment: {} }, - }, - request: completionRequest, - }, - { - name: "low-result action paired with candidate status", - stored: { - ...terminalCase, - turn_state: { - nextAction: { - kind: "present_low_result", - resultId: terminalCase.candidate_result_id, - }, - }, - }, - request: completionRequest, - }, - { - name: "medium-result action paired with rectifying status", - stored: { - ...lowTerminalCase, - turn_state: { - nextAction: { - kind: "present_medium_result", - resultId: terminalCase.candidate_result_id, - }, - }, - }, - request: completionRequest, - }, - { - name: "candidate-saved action paired with rectifying status", - stored: { - ...lowTerminalCase, - turn_state: { - nextAction: { - kind: "candidate_saved", - resultId: terminalCase.candidate_result_id, - }, - }, - }, - request: completionRequest, - }, -] as const; - -for (const scenario of rejectedCompletions) { - test(`rejects candidate completion with ${scenario.name}`, () => { - assert.equal(candidateWorkingTime(scenario.stored, scenario.request), null); - }); -} diff --git a/frontend/tests/birth-time-guided-review-fixes.test.ts b/frontend/tests/birth-time-guided-review-fixes.test.ts index 465650e2..3ee52cc7 100644 --- a/frontend/tests/birth-time-guided-review-fixes.test.ts +++ b/frontend/tests/birth-time-guided-review-fixes.test.ts @@ -56,7 +56,7 @@ test("low without a result and saved medium both return to declared-time editing }); }); -test("dynamic non-confirmable terminal stays in declared-time editing", () => { +test("dynamic medium terminal preserves its candidate range without direct adoption", () => { const medium = dynamicBirthTimePreview("medium"); assert.deepEqual(guidedTerminalPath(medium), { @@ -68,7 +68,7 @@ test("dynamic non-confirmable terminal stays in declared-time editing", () => { test("candidate completion hook cannot invoke the legacy endpoint for dynamic turns", () => { const hookSource = readFileSync(new URL("../src/hooks/use-birth-time-guided-journey.ts", import.meta.url), "utf8"); - assert.match(hookSource, /if \(turn\.journeyProtocol === "dynamic-choice-v2"\) return;/); + assert.doesNotMatch(hookSource, /completeBirthTimeCandidate|completeCandidate/); }); test("request identity cache and scheduled polling deduplicate Strict Mode starts", async () => { @@ -123,33 +123,33 @@ test("ready completion is explicit and terminal low has no finish mutation", () assert.doesNotMatch(hookSource, /turn\.nextAction\.kind === "ready"\) onReady/); assert.match(candidateSource, /acknowledgeReady/); assert.doesNotMatch(candidateSource, /controller\.finish/); + assert.doesNotMatch(hookSource, /completeGuidedBirthTimeCandidate/); + assert.doesNotMatch(hookSource, /completeCandidate:/); }); -test("terminal candidate owns one explicit next step and its completion error", () => { +test("unconfirmed terminal candidates preserve the range without offering direct adoption", () => { const candidateResultSource = readFileSync(new URL("../src/components/birth-time-candidate-result.tsx", import.meta.url), "utf8"); const choiceQuestionSource = readFileSync(new URL("../src/components/birth-time-choice-question.tsx", import.meta.url), "utf8"); const rectificationSource = readFileSync(new URL("../src/components/birth-time-rectification.tsx", import.meta.url), "utf8"); const legacyRectificationSource = readFileSync(new URL("../src/components/birth-time-legacy-rectification.tsx", import.meta.url), "utf8"); - const globalCssSource = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); - assert.match(candidateResultSource, /评估已完成,下一步/); - assert.match(candidateResultSource, /采用 \$\{path\.time\} 并进入对话/); - assert.match(candidateResultSource, /正在采用 \$\{path\.time\}…/); - assert.match(candidateResultSource, /birth-time-next-step/); + assert.match(candidateResultSource, /尚未达到采用条件/); + assert.match(candidateResultSource, /补充资料并重新评估/); + assert.doesNotMatch(candidateResultSource, /采用 \$\{path\.time\} 并进入对话/); + assert.doesNotMatch(candidateResultSource, /birth-time-next-step/); assert.match(rectificationSource, /error=\{error\}/); assert.match(rectificationSource, /const childOwnsError = action\.kind === "ask_dynamic_choice"\s*\|\| action\.kind === "clarify_unmatched_answer"/); assert.match(rectificationSource, /error && !showsCandidate && !childOwnsError/); assert.equal(choiceQuestionSource.match(/role="alert"/g)?.length, 1); assert.match(legacyRectificationSource, /error=\{error\}/); assert.match(legacyRectificationSource, /error && !showsCandidate/); - assert.match(globalCssSource, /\.birth-time-next-step/); }); test("terminal CJK copy stays intact while homepage candidates remain unconfirmed in v3", () => { const candidateResultSource = readFileSync(new URL("../src/components/birth-time-candidate-result.tsx", import.meta.url), "utf8"); const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); - assert.match(candidateResultSource, /作为当前排盘时间<\/span>并进入对话;原始填报<\/span>和本次候选结果<\/span>仍会保留<\/span>。/); + assert.match(candidateResultSource, /候选范围已保留,但当前证据不足以将具体分钟写入当前排盘时间。补充经历后可重新评估。/); assert.match(pageSource, /未确认;\$\{birthTimeConsultationOptionsCopy\(profile\)\}/); assert.match(pageSource, / assert.equal(isBirthTimeDraftReady({ ...emptyDraft, birthTimeSource: "unknown" }), true); }); -test("a persisted candidate working time can leave rectification onboarding", () => { +test("an unconfirmed candidate working time remains in rectification onboarding", () => { const candidate = { ...emptyDraft, time: "04:53", birthTimeStatus: "candidate", } satisfies BirthTimeDraft; - assert.equal(isBirthTimeReadyForConsultation(candidate), true); + assert.equal(isBirthTimeReadyForConsultation(candidate), false); assert.equal(isBirthTimeReadyForConsultation({ ...candidate, time: "" }), false); assert.equal(isBirthTimeReadyForConsultation({ ...candidate, birthTimeStatus: "rectifying" }), false); + assert.equal(isBirthTimeReadyForConsultation({ ...candidate, birthTimeStatus: "confirmed" }), true); }); test("declared birth data completes onboarding without an active or confirmed minute", () => { diff --git a/frontend/tests/birth-time-user-errors.test.ts b/frontend/tests/birth-time-user-errors.test.ts index fd611a84..445a3d44 100644 --- a/frontend/tests/birth-time-user-errors.test.ts +++ b/frontend/tests/birth-time-user-errors.test.ts @@ -16,5 +16,6 @@ test("birth-time errors preserve a safe server message", () => { test("all guided journey mutations normalize implementation errors", () => { const source = readFileSync(new URL("../src/hooks/use-birth-time-guided-journey.ts", import.meta.url), "utf8"); - assert.equal((source.match(/setError\(birthTimeUserError\(caught\)\)/g) ?? []).length, 2); + assert.ok((source.match(/setError\(birthTimeUserError\(caught\)\)/g) ?? []).length >= 1); + assert.equal(source.includes("setError(caught.message"), false); }); diff --git a/frontend/tests/chat-stream-layout.test.ts b/frontend/tests/chat-stream-layout.test.ts index 977a7ec5..00e8cc80 100644 --- a/frontend/tests/chat-stream-layout.test.ts +++ b/frontend/tests/chat-stream-layout.test.ts @@ -5,6 +5,7 @@ import test from "node:test"; import { chatMessageViews } from "../src/lib/chat-message-view.ts"; const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); const previousMessages = [ { role: "user", text: "问题" }, @@ -52,3 +53,12 @@ test("keeps the suggestion row height stable while an answer streams", () => { assert.doesNotMatch(suggestionBlock[0].split("
{ + assert.match(pageSource, /
/); + assert.match(globalStyles, /\.chat-panel[^}]*grid-template-rows:\s*68px minmax\(0,\s*1fr\) auto/); + assert.match(globalStyles, /\.conversation[^}]*padding-bottom:\s*var\(--composer-reserve\)/); + assert.match(globalStyles, /\.composer-wrap[^}]*position:\s*sticky/); + assert.match(globalStyles, /\.composer-wrap[^}]*bottom:\s*0/); + assert.doesNotMatch(globalStyles, /\.composer-wrap[^}]*position:\s*fixed/); +}); diff --git a/frontend/tests/claim-boundary-badge.test.ts b/frontend/tests/claim-boundary-badge.test.ts new file mode 100644 index 00000000..dd481914 --- /dev/null +++ b/frontend/tests/claim-boundary-badge.test.ts @@ -0,0 +1,16 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const rowSource = readFileSync(new URL("../src/components/chat-message-row.tsx", import.meta.url), "utf8"); +const badgeSource = readFileSync(new URL("../src/components/claim-boundary-badge.tsx", import.meta.url), "utf8"); +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); + +test("assistant messages render a claim boundary badge from technique truth", () => { + assert.match(rowSource, /ClaimBoundaryBadge/); + assert.match(rowSource, /status=\{message\.techniqueTruth\}/); + assert.match(badgeSource, /不把未闭环内容包装成确定预测/); + assert.match(badgeSource, /observation_only/); + assert.match(badgeSource, /reference_only/); + assert.match(globalStyles, /\.claim-boundary-badge/); +}); diff --git a/frontend/tests/consultation-report-export.test.ts b/frontend/tests/consultation-report-export.test.ts new file mode 100644 index 00000000..f35c242e --- /dev/null +++ b/frontend/tests/consultation-report-export.test.ts @@ -0,0 +1,40 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; +import { consultationReportMarkdown, downloadMarkdownReport } from "../src/lib/consultation-report-export.ts"; +const rowSource = readFileSync(new URL("../src/components/chat-message-row.tsx", import.meta.url), "utf8"); +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); + +test("exports latest consultation answer with workflow receipt and claim boundary", () => { + const report = consultationReportMarkdown({ + title: "事业咨询", + messages: [ + { role: "user", text: "未来一年事业如何?" }, + { + role: "assistant", + text: "先看阶段,不承诺具体日期。", + techniqueTruth: "partial", + workflowReceipt: { + route: "career", + status: "ready", + preciseTiming: "blocked", + missingLayers: ["MEVG"], + }, + }, + ], + }); + assert.match(report, /# 事业咨询/); + assert.match(report, /先看阶段/); + assert.match(report, /technique_truth: partial/); + assert.match(report, /workflow_route: career/); + assert.match(report, /precise_timing: blocked/); + assert.match(report, /missing_layers: MEVG/); + assert.match(report, /未闭环内容不得包装成确定预测/); +}); + +test("assistant answer exposes a markdown report download button", () => { + assert.equal(typeof downloadMarkdownReport, "function"); + assert.match(rowSource, /下载本次报告/); + assert.match(rowSource, /downloadMarkdownReport/); + assert.match(globalStyles, /\.report-download-button/); +}); diff --git a/frontend/tests/consultation-workflow-contract.test.ts b/frontend/tests/consultation-workflow-contract.test.ts index bde9249f..8d2efdd4 100644 --- a/frontend/tests/consultation-workflow-contract.test.ts +++ b/frontend/tests/consultation-workflow-contract.test.ts @@ -39,3 +39,11 @@ test("carries commercial technique truth into the model contract", () => { assert.match(mastra, /Do not use a restricted technique/); assert.match(route, /x-jyotish-technique-truth/); }); + +test("projects consultation themes through explicit strict workflow taxonomy", () => { + const projection = readFileSync(new URL("../src/lib/consultation-workflow-request.ts", import.meta.url), "utf8"); + assert.match(projection, /strictWorkflowRoute/); + assert.match(projection, /claimBoundary/); + assert.match(projection, /requiredLayers/); + assert.match(projection, /negative holdout gate/); +}); diff --git a/frontend/tests/consultation-workflow-request.test.ts b/frontend/tests/consultation-workflow-request.test.ts index 210aa518..2961f805 100644 --- a/frontend/tests/consultation-workflow-request.test.ts +++ b/frontend/tests/consultation-workflow-request.test.ts @@ -11,11 +11,13 @@ test("timing questions use a legal report theme and preserve a timing route hint // When: its workflow request is projected for the Python service. const request = projectConsultationWorkflowRequest(question, "timing"); - // Then: the illegal public theme is converted to a legal report theme with a route hint. - assert.deepEqual(request, { - question: "应期与阶段问题:未来哪些阶段值得把握?", - themes: ["career"], - }); + // Then: the illegal public theme is converted to a legal report theme with strict route metadata. + assert.equal(request.question, "应期与阶段问题:未来哪些阶段值得把握?"); + assert.deepEqual(request.themes, ["career"]); + assert.equal(request.strictWorkflowRoute, "timing"); + assert.ok(request.requiredLayers.includes("Narayana")); + assert.ok(request.requiredLayers.includes("negative holdout gate")); + assert.equal(request.claimBoundary, "candidate_day_month_window_only_until_holdout_passes"); }); test("timing input projects only legal private workflow fields", async () => { diff --git a/frontend/tests/evidence-audit-panel.test.ts b/frontend/tests/evidence-audit-panel.test.ts new file mode 100644 index 00000000..11ba762b --- /dev/null +++ b/frontend/tests/evidence-audit-panel.test.ts @@ -0,0 +1,36 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const rowSource = readFileSync(new URL("../src/components/chat-message-row.tsx", import.meta.url), "utf8"); +const panelSource = readFileSync(new URL("../src/components/evidence-audit-panel.tsx", import.meta.url), "utf8"); +const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); + +test("assistant messages include a collapsible Technique Audit Table shell", () => { + assert.match(rowSource, /EvidenceAuditPanel/); + assert.match(rowSource, /claimStatus=\{message\.techniqueTruth\}/); + assert.match(rowSource, /workflowReceipt=\{message\.workflowReceipt\}/); + assert.match(panelSource, /Technique Audit Table/); + assert.match(panelSource, /Workflow route:/); + assert.match(panelSource, /Precise timing:/); + assert.match(panelSource, /Missing route layers/); + assert.match(panelSource, /D1 \/ Natal/); + assert.match(panelSource, /Narayana Dasha/); + assert.match(panelSource, /Functional Benefic\/Malefic/); + assert.match(panelSource, /MEVG \/ Real Case Calibration/); + assert.match(panelSource, /组件 parity 未全闭环/); + assert.match(panelSource, /rawReceipt/); + assert.match(panelSource, /no_birth_data_or_private_case_raw/); + assert.match(panelSource, /查看非敏感 raw receipt/); + assert.match(globalStyles, /\.evidence-audit-panel/); + assert.match(globalStyles, /\.raw-evidence-receipt/); +}); + +test("consult responses persist workflow receipt headers for evidence rendering", () => { + assert.match(pageSource, /x-jyotish-workflow-route/); + assert.match(pageSource, /x-jyotish-workflow-status/); + assert.match(pageSource, /x-jyotish-precise-timing/); + assert.match(pageSource, /x-jyotish-missing-layers/); + assert.match(pageSource, /workflowReceipt/); +}); diff --git a/frontend/tests/parameter-freeze-panel.test.ts b/frontend/tests/parameter-freeze-panel.test.ts new file mode 100644 index 00000000..f3cc7f3f --- /dev/null +++ b/frontend/tests/parameter-freeze-panel.test.ts @@ -0,0 +1,18 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); +const panelSource = readFileSync(new URL("../src/components/parameter-freeze-panel.tsx", import.meta.url), "utf8"); +const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); + +test("starter workbench shows a parameter freeze panel when profile is complete", () => { + assert.match(pageSource, /ParameterFreezePanel/); + assert.match(pageSource, /parameterFreezeRows/); + assert.match(pageSource, /Ayanamsa/); + assert.match(pageSource, /Node mode/); + assert.match(pageSource, /出生时间精度/); + assert.match(panelSource, /当前排盘参数冻结/); + assert.match(panelSource, /这些参数会随咨询一起送入证据链/); + assert.match(globalStyles, /\.parameter-freeze-panel/); +}); diff --git a/frontend/tests/starter-questions.test.ts b/frontend/tests/starter-questions.test.ts index 565bb3de..2b0bc63b 100644 --- a/frontend/tests/starter-questions.test.ts +++ b/frontend/tests/starter-questions.test.ts @@ -5,6 +5,7 @@ import test from "node:test"; const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); const appSidebarSource = readFileSync(new URL("../src/components/app-sidebar.tsx", import.meta.url), "utf8"); +const guidedTopicsSource = readFileSync(new URL("../src/lib/guided-jyotish-topics.ts", import.meta.url), "utf8"); function sourceBetween(source: string, startMarker: string, endMarker: string) { const start = source.indexOf(startMarker); @@ -33,6 +34,20 @@ test("completed account initialization switches directly to the home cards", () assert.doesNotMatch(pageSource, /!profileComplete \|\| onboardingJustCompleted/); }); +test("default starter questions are guided Jyotish topics with evidence and claim boundaries", () => { + assert.match(pageSource, /defaultGuidedJyotishTopics/); + assert.match(pageSource, /theme\.evidencePreview\.join/); + assert.match(pageSource, /theme\.claimBoundary/); + assert.match(guidedTopicsSource, /strictWorkflowRoute/); + assert.match(guidedTopicsSource, /evidencePreview/); + assert.match(guidedTopicsSource, /confidenceCap/); + assert.match(guidedTopicsSource, /claimBoundary/); + assert.match(guidedTopicsSource, /D10/); + assert.match(guidedTopicsSource, /D9/); + assert.match(guidedTopicsSource, /Ashtakavarga/); + assert.match(guidedTopicsSource, /独立 holdout/); +}); + test("keeps follow-up suggestions visible while the user edits a draft", () => { // Given: the follow-up suggestion block and its render guard. const suggestionGuard = sourceBetween( diff --git a/frontend/tests/truth-source-runtime-identity.test.ts b/frontend/tests/truth-source-runtime-identity.test.ts new file mode 100644 index 00000000..d02a8933 --- /dev/null +++ b/frontend/tests/truth-source-runtime-identity.test.ts @@ -0,0 +1,28 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const identitySource = readFileSync( + new URL("../src/lib/truth-source-runtime-identity.ts", import.meta.url), + "utf8", +); +const healthSource = readFileSync( + new URL("../src/app/api/health/route.ts", import.meta.url), + "utf8", +); + +test("truth source identity records research source without pretending local mount is always present", () => { + assert.match(identitySource, /DEFAULT_RESEARCH_TRUTH_SOURCE_PATH/); + assert.ok(identitySource.includes("/Users/wuyongnaren/Documents/印度占星")); + assert.match(identitySource, /not_mounted/); + assert.match(identitySource, /claimGateStatus/); + assert.match(identitySource, /evidencePacketCount/); + assert.match(identitySource, /oracleSummary/); +}); + +test("health endpoint exposes truth source identity beside deployment identity", () => { + assert.match(healthSource, /getTruthSourceRuntimeIdentity/); + assert.match(healthSource, /truthSource/); + assert.match(healthSource, /truthSource:\s*truthSourceIdentity/); + assert.match(healthSource, /researchTruthSource/); +}); diff --git a/references/cross_project_contract/sync_policy.v1.json b/references/cross_project_contract/sync_policy.v1.json index c50bc8e9..1ec38df0 100644 --- a/references/cross_project_contract/sync_policy.v1.json +++ b/references/cross_project_contract/sync_policy.v1.json @@ -42,8 +42,12 @@ "tests/test_cross_project_contract.py", "tests/test_cross_project_sync_status.py", "scripts/active_rectification_questions.py", + "scripts/active_rectification_event_engine.py", + "scripts/active_rectification_events.py", "scripts/birth_time_rectifier.py", "scripts/candidate_time_sensitivity_scan.py", + "scripts/rectification_technique_contract.py", + "scripts/rectification_three_engine_packet.py", "references/oracle/rectification_technique_usage_audit_2026_07_19.json", "references/oracle/rectification_missing_layer_integration_plan_2026_07_19.json", "tests/test_active_rectification_api.py", diff --git a/references/oracle/artifacts/vedastro_divisional_degree_contract_probe.json b/references/oracle/artifacts/vedastro_divisional_degree_contract_probe.json new file mode 100644 index 00000000..e7449825 --- /dev/null +++ b/references/oracle/artifacts/vedastro_divisional_degree_contract_probe.json @@ -0,0 +1,48 @@ +{ + "boundary": "This probe validates only the divisional degree transformation. It does not establish complete D2/D4/D9/D10 sign, ayanamsa, node, timezone, or hosted-endpoint chart parity.", + "chart_sign_contract": "blocked", + "contract_status": "degree_mapping_verified", + "input_total_degrees": 3.5, + "privacy": { + "api_key_persisted": false + }, + "rows": { + "D10": { + "local_degree": 5.0, + "matches_local": true, + "official_degree": 5.0, + "official_status": "Pass", + "raw_hash": "c18c8f9033f6267d71326618350439669a298bf54df92250fe448450519ff9e0", + "request_body_hash": "0d5e0c96f6afce151b23960ab1a932ad81b68bd1d3cac568cb84811744317798", + "response_payload_hash": "355368858f2631e02e2a5dde2287a1909dae13deef6f9a4702baea32091f1807" + }, + "D2": { + "local_degree": 7.0, + "matches_local": true, + "official_degree": 7.0, + "official_status": "Pass", + "raw_hash": "265db56c75e04db854f8455c10dc87bf1b546e50bdaca078cd452382b3ddba8e", + "request_body_hash": "3270b71182f85800fece09c4a0dd2119287a692bd99bb8c1946b2c172cefe33f", + "response_payload_hash": "0132659fbfdc9e3f0ba0a07e8d2d9ce91ef2d1d8498b0ec92c236456c8df404f" + }, + "D4": { + "local_degree": 14.0, + "matches_local": true, + "official_degree": 14.0, + "official_status": "Pass", + "raw_hash": "ec3b79e9919862585115b48d69e0766debe7bc7e42bd8c5cd398af3b1d6ead19", + "request_body_hash": "6e052dd18d79a9a974b78d052f431ae165778b1987db8d8a0ecd4d3cbfe3b6ff", + "response_payload_hash": "e3d32cc6ce7be7882dbbb732e998ad443148d4edb1a7ca356d63a3d83c74197d" + }, + "D9": { + "local_degree": 1.5, + "matches_local": true, + "official_degree": 1.5, + "official_status": "Pass", + "raw_hash": "0f126a7e7e1995922a0a406e74c884e00ebcdc2e325d655c5ec8c18be7ec4358", + "request_body_hash": "187825c5229aed9e695f3bb59eb5704a854c3d272bd83094c20e9da4575e4380", + "response_payload_hash": "3e10867dac0b9a0f78c6d0c5a40e7436c3292ac334604bc015d3382bfea4d834" + } + }, + "scope": "vedastro_divisional_degree_contract_probe" +} diff --git a/references/oracle/artifacts/vedastro_steve_jobs_contract_probe.json b/references/oracle/artifacts/vedastro_steve_jobs_contract_probe.json index ccf1269b..03df55d6 100644 --- a/references/oracle/artifacts/vedastro_steve_jobs_contract_probe.json +++ b/references/oracle/artifacts/vedastro_steve_jobs_contract_probe.json @@ -6,8 +6,8 @@ }, "capability_catalog": { "capability_count": 641, - "catalog_hash": "b88d1067eb967b06de945a7773858ff1cc34f4145487216752df2857b4b3b927", - "installed_package_version": "1.23.25", + "catalog_hash": "bf10eb7ccd9e660a1d82d98a055119d6bab45f5a69dd6a6b96d1832418e513a8", + "installed_package_version": "1.23.26", "module_name": "vedastro", "source": "vedastro_python_bridge", "status": "captured" @@ -17,7 +17,7 @@ "field_statuses": { "VedAstro.D1.longitude": "blocked" }, - "generated_at": "2026-07-17T09:40:11.856902+00:00", + "generated_at": "2026-07-21T12:09:41.148914+00:00", "method_contract": { "all_planet_data_matches_nirayana": false, "all_planet_longitude_matches_nirayana": false, @@ -27,25 +27,25 @@ "all_planet_vs_nirayana": 0.0 }, "Mars": { - "all_planet_data_vs_nirayana": -0.000277778, - "all_planet_vs_nirayana": 0.0 + "all_planet_data_vs_nirayana": 0.467777778, + "all_planet_vs_nirayana": 0.468055556 }, "Mercury": { - "all_planet_data_vs_nirayana": -0.047777778, - "all_planet_vs_nirayana": -0.0475 + "all_planet_data_vs_nirayana": -0.000277778, + "all_planet_vs_nirayana": 0.0 }, "Moon": { "all_planet_data_vs_nirayana": -0.0, "all_planet_vs_nirayana": 0.0 }, "Saturn": { - "all_planet_data_vs_nirayana": 0.004722222, - "all_planet_vs_nirayana": 0.005 - }, - "Sun": { "all_planet_data_vs_nirayana": -0.000277778, "all_planet_vs_nirayana": 0.0 }, + "Sun": { + "all_planet_data_vs_nirayana": 0.670555556, + "all_planet_vs_nirayana": 0.670833333 + }, "Venus": { "all_planet_data_vs_nirayana": -0.000277778, "all_planet_vs_nirayana": 0.0 @@ -82,11 +82,11 @@ }, "PlanetNirayanaLongitude": { "Jupiter": 87.27222222222223, - "Mars": 5.854722222222223, - "Mercury": 291.17333333333335, + "Mars": 5.386666666666667, + "Mercury": 291.12583333333333, "Moon": 344.5113888888889, - "Saturn": 207.92194444444445, - "Sun": 312.51222222222225, + "Saturn": 207.92694444444444, + "Sun": 311.8413888888889, "Venus": 267.93611111111113 } }, @@ -460,7 +460,7 @@ "request_body_hash": "d45c4facf45e6f530e114d7b5bd12565ed98ce7c5ffe612c9f5d6ad54b0d4c1e", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:59 GMT", + "date": "Tue, 21 Jul 2026 12:09:27 GMT", "server": "Kestrel" }, "response_input_hash": "c0b951e8e79edf0dfc7f21f0eea8d9233baa2e7b155c0e8dd0a078c26081d83c", @@ -825,7 +825,7 @@ "request_body_hash": "f65f499ed5198e9a908f8162c7416ee1900cce776985f3431fbe585d465bb966", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:55 GMT", + "date": "Tue, 21 Jul 2026 12:09:24 GMT", "server": "Kestrel" }, "response_input_hash": "6d0ccc01163f52882b4729126b6040173b861530facc71c3c5bb4fbee775b7f9", @@ -1184,7 +1184,7 @@ "request_body_hash": "5d06bcab5ad35cc9bab8d6045c9cc94a5401355efde5fb2fcebec588ff37a82a", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:57 GMT", + "date": "Tue, 21 Jul 2026 12:09:25 GMT", "server": "Kestrel" }, "response_input_hash": "4521a381ebbf2462fd932e411bdf604872ac57f76389687af8f5ad47af16c733", @@ -1543,7 +1543,7 @@ "request_body_hash": "ecb534474630f8b3c71299279668ac78bdcb0b41b856e692880f17094526a8f6", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:53 GMT", + "date": "Tue, 21 Jul 2026 12:09:22 GMT", "server": "Kestrel" }, "response_input_hash": "93089694d5e0a5ce4817f42d69ec654682bec1dab9ec623ff76323380467830d", @@ -1914,7 +1914,7 @@ "request_body_hash": "a7c609c106c29384f57d221eef233095f98f868725f95810aaf834ab05dc3e4c", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:02 GMT", + "date": "Tue, 21 Jul 2026 12:09:31 GMT", "server": "Kestrel" }, "response_input_hash": "bfb4d685797ba0b90d2951c29843f10831bc085535ca6abcb6b9e0a86bc8fcbb", @@ -2274,7 +2274,7 @@ "request_body_hash": "ca1c489fb000c6c0fce82847290ae225bac0080b5c068b16b5b96b57d36bccdb", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:51 GMT", + "date": "Tue, 21 Jul 2026 12:09:21 GMT", "server": "Kestrel" }, "response_input_hash": "cb72a68310596f5f4533b7562dd9b13e03e7b229257d1c231e7f4590bd9cc135", @@ -2650,7 +2650,7 @@ "request_body_hash": "db1bf8a8aa52b1b9a30c8affd606cb6ac4a8c803244efb2910e3a17fe40e8d01", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:01 GMT", + "date": "Tue, 21 Jul 2026 12:09:30 GMT", "server": "Kestrel" }, "response_input_hash": "fb49f3bab33f8326366dc58078f631f561da0471f6775d2facdbe60afbb685b3", @@ -2698,7 +2698,7 @@ "request_body_hash": "d45c4facf45e6f530e114d7b5bd12565ed98ce7c5ffe612c9f5d6ad54b0d4c1e", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:09 GMT", + "date": "Tue, 21 Jul 2026 12:09:38 GMT", "server": "Kestrel" }, "response_input_hash": "e61e2eda72b1dba9b72fce2d8237ea677b3fdb45ac591ec7f370f9e2d2d54647", @@ -2733,22 +2733,22 @@ ], "Type": "SingleCall" }, - "normalized_value": 5.854722222222223, + "normalized_value": 5.386666666666667, "payload": { "PlanetNirayanaLongitude": { - "DegreeMinuteSecond": "5° 51' 17", - "TotalDegrees": "5.854722222222223" + "DegreeMinuteSecond": "5° 23' 12", + "TotalDegrees": "5.386666666666667" } }, - "raw_hash": "59f8be1c9e661688e5c5400363a4eb6a5f00947e8147a95a7ba18d4b01fb2b08", + "raw_hash": "5c9e2922439e94e0df2fabfc0c6de87afe52756f3ba67846ce583ea1464e00a7", "request_body_hash": "f65f499ed5198e9a908f8162c7416ee1900cce776985f3431fbe585d465bb966", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:06 GMT", + "date": "Tue, 21 Jul 2026 12:09:35 GMT", "server": "Kestrel" }, "response_input_hash": "8af9e6b535c04fb7c9918ade07b7ad91348080a769cf39878951d543fc63cd1f", - "response_payload_hash": "292052d508cb637199bc3b5ee80b002b8c7d5982f5830b6585b5c47e7aa66ead", + "response_payload_hash": "ffe42426ce86977e771f7afe0e9655f9805e34cd012391b6b73568c1a456e0f9", "status": "Pass" }, "Mercury": { @@ -2779,22 +2779,22 @@ ], "Type": "SingleCall" }, - "normalized_value": 291.17333333333335, + "normalized_value": 291.12583333333333, "payload": { "PlanetNirayanaLongitude": { - "DegreeMinuteSecond": "291° 10' 24", - "TotalDegrees": "291.17333333333335" + "DegreeMinuteSecond": "291° 7' 33", + "TotalDegrees": "291.12583333333333" } }, - "raw_hash": "c9868d178e0142c417e77387e906ec8671297fa0cda260ef8a0bfd142d823a97", + "raw_hash": "65629974eebe9e80f5ad0891f3a92089ccf51726dd006427153fb1d97b92a9fd", "request_body_hash": "5d06bcab5ad35cc9bab8d6045c9cc94a5401355efde5fb2fcebec588ff37a82a", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:07 GMT", + "date": "Tue, 21 Jul 2026 12:09:36 GMT", "server": "Kestrel" }, "response_input_hash": "c0ef28b19014505b62ba3078efd5491940aea6a0a0e6a40d3c36d5da5a6652ff", - "response_payload_hash": "90f55fdf61c751832b22d8d45a99cfb987f0591e1ce75907fd8a2ee78b768476", + "response_payload_hash": "985edf2ca075cc9bee89e989d435ca5b5e90965156bfc22afc70638079bd5169", "status": "Pass" }, "Moon": { @@ -2836,7 +2836,7 @@ "request_body_hash": "ecb534474630f8b3c71299279668ac78bdcb0b41b856e692880f17094526a8f6", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:05 GMT", + "date": "Tue, 21 Jul 2026 12:09:34 GMT", "server": "Kestrel" }, "response_input_hash": "e4df625ac24adb3bbc5d5eccdae52d7b2baabcf7243af20c06e7e6e58a036015", @@ -2871,22 +2871,22 @@ ], "Type": "SingleCall" }, - "normalized_value": 207.92194444444445, + "normalized_value": 207.92694444444444, "payload": { "PlanetNirayanaLongitude": { - "DegreeMinuteSecond": "207° 55' 19", - "TotalDegrees": "207.92194444444445" + "DegreeMinuteSecond": "207° 55' 37", + "TotalDegrees": "207.92694444444444" } }, - "raw_hash": "00a810322b43e0dca99e9e314da1f9c7f049063d647168f3efa9a8115932423f", + "raw_hash": "281751b85dabb7f5e6abbf7b74f567a6e2fa6cfceb724a3a7de46297de03e88e", "request_body_hash": "a7c609c106c29384f57d221eef233095f98f868725f95810aaf834ab05dc3e4c", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:11 GMT", + "date": "Tue, 21 Jul 2026 12:09:41 GMT", "server": "Kestrel" }, "response_input_hash": "61e79349787305a7ad2700e59b0193047d234f7b4428ebd9518e1882b7d2bc98", - "response_payload_hash": "f49e0a274793b50f20fb283184fefb06ee3d32a49bf8d25219b96a6b74e1aac7", + "response_payload_hash": "3a20bc9fb70a0ae28b55301ff7c4aea6b06d1ab279bcd29271cb99f73545772f", "status": "Pass" }, "Sun": { @@ -2917,22 +2917,22 @@ ], "Type": "SingleCall" }, - "normalized_value": 312.51222222222225, + "normalized_value": 311.8413888888889, "payload": { "PlanetNirayanaLongitude": { - "DegreeMinuteSecond": "312° 30' 44", - "TotalDegrees": "312.51222222222225" + "DegreeMinuteSecond": "311° 50' 29", + "TotalDegrees": "311.8413888888889" } }, - "raw_hash": "55573bed79d0af387142867e45f8a430e6d25e87496fa411eb44ebf1cd72a24c", + "raw_hash": "efc6004f4d98a75bf96ec8576c0d923174ba2c794af7f097ff78eee9d29cfaa2", "request_body_hash": "ca1c489fb000c6c0fce82847290ae225bac0080b5c068b16b5b96b57d36bccdb", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:03 GMT", + "date": "Tue, 21 Jul 2026 12:09:32 GMT", "server": "Kestrel" }, "response_input_hash": "bd722e1cb9e24693ba6c8671c7a723999db97f978413ad2c8921d66e8323f7d8", - "response_payload_hash": "21857d79a7fa6fab10ab3b2698779f605d379d372ad18b22766a8a491dfc70ca", + "response_payload_hash": "e9f4f8ae0f5c9892ecfa7bb286ab7907634e537c7984a5511f9a234c49c2f729", "status": "Pass" }, "Venus": { @@ -2974,7 +2974,7 @@ "request_body_hash": "db1bf8a8aa52b1b9a30c8affd606cb6ac4a8c803244efb2910e3a17fe40e8d01", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:40:10 GMT", + "date": "Tue, 21 Jul 2026 12:09:40 GMT", "server": "Kestrel" }, "response_input_hash": "290d41983b8413973c02ebfc840f77597a249e167fb8b2bfa85d02da9dd677bb", @@ -3022,7 +3022,7 @@ "request_body_hash": "638d6d846cae88f0137456c4dab1cd619992a04e43cab576be290c0d65fa275f", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:45 GMT", + "date": "Tue, 21 Jul 2026 12:09:13 GMT", "server": "Kestrel" }, "response_input_hash": "1e529077a4b6ea7cafb4e5ac9ec67577dbe0e1d87e20c509a9adc4eb50dcf7f1", @@ -3067,7 +3067,7 @@ "request_body_hash": "638d6d846cae88f0137456c4dab1cd619992a04e43cab576be290c0d65fa275f", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:46 GMT", + "date": "Tue, 21 Jul 2026 12:09:14 GMT", "server": "Kestrel" }, "response_input_hash": "1e529077a4b6ea7cafb4e5ac9ec67577dbe0e1d87e20c509a9adc4eb50dcf7f1", @@ -3112,7 +3112,7 @@ "request_body_hash": "638d6d846cae88f0137456c4dab1cd619992a04e43cab576be290c0d65fa275f", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:47 GMT", + "date": "Tue, 21 Jul 2026 12:09:16 GMT", "server": "Kestrel" }, "response_input_hash": "1e529077a4b6ea7cafb4e5ac9ec67577dbe0e1d87e20c509a9adc4eb50dcf7f1", @@ -3144,26 +3144,26 @@ }, "interpreted_utc": "1955-02-24T11:15:00+00:00", "normalized": { - "Jupiter": 87.27222222222223, - "Mars": 5.854722222222223, - "Mercury": 291.12583333333333, - "Moon": 344.5113888888889, - "Saturn": 207.92694444444444, - "Sun": 312.51222222222225, - "Venus": 267.93611111111113 + "Jupiter": 87.31472222222222, + "Mars": 5.386666666666667, + "Mercury": 291.17333333333335, + "Moon": 335.0911111111111, + "Saturn": 207.92194444444445, + "Sun": 311.8413888888889, + "Venus": 267.1788888888889 }, "payload": { - "AllPlanetLongitude": "Sun - 312.51222222222225, Moon - 344.5113888888889, Mars - 5.854722222222223, Mercury - 291.12583333333333, Jupiter - 87.27222222222223, Venus - 267.93611111111113, Saturn - 207.92694444444444, Ketu - 69.2688888888889, Rahu - 249.26916666666668" + "AllPlanetLongitude": "Sun - 311.8413888888889, Moon - 335.0911111111111, Mars - 5.386666666666667, Mercury - 291.17333333333335, Jupiter - 87.31472222222222, Venus - 267.1788888888889, Saturn - 207.92194444444445, Ketu - 69.30444444444444, Rahu - 249.30444444444444" }, - "raw_hash": "d87b7025392efd7411ae56db4e46c199deba565a68bebbab0a9b318727113291", + "raw_hash": "ef8dfad6e8da61e6a3409f5058787d7d8bc5f43592bf9a05e9db1cb0b158f031", "request_body_hash": "b4f6d47f9a2223d7ef81457c8e3e6ba1abcf9238900f8472baf5f31eb359068e", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:50 GMT", + "date": "Tue, 21 Jul 2026 12:09:20 GMT", "server": "Kestrel" }, "response_input_hash": "09057eb68ad30572d165a46d258b5f93d8e39fd22814c50dc79864be6cd7c721", - "response_payload_hash": "21bbebeffe2ec586d45286161abe89bc2dfdda7329133ce4d0c8156a082831da", + "response_payload_hash": "03b1f1d8cdbcdd5a67a6abf8b8c2b48659848dd91c2b08dcb54f13bea0ed8e18", "status": "Pass" } ], @@ -3206,7 +3206,7 @@ "request_body_hash": "66a847008737bce56835e50795db663c435b0bcb9de05657e0680fe9f9a414a4", "request_url_host": "api.vedastro.org", "response_headers": { - "date": "Fri, 17 Jul 2026 09:39:49 GMT", + "date": "Tue, 21 Jul 2026 12:09:17 GMT", "server": "Kestrel" }, "response_input_hash": "26ace2c3732b246f0d503110cd3d6e312bea411d52a63771bca192aeefea1769", @@ -3226,7 +3226,7 @@ }, "time_contract": { "equivalent_local_utc": true, - "positive_offset_control_distinct": false, + "positive_offset_control_distinct": true, "raw_hash_stable": true, "repeat_normalized_stable": true }, diff --git a/references/oracle/commercial_golden_oss_case_ci_contract_2026_07_21.json b/references/oracle/commercial_golden_oss_case_ci_contract_2026_07_21.json new file mode 100644 index 00000000..c64d07d4 --- /dev/null +++ b/references/oracle/commercial_golden_oss_case_ci_contract_2026_07_21.json @@ -0,0 +1,22 @@ +{ + "scope": "commercial_golden_oss_case_ci_contract", + "created_at": "2026-07-21", + "status": "ready_contract", + "purpose": "Commercial CI must replay at least one public OSS golden observation from the main research repo to detect accidental legacy WorkBuddy or incomplete artifact source wiring.", + "golden_case": { + "name": "pyjhora_jhora_sphuta_oss_case", + "probe": "scripts/prashna_sphuta_oss_case_probe.py", + "test": "tests/test_prashna_sphuta_oss_case_probe.py", + "source_packet": "references/oracle/prashna_sphuta_oss_case_probe_2026_07_20.json", + "expected_raw_hash": "f0705d205440ea8d7f39116042a0723d971f4ab79c94f7d448fc42d683d52326", + "claim_status": "tooling_observation_only" + }, + "gate_policy": { + "fail_if_probe_missing": true, + "fail_if_raw_hash_mismatch": true, + "fail_if_claim_status_upgraded": true, + "truth_upgrade_allowed": false, + "allow_business_runtime_to_continue_after_warning": false + }, + "claim_boundary": "ci_golden_observation_gate_only_not_oracle_truth" +} diff --git a/references/oracle/commercial_startup_self_check_contract_2026_07_21.json b/references/oracle/commercial_startup_self_check_contract_2026_07_21.json new file mode 100644 index 00000000..0eeca119 --- /dev/null +++ b/references/oracle/commercial_startup_self_check_contract_2026_07_21.json @@ -0,0 +1,36 @@ +{ + "scope": "commercial_startup_self_check_contract", + "created_at": "2026-07-21", + "status": "ready_contract", + "purpose": "Commercial runtime must prove which research truth source, skill version, evidence index and oracle gates it is using before claiming website capability readiness.", + "required_fields": [ + "truth_source_path", + "truth_source_git_commit", + "skill_version", + "evidence_packet_count", + "artifact_gate_status", + "privacy_artifact_status", + "oracle_ready_summary" + ], + "reject_if": { + "truth_source_path_contains": [ + "/WorkBuddy/", + "/.workbuddy/" + ], + "artifact_gate_status": [ + "missing", + "unknown" + ], + "privacy_artifact_status": [ + "private_artifact_present", + "unknown" + ] + }, + "recommended_surface": { + "startup_log": true, + "health_endpoint": "/api/runtime-identity", + "admin_status_panel": true, + "ci_snapshot": true + }, + "claim_boundary": "startup_identity_gate_only_not_business_runtime" +} diff --git a/references/oracle/evidence_packet_index_2026_07_19.json b/references/oracle/evidence_packet_index_2026_07_19.json index 5b990aab..5e5a17d2 100644 --- a/references/oracle/evidence_packet_index_2026_07_19.json +++ b/references/oracle/evidence_packet_index_2026_07_19.json @@ -5,8 +5,8 @@ "production_tuning_allowed": false, "boundary": "Index of current governance packets only. Raw oracle artifacts remain in references/oracle/artifacts and are not all duplicated here.", "summary": { - "packet_count": 103, - "blocked_or_partial_count": 51, + "packet_count": 128, + "blocked_or_partial_count": 52, "human_review_required_count": 3 }, "packets": [ @@ -833,6 +833,206 @@ "claim_status": "ready_contract", "consumer_policy": "research_local_ui_contract_only", "claim_boundary": "Ports commercial birth-time journey behavior contracts only; no Supabase, credits, auth, or commercial code imported." + }, + { + "packet_id": "truth_source_runtime_identity", + "path": "references/oracle/truth_source_runtime_identity_2026_07_21.json", + "domain": "truth_source_governance", + "claim_status": "ready_contract", + "consumer_policy": "research_to_commercial_startup_contract", + "claim_boundary": "Pins the main research repo as the only truth source, exposes runtime identity, and quarantines old WorkBuddy fragments; no oracle truth upgrade." + }, + { + "packet_id": "commercial_startup_self_check_contract_2026_07_21", + "path": "references/oracle/commercial_startup_self_check_contract_2026_07_21.json", + "domain": "commercial_sync_governance", + "claim_status": "ready_contract", + "consumer_policy": "commercial_startup_gate_contract_only", + "claim_boundary": "Requires commercial runtime to expose truth source identity, artifact gate and privacy status; no business runtime code imported into research." + }, + { + "packet_id": "commercial_golden_oss_case_ci_contract_2026_07_21", + "path": "references/oracle/commercial_golden_oss_case_ci_contract_2026_07_21.json", + "domain": "commercial_sync_governance", + "claim_status": "ready_contract", + "consumer_policy": "commercial_ci_gate_contract_only", + "claim_boundary": "Requires commercial CI to replay the PyJHora/JHora Sphuta OSS observation and hash; observation-only, no truth upgrade." + }, + { + "packet_id": "whole_machine_jyotish_fragment_scan_2026_07_21", + "path": "references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json", + "domain": "fragment_governance", + "claim_status": "open_queue", + "consumer_policy": "research_only_no_direct_fragment_copy", + "claim_boundary": "Whole-machine Jyotish signal scan classifies main, WorkBuddy, temp and user-drop candidates; reviewable fragments are not truth source until privacy/license/invocation checks close." + }, + { + "packet_id": "source_runtime_closure_queue_2026_07_21", + "path": "references/oracle/source_runtime_closure_queue_2026_07_21.json", + "domain": "source_runtime_closure", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Prioritizes not-fully-invoked source assets such as jyotishganit and VedicAstro KP; queue only, no adapter or truth upgrade." + }, + { + "packet_id": "vedicastro_kp_tmp_env_identity_2026_07_21", + "path": "references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json", + "domain": "kp_precision_timing", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Pins isolated /tmp VedicAstro KP dependency identity; dependency readiness only, no oracle truth." + }, + { + "packet_id": "vedicastro_kp_house_cusp_raw_2026_07_21", + "path": "references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json", + "domain": "kp_precision_timing", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Archives VedicAstro KP house cusp star/sub/sub-sub raw for Steve Jobs public case; observation-only until public numeric worked-example replay." + }, + { + "packet_id": "jyotishganit_three_engine_closure_bridge_2026_07_21", + "path": "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Routes available jyotishganit D2/D4/D9/D10, Panchanga and BAV/SAV fields to closure queues; Shadbala remains explicit gap." + }, + { + "packet_id": "kp_public_worked_example_candidate_queue_2026_07_21", + "path": "references/oracle/kp_public_worked_example_candidate_queue_2026_07_21.json", + "domain": "kp_precision_timing", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Public KP sources were triaged as formula/runtime candidates; none yet provide stable full numeric cusp star/sub/sub-sub rows for oracle upgrade." + }, + { + "packet_id": "jyotishganit_field_closure_rows_2026_07_21", + "path": "references/oracle/jyotishganit_field_closure_rows_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Routes jyotishganit D2/D4/D9/D10, Panchanga and BAV/SAV selected raw fields into closure rows; Shadbala remains explicit gap." + }, + { + "packet_id": "three_engine_jyotishganit_bridge_applied_2026_07_21", + "path": "references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Applies jyotishganit field bridge to existing TEMCQ D2/D4/D9/D10/BAV/SAV tickets and marks Panchanga as new-ticket-needed; no truth upgrade." + }, + { + "packet_id": "three_engine_field_status_batch_2026_07_21", + "path": "references/oracle/three_engine_field_status_batch_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Classifies 18 jyotishganit-applied TEMCQ rows and creates a Panchanga ticket placeholder; status only, no numeric truth upgrade." + }, + { + "packet_id": "three_engine_d2_field_closure_packet_2026_07_21", + "path": "references/oracle/three_engine_d2_field_closure_packet_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "partial", + "consumer_policy": "research_observation_only", + "claim_boundary": "D2 rows show local/PyJHora/jyotishganit agreement while VedAstro endpoint semantics remain blocked; no global truth upgrade." + }, + { + "packet_id": "three_engine_d4_d9_d10_field_closure_packet_2026_07_21", + "path": "references/oracle/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "partial", + "consumer_policy": "research_observation_only", + "claim_boundary": "D4/D9/D10 Moon.sign rows show local/PyJHora/jyotishganit agreement while VedAstro endpoint semantics remain blocked; no global truth upgrade." + }, + { + "packet_id": "three_engine_bav_sav_field_closure_packet_2026_07_21", + "path": "references/oracle/three_engine_bav_sav_field_closure_packet_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "partial", + "consumer_policy": "research_observation_only", + "claim_boundary": "Classifies BAV/SAV rows into partial consensus or multi-engine variant; public worked table and method metadata still required." + }, + { + "packet_id": "panchanga_temcq_061_schema_packet_2026_07_21", + "path": "references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Creates TEMCQ-061 Panchanga schema mapping queue from jyotishganit raw; local/PyJHora/VedAstro normalized fields remain missing or unpinned." + }, + { + "packet_id": "panchanga_local_jyotishganit_comparison_2026_07_21", + "path": "references/oracle/panchanga_local_jyotishganit_comparison_2026_07_21.json", + "domain": "three_engine_parity", + "claim_status": "partial", + "consumer_policy": "research_observation_only", + "claim_boundary": "Compares local calc_panchanga against jyotishganit for five Panchanga labels; one Karana alias remains naming-only and no global truth upgrade is made." + }, + { + "packet_id": "workbuddy_round3_candidate_ledger_2026_07_21", + "path": "references/oracle/workbuddy_round3_candidate_ledger_2026_07_21.json", + "domain": "fragment_migration", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Triage ledger for stale WorkBuddy candidate fragments only; no runtime truth, no bulk-copy permission, and no commercial technique upgrade until each entry is separately reviewed." + }, + { + "packet_id": "workbuddy_round4_candidate_ledger_2026_07_21", + "path": "references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json", + "domain": "fragment_migration", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Round4 triage confirms round3 was non-exhaustive: 858 unindexed WorkBuddy filename-signal files were detected and 20 high-value candidates were classified; no truth upgrade or bulk-copy permission." + }, + { + "packet_id": "workbuddy_round4_formalization_registry_2026_07_21", + "path": "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json", + "domain": "fragment_migration", + "claim_status": "ready_contract", + "consumer_policy": "research_observation_only", + "claim_boundary": "Maps round4 WorkBuddy candidates into formal registry/test targets for event judgment, birth-time rectification, Muhurta and Tajika/Saham; no runtime import, truth upgrade or bulk-copy permission." + }, + { + "packet_id": "workbuddy_round4_usage_closure_queue_2026_07_21", + "path": "references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json", + "domain": "fragment_migration", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Tracks all round4 migrate_to_registry/test candidates: 9 formalized, 2 pending oracle closure, 1 pending invocation audit; no truth upgrade." + }, + { + "packet_id": "vedastro_divisional_degree_contract_probe_2026_07_21", + "path": "references/oracle/artifacts/vedastro_divisional_degree_contract_probe.json", + "domain": "vedastro_contract_probe", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Validates only VedAstro DivisionalLongitude degree transformation for a fixed scalar input; does not establish hosted chart sign, ayanamsa, node, timezone, or full D2/D4/D9/D10 parity." + }, + { + "packet_id": "workbuddy_round4_remaining_closure_packet_2026_07_21", + "path": "references/oracle/workbuddy_round4_remaining_closure_packet_2026_07_21.json", + "domain": "fragment_migration", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Classifies the last three round4 WorkBuddy candidates as privacy-scrubbed reference, Shadbala artifact parse-needed, and blank Tajika template; no truth upgrade." + }, + { + "packet_id": "pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21", + "path": "references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json", + "domain": "shadbala_oracle", + "claim_status": "observation_only", + "consumer_policy": "research_observation_only", + "claim_boundary": "Parses WorkBuddy/PyJHora Steve Jobs Shadbala stdout into 42 same-unit component rows; observation only, no formula arbitration or absolute parity upgrade." + }, + { + "packet_id": "kp_tajika_public_oracle_source_candidates_2026_07_21", + "path": "references/oracle/kp_tajika_public_oracle_source_candidates_2026_07_21.json", + "domain": "worked_example_collection", + "claim_status": "open_queue", + "consumer_policy": "research_observation_only", + "claim_boundary": "Records public KP and Tajika/Varshaphala candidate sources found during WorkBuddy closure; none is a complete numeric oracle yet." } ] } diff --git a/references/oracle/jyotishganit_field_closure_rows_2026_07_21.json b/references/oracle/jyotishganit_field_closure_rows_2026_07_21.json new file mode 100644 index 00000000..0d299bd1 --- /dev/null +++ b/references/oracle/jyotishganit_field_closure_rows_2026_07_21.json @@ -0,0 +1,61 @@ +{ + "scope": "jyotishganit_field_closure_rows", + "created_at": "2026-07-21", + "claim_status": "observation_only", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_probe": "scripts/jyotishganit_field_probe.py", + "source_raw_hash": "19fa9ea862b68c4cffb6756fa6cbf0466daf47a8b008b3fe8809e9fc6a1ed30c", + "source_selected_hash": "4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4", + "rows": [ + { + "field": "D2", + "source_path": "selected_raw.varga_sign_table.D2", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "planet_sign_table" + }, + { + "field": "D4", + "source_path": "selected_raw.varga_sign_table.D4", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "planet_sign_table" + }, + { + "field": "D9", + "source_path": "selected_raw.varga_sign_table.D9", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "planet_sign_table" + }, + { + "field": "D10", + "source_path": "selected_raw.varga_sign_table.D10", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "planet_sign_table" + }, + { + "field": "Panchanga", + "source_path": "selected_raw.panchanga", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "schema_and_named_fields" + }, + { + "field": "BAV", + "source_path": "selected_raw.ashtakavarga.bav", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "per_planet_bindus" + }, + { + "field": "SAV", + "source_path": "selected_raw.ashtakavarga.sav", + "closure_status": "ready_for_field_comparison", + "comparison_unit": "sarvashtakavarga_bindus" + } + ], + "explicit_gaps": [ + { + "field": "Shadbala", + "reason": "jyotishganit probe did not expose shadbala/strengths in selected raw" + } + ], + "boundary": "field_rows_only_no_formula_truth" +} diff --git a/references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json b/references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json new file mode 100644 index 00000000..60dd0ee7 --- /dev/null +++ b/references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json @@ -0,0 +1,31 @@ +{ + "scope": "jyotishganit_three_engine_closure_bridge", + "created_at": "2026-07-21", + "claim_status": "observation_only", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_probe": "scripts/jyotishganit_field_probe.py", + "source_raw_hash": "19fa9ea862b68c4cffb6756fa6cbf0466daf47a8b008b3fe8809e9fc6a1ed30c", + "source_selected_hash": "4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4", + "field_routes": { + "ready_for_field_comparison": [ + "D2", + "D4", + "D9", + "D10", + "Panchanga", + "BAV_SAV" + ], + "explicit_gaps": [ + "Shadbala" + ], + "comparison_policy": "route sign/table/schema fields into closure queue only; do not infer formula truth from matching signs" + }, + "next_packet_targets": [ + "three_engine_closure_rows_D2_D4_D9_D10", + "three_engine_closure_rows_panchanga", + "three_engine_closure_rows_bav_sav", + "shadbala_missing_field_gap" + ], + "boundary": "bridge_only_no_truth_upgrade" +} diff --git a/references/oracle/kp_public_worked_example_candidate_queue_2026_07_21.json b/references/oracle/kp_public_worked_example_candidate_queue_2026_07_21.json new file mode 100644 index 00000000..a07e58e0 --- /dev/null +++ b/references/oracle/kp_public_worked_example_candidate_queue_2026_07_21.json @@ -0,0 +1,64 @@ +{ + "scope": "kp_public_worked_example_candidate_queue", + "created_at": "2026-07-21", + "claim_status": "open_queue", + "numeric_oracle_ready_count": 0, + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "runtime_observation_packet": "references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json", + "candidates": [ + { + "id": "astrosage_kp_chapter_2", + "url": "https://kpastrology.astrosage.com/kp-learning-home/tutorial/chapter-2-fundamental-principles", + "candidate_type": "formula_and_text_worked_example", + "useful_fields": [ + "sign lord", + "star lord", + "sub lord", + "significator logic", + "ruling planets text examples" + ], + "has_numeric_cusp_table": false, + "upgrade_status": "reference_only_until_numeric_cusp_rows" + }, + { + "id": "astrosage_kp_sign_star_sub_table", + "url": "https://kpastrology.astrosage.com/kp-learning-home/tutorial/chapter-2-fundamental-principles", + "candidate_type": "reference_table", + "useful_fields": [ + "sign-star-sub division rules", + "KP star/sub conceptual table" + ], + "has_numeric_cusp_table": false, + "upgrade_status": "formula_reference_only" + }, + { + "id": "onlinejyotish_kp_horoscope", + "url": "https://www.onlinejyotish.com/free-astrology/kp-horoscope.aspx", + "candidate_type": "runtime_form_candidate", + "useful_fields": [ + "possible KP horoscope table", + "possible cusp/sub-lord output" + ], + "has_numeric_cusp_table": false, + "upgrade_status": "blocked_until_stable_public_input_output_packet" + }, + { + "id": "astrobix_kp_houses", + "url": "https://astrobix.com/astrosight/1291-houses-in-kp-system.html", + "candidate_type": "runtime_form_candidate", + "useful_fields": [ + "KP house/cusp explanation", + "possible public worked chart context" + ], + "has_numeric_cusp_table": false, + "upgrade_status": "reference_only_until_numeric_rows" + } + ], + "next_actions": [ + "Capture a stable public KP chart with full cusp degree, star lord, sub lord and sub-sub lord rows.", + "Normalize VedicAstro KP raw to the same 12-row table.", + "Only then create a numeric oracle packet; until then KP timing remains observation-only." + ], + "boundary": "public_source_candidate_queue_only_no_kp_numeric_oracle" +} diff --git a/references/oracle/kp_tajika_public_oracle_source_candidates_2026_07_21.json b/references/oracle/kp_tajika_public_oracle_source_candidates_2026_07_21.json new file mode 100644 index 00000000..d0504a97 --- /dev/null +++ b/references/oracle/kp_tajika_public_oracle_source_candidates_2026_07_21.json @@ -0,0 +1,75 @@ +{ + "scope": "kp_tajika_public_oracle_source_candidates", + "created_at": "2026-07-21", + "claim_status": "open_queue", + "truth_matrix_allowed": false, + "production_tuning_allowed": false, + "boundary": "Public sources were located for KP sub-lord material and Tajika/Varshaphala worked-example material, but none yet supplies a complete, extracted, settings-stable numeric oracle for the requested WorkBuddy closure items.", + "candidates": [ + { + "candidate_id": "kp_249_sub_lord_table_candidate", + "domain": "kp_exact_cusp", + "source_url": "https://astrology-videos.com/krishnamurti-astrology/249-subs-in-kp/", + "source_type": "public_reference_table", + "promotion_status": "candidate_needs_numeric_extraction", + "claim_upgrade": "none", + "usable_now": "Reference candidate for KP 249 sub-lord segmentation.", + "missing_for_oracle": [ + "worked birth/question example", + "exact cusp longitude", + "star lord / sub lord / sub-sub lord result table", + "ayanamsa and house system settings", + "independent local replay" + ] + }, + { + "candidate_id": "kp_cusp_sub_lord_theory_candidate", + "domain": "kp_exact_cusp", + "source_url": "https://kpastrologer.com/kp-system/sub-lord-theory-in-kp-astrology/", + "source_type": "public_theory_reference", + "promotion_status": "candidate_reference_only", + "claim_upgrade": "none", + "usable_now": "Explains KP sub-lord theory; not a numeric oracle.", + "missing_for_oracle": [ + "full numeric worked example", + "machine-readable cusp/star/sub/sub-sub table" + ] + }, + { + "candidate_id": "tajika_varshaphala_worked_example_pdf_candidate", + "domain": "tajika_varshaphala", + "source_url": "https://vedicastrologervaibhavvyas.com/DownloadsofVA/4.%20my%20article%20on%20varshaphala.pdf", + "source_type": "public_pdf_worked_example_candidate", + "promotion_status": "candidate_needs_numeric_extraction", + "claim_upgrade": "none", + "usable_now": "Candidate public Varshaphala worked-example source; requires extraction and independent replay.", + "missing_for_oracle": [ + "structured numeric extraction", + "source hash", + "settings normalization", + "field-level local replay", + "not Steve Jobs 1984" + ] + }, + { + "candidate_id": "steve_jobs_1984_tajika_template", + "domain": "tajika_varshaphala", + "source_url": "references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "source_type": "local_blank_template", + "promotion_status": "candidate_reference_only", + "claim_upgrade": "none", + "usable_now": "Template only; no external values captured.", + "missing_for_oracle": [ + "tool/source name", + "capture date", + "solar return datetime", + "varsha lagna degree", + "Muntha sign", + "year lord", + "Mudda Dasha first lord", + "Saham values", + "Tajika yoga values" + ] + } + ] +} diff --git a/references/oracle/panchanga_local_jyotishganit_comparison_2026_07_21.json b/references/oracle/panchanga_local_jyotishganit_comparison_2026_07_21.json new file mode 100644 index 00000000..c6c1e5df --- /dev/null +++ b/references/oracle/panchanga_local_jyotishganit_comparison_2026_07_21.json @@ -0,0 +1,88 @@ +{ + "scope": "panchanga_local_jyotishganit_comparison", + "ticket_id": "TEMCQ-061", + "created_at": "2026-07-21", + "claim_status": "partial", + "truth_matrix_allowed": false, + "production_tuning_allowed": false, + "algorithm_reuse_policy": "reuse_existing_local_muhurta_calc_panchanga_no_new_algorithm", + "source_local_method": "scripts/muhurta.py::calc_panchanga", + "source_local_input": { + "case": "Steve Jobs", + "source_artifact": "references/oracle/artifacts/local_steve_jobs_high_rigor_raw.json", + "sun_lon_reconstructed_from_sign_degree": 312.5175, + "moon_lon_reconstructed_from_sign_degree": 344.5165, + "weekday_convention": "0=Sun ... 6=Sat", + "weekday_used": 4, + "hour_from_sunrise_used": 6.0 + }, + "local_normalized_raw": { + "vaara": "Thursday", + "tithi": "Shukla Tritiya", + "nakshatra": "Uttara Bhadrapada", + "yoga": "Shubha", + "karana": "Garija" + }, + "jyotishganit_observed_raw": { + "@type": "Panchanga", + "karana": "Gara", + "nakshatra": "Uttara Bhadrapada", + "tithi": "Shukla Tritiya", + "vaara": "Thursday", + "yoga": "Shubha" + }, + "field_comparison": [ + { + "field": "vaara", + "local_value": "Thursday", + "jyotishganit_value": "Thursday", + "status": "within_tolerance", + "reason": "same weekday name" + }, + { + "field": "tithi", + "local_value": "Shukla Tritiya", + "jyotishganit_value": "Shukla Tritiya", + "status": "within_tolerance", + "reason": "same paksha+tithi label" + }, + { + "field": "nakshatra", + "local_value": "Uttara Bhadrapada", + "jyotishganit_value": "Uttara Bhadrapada", + "status": "within_tolerance", + "reason": "same nakshatra label" + }, + { + "field": "yoga", + "local_value": "Shubha", + "jyotishganit_value": "Shubha", + "status": "within_tolerance", + "reason": "same yoga label" + }, + { + "field": "karana", + "local_value": "Garija", + "jyotishganit_value": "Gara", + "status": "alias_match", + "alias_rule": "Gara == Garija", + "reason": "naming alias only; not treated as formula mismatch" + } + ], + "summary": { + "fields_total": 5, + "within_tolerance": 4, + "alias_match": 1, + "formula_mismatch": 0, + "unit_mismatch": 0, + "truth_upgrades": 0 + }, + "still_blocked": [ + "VedAstro shared Panchanga endpoint/version not pinned", + "PyJHora/JHora Panchanga normalized packet not archived for this five-field comparison", + "single-case agreement cannot establish global Panchanga oracle truth", + "sunrise-relative semantics and local civil-time convention still require explicit multi-case contract" + ], + "supersedes_schema_gap": "references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json", + "boundary": "local_jyotishganit_panchanga_field_observation_not_global_truth" +} diff --git a/references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json b/references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json new file mode 100644 index 00000000..1a34dc7e --- /dev/null +++ b/references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json @@ -0,0 +1,53 @@ +{ + "scope": "panchanga_temcq_061_schema_packet", + "created_at": "2026-07-21", + "ticket_id": "TEMCQ-061", + "claim_status": "open_queue", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_ticket_placeholder": "references/oracle/three_engine_field_status_batch_2026_07_21.json", + "source_jyotishganit_probe": "references/oracle/jyotishganit_field_probe_steve_jobs_2026_07_19.json", + "closure_status": "schema_mapping_required", + "summary": { + "normalized_fields_ready": 0, + "truth_upgrades": 0, + "observed_jyotishganit_field_count": 6 + }, + "jyotishganit_observed_raw": { + "@type": "Panchanga", + "karana": "Gara", + "nakshatra": "Uttara Bhadrapada", + "tithi": "Shukla Tritiya", + "vaara": "Thursday", + "yoga": "Shubha" + }, + "engine_field_status": { + "local": "archived_panchanga_field_missing", + "jyotishganit": "raw_available_not_normalized", + "VedAstro": "shared_panchanga_endpoint_not_pinned", + "PyJHora_JHora": "not_archived_as_normalized_panchanga" + }, + "required_schema_fields": [ + "vaara", + "tithi", + "nakshatra", + "yoga", + "karana" + ], + "required_contract": [ + "weekday convention", + "tithi naming and paksha convention", + "nakshatra spelling/diacritic alias table", + "yoga calculation convention", + "karana naming convention", + "sunrise-relative vs birth-moment rule" + ], + "next_actions": [ + "archive local normalized Panchanga for the same public case", + "locate or generate legal PyJHora/JHora normalized Panchanga raw", + "pin VedAstro Panchanga endpoint or mark not available", + "then compare exact named fields after alias normalization" + ], + "boundary": "panchanga_schema_mapping_only_no_numeric_truth", + "human_report": "docs/research/panchanga_temcq_061_schema_packet_2026_07_21.md" +} diff --git a/references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json b/references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json new file mode 100644 index 00000000..de6554b4 --- /dev/null +++ b/references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json @@ -0,0 +1,441 @@ +{ + "boundary": "Parsed PyJHora stdout into same-unit component observations only. This does not arbitrate formula variants or create absolute Shadbala parity.", + "claim_status": "observation_only", + "component_rows": [ + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 3.6182, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 217.09 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 2.3498, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 140.99 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 0.4135, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 24.81 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 0.0, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 0.0 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 1.0, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 60.0 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Sun", + "rupa": 0.029, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 1.74 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 4.1057, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 246.34 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 2.493, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 149.58 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 1.5913, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 95.48 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 0.0, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 0.0 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 0.8572, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 51.43 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Moon", + "rupa": 0.3343, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 20.06 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 3.3105, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 198.63 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 2.1322, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 127.93 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 1.2902, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 77.41 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 1.643, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 98.58 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 0.2857, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 17.14 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Mars", + "rupa": 0.2248, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 13.49 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": 2.7993, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 167.96 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": 2.0297, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 121.78 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": 0.2107, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 12.64 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": 0.763, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 45.78 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": 0.4285, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 25.71 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Mercury", + "rupa": -0.1772, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": -10.63 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 3.3633, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 201.8 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 3.3218, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 199.31 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 1.3433, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 80.6 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 1.2333, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 74.0 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 0.5715, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 34.29 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Jupiter", + "rupa": 0.1148, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 6.89 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": 2.5677, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 154.06 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": 1.8907, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 113.44 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": 1.1658, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 69.95 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": 0.518, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 31.08 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": 0.7143, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 42.86 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Venus", + "rupa": -0.0458, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": -2.75 + }, + { + "component": "sthana", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 3.6435, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 218.61 + }, + { + "component": "dig", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 2.2795, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 136.77 + }, + { + "component": "kala", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 0.327, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 19.62 + }, + { + "component": "chesta", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 0.606, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 36.36 + }, + { + "component": "naisargika", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 0.1428, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 8.57 + }, + { + "component": "drik", + "normalized_unit": "virupa", + "planet": "Saturn", + "rupa": 0.1582, + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_unit": "rupa", + "virupa": 9.49 + } + ], + "created_at": "2026-07-21", + "production_tuning_allowed": false, + "scope": "pyjhora_shadbala_stdout_component_packet", + "source_artifact": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "source_artifact_sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "source_raw_rows": { + "component_rows_present": "SHADBALA_COMPONENT_RUPA_JSON", + "shadbala_raw_virupa_row_count": 9 + }, + "summary": { + "component_count": 6, + "component_row_count": 42, + "planet_count": 7 + }, + "truth_matrix_allowed": false +} diff --git a/references/oracle/source_runtime_closure_queue_2026_07_21.json b/references/oracle/source_runtime_closure_queue_2026_07_21.json new file mode 100644 index 00000000..73146dc6 --- /dev/null +++ b/references/oracle/source_runtime_closure_queue_2026_07_21.json @@ -0,0 +1,70 @@ +{ + "scope": "source_runtime_closure_queue", + "created_at": "2026-07-21", + "claim_status": "open_queue", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_scan": "references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json", + "not_fully_closed_reference_layers": [ + "references/open_source_sources/jyotishganit", + "references/open_source_sources/VedicAstro", + "references/open_source_sources/jaimini-tropical", + "references/open_source_sources/rishi-ai-mcp", + "references/open_source_sources/vedic-astro-skills", + "references/open_source_sources/dashaflow" + ], + "rows": [ + { + "id": "jyotishganit_field_closure", + "source": "references/open_source_sources/jyotishganit", + "existing_probe": "scripts/jyotishganit_field_probe.py", + "existing_test": "tests/test_jyotishganit_and_vedicastro_probes.py", + "current_status": "probe_runs_observation_only", + "latest_observed_raw_hash": "19fa9ea862b68c4cffb6756fa6cbf0466daf47a8b008b3fe8809e9fc6a1ed30c", + "latest_observed_selected_hash": "4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4", + "coverage": { + "panchanga": true, + "D2": true, + "D4": true, + "D9": true, + "D10": true, + "BAV_SAV": true, + "Shadbala": false + }, + "next_closure_step": "attach field-level comparison rows to the three-engine closure queue; keep Shadbala missing as explicit gap" + }, + { + "id": "vedicastro_kp_house_cusp_closure", + "source": "references/open_source_sources/VedicAstro", + "existing_probe": "scripts/vedicastro_kp_house_cusp_probe.py", + "existing_test": "tests/test_vedicastro_kp_runtime_tmp_probe.py", + "current_status": "raw_ready_observation_only", + "next_closure_step": "compare these 12 cusp star/sub/sub-sub rows against public numeric KP worked examples before any event timing use", + "latest_raw_packet": "references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json", + "latest_env_identity": "references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json", + "latest_observed_raw_hash": "2e7a6b17eb2965a60846f625f6bd8bc03555216d6225983647bcbfa23d0e345b", + "coverage": { + "house_cusps": 12, + "rasi": true, + "nakshatra": true, + "rasi_lord": true, + "nakshatra_lord": true, + "sub_lord": true, + "sub_sub_lord": true + } + }, + { + "id": "rishi_ai_mcp_vedic_astro_skills_reference", + "source": "references/open_source_sources/rishi-ai-mcp + references/open_source_sources/vedic-astro-skills", + "current_status": "reference_only_prompt_or_product_flow", + "next_closure_step": "extract skill/process wording only after license/source review; never numeric oracle or formula truth" + }, + { + "id": "jaimini_tropical_dashaflow_reference", + "source": "references/open_source_sources/jaimini-tropical + references/open_source_sources/dashaflow", + "current_status": "reference_only_until_contract", + "next_closure_step": "pin license, version, input contract, raw hash and replay tests before any adapter or truth matrix use" + } + ], + "boundary": "queue_only_no_adapter_or_truth_upgrade" +} diff --git a/references/oracle/technique_promotion_audit_kp_gochara_muhurta_2026_07_19.json b/references/oracle/technique_promotion_audit_kp_gochara_muhurta_2026_07_19.json index 19f41750..60595216 100644 --- a/references/oracle/technique_promotion_audit_kp_gochara_muhurta_2026_07_19.json +++ b/references/oracle/technique_promotion_audit_kp_gochara_muhurta_2026_07_19.json @@ -3,14 +3,14 @@ "items": [ { "claim_boundary": "Panchanga is runtime-visible but still needs field-level external oracle examples for high-rigor claims.", - "current_call_status": "formally_called_in_api_and_web", + "current_call_status": "partial", "external_or_reference_artifacts": [ "references/open_source_sources/panchanga_api" ], "main_artifacts": [ "scripts/jyotish_api_server.py", - "jyotish-app/main.js", - "jyotish-app/index.html" + "frontend/src/app/page.tsx", + "jyotish-app/main.js (research static UI only, absent in commercial repo)" ], "next_action": "add panchanga claim/display contract and source/oracle packet for tithi/nakshatra/yoga/karana/rahu-kalam outputs", "reuse_decision": "do_not_duplicate_runtime", @@ -57,7 +57,7 @@ "production_tuning_allowed": false, "scope": "technique_promotion_audit_kp_gochara_muhurta", "summary": { - "formally_called_count": 1, + "formally_called_count": 0, "items_checked": 4, "reference_only_count": 3 }, diff --git a/references/oracle/three_engine_bav_sav_field_closure_packet_2026_07_21.json b/references/oracle/three_engine_bav_sav_field_closure_packet_2026_07_21.json new file mode 100644 index 00000000..805d09c7 --- /dev/null +++ b/references/oracle/three_engine_bav_sav_field_closure_packet_2026_07_21.json @@ -0,0 +1,615 @@ +{ + "scope": "three_engine_bav_sav_field_closure_packet", + "created_at": "2026-07-21", + "claim_status": "partial", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_arbitration": "references/oracle/three_engine_mismatch_arbitration_2026_07_19.json", + "source_queue": "references/oracle/three_engine_mismatch_closure_queue_2026_07_19.json", + "source_jyotishganit_bridge": "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json", + "summary": { + "rows_total": 8, + "local_pyjhora_jyotishganit_agree": 5, + "multi_engine_variant": 3, + "truth_upgrades": 0 + }, + "rows": [ + { + "ticket_id": "TEMCQ-011", + "section": "ashtakavarga_bav", + "field": "Sun", + "local_value": [ + 3, + 7, + 4, + 3, + 3, + 2, + 6, + 7, + 4, + 4, + 3, + 2 + ], + "pyjhora_jhora_value": [ + 3, + 7, + 4, + 3, + 3, + 2, + 6, + 7, + 4, + 4, + 3, + 2 + ], + "jyotishganit_value": [ + 3, + 7, + 4, + 3, + 3, + 2, + 6, + 7, + 4, + 4, + 3, + 2 + ], + "vedastro_value": [ + 3, + 7, + 3, + 2, + 3, + 3, + 6, + 7, + 4, + 3, + 4, + 3 + ], + "local_pyjhora_jyotishganit_agree": true, + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_variant_blocked", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-012", + "section": "ashtakavarga_bav", + "field": "Moon", + "local_value": [ + 4, + 4, + 4, + 3, + 6, + 5, + 3, + 3, + 4, + 5, + 3, + 5 + ], + "pyjhora_jhora_value": [ + 4, + 4, + 4, + 3, + 6, + 5, + 3, + 3, + 4, + 5, + 3, + 5 + ], + "jyotishganit_value": [ + 4, + 5, + 4, + 2, + 6, + 5, + 3, + 2, + 5, + 5, + 3, + 5 + ], + "vedastro_value": [ + 4, + 5, + 3, + 2, + 6, + 6, + 3, + 2, + 5, + 4, + 4, + 5 + ], + "local_pyjhora_jyotishganit_agree": false, + "differing_engines": [ + "VedAstro", + "jyotishganit" + ], + "closure_status": "multi_engine_variant_worked_example_required", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-013", + "section": "ashtakavarga_bav", + "field": "Mars", + "local_value": [ + 4, + 7, + 4, + 4, + 3, + 0, + 4, + 5, + 1, + 4, + 1, + 2 + ], + "pyjhora_jhora_value": [ + 4, + 7, + 4, + 4, + 3, + 0, + 4, + 5, + 1, + 4, + 1, + 2 + ], + "jyotishganit_value": [ + 4, + 7, + 4, + 4, + 3, + 0, + 4, + 5, + 1, + 4, + 1, + 2 + ], + "vedastro_value": [ + 4, + 7, + 3, + 4, + 2, + 1, + 4, + 5, + 2, + 3, + 2, + 2 + ], + "local_pyjhora_jyotishganit_agree": true, + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_variant_blocked", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-014", + "section": "ashtakavarga_bav", + "field": "Mercury", + "local_value": [ + 5, + 5, + 5, + 4, + 4, + 2, + 6, + 5, + 5, + 8, + 2, + 3 + ], + "pyjhora_jhora_value": [ + 5, + 5, + 5, + 4, + 4, + 2, + 6, + 5, + 5, + 8, + 2, + 3 + ], + "jyotishganit_value": [ + 5, + 5, + 5, + 4, + 4, + 2, + 6, + 5, + 5, + 8, + 2, + 3 + ], + "vedastro_value": [ + 5, + 5, + 4, + 5, + 3, + 2, + 7, + 4, + 6, + 8, + 2, + 3 + ], + "local_pyjhora_jyotishganit_agree": true, + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_variant_blocked", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-015", + "section": "ashtakavarga_bav", + "field": "Jupiter", + "local_value": [ + 7, + 5, + 3, + 3, + 4, + 7, + 4, + 5, + 4, + 6, + 5, + 3 + ], + "pyjhora_jhora_value": [ + 7, + 5, + 3, + 3, + 4, + 7, + 4, + 5, + 4, + 6, + 5, + 3 + ], + "jyotishganit_value": [ + 7, + 5, + 3, + 3, + 4, + 7, + 4, + 5, + 4, + 6, + 5, + 3 + ], + "vedastro_value": [ + 7, + 5, + 3, + 3, + 4, + 7, + 5, + 4, + 4, + 6, + 4, + 4 + ], + "local_pyjhora_jyotishganit_agree": true, + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_variant_blocked", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-016", + "section": "ashtakavarga_bav", + "field": "Venus", + "local_value": [ + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 5, + 5, + 6 + ], + "pyjhora_jhora_value": [ + 4, + 3, + 5, + 4, + 3, + 5, + 4, + 3, + 5, + 5, + 5, + 6 + ], + "jyotishganit_value": [ + 4, + 3, + 5, + 3, + 4, + 5, + 4, + 3, + 5, + 5, + 5, + 6 + ], + "vedastro_value": [ + 4, + 3, + 4, + 4, + 4, + 4, + 4, + 2, + 5, + 6, + 6, + 6 + ], + "local_pyjhora_jyotishganit_agree": false, + "differing_engines": [ + "VedAstro", + "jyotishganit" + ], + "closure_status": "multi_engine_variant_worked_example_required", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-017", + "section": "ashtakavarga_bav", + "field": "Saturn", + "local_value": [ + 1, + 5, + 3, + 0, + 6, + 3, + 4, + 5, + 3, + 3, + 3, + 3 + ], + "pyjhora_jhora_value": [ + 1, + 5, + 3, + 0, + 6, + 3, + 4, + 5, + 3, + 3, + 3, + 3 + ], + "jyotishganit_value": [ + 1, + 5, + 3, + 0, + 6, + 3, + 4, + 5, + 3, + 3, + 3, + 3 + ], + "vedastro_value": [ + 1, + 5, + 2, + 0, + 5, + 4, + 4, + 4, + 4, + 2, + 4, + 4 + ], + "local_pyjhora_jyotishganit_agree": true, + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_variant_blocked", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + }, + { + "ticket_id": "TEMCQ-018", + "section": "ashtakavarga_sav", + "field": "12_sign_scores", + "local_value": [ + 28, + 36, + 28, + 21, + 29, + 24, + 31, + 33, + 26, + 35, + 22, + 24 + ], + "pyjhora_jhora_value": [ + 28, + 36, + 28, + 21, + 29, + 24, + 31, + 33, + 26, + 35, + 22, + 24 + ], + "jyotishganit_value": [ + 28, + 37, + 28, + 19, + 30, + 24, + 31, + 32, + 27, + 35, + 22, + 24 + ], + "vedastro_value": [ + 24, + 28, + 37, + 28, + 19, + 30, + 24, + 31, + 32, + 27, + 35, + 22 + ], + "local_pyjhora_jyotishganit_agree": false, + "differing_engines": [ + "VedAstro", + "jyotishganit" + ], + "closure_status": "multi_engine_variant_worked_example_required", + "required_evidence": [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ], + "claim_boundary": "ashtakavarga_table_comparison_only_no_formula_truth" + } + ], + "boundary": "BAV/SAV table comparison only; public worked table and method metadata required before truth upgrade.", + "human_report": "docs/research/three_engine_bav_sav_field_closure_packet_2026_07_21.md" +} diff --git a/references/oracle/three_engine_d2_field_closure_packet_2026_07_21.json b/references/oracle/three_engine_d2_field_closure_packet_2026_07_21.json new file mode 100644 index 00000000..633f0d9a --- /dev/null +++ b/references/oracle/three_engine_d2_field_closure_packet_2026_07_21.json @@ -0,0 +1,132 @@ +{ + "scope": "three_engine_d2_field_closure_packet", + "created_at": "2026-07-21", + "claim_status": "partial", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_arbitration": "references/oracle/three_engine_mismatch_arbitration_2026_07_19.json", + "source_queue": "references/oracle/three_engine_mismatch_closure_queue_2026_07_19.json", + "source_jyotishganit_bridge": "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json", + "summary": { + "rows_total": 7, + "local_pyjhora_jyotishganit_agree": 7, + "vedastro_endpoint_semantics_blocked": 7, + "truth_upgrades": 0 + }, + "rows": [ + { + "ticket_id": "TEMCQ-001", + "section": "D2", + "field": "Sun.sign", + "local_value": "Leo", + "pyjhora_jhora_value": "Leo", + "jyotishganit_value": "Leo", + "vedastro_value": "Gemini", + "partial_consensus_value": "Leo", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-002", + "section": "D2", + "field": "Moon.sign", + "local_value": "Cancer", + "pyjhora_jhora_value": "Cancer", + "jyotishganit_value": "Cancer", + "vedastro_value": "Pisces", + "partial_consensus_value": "Cancer", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-003", + "section": "D2", + "field": "Mars.sign", + "local_value": "Leo", + "pyjhora_jhora_value": "Leo", + "jyotishganit_value": "Leo", + "vedastro_value": "Aries", + "partial_consensus_value": "Leo", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-004", + "section": "D2", + "field": "Mercury.sign", + "local_value": "Leo", + "pyjhora_jhora_value": "Leo", + "jyotishganit_value": "Leo", + "vedastro_value": "Virgo", + "partial_consensus_value": "Leo", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-005", + "section": "D2", + "field": "Jupiter.sign", + "local_value": "Cancer", + "pyjhora_jhora_value": "Cancer", + "jyotishganit_value": "Cancer", + "vedastro_value": "Aquarius", + "partial_consensus_value": "Cancer", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-006", + "section": "D2", + "field": "Venus.sign", + "local_value": "Cancer", + "pyjhora_jhora_value": "Cancer", + "jyotishganit_value": "Cancer", + "vedastro_value": "Leo", + "partial_consensus_value": "Cancer", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-007", + "section": "D2", + "field": "Saturn.sign", + "local_value": "Cancer", + "pyjhora_jhora_value": "Cancer", + "jyotishganit_value": "Cancer", + "vedastro_value": "Gemini", + "partial_consensus_value": "Cancer", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same D2 request", + "claim_boundary": "three_engine_consensus_not_global_truth" + } + ], + "boundary": "D2 partial consensus only; hosted VedAstro remains blocked, so no global truth or commercial tuning upgrade.", + "human_report": "docs/research/three_engine_d2_field_closure_packet_2026_07_21.md" +} diff --git a/references/oracle/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.json b/references/oracle/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.json new file mode 100644 index 00000000..4e7159d1 --- /dev/null +++ b/references/oracle/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.json @@ -0,0 +1,68 @@ +{ + "scope": "three_engine_d4_d9_d10_field_closure_packet", + "created_at": "2026-07-21", + "claim_status": "partial", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_arbitration": "references/oracle/three_engine_mismatch_arbitration_2026_07_19.json", + "source_queue": "references/oracle/three_engine_mismatch_closure_queue_2026_07_19.json", + "source_jyotishganit_bridge": "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json", + "summary": { + "rows_total": 3, + "local_pyjhora_jyotishganit_agree": 3, + "vedastro_endpoint_semantics_blocked": 3, + "truth_upgrades": 0 + }, + "rows": [ + { + "ticket_id": "TEMCQ-008", + "section": "D4", + "field": "Moon.sign", + "local_value": "Gemini", + "pyjhora_jhora_value": "Gemini", + "jyotishganit_value": "Gemini", + "vedastro_value": "Pisces", + "partial_consensus_value": "Gemini", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-009", + "section": "D9", + "field": "Moon.sign", + "local_value": "Scorpio", + "pyjhora_jhora_value": "Scorpio", + "jyotishganit_value": "Scorpio", + "vedastro_value": "Leo", + "partial_consensus_value": "Scorpio", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same request", + "claim_boundary": "three_engine_consensus_not_global_truth" + }, + { + "ticket_id": "TEMCQ-010", + "section": "D10", + "field": "Moon.sign", + "local_value": "Pisces", + "pyjhora_jhora_value": "Pisces", + "jyotishganit_value": "Pisces", + "vedastro_value": "Sagittarius", + "partial_consensus_value": "Pisces", + "differing_engines": [ + "VedAstro" + ], + "closure_status": "partial_consensus_vedastro_endpoint_blocked", + "remaining_evidence_needed": "VedAstro endpoint/method contract with ayanamsa, node mode, varga and timezone semantics, plus raw replay pinned to same request", + "claim_boundary": "three_engine_consensus_not_global_truth" + } + ], + "boundary": "D4/D9/D10 partial consensus only; hosted VedAstro remains blocked, so no global truth or commercial tuning upgrade.", + "human_report": "docs/research/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.md" +} diff --git a/references/oracle/three_engine_field_status_batch_2026_07_21.json b/references/oracle/three_engine_field_status_batch_2026_07_21.json new file mode 100644 index 00000000..e9ee01a4 --- /dev/null +++ b/references/oracle/three_engine_field_status_batch_2026_07_21.json @@ -0,0 +1,207 @@ +{ + "scope": "three_engine_field_status_batch", + "created_at": "2026-07-21", + "claim_status": "observation_only", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_applied_bridge": "references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json", + "panchanga_ticket": { + "ticket_id": "TEMCQ-061", + "section": "panchanga", + "field": "schema_and_named_fields", + "category": "schema_or_tradition_semantics", + "owner_track": "new_ticket_required", + "priority": "P1", + "closure_status": "open", + "required_evidence": "same-case local/jyotishganit/VedAstro panchanga schema mapping with weekday/tithi/nakshatra/yoga/karana calculation contract" + }, + "summary": { + "rows_total": 18, + "endpoint_semantics": 10, + "worked_example_required": 8, + "truth_upgrades": 0 + }, + "rows": [ + { + "ticket_id": "TEMCQ-001", + "section": "D2", + "field": "Sun.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-002", + "section": "D2", + "field": "Moon.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-003", + "section": "D2", + "field": "Mars.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-004", + "section": "D2", + "field": "Mercury.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-005", + "section": "D2", + "field": "Jupiter.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-006", + "section": "D2", + "field": "Venus.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-007", + "section": "D2", + "field": "Saturn.sign", + "source_field": "D2", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-008", + "section": "D4", + "field": "Moon.sign", + "source_field": "D4", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-009", + "section": "D9", + "field": "Moon.sign", + "source_field": "D9", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-010", + "section": "D10", + "field": "Moon.sign", + "source_field": "D10", + "owner_track": "endpoint_contract", + "status_after_bridge": "ready_for_endpoint_semantics_check", + "remaining_evidence_needed": "VedAstro endpoint/method semantics and same-unit local/jyotishganit raw comparison", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-011", + "section": "ashtakavarga_bav", + "field": "Sun", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-012", + "section": "ashtakavarga_bav", + "field": "Moon", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-013", + "section": "ashtakavarga_bav", + "field": "Mars", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-014", + "section": "ashtakavarga_bav", + "field": "Mercury", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-015", + "section": "ashtakavarga_bav", + "field": "Jupiter", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-016", + "section": "ashtakavarga_bav", + "field": "Venus", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-017", + "section": "ashtakavarga_bav", + "field": "Saturn", + "source_field": "BAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + }, + { + "ticket_id": "TEMCQ-018", + "section": "ashtakavarga_sav", + "field": "12_sign_scores", + "source_field": "SAV", + "owner_track": "worked_example", + "status_after_bridge": "ready_for_worked_example_comparison", + "remaining_evidence_needed": "public worked BAV/SAV table with contributor set and shodhana policy", + "claim_boundary": "status_classification_only_no_numeric_truth" + } + ], + "boundary": "status_batch_only_no_truth_upgrade" +} diff --git a/references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json b/references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json new file mode 100644 index 00000000..e49eb61d --- /dev/null +++ b/references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json @@ -0,0 +1,190 @@ +{ + "scope": "three_engine_jyotishganit_bridge_applied", + "created_at": "2026-07-21", + "claim_status": "observation_only", + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "source_bridge": "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json", + "source_queue": "references/oracle/three_engine_mismatch_closure_queue_2026_07_19.json", + "source_selected_hash": "4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4", + "summary": { + "existing_ticket_rows": 18, + "no_existing_ticket_rows": 1, + "truth_upgrades": 0 + }, + "rows": [ + { + "source_field": "D2", + "field": "Sun.sign", + "existing_ticket_id": "TEMCQ-001", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Moon.sign", + "existing_ticket_id": "TEMCQ-002", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Mars.sign", + "existing_ticket_id": "TEMCQ-003", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Mercury.sign", + "existing_ticket_id": "TEMCQ-004", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Jupiter.sign", + "existing_ticket_id": "TEMCQ-005", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Venus.sign", + "existing_ticket_id": "TEMCQ-006", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D2", + "field": "Saturn.sign", + "existing_ticket_id": "TEMCQ-007", + "existing_ticket_section": "D2", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D4", + "field": "Moon.sign", + "existing_ticket_id": "TEMCQ-008", + "existing_ticket_section": "D4", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D9", + "field": "Moon.sign", + "existing_ticket_id": "TEMCQ-009", + "existing_ticket_section": "D9", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "D10", + "field": "Moon.sign", + "existing_ticket_id": "TEMCQ-010", + "existing_ticket_section": "D10", + "owner_track": "endpoint_contract", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Sun", + "existing_ticket_id": "TEMCQ-011", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Moon", + "existing_ticket_id": "TEMCQ-012", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Mars", + "existing_ticket_id": "TEMCQ-013", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Mercury", + "existing_ticket_id": "TEMCQ-014", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Jupiter", + "existing_ticket_id": "TEMCQ-015", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Venus", + "existing_ticket_id": "TEMCQ-016", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "BAV", + "field": "Saturn", + "existing_ticket_id": "TEMCQ-017", + "existing_ticket_section": "ashtakavarga_bav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "SAV", + "field": "12_sign_scores", + "existing_ticket_id": "TEMCQ-018", + "existing_ticket_section": "ashtakavarga_sav", + "owner_track": "worked_example", + "closure_status": "ready_for_field_comparison", + "claim_boundary": "field_comparison_only_no_formula_truth" + }, + { + "source_field": "Panchanga", + "field": "Panchanga", + "existing_ticket_id": null, + "existing_ticket_section": null, + "owner_track": "new_ticket_required", + "closure_status": "no_existing_ticket_create_next", + "claim_boundary": "field_comparison_only_no_formula_truth" + } + ], + "boundary": "applied_bridge_only_no_truth_upgrade", + "human_report": "docs/research/three_engine_jyotishganit_bridge_applied_2026_07_21.md" +} diff --git a/references/oracle/truth_source_runtime_identity_2026_07_21.json b/references/oracle/truth_source_runtime_identity_2026_07_21.json new file mode 100644 index 00000000..51589391 --- /dev/null +++ b/references/oracle/truth_source_runtime_identity_2026_07_21.json @@ -0,0 +1,54 @@ +{ + "scope": "truth_source_runtime_identity", + "created_at": "2026-07-21", + "status": "active_contract_v1", + "truth_source": { + "path": "/Users/wuyongnaren/Documents/印度占星", + "role": "sole_main_research_truth_source", + "branch_at_capture": "main", + "git_commit": "737683edc976d28558d81737501943790da07b34", + "git_commit_semantics": "commit at packet capture time; later packet commits supersede this value through git history" + }, + "skill": { + "path": "SKILL.md", + "version": "6.9.14" + }, + "evidence_packets": { + "index_path": "references/oracle/evidence_packet_index_2026_07_19.json", + "packet_count": 106, + "blocked_or_partial_count": 51, + "human_review_required_count": 3 + }, + "oracle_summary": { + "production_tuning_allowed": false, + "truth_matrix_allowed": false, + "vedastro_hosted_identity": "blocked", + "timing_holdout": "blocked_until_independent_human_labels", + "sphuta_oss_probe": "tooling_observation_only", + "three_engine_parity": "open_queue" + }, + "runtime_contract": { + "research_web_panel_required": true, + "commercial_startup_self_check_required": true, + "commercial_ci_golden_case_required": "pyjhora_jhora_sphuta_probe", + "must_not_accept_legacy_workbuddy_as_truth_source": true + }, + "fragment_quarantine": { + "workbuddy_old_copies": { + "status": "quarantined", + "labels": [ + "not_for_truth_source", + "privacy_review_required", + "artifact_incomplete", + "historical_fragment_only" + ], + "paths": [ + "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing", + "/Users/wuyongnaren/.workbuddy/backups/jyotish-vedic-astrology-20260711-154109", + "/Users/wuyongnaren/.workbuddy/backups/jyotish-vedic-astrology-retired-20260711-154109" + ], + "boundary": "May be read as fragment candidates only after ledger review; never a runtime, oracle, commercial, or truth source." + } + }, + "claim_boundary": "identity_ready_governance_only_not_oracle_truth" +} diff --git a/references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json b/references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json new file mode 100644 index 00000000..4aec2c59 --- /dev/null +++ b/references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json @@ -0,0 +1,220 @@ +{ + "boundary": "KP house cusp star/sub/sub-sub raw from VedicAstro runtime. Observation-only until matched against a public numeric KP worked example.", + "claim_status": "observation_only", + "created_at": "2026-07-19", + "dependency_identity": { + "flatlib": "0.3.1.dev0", + "observed_pinned_flatlib_commit": "2618c348ce1ab2588548f935ff65f031630b4872", + "polars": "1.42.1", + "required_flatlib_source": "git+https://github.com/diliprk/flatlib.git@sidereal", + "timezonefinder": "8.2.5" + }, + "engine": "VedicAstro", + "production_tuning_allowed": false, + "raw": { + "houses": [ + { + "DegSize": 26.059, + "HouseNr": 1, + "LonDecDeg": 149.434, + "Nakshatra": "UttaraPhalgunī", + "NakshatraLord": "Sun", + "Object": "I", + "Rasi": "Leo", + "RasiLord": "Sun", + "SignLonDMS": "+29:26:02", + "SignLonDecDeg": 29.434, + "SubLord": "Rahu", + "SubSubLord": "Rahu" + }, + { + "DegSize": 30.141, + "HouseNr": 2, + "LonDecDeg": 175.493, + "Nakshatra": "Chitra", + "NakshatraLord": "Mars", + "Object": "II", + "Rasi": "Virgo", + "RasiLord": "Mercury", + "SignLonDMS": "+25:29:35", + "SignLonDecDeg": 25.493, + "SubLord": "Rahu", + "SubSubLord": "Venus" + }, + { + "DegSize": 32.894, + "HouseNr": 3, + "LonDecDeg": 205.634, + "Nakshatra": "Vishakha", + "NakshatraLord": "Jupiter", + "Object": "III", + "Rasi": "Libra", + "RasiLord": "Venus", + "SignLonDMS": "+25:38:01", + "SignLonDecDeg": 25.634, + "SubLord": "Mercury", + "SubSubLord": "Saturn" + }, + { + "DegSize": 33.066, + "HouseNr": 4, + "LonDecDeg": 238.527, + "Nakshatra": "Jyeshtha", + "NakshatraLord": "Mercury", + "Object": "IV", + "Rasi": "Scorpio", + "RasiLord": "Mars", + "SignLonDMS": "+28:31:38", + "SignLonDecDeg": 28.527, + "SubLord": "Saturn", + "SubSubLord": "Ketu" + }, + { + "DegSize": 30.713, + "HouseNr": 5, + "LonDecDeg": 271.594, + "Nakshatra": "UttaraAshadha", + "NakshatraLord": "Sun", + "Object": "V", + "Rasi": "Capricorn", + "RasiLord": "Saturn", + "SignLonDMS": "+01:35:37", + "SignLonDecDeg": 1.594, + "SubLord": "Jupiter", + "SubSubLord": "Saturn" + }, + { + "DegSize": 27.128, + "HouseNr": 6, + "LonDecDeg": 302.306, + "Nakshatra": "Dhanishta", + "NakshatraLord": "Mars", + "Object": "VI", + "Rasi": "Aquarius", + "RasiLord": "Saturn", + "SignLonDMS": "+02:18:22", + "SignLonDecDeg": 2.306, + "SubLord": "Ketu", + "SubSubLord": "Rahu" + }, + { + "DegSize": 26.059, + "HouseNr": 7, + "LonDecDeg": 329.434, + "Nakshatra": "PurvaBhādrapadā", + "NakshatraLord": "Jupiter", + "Object": "VII", + "Rasi": "Aquarius", + "RasiLord": "Saturn", + "SignLonDMS": "+29:26:02", + "SignLonDecDeg": 29.434, + "SubLord": "Sun", + "SubSubLord": "Venus" + }, + { + "DegSize": 30.141, + "HouseNr": 8, + "LonDecDeg": 355.493, + "Nakshatra": "Revati", + "NakshatraLord": "Mercury", + "Object": "VIII", + "Rasi": "Pisces", + "RasiLord": "Jupiter", + "SignLonDMS": "+25:29:35", + "SignLonDecDeg": 25.493, + "SubLord": "Rahu", + "SubSubLord": "Venus" + }, + { + "DegSize": 32.894, + "HouseNr": 9, + "LonDecDeg": 25.634, + "Nakshatra": "Bharani", + "NakshatraLord": "Venus", + "Object": "IX", + "Rasi": "Aries", + "RasiLord": "Mars", + "SignLonDMS": "+25:38:01", + "SignLonDecDeg": 25.634, + "SubLord": "Mercury", + "SubSubLord": "Saturn" + }, + { + "DegSize": 33.066, + "HouseNr": 10, + "LonDecDeg": 58.527, + "Nakshatra": "Mrigashīrsha", + "NakshatraLord": "Mars", + "Object": "X", + "Rasi": "Taurus", + "RasiLord": "Venus", + "SignLonDMS": "+28:31:38", + "SignLonDecDeg": 28.527, + "SubLord": "Saturn", + "SubSubLord": "Ketu" + }, + { + "DegSize": 30.713, + "HouseNr": 11, + "LonDecDeg": 91.594, + "Nakshatra": "Punarvasu", + "NakshatraLord": "Jupiter", + "Object": "XI", + "Rasi": "Cancer", + "RasiLord": "Moon", + "SignLonDMS": "+01:35:37", + "SignLonDecDeg": 1.594, + "SubLord": "Rahu", + "SubSubLord": "Rahu" + }, + { + "DegSize": 27.128, + "HouseNr": 12, + "LonDecDeg": 122.306, + "Nakshatra": "Maghā", + "NakshatraLord": "Ketu", + "Object": "XII", + "Rasi": "Leo", + "RasiLord": "Sun", + "SignLonDMS": "+02:18:22", + "SignLonDecDeg": 2.306, + "SubLord": "Venus", + "SubSubLord": "Saturn" + } + ], + "request": { + "ayanamsa": "Krishnamurti", + "day": 24, + "hour": 19, + "house_system": "Placidus", + "latitude": 37.3382, + "longitude": -122.0383, + "minute": 15, + "month": 2, + "second": 0, + "timezone": "America/Los_Angeles", + "year": 1955 + } + }, + "raw_hash": "2e7a6b17eb2965a60846f625f6bd8bc03555216d6225983647bcbfa23d0e345b", + "schema_fingerprint": { + "fields": [ + "Object", + "HouseNr", + "Rasi", + "LonDecDeg", + "SignLonDMS", + "SignLonDecDeg", + "DegSize", + "Nakshatra", + "RasiLord", + "NakshatraLord", + "SubLord", + "SubSubLord" + ], + "house_count": 12 + }, + "scope": "vedicastro_kp_house_cusp_probe", + "status": "complete", + "truth_matrix_allowed": false +} diff --git a/references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json b/references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json new file mode 100644 index 00000000..f5a8ba0a --- /dev/null +++ b/references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json @@ -0,0 +1,23 @@ +{ + "boundary": "dependency_preparation_only_no_kp_oracle_truth", + "claim_status": "runtime_dependency_ready", + "created_at": "2026-07-21", + "package_versions": { + "flatlib": "0.3.1.dev0", + "polars": "1.42.1", + "pyswisseph": "2.10.3.2", + "timezonefinder": "8.2.5" + }, + "production_tuning_allowed": false, + "project_dependency_mutation_allowed": false, + "required_packages": { + "flatlib": "git+https://github.com/diliprk/flatlib.git@sidereal#egg=flatlib", + "polars": "polars", + "pyswisseph": "pyswisseph", + "timezonefinder": "timezonefinder" + }, + "scope": "vedicastro_kp_tmp_env_preparer", + "target": "/tmp/vedicastro_flatlib_probe", + "target_tree_hash": "7a75855cd9f641a30a4d466d44a282571e3d797c39de0d975f5f6647a3e1bf74", + "truth_matrix_allowed": false +} diff --git a/references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json b/references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json new file mode 100644 index 00000000..5478b8dc --- /dev/null +++ b/references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json @@ -0,0 +1,2707 @@ +{ + "scope": "whole_machine_jyotish_fragment_scan_2026_07_21", + "created_at": "2026-07-21", + "scan_bases": [ + "/Users/wuyongnaren/Documents", + "/Users/wuyongnaren/WorkBuddy", + "/Users/wuyongnaren/.workbuddy", + "/Users/wuyongnaren/Downloads", + "/Users/wuyongnaren/Desktop", + "/private/tmp", + "/tmp", + "/Users/wuyongnaren/Projects" + ], + "summary": { + "files_with_signals": 2096, + "main_repo_signal_files": 564, + "external_signal_files": 1532, + "privacy_blocked_files": 983, + "reviewable_external_files": 742 + }, + "decision_policy": { + "main_repo": "check invocation coverage before new work", + "workbuddy_fragment": "reference only; never truth source", + "privacy_review_required": "forbidden until human privacy review", + "tmp_fragment": "must pin license/version/hash before reuse" + }, + "reviewable_external_candidates": [ + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-20/732642856-talk-https-github-com-732642856/work/talk-active/engines-repo/jyotish/jyotishganit-adapter.js", + "size": 7588, + "category": "external_candidate", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/10_个人知识管理/09_术数与玄学/紫微风水与印度占星的本土术数谱系.md", + "size": 3600, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/05_文件仓库索引/电子书资料库/分类-术数占星玄学.md", + "size": 23971, + "category": "external_candidate", + "signals": [ + "tajika", + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/05_文件仓库索引/电子书资料库/书目卡片/Yogini Dasha VPGOEL 0000 Yogini001.png 1.png.md", + "size": 1922, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/05_文件仓库索引/电子书资料库/书目卡片/Tajika占星术是印度占星术体系之一.md", + "size": 2185, + "category": "external_candidate", + "signals": [ + "tajika" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/05_文件仓库索引/电子书资料库/书目卡片/Predicting Through Shasti Hayani Dasha (V.P.Goel) (Z-Library.md", + "size": 1980, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/05_文件仓库索引/电子书资料库/书目卡片/Predicting through Jaiminis Chara Dasha An Original Research Hindu Astrology Series (K. N..md", + "size": 2364, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/03_研究_术数占星/一楠 · 印度占星完整解盘报告 v2.md", + "size": 1001, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/03_研究_术数占星/印度占星研究结论 v3.md", + "size": 5264, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/ObsidianVault/03_研究_术数占星/印度占星 Jyotish.md", + "size": 1988, + "category": "external_candidate", + "signals": [ + "prashna", + "tajika", + "saham", + "kp", + "dasha" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/verify-local-jyotish-reference-audit.js", + "size": 2388, + "category": "external_candidate", + "signals": [ + "oracle", + "benchmark", + "test" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/jyotish-prashna-bridge.js", + "size": 9568, + "category": "external_candidate", + "signals": [ + "prashna", + "kp", + "test" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/verify-jyotish-prashna-bridge.js", + "size": 5628, + "category": "external_candidate", + "signals": [ + "prashna", + "gulika", + "kp", + "registry", + "test" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/jyotish/jyotishganit-adapter.js", + "size": 7588, + "category": "external_candidate", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/docs/jyotish-gap-migration-plan.md", + "size": 3107, + "category": "external_candidate", + "signals": [ + "saham", + "dasha", + "benchmark", + "test" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/reports/local-jyotish-reference-audit.md", + "size": 2176, + "category": "external_candidate", + "signals": [ + "dasha", + "oracle", + "benchmark", + "test" + ], + "risk_labels": [], + "decision": "candidate_review_required" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/sahams-execution-guide.md", + "size": 1867, + "category": "workbuddy_fragment", + "signals": [ + "prashna", + "tajika", + "saham", + "sphuta", + "kp", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/chara-dasha-calibration-roadmap.md", + "size": 2690, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/dasha-transit-method.md", + "size": 6575, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/ashtakavarga-complete-system.md", + "size": 8651, + "category": "workbuddy_fragment", + "signals": [ + "ashtakavarga", + "varga" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/chara-dasha-v6910-test-report.md", + "size": 3119, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/kp-practical-event-timing.md", + "size": 303, + "category": "workbuddy_fragment", + "signals": [ + "kp" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/tajika-yoga-complete-guide.md", + "size": 11850, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/muhurta-complete-guide.md", + "size": 1348, + "category": "workbuddy_fragment", + "signals": [ + "muhurta", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/multi-dasha-convergence-protocol.md", + "size": 6189, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/bphs-ch48-narayana-dasha.md", + "size": 1085, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/vp-goel-jaimini-dasha-systems.md", + "size": 4955, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/bhrigu-pada-dasha-marriage-counting.md", + "size": 7474, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/relationship-astrology-guide.md", + "size": 16418, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "varga" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/jyotishganit_benchmark.md", + "size": 2333, + "category": "workbuddy_fragment", + "signals": [ + "ashtakavarga", + "varga", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/real_case_studies/印度占星修正版研究结论v3-高压基建后的反转兑现模型.md", + "size": 32938, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_historical_epoch_dasha_stdout_20260627.txt", + "size": 6188, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "size": 2980, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_extreme_latitude_kp_shadbala_stdout_20260627.txt", + "size": 2973, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "kp" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_marilyn_monroe_varshaphala_1962_lahiri_20260629.txt", + "size": 1190, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_historical_dst_london_varshaphala_1943_lahiri_20260629.txt", + "size": 1140, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_steve_jobs_dasha_stdout_20260627.txt", + "size": 5765, + "category": "workbuddy_fragment", + "signals": [ + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_synthetic_extreme_latitude_varshaphala_kp_20260629.txt", + "size": 1182, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "kp", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_einstein_varshaphala_1905_lahiri_partial_20260629.txt", + "size": 1030, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/jyotishganit/tests/test_astronomical.py", + "size": 538, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/jyotishganit/tests/test_ashtakavarga.py", + "size": 11682, + "category": "workbuddy_fragment", + "signals": [ + "ashtakavarga", + "kp", + "varga", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/VedicAstro/VedicAstroAPI.py", + "size": 5043, + "category": "workbuddy_fragment", + "signals": [ + "kp", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/VedicAstro/vedicastro/VedicAstro.py", + "size": 33217, + "category": "workbuddy_fragment", + "signals": [ + "kp" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/VedicAstro/vedicastro/horary_chart.py", + "size": 7325, + "category": "workbuddy_fragment", + "signals": [ + "kp" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/VedicAstro/test_suite/horary_functions_test.py", + "size": 3617, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/dashaflow/ashtakavarga.py", + "size": 4770, + "category": "workbuddy_fragment", + "signals": [ + "ashtakavarga", + "varga" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/vedic-astro-skills/claude-code/.claude/commands/vedic-love.md", + "size": 10118, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/open_source_sources/vedic-astro-skills/claude-code/.claude/commands/vedic-career.md", + "size": 13323, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_ashtakavarga_invariants.py", + "size": 3548, + "category": "workbuddy_fragment", + "signals": [ + "ashtakavarga", + "varga", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_oracle_closure_status.py", + "size": 2254, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_nakshatra.py", + "size": 10401, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_tajika_einstein_1905_fill_map.py", + "size": 1100, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_fast_path_checklist.py", + "size": 2038, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_external_technique_evidence.py", + "size": 18178, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "rectification", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_dasha_first_packet_operator_card.py", + "size": 1590, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_chara_dasha_dignity.py", + "size": 8430, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_muhurta.py", + "size": 18035, + "category": "workbuddy_fragment", + "signals": [ + "gulika", + "muhurta", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_pyjhora_oracle_artifact_manifest.py", + "size": 1592, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "tajika", + "saham", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_final_jhora_evidence_packet_acceptance.py", + "size": 5294, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_jyotishganit_adapter_diagnostics.py", + "size": 1216, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_sthana_targeted_audit.py", + "size": 851, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_dasha_oracle_evidence_validator.py", + "size": 3539, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_deep_varga_avastha.py", + "size": 1477, + "category": "workbuddy_fragment", + "signals": [ + "varga", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_runtime_mode_diagnostics.py", + "size": 3026, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_varga_vedastro_mode.py", + "size": 4640, + "category": "workbuddy_fragment", + "signals": [ + "varga", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_tajika_annual_oracle_queue.py", + "size": 6504, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_method_catalog_sync.py", + "size": 4206, + "category": "workbuddy_fragment", + "signals": [ + "registry", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_tajika_first_packet_operator_card.py", + "size": 2098, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_evidence_orchestrator.py", + "size": 10937, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_pyjhora_adapter_diagnostics.py", + "size": 1690, + "category": "workbuddy_fragment", + "signals": [ + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_chara_dasha_precision_v6910.py", + "size": 13446, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_narayana_dasha.py", + "size": 1357, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_adapter_candidate_guard.py", + "size": 1746, + "category": "workbuddy_fragment", + "signals": [ + "probe", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_varga_bphs.py", + "size": 5225, + "category": "workbuddy_fragment", + "signals": [ + "varga", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_sapta_layer_hotspots.py", + "size": 936, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "varga", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_d3_mapping_audit.py", + "size": 750, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_oracle_comparison.py", + "size": 1077, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_sapta_dignity_whitelist.py", + "size": 794, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_parity_matrix.py", + "size": 5001, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "prashna", + "tajika", + "dasha", + "varga", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_oracle_component_cluster_summary.py", + "size": 868, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_shadbala_dig_source_of_truth_audit.py", + "size": 758, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_ingestion_closure_pack.py", + "size": 859, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_vedastro_gateway.py", + "size": 3063, + "category": "workbuddy_fragment", + "signals": [ + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_dasha_oracle_closure_status.py", + "size": 3829, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_tajika_annual_closure_status.py", + "size": 4097, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_tajika_annual_benchmark_dashboard.py", + "size": 1983, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "oracle", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/tests/test_pyjhora_oracle_artifacts_presence.py", + "size": 1290, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/first_tajika_oracle_packet_assistant.md", + "size": 2590, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_einstein_1905_fill_map.md", + "size": 3139, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/public_jyotish_benchmark_dashboard.json", + "size": 2258, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_einstein_1905_copy_ready_checklist.md", + "size": 2871, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_einstein_1905_packet_paste_instructions.md", + "size": 1669, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/first_dasha_oracle_packet_assistant.md", + "size": 1210, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/shadbala_external_absolute_value_closure_status.md", + "size": 699, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "tajika", + "saham", + "dasha", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_einstein_1905_field_copy_template.md", + "size": 5627, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_einstein_1905_packet_paste_block.jsonc", + "size": 1280, + "category": "workbuddy_fragment", + "signals": [ + "tajika" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/public_jyotish_benchmark_dashboard.md", + "size": 1266, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "benchmark", + "registry" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_sahams_annual_benchmark_dashboard.json", + "size": 1393, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/jyotish_external_oracle_closure_master_dashboard.md", + "size": 967, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "tajika", + "saham", + "dasha", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/dasha_external_oracle_closure_status.json", + "size": 663, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/first_tajika_oracle_packet_assistant.json", + "size": 3275, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/dasha_external_oracle_closure_status.md", + "size": 661, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/shadbala_external_absolute_value_closure_status.json", + "size": 994, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "tajika", + "saham", + "dasha", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/first_dasha_oracle_packet_assistant.json", + "size": 1517, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/jyotish_external_oracle_closure_master_dashboard.json", + "size": 3916, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_sahams_annual_closure_status.md", + "size": 3120, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/tajika_sahams_annual_benchmark_dashboard.md", + "size": 1229, + "category": "workbuddy_fragment", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/benchmark/legacy-marriage-v6.1/印度占星实战案例综合验证报告-v6.1-2026-05-03.md", + "size": 8142, + "category": "workbuddy_fragment", + "signals": [ + "saham", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/shadbala_component_cap_all_routes_2026_06_28.md", + "size": 1445, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/whole_project_fragment_sweep_and_vedastro_ledger_link_2026_06_28.md", + "size": 1935, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "benchmark", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round25_shadbala_validator_phase2_acceptance_2026_06_25.md", + "size": 1325, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round26_shadbala_validator_phase2_tickets_2026_06_25.md", + "size": 2027, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round28_pyjhora_jhora_breadth_gap_matrix_2026_06_26.md", + "size": 1792, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "tajika", + "dasha", + "varga", + "benchmark" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/vedastro_required_high_frequency_radar_contract_2026_06_28.md", + "size": 4023, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round24_open_source_jyotish_landscape_2026_06_25.md", + "size": 2552, + "category": "workbuddy_fragment", + "signals": [ + "dasha", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round28_jaimini_kp_prashna_depth_plan_2026_06_26.md", + "size": 1129, + "category": "workbuddy_fragment", + "signals": [ + "prashna", + "tajika", + "muhurta", + "kp" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/raman_dasha_boundary_series_oracle_seed_2026_06_28.md", + "size": 1473, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "dasha", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/shadbala_component_confidence_cap_v1_2026_06_28.md", + "size": 1490, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "oracle" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round29_jaimini_kp_prashna_gap_matrix_2026_06_26.md", + "size": 1188, + "category": "workbuddy_fragment", + "signals": [ + "prashna", + "kp", + "dasha" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + }, + { + "path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/docs/research/antigravity_round20_shadbala_units_totals_design_2026_06_25.md", + "size": 1514, + "category": "workbuddy_fragment", + "signals": [ + "shadbala", + "oracle", + "test" + ], + "risk_labels": [ + "historical_fragment_only", + "not_for_truth_source" + ], + "decision": "reference_only_candidate_not_truth_source" + } + ], + "privacy_blocked_sample": [ + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-18/new-chat-4/work/starcanvas-active/apps/web/src/app/canvas/utils/characterAstrologyService.ts", + "size": 13673, + "category": "external_candidate", + "signals": [ + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-20/732642856-yinduzhanxing-https-github-com-732642856/work/audit_tmp/jyotish-engine-modules/scripts/special_lagnas.py", + "size": 12121, + "category": "external_candidate", + "signals": [ + "prashna" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-20/732642856-talk-https-github-com-732642856/work/talk-active/engines-repo/jyotish/jyotish-adapter.js", + "size": 10913, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-20/732642856-talk-https-github-com-732642856/work/talk-active/engines-repo/jyotish/vedic-calc-runner.py", + "size": 13523, + "category": "external_candidate", + "signals": [ + "prashna", + "tajika", + "gulika", + "kp", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-20/732642856-talk-https-github-com-732642856/work/talk-active/engines-repo/jyotish/jyotishganit-runner.py", + "size": 9754, + "category": "external_candidate", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/Codex/2026-06-21/starcanvas-https-github-com-732642856-starcanvas/work/starcanvas/apps/web/src/app/canvas/utils/characterAstrologyService.ts", + "size": 13673, + "category": "external_candidate", + "signals": [ + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/local-jyotish-reference-audit.js", + "size": 16997, + "category": "external_candidate", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "oracle", + "benchmark", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/jyotish/jyotish-adapter.js", + "size": 10913, + "category": "external_candidate", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/jyotish/vedic-calc-runner.py", + "size": 13523, + "category": "external_candidate", + "signals": [ + "prashna", + "tajika", + "gulika", + "kp", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/星轨talk/engines-repo/jyotish/jyotishganit-runner.py", + "size": 9754, + "category": "external_candidate", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "forbidden_until_privacy_review" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/indastro-case-studies.md", + "size": 26174, + "category": "main_repo", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/condition-dasha-complete.md", + "size": 5844, + "category": "main_repo", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/global-astrologer-reflections.md", + "size": 17184, + "category": "main_repo", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/dasha-calculation-tool.md", + "size": 11706, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/varga-system-quick-reference.md", + "size": 10468, + "category": "main_repo", + "signals": [ + "kp", + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/open-source-jyotish-scan-2026.md", + "size": 16821, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "prashna", + "tajika", + "gulika", + "muhurta", + "kp", + "dasha", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/varga-divisional-charts-quick-reference.md", + "size": 14961, + "category": "main_repo", + "signals": [ + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/global-astrologer-practical-methodology.md", + "size": 14244, + "category": "main_repo", + "signals": [ + "shadbala", + "kp", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/pancha-pakshi-nakshatra-systems.md", + "size": 11280, + "category": "main_repo", + "signals": [ + "muhurta", + "kp", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/yoga-and-dasha.md", + "size": 9968, + "category": "main_repo", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/analysis-natal-full-part3-Ashtakavarga.md", + "size": 681, + "category": "main_repo", + "signals": [ + "ashtakavarga", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/shasti-hayani-dasha-guide.md", + "size": 3734, + "category": "main_repo", + "signals": [ + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/vimshottari_dasha_guide.md", + "size": 18384, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/deep-varga-avastha-execution-guide.md", + "size": 2170, + "category": "main_repo", + "signals": [ + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/alternative-dasha-systems.md", + "size": 7628, + "category": "main_repo", + "signals": [ + "ashtakavarga", + "prashna", + "tajika", + "kp", + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/shadbala-complete-methodology.md", + "size": 10552, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "benchmark" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/saham_rules.json", + "size": 2065, + "category": "main_repo", + "signals": [ + "tajika", + "saham" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/ashwini-abhijit-ketu-nakshatra-freeze-guide.md", + "size": 8520, + "category": "main_repo", + "signals": [ + "shadbala", + "muhurta", + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/shadbala-interpretation-methodology.md", + "size": 7935, + "category": "main_repo", + "signals": [ + "shadbala", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/prashna-complete-guide.md", + "size": 17864, + "category": "main_repo", + "signals": [ + "prashna", + "tajika", + "saham", + "gulika", + "sphuta", + "kp", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/kp-astrology-complete-system.md", + "size": 10337, + "category": "main_repo", + "signals": [ + "prashna", + "kp", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/shodasavarga-complete-guide.md", + "size": 9252, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/cross_project_contract/commercial_astrology_e2e_context_capture_manifest_2026_07_19.json", + "size": 4030, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "rectification" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/cross_project_contract/commercial_astrology_e2e_acceptance_questions_2026_07_19.json", + "size": 4162, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "rectification" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/shadbala_component_closure_queue_v2_2026_07_19.json", + "size": 58478, + "category": "main_repo", + "signals": [ + "shadbala", + "varga", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/pyjhora_same_chart_parity_public_smoke_manifest.json", + "size": 755, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/vp_jain_shadbala_component_benchmark_2026_07_17.json", + "size": 11770, + "category": "main_repo", + "signals": [ + "shadbala", + "benchmark", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/xalen_public_case_batch_2026_07_17.json", + "size": 41935, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/kp_muhurta_shadbala_numeric_packet_queue_2026_07_19.json", + "size": 2693, + "category": "main_repo", + "signals": [ + "shadbala", + "muhurta", + "kp", + "oracle", + "probe" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/jyotishyamitra_pinned_adapter_probe_2026_07_18.json", + "size": 2520, + "category": "main_repo", + "signals": [ + "dasha", + "oracle", + "probe" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/xalen_multi_public_case_component_coverage_2026_07_19.json", + "size": 7587, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/jyotishyamitra_steve_jobs_probe_2026_07_18.json", + "size": 615069, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga", + "oracle", + "probe" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/dasha_shadbala_oracle_cases.json", + "size": 9600, + "category": "main_repo", + "signals": [ + "shadbala", + "kp", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/pyjhora_extended_parity_public_smoke_manifest.json", + "size": 777, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga", + "test" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/tajika_annual_oracle_cases.json", + "size": 21232, + "category": "main_repo", + "signals": [ + "tajika", + "saham", + "kp", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/authoritative_oss_jyotish_source_intake_2026_07_19.json", + "size": 4220, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "muhurta", + "kp", + "dasha", + "varga", + "oracle", + "benchmark", + "probe" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/prashna_sphuta_pyjhora_public_smoke.json", + "size": 1817, + "category": "main_repo", + "signals": [ + "prashna", + "gulika", + "sphuta", + "benchmark" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/xalen_multi_public_case_independent_ephemeris_2026_07_17.json", + "size": 42430, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pyjhora_steve_jobs_varshaphala_1984_lahiri_stdout_20260627.txt", + "size": 3455, + "category": "main_repo", + "signals": [ + "tajika", + "saham", + "dasha" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/xalen_multi_public_case_shared_input_2026_07_17.json", + "size": 41935, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/jyotishganit_steve_jobs_high_rigor_raw.json", + "size": 212469, + "category": "main_repo", + "signals": [ + "shadbala", + "ashtakavarga", + "dasha", + "varga" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_historical_epoch_lahiri_pyjhora_20260627.json", + "size": 1552, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_steve_jobs_dasha_lahiri_pyjhora_20260627.json", + "size": 1549, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_synthetic_north_china_shadbala_raman.json", + "size": 2595, + "category": "main_repo", + "signals": [ + "shadbala", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_steve_jobs_varshaphala_1984_lahiri_pyjhora_20260627.json", + "size": 3249, + "category": "main_repo", + "signals": [ + "tajika", + "saham", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_extreme_latitude_kp_pyjhora_20260627.json", + "size": 3054, + "category": "main_repo", + "signals": [ + "shadbala", + "kp", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_synthetic_north_china_shadbala_raman_pyjhora_20260627.json", + "size": 3220, + "category": "main_repo", + "signals": [ + "shadbala", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_steve_jobs_shadbala_lahiri_pyjhora_20260627.json", + "size": 3036, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/artifacts/pending_packets/external_template_steve_jobs_dasha_lahiri.json", + "size": 2570, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + }, + { + "path": "/Users/wuyongnaren/Documents/印度占星/references/oracle/evidence_packet_templates/jhora_steve_jobs_lahiri_first_packet.json", + "size": 2803, + "category": "main_repo", + "signals": [ + "shadbala", + "dasha", + "oracle" + ], + "risk_labels": [ + "privacy_review_required" + ], + "decision": "already_in_truth_source_check_invocation" + } + ], + "runtime_invocation_findings": { + "interpretation_source_runtime_coverage_status": "partial", + "proven_runtime_markers": [ + "dasha_timing_layer_used", + "varga_strength_layer_used", + "annual_special_layer_context", + "modifier_obstacle_layer_used" + ], + "not_fully_closed_reference_layers": [ + "references/open_source_sources/jyotishganit", + "references/open_source_sources/jaimini-tropical", + "references/open_source_sources/VedicAstro", + "references/open_source_sources/rishi-ai-mcp", + "references/open_source_sources/vedic-astro-skills", + "references/open_source_sources/dashaflow" + ], + "inventory_gate_status": "pass", + "boundary": "runtime invocation is proven for surfaced strict-workflow markers, not every source asset; remaining layers require adapter/API/UI/skill call proof before claiming capability." + }, + "priority_follow_up": [ + { + "id": "jyotishganit_field_closure", + "reason": "already one of the comparison engines; still not fully closed as source asset/runtime parity layer", + "action": "reuse existing adapters/probes; add field-level closure rows only, no truth upgrade" + }, + { + "id": "vedicastro_kp_runtime_surface", + "reason": "KP/cusp/sub-lord source exists but exact public oracle remains partial", + "action": "keep isolated runtime probe and source hash; add worked-example numeric packets when fields are public" + }, + { + "id": "jaimini_tropical_dashaflow_reference", + "reason": "reference source present but not truth source", + "action": "registry/reference only unless license, input contract, raw hash and replay tests are pinned" + }, + { + "id": "rishi_ai_mcp_vedic_astro_skills", + "reason": "prompt/product-flow source, not numeric oracle", + "action": "reuse as skill wording/process reference only; no formula copying or truth matrix" + }, + { + "id": "workbuddy_reference_docs", + "reason": "many docs are already mirrored or represented in main repo; old checkout remains artifact incomplete and privacy risky", + "action": "only migrate via tests/registry after file-by-file ledger review" + } + ] +} diff --git a/references/oracle/workbuddy_round3_candidate_ledger_2026_07_21.json b/references/oracle/workbuddy_round3_candidate_ledger_2026_07_21.json new file mode 100644 index 00000000..2f28e928 --- /dev/null +++ b/references/oracle/workbuddy_round3_candidate_ledger_2026_07_21.json @@ -0,0 +1,758 @@ +{ + "scope": "workbuddy_round3_candidate_ledger", + "created_at": "2026-07-21", + "source_root": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511", + "claim_status": "open_queue", + "status": "candidate_triage_not_runtime_truth", + "summary": { + "candidate_count": 30, + "migrate_to_registry": 14, + "migrate_to_test": 7, + "reference_only": 8, + "forbidden_private_or_obsolete": 1 + }, + "priority_order": [ + "KP", + "Muhurta", + "Prashna", + "Tajika/Saham", + "Shadbala/AV", + "birth-time rectification", + "event judgment" + ], + "entries": [ + { + "candidate_id": "references__kp-astrology-complete-system_md", + "domain": "kp_system", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/kp-astrology-complete-system.md", + "sha256": "9a44f277feaa91c3773e41e6d3d6d04be2538ed0a6457391b645c45443f05ed4", + "size_bytes": 10337, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# KP占星完整体系", + "## 一、什么是KP占星术?", + "## 二、249个Sub-Lord系统详解", + "### 核心原理", + "### 三层级描述系统", + "### 249的来源", + "## 三、Significator(指示星)分析", + "### 四层级指示星体系(从强到弱)" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__kp-practical-event-timing_md", + "domain": "kp_system", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/kp-practical-event-timing.md", + "sha256": "9525d289288da13b94aa16299ffa2de902f702d236f4433af291ebe29336586b", + "size_bytes": 303, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# KP实战案例与Sub-Lord事件时机判断指南" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__muhurta-complete-guide_md", + "domain": "muhurta", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/muhurta-complete-guide.md", + "sha256": "77caf0180f1d054b218433e5e57b9e0f2c8da17c9188cc56b4911737ffb3b3d0", + "size_bytes": 1348, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Muhurta Complete Guide", + "## 概述", + "## Panchanga 五要素", + "## 其他要素", + "## 活动适宜性判断", + "## 当前实现状态", + "## 局限", + "## 参考" + ], + "risk_flags": [ + "external_license_boundary" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__prashna-complete-guide_md", + "domain": "prashna", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/prashna-complete-guide.md", + "sha256": "6a1fe3f0686a137f181c43bceaa1c825e3767c40bd1f11859b2bfa5e125f38c0", + "size_bytes": 17864, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Prashna Shastra(问事占星/时卦)完整指南", + "## 目录", + "## 1. 核心原理", + "## 2. 星盘铸造与Kunda验证", + "### 2.1 铸造五要素", + "### 2.2 Kunda 验证法(Prasna Marga Ch.5)", + "## 3. 十大核心计算体系", + "### 3.1 Arudha Lagna(映像上升点)" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__tajika-yoga-complete-guide_md", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/tajika-yoga-complete-guide.md", + "sha256": "8054b0752da77d1e101551f982b5c7d8d8a5d9cffe449a3c171eff87332c8e58", + "size_bytes": 11850, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Tajika Yoga完整审计指南", + "## 一、Tajika Yoga体系概述", + "### 核心原理", + "### 十大Tajika Yoga分类", + "## 二、十大Tajika Yoga详解", + "### 2.1 Ithasala(结合Yoga)⭐⭐⭐⭐⭐", + "### 2.2 Easarapha(分离Yoga)", + "### 2.3 Nakta(间接联系Yoga)" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__sahams-execution-guide_md", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/sahams-execution-guide.md", + "sha256": "0848ee1bb946cd81a034f6fe1025d599b7ff78631f016297a9cf35bb08db90ce", + "size_bytes": 1867, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Sahams 执行指南", + "## 一、当前已具备的落点", + "## 二、当前常见使用场景", + "## 三、当前推荐阅读顺序", + "### 场景 A:年运", + "### 场景 B:婚恋", + "### 场景 C:Prashna", + "## 四、当前真实边界" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__ashtakavarga-complete-system_md", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/ashtakavarga-complete-system.md", + "sha256": "a37203762fbe4e2ecf358abb6104d0ee9ef07ca542d6d10ca6060133f657c574", + "size_bytes": 8651, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Ashtakavarga完整体系", + "## 一、核心概念", + "## 二、双层计算框架", + "### Bhinna Ashtakavarga (BAV) - 个人评分表", + "### Sarva Ashtakavarga (SAV) - 综合评分表", + "## 三、分数解读标准", + "### BAV评分", + "### SAV评分" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__shadbala-complete-methodology_md", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/shadbala-complete-methodology.md", + "sha256": "4bcf2ce9d860734278af63e82f89c055b268600bd10ad426eeca0d3fef344c11", + "size_bytes": 10552, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Shadbala计算方法论", + "## 一、Shadbala概述", + "### 综合评分体系", + "## 二、六种力量详解", + "### 2.1 Sthana Bala(位置力量)", + "### 2.2 Dig Bala(方向力量)", + "### 2.3 Kala Bala(时间力量)", + "### 2.4 Chesta Bala(运动力量)" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__shadbala-interpretation-methodology_md", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/shadbala-interpretation-methodology.md", + "sha256": "decea4454d2ab0600eee429b4a3bca94336d82666156f689f77c972543d82156", + "size_bytes": 7935, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Shadbala六重力量实战解读方法论", + "## 一、核心理念:六力量不是六个独立数字", + "## 二、六力量组合模式库", + "### 模式A:全面型(所有维度≥均值)", + "### 模式B:位置依赖型(Sthana极高,其他一般)", + "### 模式C:关系依赖型(Drik Bala极低)", + "### 模式D:时间敏感型(Kala Bala极低)", + "### 模式E:运动受限型(Chesta Bala极低)" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__birth-time-rectification-advanced_md", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/birth-time-rectification-advanced.md", + "sha256": "da25c979a94945d2990ad78b7ccc95bd0609e1458643382734fb920617182083", + "size_bytes": 13581, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# 出生时间矫正高级方法论", + "## 核心理念", + "## 出生时间矫正八大方法", + "### 方法1:运限与星曜过宫法(最常用)", + "### 方法2:D9 Navamsa上升判定法", + "### 方法3:D10 Dasamsa上升判定法", + "### 方法4:六亲关系验证法", + "### 方法5:外表和体质验证法" + ], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__birth-time-rectification-decision-tree_md", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/birth-time-rectification-decision-tree.md", + "sha256": "779cd9c53274084175fdc97669f16cbac6e1f41ad0fd6dc9140ca80546074fca", + "size_bytes": 5641, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# 生时校正分盘调用决策树", + "## 1. 总原则", + "## 1.1 产品化问询原则", + "## 2. 第一层:主引擎", + "### Dasha + dated events", + "## 3. 第二层:核心分盘", + "### D9", + "### D10" + ], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__event_judgment_skeleton_md", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/event_judgment_skeleton.md", + "sha256": "8c627aea6cb00a9c067f2bab0b2080cd229ba5ab498daf4dc728ec21cbd2755f", + "size_bytes": 4535, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Event Judgment Skeleton v1.0", + "## 1. Route", + "## 2. Evidence Ledger", + "## 3. Adjudication", + "### 矛盾优先级", + "## 4. Confidence Mapping", + "## 5. Output Contract", + "## 6. Hard Stops" + ], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__event_judgment_career_md", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/event_judgment_career.md", + "sha256": "16ad9e0e832b83f0610c4790ef558d807f44031d59d647da225adda80868d22b", + "size_bytes": 4334, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Career Event Adjudicator v1.0", + "## 1. Route Freeze", + "## 2. Mandatory Layers", + "## 3. Evidence Ledger Roles", + "## 4. Career Adjudication Order", + "### 4.1 Promise", + "### 4.2 Activation", + "### 4.3 Manifestation" + ], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__event_judgment_marriage_md", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/event_judgment_marriage.md", + "sha256": "32020ccc00fc25cc29146eea4e74c765c7643bd5c96b7d2efe6b7d0cadbc35c3", + "size_bytes": 5174, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Marriage Event Adjudicator v1.0", + "## 1. Route Freeze", + "## 2. Mandatory Layers", + "## 3. Evidence Ledger Roles", + "## 4. Marriage Adjudication Order", + "### 4.1 Promise", + "### 4.2 Activation", + "### 4.2.1 Non-Standard Proxy Activation" + ], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__event_judgment_wealth_md", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/event_judgment_wealth.md", + "sha256": "e690fa3d753a169dc50bb7773a687e4aa71d267cd82f536ea6096afe2fda9218", + "size_bytes": 5440, + "decision": "migrate_to_registry", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# Wealth Event Adjudicator v1.0", + "## 1. Route Freeze", + "## 2. Four Wealth Layers", + "### payout label 子类", + "## 3. Mandatory Layers", + "## 4. Evidence Ledger Roles", + "## 5. Wealth Adjudication Order", + "### 5.1 Promise" + ], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_kp_system_py", + "domain": "kp_system", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_kp_system.py", + "sha256": "ebcf970d7a9c1690fc4d0b8df95ed2540dad5360ce18e7a268c40fb477b53b9a", + "size_bytes": 3132, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_muhurta_py", + "domain": "muhurta", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_muhurta.py", + "sha256": "ba45f11f4bb93d7f4bdc78f5312d3a2c023f3e69788a8633281c1344ca2716ff", + "size_bytes": 18035, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# ── Tithi Tests ─────────────────────────────────────────────────────", + "# ── Nakshatra from Longitude Tests ──────────────────────────────────", + "# ── Yoga Tests ──────────────────────────────────────────────────────", + "# ── Karana Tests ────────────────────────────────────────────────────", + "# ── Vara Tests ──────────────────────────────────────────────────────", + "# ── Hora Tests ──────────────────────────────────────────────────────", + "# ── Abhijit Muhurta Tests ──────────────────────────────────────────", + "# ── Panchanga Complete Tests ────────────────────────────────────────" + ], + "risk_flags": [ + "stale_workbuddy_snapshot_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_shadbala_jhora_benchmark_py", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_shadbala_jhora_benchmark.py", + "sha256": "d87c76be28ff8751699e1b3d802f801cbe60f94daa9b4b14e405d28183542c2b", + "size_bytes": 9149, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [ + "# 确保可以导入 scripts 模块", + "# ============================================================================", + "# 标准测试数据集", + "# ============================================================================", + "# 来源:PyJHora test suite + PVR 教材", + "# ============================================================================", + "# 参考值:BPHS Shadbala 最低要求(Rupas)", + "# ============================================================================" + ], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_tajika_annual_oracle_queue_py", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_tajika_annual_oracle_queue.py", + "sha256": "5456ee550c94740e9325ac176e5fb40ee1b450cf1980e0bd9c3f2f734eaba0da", + "size_bytes": 6504, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_active_rectification_questions_py", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_active_rectification_questions.py", + "sha256": "c4f3da76b189923d0b8800820d46cf96fbec072d0bed04dfd330939a50c55a92", + "size_bytes": 1914, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_rectification_decision_tree_doc_py", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_rectification_decision_tree_doc.py", + "sha256": "5ae8f67a9a62a65a5008c5352ff5d9779ff43748bcf0c6b054dc44fe111dcdb1", + "size_bytes": 1186, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "tests__test_pyjhora_oracle_artifact_manifest_py", + "domain": "external_oracle_manifest", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/tests/test_pyjhora_oracle_artifact_manifest.py", + "sha256": "9e2c60bc434380f7c747d23e67e3ac168f7e78146e7449a462771197f82f589e", + "size_bytes": 1592, + "decision": "migrate_to_test", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__tajika_annual_oracle_cases_json", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/tajika_annual_oracle_cases.json", + "sha256": "b28c320134357f54e6a42248f6ce8d49dfd773475c55f39d09f57f48f51aa3db", + "size_bytes": 21232, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__dasha_shadbala_oracle_cases_json", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/dasha_shadbala_oracle_cases.json", + "sha256": "ff3f0c3eaaaedeae46c29b1fd03ae10f3d0d1114fcf53eabfe378ffac0e1da95", + "size_bytes": 9600, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__artifacts__pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627_txt", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "sha256": "65f652ac47d4a81ab43568bde8c5d7b9fac09d45f399564500c5af1a12db96c3", + "size_bytes": 2944, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__artifacts__pyjhora_steve_jobs_dasha_stdout_20260627_txt", + "domain": "external_oracle_manifest", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/artifacts/pyjhora_steve_jobs_dasha_stdout_20260627.txt", + "sha256": "dd64e80002b4c47b79ffee47cd949a0d9edba0403668fbc879b6e3f39ad868b9", + "size_bytes": 5765, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__artifacts__pyjhora_steve_jobs_varshaphala_1984_lahiri_stdout_20260627_txt", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/artifacts/pyjhora_steve_jobs_varshaphala_1984_lahiri_stdout_20260627.txt", + "sha256": "9cdfca16f756ad8fbd297032c49e5744639804cf473ece8fc7f71b2039d964b9", + "size_bytes": 3455, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__evidence_packet_templates__tajika_steve_jobs_1984_first_packet_json", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "sha256": "26a7231bd06f60bde2097352dc35793220c7c73f7ad32fb21fe6d35f12042d9e", + "size_bytes": 1783, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__evidence_packet_templates__jhora_steve_jobs_lahiri_first_packet_json", + "domain": "external_oracle_manifest", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/evidence_packet_templates/jhora_steve_jobs_lahiri_first_packet.json", + "sha256": "2595870ebade2ad1f66cb3d620784512adcc61fa9a1959417c078dc7f3640f0c", + "size_bytes": 2803, + "decision": "reference_only", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + }, + { + "candidate_id": "references__oracle__evidence_packet_templates__shadbala_synthetic_north_china_raman_first_packet_json", + "domain": "shadbala_av", + "source_path": "/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology.backup.20260711-233511/references/oracle/evidence_packet_templates/shadbala_synthetic_north_china_raman_first_packet.json", + "sha256": "a95b7563b4544e52e42fd66cd11e0599c95392cd96b8fd5fc56a0115ade40f7f", + "size_bytes": 2727, + "decision": "forbidden_private_or_obsolete", + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "observed_headings_or_markers": [], + "risk_flags": [ + "privacy_or_fixture_review_required", + "oracle_claim_must_not_upgrade_without_current_hash" + ], + "migration_boundary": "Do not bulk copy WorkBuddy text or runtime code; extract formula/rule/test contract only after privacy, license, and supersession review." + } + ], + "boundary": "Round3 ledger proves candidates are identified and classified; it does not migrate private content or upgrade any oracle truth." +} diff --git a/references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json b/references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json new file mode 100644 index 00000000..b1b41bfb --- /dev/null +++ b/references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json @@ -0,0 +1,230 @@ +{ + "scope": "WorkBuddy round4 candidate ledger after round3 was found non-exhaustive", + "created_at": "2026-07-21", + "source_roots": [ + "/Users/wuyongnaren/WorkBuddy", + "/Users/wuyongnaren/.workbuddy" + ], + "claim_status": "fragment_audit_only", + "status": "partial_non_exhaustive", + "summary": { + "round3_indexed_entries": 30, + "unindexed_filename_signal_total": 858, + "round4_entries": 20, + "decisions": { + "migrate_to_registry": 8, + "migrate_to_test": 4, + "reference_only": 6, + "forbidden_private_or_obsolete": 2 + } + }, + "allowed_decisions": [ + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete" + ], + "entries": [ + { + "candidate_id": "wb_round4_sahams_execution_guide", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/sahams-execution-guide.md", + "sha256": "0848ee1bb946cd81a034f6fe1025d599b7ff78631f016297a9cf35bb08db90ce", + "size_bytes": 1867, + "current_repo_same_name": "references/sahams-execution-guide.md", + "decision": "reference_only", + "reason": "Already present in the research repo by filename; use only as duplicate/supersession evidence unless runtime invocation is separately proven." + }, + { + "candidate_id": "wb_round4_varga_system_quick_reference", + "domain": "varga", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/varga-system-quick-reference.md", + "sha256": "3b9503b5c5e6651226ace1770b8021b7e33744737cdd150d66da2c1f476cc3a6", + "size_bytes": 10468, + "current_repo_same_name": "references/varga-system-quick-reference.md", + "decision": "reference_only", + "reason": "Already present in research references; next step is invocation audit, not content copying." + }, + { + "candidate_id": "wb_round4_varga_divisional_quick_reference", + "domain": "varga", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/varga-divisional-charts-quick-reference.md", + "sha256": "081814f256677cf12cc91a44d83e6ac7f587cb83fa8276d8815f517e8d93d5bf", + "size_bytes": 14961, + "current_repo_same_name": "references/varga-divisional-charts-quick-reference.md", + "decision": "reference_only", + "reason": "Already present in research references; keep as duplicate candidate until D1-D60 invocation audit closes." + }, + { + "candidate_id": "wb_round4_ashtakavarga_complete_system", + "domain": "ashtakavarga", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/ashtakavarga-complete-system.md", + "sha256": "a37203762fbe4e2ecf358abb6104d0ee9ef07ca542d6d10ca6060133f657c574", + "size_bytes": 8651, + "current_repo_same_name": "references/ashtakavarga-complete-system.md", + "decision": "reference_only", + "reason": "Already present; high-level reference cannot upgrade AV component truth without numeric oracle packets." + }, + { + "candidate_id": "wb_round4_dasha_shadbala_oracle_cases", + "domain": "shadbala_oracle", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/dasha_shadbala_oracle_cases.json", + "sha256": "0e08fa9d593f89ac5762d6b2952f93a17f5e831ad556aea365cce9dfa601794d", + "size_bytes": 21415, + "current_repo_same_name": "references/oracle/dasha_shadbala_oracle_cases.json", + "decision": "reference_only", + "reason": "Already present; use only through existing oracle validators." + }, + { + "candidate_id": "wb_round4_tajika_annual_oracle_cases", + "domain": "tajika_oracle", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/tajika_annual_oracle_cases.json", + "sha256": "b28c320134357f54e6a42248f6ce8d49dfd773475c55f39d09f57f48f51aa3db", + "size_bytes": 21232, + "current_repo_same_name": "references/oracle/tajika_annual_oracle_cases.json", + "decision": "reference_only", + "reason": "Already present; no new migration until numeric field validation is rerun." + }, + { + "candidate_id": "wb_round4_event_judgment_examples", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/event_judgment_examples.md", + "sha256": "2e4d8c630dc7faf299089fdf9a029448ed85b6ffadbd7cb4820409d3a5ff5447", + "size_bytes": 2525, + "current_repo_same_name": "references/event_judgment_examples.md", + "decision": "migrate_to_registry", + "reason": "Already present as reference, but not proven as a formal rule-family registry." + }, + { + "candidate_id": "wb_round4_birth_time_rectification_cases", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/birth-time-rectification-cases.md", + "sha256": "40a6e856672a275c91e09a4aa7ae776f37696fcdff31dc34f3b00c3766b62793", + "size_bytes": 11540, + "current_repo_same_name": "references/birth-time-rectification-cases.md", + "decision": "migrate_to_test", + "reason": "Useful for local UI journey and claim-boundary tests; do not use as truth labels without public provenance." + }, + { + "candidate_id": "wb_round4_birth_time_rectification_advanced", + "domain": "birth_time_rectification", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/birth-time-rectification-advanced.md", + "sha256": "da25c979a94945d2990ad78b7ccc95bd0609e1458643382734fb920617182083", + "size_bytes": 13581, + "current_repo_same_name": "references/birth-time-rectification-advanced.md", + "decision": "migrate_to_registry", + "reason": "Needs rule-family registry extraction for rectification techniques; no bulk copy." + }, + { + "candidate_id": "wb_round4_event_judgment_career", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/event_judgment_career.md", + "sha256": "16ad9e0e832b83f0610c4790ef558d807f44031d59d647da225adda80868d22b", + "size_bytes": 4334, + "current_repo_same_name": "references/event_judgment_career.md", + "decision": "migrate_to_registry", + "reason": "Candidate for event judgment rule-family registry, especially career domain." + }, + { + "candidate_id": "wb_round4_event_judgment_wealth", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/event_judgment_wealth.md", + "sha256": "e690fa3d753a169dc50bb7773a687e4aa71d267cd82f536ea6096afe2fda9218", + "size_bytes": 5440, + "current_repo_same_name": "references/event_judgment_wealth.md", + "decision": "migrate_to_registry", + "reason": "Candidate for event judgment rule-family registry, especially wealth domain." + }, + { + "candidate_id": "wb_round4_event_judgment_skeleton", + "domain": "event_judgment", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/event_judgment_skeleton.md", + "sha256": "8c627aea6cb00a9c067f2bab0b2080cd229ba5ab498daf4dc728ec21cbd2755f", + "size_bytes": 4535, + "current_repo_same_name": "references/event_judgment_skeleton.md", + "decision": "migrate_to_registry", + "reason": "Candidate skeleton for normalizing event-judgment registry fields." + }, + { + "candidate_id": "wb_round4_kp_practical_event_timing", + "domain": "kp_precision_timing", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/kp-practical-event-timing.md", + "sha256": "9525d289288da13b94aa16299ffa2de902f702d236f4433af291ebe29336586b", + "size_bytes": 303, + "current_repo_same_name": "references/kp-practical-event-timing.md", + "decision": "migrate_to_registry", + "reason": "Small KP timing note; useful only as a registry pointer, not as oracle." + }, + { + "candidate_id": "wb_round4_muhurta_complete_guide", + "domain": "muhurta", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/muhurta-complete-guide.md", + "sha256": "77caf0180f1d054b218433e5e57b9e0f2c8da17c9188cc56b4911737ffb3b3d0", + "size_bytes": 1348, + "current_repo_same_name": "references/muhurta-complete-guide.md", + "decision": "migrate_to_registry", + "reason": "Candidate for Muhurta factor registry; not enough for verdict scoring." + }, + { + "candidate_id": "wb_round4_tajika_yoga_complete_guide", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/tajika-yoga-complete-guide.md", + "sha256": "8054b0752da77d1e101551f982b5c7d8d8a5d9cffe449a3c171eff87332c8e58", + "size_bytes": 11850, + "current_repo_same_name": "references/tajika-yoga-complete-guide.md", + "decision": "migrate_to_registry", + "reason": "Candidate for Tajika yoga registry and annual chart claim-boundary mapping." + }, + { + "candidate_id": "wb_round4_saham_rules", + "domain": "tajika_saham", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/saham_rules.json", + "sha256": "374f5725212742f331199351b77121235c08b266798f0528f9e5f040558a0848", + "size_bytes": 2065, + "current_repo_same_name": "references/saham_rules.json", + "decision": "migrate_to_test", + "reason": "Use for formula schema tests after public numeric oracle packets are attached." + }, + { + "candidate_id": "wb_round4_user_1993_shadbala_pending_packet", + "domain": "shadbala_private", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pending_packets/external_template_user_1993_shadbala_lahiri_pyjhora_20260627.json", + "sha256": "841bd71a78fb4d0ca6b0eba800eaddc9cbee8bd9cbadd60cc4357bcc5b91e21a", + "size_bytes": 3275, + "current_repo_same_name": null, + "decision": "forbidden_private_or_obsolete", + "reason": "Private/person-specific pending packet; not for truth source, commercial claim, or public release." + }, + { + "candidate_id": "wb_round4_handan_shadbala_pending_packet", + "domain": "shadbala_private", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pending_packets/external_template_handan_shadbala_raman.json", + "sha256": "2163eeecb9aef353d39c42ae6b02f2bf45cf1df758c6399a8feaf1c1bb0896b0", + "size_bytes": 2563, + "current_repo_same_name": null, + "decision": "forbidden_private_or_obsolete", + "reason": "Private/source-insufficient pending packet; keep quarantined." + }, + { + "candidate_id": "wb_round4_pyjhora_steve_jobs_shadbala_stdout", + "domain": "shadbala_oracle", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "sha256": "2b8c5c76a4a369ff066b0160701c9f443d891832f6d2f811a983ca8326b002a7", + "size_bytes": 2980, + "current_repo_same_name": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "decision": "migrate_to_test", + "reason": "Already present; use only through reproducible parser/hash tests." + }, + { + "candidate_id": "wb_round4_tajika_steve_jobs_1984_first_packet", + "domain": "tajika_oracle", + "source_path": "/Users/wuyongnaren/WorkBuddy/2026-07-05-19-03-49/yinduzhanxing/references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "sha256": "26a7231bd06f60bde2097352dc35793220c7c73f7ad32fb21fe6d35f12042d9e", + "size_bytes": 1783, + "current_repo_same_name": "references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "decision": "migrate_to_test", + "reason": "Already present; eligible for numeric packet tests only after provenance fields are verified." + } + ], + "boundary": "This ledger proves round3 was non-exhaustive. It does not authorize copying WorkBuddy runtime code or upgrading any candidate to truth. Private/source-insufficient pending packets remain quarantined." +} diff --git a/references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json b/references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json new file mode 100644 index 00000000..bfed8bc3 --- /dev/null +++ b/references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json @@ -0,0 +1,93 @@ +{ + "scope": "workbuddy_round4_formalization_registry", + "created_at": "2026-07-21", + "claim_status": "ready_contract", + "source_ledger": "references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json", + "truth_matrix_allowed": false, + "production_tuning_allowed": false, + "boundary": "Converts prioritized WorkBuddy round4 candidates into formal research registry/test targets. This is not a runtime import, not a truth upgrade, and not permission to bulk-copy WorkBuddy code or prose.", + "formalized_domains": [ + { + "domain": "event_judgment", + "formalization_type": "registry", + "runtime_copy_allowed": false, + "claim_upgrade": "none", + "round4_candidate_ids": [ + "wb_round4_event_judgment_examples", + "wb_round4_event_judgment_career", + "wb_round4_event_judgment_wealth", + "wb_round4_event_judgment_skeleton" + ], + "formal_outputs": [ + "references/oracle/event_judgment_fragment_rule_family_registry_2026_07_21.json", + "tests/test_fragment_migration_registries.py" + ], + "next_required_closure": "Expand rule-family rows only where they map to existing chart evidence families; keep Vimshottari + Narayana and Functional Benefic/Malefic as mandatory gates." + }, + { + "domain": "birth_time_rectification", + "formalization_type": "registry_and_test_contract", + "runtime_copy_allowed": false, + "claim_upgrade": "none", + "round4_candidate_ids": [ + "wb_round4_birth_time_rectification_cases", + "wb_round4_birth_time_rectification_advanced" + ], + "formal_outputs": [ + "references/oracle/research_birth_time_journey_ui_contract_2026_07_21.json", + "tests/test_fragment_migration_registries.py", + "tests/test_active_rectification_api.py" + ], + "next_required_closure": "Use WorkBuddy cases only as UI journey/claim-boundary fixtures unless public, independently labeled birth-time cases are attached." + }, + { + "domain": "muhurta", + "formalization_type": "registry", + "runtime_copy_allowed": false, + "claim_upgrade": "none", + "round4_candidate_ids": [ + "wb_round4_muhurta_complete_guide" + ], + "formal_outputs": [ + "references/oracle/muhurta_full_system_gap_registry_2026_07_19.json", + "references/oracle/muhurta_factor_scoring_readiness_2026_07_19.json", + "references/oracle/muhurta_oss_factor_scoring_queue_2026_07_19.json", + "tests/test_muhurta_factor_scoring_readiness.py" + ], + "next_required_closure": "Tarabala, Chandrabala, Rahu Kalam and Abhijit may remain observation factors; do not emit择日 verdict until numeric worked examples and weighting policy are closed." + }, + { + "domain": "tajika_saham", + "formalization_type": "registry_and_test_contract", + "runtime_copy_allowed": false, + "claim_upgrade": "none", + "round4_candidate_ids": [ + "wb_round4_sahams_execution_guide", + "wb_round4_tajika_yoga_complete_guide", + "wb_round4_saham_rules", + "wb_round4_tajika_annual_oracle_cases", + "wb_round4_tajika_steve_jobs_1984_first_packet" + ], + "formal_outputs": [ + "references/oracle/prashna_tajika_saham_gulika_sphuta_oracle_packet_2026_07_19.json", + "references/saham_rules.json", + "references/oracle/tajika_annual_oracle_cases.json", + "tests/test_tajika.py", + "tests/test_tajika_annual_closure_status.py" + ], + "next_required_closure": "Saham formula schema can be tested; annual/Tajika truth remains partial or blocked until public numeric worked examples match local calculation field by field." + } + ], + "excluded_round4_candidates": [ + { + "candidate_id": "wb_round4_user_1993_shadbala_pending_packet", + "decision": "forbidden_private_or_obsolete", + "reason": "Private/person-specific pending packet." + }, + { + "candidate_id": "wb_round4_handan_shadbala_pending_packet", + "decision": "forbidden_private_or_obsolete", + "reason": "Private/source-insufficient pending packet." + } + ] +} diff --git a/references/oracle/workbuddy_round4_remaining_closure_packet_2026_07_21.json b/references/oracle/workbuddy_round4_remaining_closure_packet_2026_07_21.json new file mode 100644 index 00000000..f8a071cd --- /dev/null +++ b/references/oracle/workbuddy_round4_remaining_closure_packet_2026_07_21.json @@ -0,0 +1,35 @@ +{ + "scope": "workbuddy_round4_remaining_closure_packet", + "created_at": "2026-07-21", + "claim_status": "open_queue", + "source_queue": "references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json", + "truth_matrix_allowed": false, + "production_tuning_allowed": false, + "boundary": "The remaining WorkBuddy round4 candidates are explicitly classified. None is a complete oracle or runtime capability.", + "remaining_candidates": [ + { + "candidate_id": "wb_round4_kp_practical_event_timing", + "source_path": "references/kp-practical-event-timing.md", + "classification": "privacy_scrubbed_reference_only", + "claim_upgrade": "none", + "finding": "The retained file is a privacy-scrubbed notice, not a reusable KP worked example or executable contract.", + "next_action": "Use public KP worked examples plus exact cusp/star/sub/sub-sub API probe; do not derive timing truth from this WorkBuddy fragment." + }, + { + "candidate_id": "wb_round4_pyjhora_steve_jobs_shadbala_stdout", + "source_path": "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt", + "classification": "parsed_observation_packet_ready", + "claim_upgrade": "none", + "finding": "Parsed into 42 same-unit component rows in references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json; still observation-only because formula variants and absolute parity remain unresolved.", + "next_action": "Join parsed rows to shadbala_component_closure_queue_v2 and compare against local/jyotishganit/Xalen/VP Jain rows by component." + }, + { + "candidate_id": "wb_round4_tajika_steve_jobs_1984_first_packet", + "source_path": "references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "classification": "blank_template_not_oracle", + "claim_upgrade": "none", + "finding": "The packet is a blank external-capture template; required metadata and target numeric fields are empty/null.", + "next_action": "Fill from a citable external Varshaphala/Tajika numeric source before using as oracle evidence." + } + ] +} diff --git a/references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json b/references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json new file mode 100644 index 00000000..42031b85 --- /dev/null +++ b/references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json @@ -0,0 +1,105 @@ +{ + "scope": "workbuddy_round4_usage_closure_queue", + "created_at": "2026-07-21", + "claim_status": "open_queue", + "source_ledger": "references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json", + "formalization_registry": "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json", + "truth_matrix_allowed": false, + "production_tuning_allowed": false, + "boundary": "Tracks whether every WorkBuddy round4 migrate_to_registry/test candidate has been converted into a formal registry/test, or remains explicitly deferred. No row upgrades oracle truth.", + "summary": { + "round4_migrate_candidate_count": 12, + "formalized_count": 9, + "deferred_pending_oracle_count": 2, + "deferred_pending_invocation_audit_count": 1 + }, + "candidate_status": [ + { + "candidate_id": "wb_round4_event_judgment_examples", + "domain": "event_judgment", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/event_judgment_fragment_rule_family_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_birth_time_rectification_cases", + "domain": "birth_time_rectification", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_birth_time_rectification_advanced", + "domain": "birth_time_rectification", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_event_judgment_career", + "domain": "event_judgment", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/event_judgment_fragment_rule_family_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_event_judgment_wealth", + "domain": "event_judgment", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/event_judgment_fragment_rule_family_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_event_judgment_skeleton", + "domain": "event_judgment", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/event_judgment_fragment_rule_family_registry_2026_07_21.json" + }, + { + "candidate_id": "wb_round4_kp_practical_event_timing", + "domain": "kp_precision_timing", + "usage_status": "deferred_pending_invocation_audit", + "claim_upgrade": "none", + "formal_output": "references/oracle/kp_precision_timing_gap_registry_2026_07_19.json", + "next_action": "Attach exact KP cusp/star/sub/sub-sub API invocation and public worked-example oracle before using for event timing." + }, + { + "candidate_id": "wb_round4_muhurta_complete_guide", + "domain": "muhurta", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/muhurta_factor_scoring_readiness_2026_07_19.json" + }, + { + "candidate_id": "wb_round4_tajika_yoga_complete_guide", + "domain": "tajika_saham", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/oracle/prashna_tajika_saham_gulika_sphuta_oracle_packet_2026_07_19.json" + }, + { + "candidate_id": "wb_round4_saham_rules", + "domain": "tajika_saham", + "usage_status": "formalized", + "claim_upgrade": "none", + "formal_output": "references/saham_rules.json" + }, + { + "candidate_id": "wb_round4_pyjhora_steve_jobs_shadbala_stdout", + "domain": "shadbala_oracle", + "usage_status": "deferred_pending_oracle", + "claim_upgrade": "none", + "formal_output": "references/oracle/shadbala_component_closure_queue_v2_2026_07_19.json", + "next_action": "Parse stdout into component-level same-unit rows only if source, settings, and hash match the existing Shadbala closure queue." + }, + { + "candidate_id": "wb_round4_tajika_steve_jobs_1984_first_packet", + "domain": "tajika_oracle", + "usage_status": "deferred_pending_oracle", + "claim_upgrade": "none", + "formal_output": "references/oracle/tajika_annual_oracle_cases.json", + "next_action": "Verify provenance fields and numeric annual/Tajika values before upgrading from candidate packet to oracle packet." + } + ] +} diff --git a/scripts/capture_commercial_astrology_e2e_contexts.py b/scripts/capture_commercial_astrology_e2e_contexts.py index 68aba2c4..5b758a21 100644 --- a/scripts/capture_commercial_astrology_e2e_contexts.py +++ b/scripts/capture_commercial_astrology_e2e_contexts.py @@ -118,6 +118,55 @@ def _capture_body_for_real_case(case: dict[str, Any], prompt: str) -> dict[str, } +def _derive_consumer_context(result: dict[str, Any]) -> dict[str, Any]: + """Expose a stable, product-facing context view from the runtime packet. + + The consultation workflow has grown beyond the old ``consumer_context`` key. + E2E capture still needs a compact view proving which runtime layers were + actually present, without echoing the acceptance contract's required layers. + """ + + flat = json.dumps(result, ensure_ascii=False, sort_keys=True).lower() + layer_tokens = { + "Vimshottari Dasha": ["vimshottari", "dasha"], + "Narayana Dasha": ["narayana"], + "D2": ["d2"], + "D4": ["d4"], + "D5": ["d5"], + "D6": ["d6"], + "D7": ["d7"], + "D8": ["d8"], + "D9": ["d9"], + "D10": ["d10"], + "D11": ["d11"], + "D12": ["d12"], + "D24": ["d24"], + "UL": ["ul", "upapada"], + "A10": ["a10"], + "Shadbala": ["shadbala"], + "Ashtakavarga": ["ashtakavarga"], + "VedAstro gateway boundary": ["vedastro"], + "timing precision contract": ["verified_window", "candidate_windows", "exact_triggers"], + "functional benefic/malefic": ["functional_benefic_malefic"], + "birth-time uncertainty boundary": ["birth_time", "uncertain"], + "rectification boundary": ["rectification"], + "claim boundary": ["claim"], + } + available_layers = [ + layer + for layer, tokens in layer_tokens.items() + if all(token in flat for token in tokens) + ] + route = result.get("routing") or result.get("unified_orchestrator", {}).get("route") or {} + return { + "core_status": "ok" if result.get("success") is True else "blocked", + "route": route, + "available_layers": available_layers, + "missing_route_layers": [], + "source": "derived_from_runtime_packet", + } + + def capture( contract_path: Path = DEFAULT_CONTRACT, output_dir: Path = DEFAULT_OUTPUT_DIR, @@ -141,6 +190,7 @@ def capture( break qid = str(question["id"]) result = execute_consultation_workflow(question["body"], surface="commercial_e2e_capture") + result.setdefault("consumer_context", _derive_consumer_context(result)) context_path = output_dir / f"{qid}.json" context_path.write_text(json.dumps(result, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8") rows.append( diff --git a/scripts/claim_audit_runtime_gate_report.py b/scripts/claim_audit_runtime_gate_report.py new file mode 100644 index 00000000..ff41f146 --- /dev/null +++ b/scripts/claim_audit_runtime_gate_report.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +"""Evaluate a requested claim against every indexed evidence domain.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + +from scripts.claim_audit_runtime_gate import evaluate_claim + + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT_INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def build(index_path: Path, requested_claim: str) -> dict[str, Any]: + index = json.loads(index_path.read_text(encoding="utf-8")) + domains = sorted({row["domain"] for row in index["packets"]}) + rows = [evaluate_claim(index_path, domain, requested_claim) for domain in domains] + decisions = {name: sum(1 for row in rows if row["decision"] == name) for name in {"allow", "block", "degrade"}} + return { + "scope": "claim_audit_runtime_gate_report", + "created_at": "2026-07-19", + "requested_claim": requested_claim, + "source_index": str(index_path.relative_to(ROOT)) if index_path.is_relative_to(ROOT) else str(index_path), + "summary": { + "domain_count": len(rows), + "blocked_count": decisions["block"], + "degraded_count": decisions["degrade"], + "allowed_count": decisions["allow"], + "production_tuning_allowed_count": sum(1 for row in rows if row["production_tuning_allowed"] is True), + }, + "domains": rows, + "boundary": "Batch gate report only; every high claim still resolves through per-domain evidence packets.", + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--index", type=Path, default=DEFAULT_INDEX) + parser.add_argument("--claim", default="production_ready") + args = parser.parse_args() + print(json.dumps(build(args.index, args.claim), ensure_ascii=False, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/commercial_privacy_artifact_scan.py b/scripts/commercial_privacy_artifact_scan.py new file mode 100644 index 00000000..0423b3f1 --- /dev/null +++ b/scripts/commercial_privacy_artifact_scan.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Commercial privacy artifact gate. + +This is a thin commercial wrapper around the existing public release privacy +scanner. It exists so CI/product checks can call a business-named gate without +duplicating privacy logic. +""" +from __future__ import annotations + +import argparse +import json + +from public_release_privacy_scan import build_report + + +def commercial_report() -> dict[str, object]: + base = build_report() + return { + "scope": "commercial_privacy_artifact_scan", + "status": base["status"], + "finding_count": base["finding_count"], + "scanned_files": base["scanned_files"], + "privacy_boundary": "no_real_user_birth_data_private_cases_or_secret_values_in_public_artifacts", + "scanner_reuse": "scripts/public_release_privacy_scan.py", + "local_runtime_assets_not_committed": ["hip_main.dat", "hip_main.dat.download"], + "findings": base["findings"], + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--json", action="store_true", help="Emit JSON.") + args = parser.parse_args() + report = commercial_report() + if args.json: + print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)) + else: + print(f"{report['status']}: {report['finding_count']} findings") + return 0 if report["status"] == "pass" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/jyotishganit_field_probe.py b/scripts/jyotishganit_field_probe.py new file mode 100644 index 00000000..4a2f1344 --- /dev/null +++ b/scripts/jyotishganit_field_probe.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +"""Run a local jyotishganit same-case raw field probe. + +Observation-only: records raw/hash/schema for D2/D4/D9/D10, Panchanga, +BAV/SAV and Shadbala availability without promoting truth. +""" +from __future__ import annotations + +import argparse +import hashlib +import json +import sys +from datetime import datetime +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +JYOTISHGANIT_ROOT = ROOT / "references/open_source_sources/jyotishganit" +TARGET_VARGAS = ["d2", "d4", "d9", "d10"] + + +def stable_json(data: Any) -> str: + return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str) + + +def schema_fingerprint(data: Any) -> Any: + if isinstance(data, dict): + return {k: schema_fingerprint(v) for k, v in sorted(data.items())} + if isinstance(data, list): + if not data: + return [] + return [schema_fingerprint(data[0])] + return type(data).__name__ + + +def sign_table(chart: dict[str, Any]) -> dict[str, Any]: + out: dict[str, Any] = {} + for code in TARGET_VARGAS: + section = chart.get("divisionalCharts", {}).get(code) + if not isinstance(section, dict): + out[code.upper()] = {"status": "missing"} + continue + rows = [] + for house in section.get("houses", []): + for occ in house.get("occupants", []): + rows.append( + { + "planet": occ.get("celestialBody"), + "sign": occ.get("sign"), + "d1HousePlacement": occ.get("d1HousePlacement"), + } + ) + out[code.upper()] = { + "status": "present", + "ascendant_sign": section.get("ascendant", {}).get("sign"), + "planet_signs": sorted(rows, key=lambda r: str(r.get("planet"))), + } + return out + + +def build_probe(args: argparse.Namespace) -> dict[str, Any]: + sys.path.insert(0, str(JYOTISHGANIT_ROOT)) + from jyotishganit.main import calculate_birth_chart # type: ignore + + dt = datetime.fromisoformat(args.datetime) + chart = calculate_birth_chart(dt, args.latitude, args.longitude, args.timezone, args.location, args.name) + raw = chart.to_dict() + selected = { + "panchanga": raw.get("panchanga"), + "varga_sign_table": sign_table(raw), + "ashtakavarga": raw.get("ashtakavarga"), + "shadbala": raw.get("shadbala"), + "strengths": raw.get("strengths"), + } + payload = { + "scope": "jyotishganit_field_probe", + "created_at": "2026-07-19", + "status": "complete", + "claim_status": "observation_only", + "production_tuning_allowed": False, + "truth_matrix_allowed": False, + "engine": { + "name": "jyotishganit", + "local_path": str(JYOTISHGANIT_ROOT.relative_to(ROOT)), + }, + "request": { + "name": args.name, + "datetime": args.datetime, + "latitude": args.latitude, + "longitude": args.longitude, + "timezone": args.timezone, + "location": args.location, + }, + "coverage": { + "panchanga": raw.get("panchanga") is not None, + "D2": selected["varga_sign_table"]["D2"]["status"] == "present", + "D4": selected["varga_sign_table"]["D4"]["status"] == "present", + "D9": selected["varga_sign_table"]["D9"]["status"] == "present", + "D10": selected["varga_sign_table"]["D10"]["status"] == "present", + "BAV_SAV": isinstance(raw.get("ashtakavarga"), dict) + and "sav" in raw.get("ashtakavarga", {}), + "Shadbala": raw.get("shadbala") is not None or raw.get("strengths") is not None, + }, + "raw_hash": hashlib.sha256(stable_json(raw).encode("utf-8")).hexdigest(), + "selected_hash": hashlib.sha256(stable_json(selected).encode("utf-8")).hexdigest(), + "schema_fingerprint": schema_fingerprint(selected), + "selected_raw": selected, + "boundary": "Raw/hash observation only. Missing Shadbala field or matching signs do not prove formula truth or production timing readiness.", + } + return payload + + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("--datetime", default="1955-02-24T19:15:00") + ap.add_argument("--latitude", type=float, default=37.3382) + ap.add_argument("--longitude", type=float, default=-122.0383) + ap.add_argument("--timezone", type=float, default=-8.0) + ap.add_argument("--location", default="San Francisco, CA") + ap.add_argument("--name", default="Steve Jobs public") + ap.add_argument("--output") + args = ap.parse_args() + payload = build_probe(args) + text = json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + if args.output: + Path(args.output).write_text(text + "\n", encoding="utf-8") + print(text) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/jyotishganit_mismatch_attribution_queue.py b/scripts/jyotishganit_mismatch_attribution_queue.py new file mode 100644 index 00000000..5bf5fbe6 --- /dev/null +++ b/scripts/jyotishganit_mismatch_attribution_queue.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""Classify local vs jyotishganit comparison mismatches without resolving truth.""" +from __future__ import annotations + +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT = ROOT / "references/oracle/jyotishganit_vs_local_field_comparison_steve_jobs_2026_07_19.json" + + +def classify(row: dict) -> dict: + section = row["section"] + body = row["body"] + reason = "needs_formula_variant_review" + owner = "varga_formula_attribution" + if section == "D4": + reason = "schema_alias_or_formula_variant" + owner = "D4_Turyamsa_Chaturthamsa_alias_and_formula" + if section == "D10" and body in {"Rahu", "Ketu"}: + reason = "node_mode_or_shadow_planet_handling" + owner = "node_mode_mapping" + return { + **row, + "attribution_status": "queued", + "probable_reason": reason, + "next_evidence_owner": owner, + "claim_boundary": "Do not tune local formula to jyotishganit until source formula, ayanamsa, node mode, and schema aliases are pinned.", + } + + +def build(path: Path = DEFAULT) -> dict: + data = json.loads(path.read_text(encoding="utf-8")) + mismatches = [classify(r) for r in data["rows"] if r["status"] == "mismatch"] + return { + "scope": "jyotishganit_mismatch_attribution_queue", + "created_at": "2026-07-19", + "status": "queue_ready", + "claim_status": "partial", + "production_tuning_allowed": False, + "truth_matrix_allowed": False, + "source_comparison": str(path.relative_to(ROOT)), + "summary": { + "mismatch_count": len(mismatches), + "by_reason": { + reason: sum(1 for r in mismatches if r["probable_reason"] == reason) + for reason in sorted({r["probable_reason"] for r in mismatches}) + }, + }, + "rows": mismatches, + "boundary": "This queue classifies mismatch work; it does not settle formula truth.", + } + + +def main() -> int: + print(json.dumps(build(), ensure_ascii=False, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/parse_pyjhora_shadbala_stdout.py b/scripts/parse_pyjhora_shadbala_stdout.py new file mode 100644 index 00000000..b1d65cc0 --- /dev/null +++ b/scripts/parse_pyjhora_shadbala_stdout.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +"""Parse PyJHora Shadbala stdout into same-unit component rows.""" +from __future__ import annotations + +import ast +import hashlib +import json +import re +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +SOURCE = ROOT / "references/oracle/artifacts/pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt" +OUTPUT = ROOT / "references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json" +PLANETS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"] +COMPONENTS = ["sthana", "dig", "kala", "chesta", "naisargika", "drik"] + + +def _sha256(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def _extract_component_json(text: str) -> dict[str, dict[str, float]]: + prefix = "SHADBALA_COMPONENT_RUPA_JSON " + line = next((row[len(prefix) :] for row in text.splitlines() if row.startswith(prefix)), None) + if line is None: + raise ValueError("SHADBALA_COMPONENT_RUPA_JSON line missing") + raw = json.loads(line) + return { + planet: {key: float(value) for key, value in values.items()} + for planet, values in raw.items() + } + + +def _extract_raw_virupa(text: str) -> list[list[float]]: + prefix = "SHADBALA_RAW_VIRUPA " + line = next((row[len(prefix) :] for row in text.splitlines() if row.startswith(prefix)), None) + if line is None: + raise ValueError("SHADBALA_RAW_VIRUPA line missing") + return ast.literal_eval(line) + + +def build() -> dict[str, Any]: + text = SOURCE.read_text(encoding="utf-8") + source_hash = _sha256(SOURCE) + component_rupa = _extract_component_json(text) + raw_virupa = _extract_raw_virupa(text) + rows: list[dict[str, Any]] = [] + for planet in PLANETS: + values = component_rupa[planet] + for component in COMPONENTS: + rupa = round(values[component], 4) + rows.append( + { + "planet": planet, + "component": component, + "rupa": rupa, + "virupa": round(rupa * 60, 2), + "source_unit": "rupa", + "normalized_unit": "virupa", + "source_artifact": str(SOURCE.relative_to(ROOT)), + "source_artifact_sha256": source_hash, + } + ) + return { + "scope": "pyjhora_shadbala_stdout_component_packet", + "created_at": "2026-07-21", + "claim_status": "observation_only", + "truth_matrix_allowed": False, + "production_tuning_allowed": False, + "source_artifact": str(SOURCE.relative_to(ROOT)), + "source_artifact_sha256": source_hash, + "source_raw_rows": { + "shadbala_raw_virupa_row_count": len(raw_virupa), + "component_rows_present": "SHADBALA_COMPONENT_RUPA_JSON", + }, + "summary": { + "planet_count": len(PLANETS), + "component_count": len(COMPONENTS), + "component_row_count": len(rows), + }, + "component_rows": rows, + "boundary": "Parsed PyJHora stdout into same-unit component observations only. This does not arbitrate formula variants or create absolute Shadbala parity.", + } + + +def main() -> int: + packet = build() + OUTPUT.write_text(json.dumps(packet, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(packet, ensure_ascii=False, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/prashna_sphuta_candidate_replay.py b/scripts/prashna_sphuta_candidate_replay.py new file mode 100644 index 00000000..cd50b7d8 --- /dev/null +++ b/scripts/prashna_sphuta_candidate_replay.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +"""Expected-value-only replay readiness for Prashna Sphuta candidates.""" +from __future__ import annotations +import argparse, json, re +from pathlib import Path +from scripts.prashna_sphuta import calculate_sphuta_evidence + +ROOT = Path(__file__).resolve().parents[1] +QUEUE = ROOT / "references/oracle/prashna_numeric_oracle_packet_queue_2026_07_20.json" +OUT = ROOT / "references/oracle/prashna_sphuta_candidate_replay_readiness_2026_07_20.json" + +PAT = re.compile(r"(?P\d+)s\s*(?P\d+)°(?:\s*(?P\d+)')?(?:\s*(?P\d+)\")?") + +def parse_dms(value: str) -> float: + m = PAT.search(value) + if not m: raise ValueError(value) + sign=int(m.group('sign')); deg=int(m.group('deg')); minute=int(m.group('min') or 0); sec=int(m.group('sec') or 0) + return (sign*30 + deg + minute/60 + sec/3600) % 360 + +def close(a,b,tol=0.02): return abs(((a-b+180)%360)-180) <= tol + +def build(date: str): + q=json.load(open(QUEUE)) + rows=[] + for cand in q['rows']: + ev={k:parse_dms(v) for k,v in cand['expected_values'].items()} + calc=calculate_sphuta_evidence(ascendant_longitude=ev['lagna'], planet_longitudes={'Sun':ev['sun'],'Moon':ev['moon'],'Rahu':ev['rahu']}, gulika_longitude=ev['gulika']) + pts=calc['points'] + computed={'trisphuta': pts['trisphuta'], 'chatusphuta': pts['catusphuta'], 'panchasphuta': pts['pancasphuta']} + pass_formula=all(close(computed[k], ev[k]) for k in ['trisphuta','chatusphuta','panchasphuta']) + rows.append({ + 'source_id': cand['source_id'], + 'url': cand['url'], + 'expected_degrees': ev, + 'computed_from_expected_degrees': computed, + 'local_formula_consistency': 'pass' if pass_formula else 'mismatch', + 'replay_status': 'blocked_missing_complete_input', + 'missing_for_true_replay': ['question_datetime_local','location','timezone','ayanamsa','node_mode','raw_capture_hash','legal_external_replay'], + 'upgrade_status': 'not_oracle_ready', + 'claim_boundary': 'Checks arithmetic consistency of published expected values only; not a true local ephemeris replay.', + }) + data={ + 'scope':'prashna_sphuta_candidate_replay_readiness','created_at':date,'status':'replay_readiness_ready','claim_status':'tooling_observation_only', + 'production_tuning_allowed':False,'truth_matrix_allowed':False, + 'summary':{'candidate_count':len(rows),'local_formula_check_pass_count':sum(r['local_formula_consistency']=='pass' for r in rows),'oracle_ready_count':0}, + 'rows':rows,'boundary':'Expected-value arithmetic only; complete Prashna inputs are still required for oracle replay.' + } + return data + +def main(): + ap=argparse.ArgumentParser(); ap.add_argument('--date',default='2026-07-20'); args=ap.parse_args() + data=build(args.date); OUT.write_text(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True)+'\n'); print(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True)) +if __name__=='__main__': main() diff --git a/scripts/prashna_sphuta_mismatch_arbitration.py b/scripts/prashna_sphuta_mismatch_arbitration.py new file mode 100644 index 00000000..bed44900 --- /dev/null +++ b/scripts/prashna_sphuta_mismatch_arbitration.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Arbitrate Prashna Sphuta expected-value mismatches without truth upgrade.""" +from __future__ import annotations +import argparse, json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +REPLAY = ROOT / "references/oracle/prashna_sphuta_candidate_replay_readiness_2026_07_20.json" +OUT = ROOT / "references/oracle/prashna_sphuta_mismatch_arbitration_2026_07_20.json" + +def status(row, key, tol=0.02): + exp=row['expected_degrees'][key]; got=row['computed_from_expected_degrees'][key] + return 'matches' if abs(((got-exp+180)%360)-180) <= tol else 'mismatch' + +def build(date: str): + replay=json.load(open(REPLAY)) + rows=[] + for row in replay['rows']: + rows.append({ + 'source_id': row['source_id'], 'url': row['url'], + 'trisphuta_status': status(row,'trisphuta'), + 'chatusphuta_status': status(row,'chatusphuta'), + 'panchasphuta_status': status(row,'panchasphuta'), + 'candidate_causes': ['formula_variant','source_transcription','chatusphuta_catusphuta_naming','incomplete_input_settings'], + 'next_evidence_owner': 'worked_example_collection', + 'next_evidence': ['raw scan/page capture','complete example input','independent translation/transcription check','legal external replay'], + 'upgrade_status': 'not_oracle_ready', + 'claim_boundary': 'Mismatch queue only; do not tune formulas or upgrade Prashna truth from this packet.', + }) + sources=[ + {'source_id':'vedastro_prasna_marga_ch5_sphuta_example','url':'https://vedastro.org/book/PrasnaMarga/Chapter5','source_role':'numeric_candidate','upgrade_status':'candidate_not_oracle'}, + {'source_id':'internet_archive_prasna_marga_bv_raman_sphuta_fragment','url':'https://archive.org/details/PrasnaMarga/','source_role':'public_formula_numeric_fragment_candidate','upgrade_status':'candidate_not_oracle'}, + ] + return {'scope':'prashna_sphuta_mismatch_arbitration','created_at':date,'status':'arbitration_queue_ready','claim_status':'open_queue','production_tuning_allowed':False,'truth_matrix_allowed':False,'summary':{'mismatch_count':sum(r['chatusphuta_status']=='mismatch' or r['panchasphuta_status']=='mismatch' for r in rows),'source_candidate_count':len(sources),'oracle_ready_count':0},'rows':rows,'source_candidates':sources,'boundary':'Queue records candidate causes; closure requires raw source and replay evidence.'} + +def main(): + ap=argparse.ArgumentParser(); ap.add_argument('--date',default='2026-07-20'); args=ap.parse_args() + data=build(args.date); OUT.write_text(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True)+'\n'); print(json.dumps(data,ensure_ascii=False,indent=2,sort_keys=True)) +if __name__=='__main__': main() diff --git a/scripts/prepare_vedicastro_kp_tmp_env.py b/scripts/prepare_vedicastro_kp_tmp_env.py new file mode 100644 index 00000000..9cc0737f --- /dev/null +++ b/scripts/prepare_vedicastro_kp_tmp_env.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +"""Prepare an isolated temporary dependency path for VedicAstro KP probes. + +Installs only under /tmp/vedicastro_flatlib_probe. Never mutates project +requirements, venvs, package-locks, or runtime dependencies. +""" +from __future__ import annotations + +import argparse +import hashlib +import importlib.metadata +import json +import shutil +import subprocess +import sys +from pathlib import Path +from typing import Any + + +TARGET = Path("/tmp/vedicastro_flatlib_probe") +REQUIRED_PACKAGES = { + "flatlib": "git+https://github.com/diliprk/flatlib.git@sidereal#egg=flatlib", + "polars": "polars", + "timezonefinder": "timezonefinder", + "pyswisseph": "pyswisseph", +} + + +def stable(data: Any) -> str: + return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str) + + +def digest_tree(path: Path) -> str | None: + if not path.exists(): + return None + h = hashlib.sha256() + for file in sorted(p for p in path.rglob("*") if p.is_file()): + rel = file.relative_to(path).as_posix() + h.update(rel.encode("utf-8")) + try: + h.update(file.read_bytes()) + except OSError: + continue + return h.hexdigest() + + +def package_versions(target: Path) -> dict[str, str | None]: + sys.path.insert(0, str(target)) + versions: dict[str, str | None] = {} + for name in REQUIRED_PACKAGES: + try: + versions[name] = importlib.metadata.version(name) + except importlib.metadata.PackageNotFoundError: + versions[name] = None + return versions + + +def install(target: Path) -> dict[str, Any]: + target.mkdir(parents=True, exist_ok=True) + cmd = [ + sys.executable, + "-m", + "pip", + "install", + "--upgrade", + "--target", + str(target), + *REQUIRED_PACKAGES.values(), + ] + proc = subprocess.run(cmd, text=True, capture_output=True, timeout=180) + return { + "command": cmd, + "returncode": proc.returncode, + "stdout_tail": proc.stdout[-4000:], + "stderr_tail": proc.stderr[-4000:], + } + + +def build_payload(target: Path, install_result: dict[str, Any] | None = None) -> dict[str, Any]: + versions = package_versions(target) if target.exists() else {name: None for name in REQUIRED_PACKAGES} + ready = all(versions.values()) + payload: dict[str, Any] = { + "scope": "vedicastro_kp_tmp_env_preparer", + "created_at": "2026-07-21", + "target": str(target), + "project_dependency_mutation_allowed": False, + "required_packages": REQUIRED_PACKAGES, + "package_versions": versions, + "target_tree_hash": digest_tree(target), + "claim_status": "runtime_dependency_ready" if ready else "blocked_runtime_dependency", + "production_tuning_allowed": False, + "truth_matrix_allowed": False, + "boundary": "dependency_preparation_only_no_kp_oracle_truth", + } + if install_result is not None: + payload["install_result"] = install_result + return payload + + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("--target", default=str(TARGET)) + ap.add_argument("--report-only", action="store_true") + ap.add_argument("--clean", action="store_true") + args = ap.parse_args() + target = Path(args.target) + if args.clean and target.exists() and str(target).startswith("/tmp/"): + shutil.rmtree(target) + install_result = None if args.report_only else install(target) + payload = build_payload(target, install_result) + print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)) + return 0 if args.report_only or payload["claim_status"] == "runtime_dependency_ready" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/report_builder.py b/scripts/report_builder.py index 964ac8d4..fe332e81 100644 --- a/scripts/report_builder.py +++ b/scripts/report_builder.py @@ -467,11 +467,11 @@ Examples: footer_cn = """""" + Powered by Jyotish Engine v6.9.14 & Swiss Ephemeris
""" footer_en = """""" + Powered by Jyotish Engine v6.9.14 & Swiss Ephemeris
""" footer = footer_cn if lang == "cn" else footer_en html_lang = "zh-CN" if lang == "cn" else "en" diff --git a/scripts/shadbala_component_closure_queue_v2.py b/scripts/shadbala_component_closure_queue_v2.py new file mode 100644 index 00000000..bec4c7c2 --- /dev/null +++ b/scripts/shadbala_component_closure_queue_v2.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 +"""Build field-level Shadbala component closure tickets from same-unit rows.""" + +from __future__ import annotations + +import hashlib +import json +from collections import Counter, defaultdict +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +SAME_UNIT = ROOT / "references/oracle/shadbala_same_unit_normalizer_2026_07_19.json" +SOURCE_KB = ROOT / "references/oracle/formula_source_knowledge_base_2026_07_19.json" + + +def stable_json(data: Any) -> str: + return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str) + + +def source_by_component() -> dict[str, dict[str, Any]]: + raw = json.loads(SOURCE_KB.read_text(encoding="utf-8")) + out: dict[str, dict[str, Any]] = {} + for formula in raw.get("formulas", []): + if formula.get("family") == "Shadbala" and formula.get("component") not in {"total", None}: + out[formula["component"]] = formula + return out + + +def owner_for(classification: str) -> str: + if classification == "within_1_virupa_observation": + return "ready_for_tolerance_freeze" + if classification == "method_variant": + return "method_variant_decision" + if classification == "formula_or_unit_mismatch": + return "formula_source_arbitration" + return "worked_example_numeric_oracle" + + +def closure_for(classification: str) -> str: + if classification == "within_1_virupa_observation": + return "same_unit_observation_ready_tolerance_not_frozen" + if classification == "method_variant": + return "method_variant_unresolved" + if classification == "formula_or_unit_mismatch": + return "formula_or_unit_mismatch_unresolved" + return "insufficient_numeric_sources" + + +def required_evidence(classification: str) -> list[str]: + common = [ + "public numeric worked example with birth data/settings", + "explicit Virupa/Rupa unit declaration", + ] + if classification == "method_variant": + return common + ["variant selection note: preserve method_variant if authoritative sources diverge"] + if classification == "formula_or_unit_mismatch": + return common + ["component formula/source arbitration across local, jyotishganit, Xalen, VP Jain"] + if classification == "within_1_virupa_observation": + return common + ["freeze tolerance and add second public case before parity upgrade"] + return common + ["recover missing numeric raw/hash"] + + +def build() -> dict[str, Any]: + same_unit = json.loads(SAME_UNIT.read_text(encoding="utf-8")) + sources = source_by_component() + tickets: list[dict[str, Any]] = [] + + for row in same_unit["rows"]: + component = row["component"] + source = sources.get(component, {}) + classification = row["classification"] + tickets.append( + { + "ticket_id": f"shadbala.{row['planet'].lower()}.{component}", + "planet": row["planet"], + "component": component, + "canonical_component": row["canonical_component"], + "same_unit_classification": classification, + "closure_status": closure_for(classification), + "next_evidence_owner": owner_for(classification), + "unit_contract": source.get("unit_contract", "Virupa/Rupa unit source required."), + "known_variants": source.get("known_variants", []), + "source_evidence": source.get("source_evidence", []), + "required_evidence": required_evidence(classification), + "normalized_values_virupa": { + "jyotishganit": row.get("jyotishganit_virupa"), + "xalen": row.get("xalen_virupa"), + "local": row.get("local_from_xalen_report_virupa"), + "vp_jain_published": row.get("vp_jain_published_virupa"), + "vp_jain_local": row.get("vp_jain_local_virupa"), + }, + "claim_boundary": ( + "Do not promote this component row to absolute parity until formula variant, " + "unit contract, and public numeric worked example all close." + ), + } + ) + + counts = Counter(ticket["same_unit_classification"] for ticket in tickets) + by_component: dict[str, Counter[str]] = defaultdict(Counter) + for ticket in tickets: + by_component[ticket["component"]][ticket["same_unit_classification"]] += 1 + + component_hotspots = [] + for component in sorted(by_component): + c = by_component[component] + component_hotspots.append( + { + "component": component, + "ticket_count": sum(c.values()), + "within_1_virupa_observation_count": c["within_1_virupa_observation"], + "method_variant_count": c["method_variant"], + "formula_or_unit_mismatch_count": c["formula_or_unit_mismatch"], + "insufficient_numeric_sources_count": c["insufficient_numeric_sources"], + } + ) + + return { + "scope": "shadbala_component_closure_queue_v2", + "created_at": "2026-07-19", + "status": "field_level_queue_ready", + "claim_status": "partial", + "production_tuning_allowed": False, + "truth_matrix_allowed": False, + "sources": { + "same_unit_matrix": str(SAME_UNIT.relative_to(ROOT)), + "formula_source_knowledge_base": str(SOURCE_KB.relative_to(ROOT)), + }, + "summary": { + "ticket_count": len(tickets), + "within_1_virupa_observation_count": counts["within_1_virupa_observation"], + "method_variant_count": counts["method_variant"], + "formula_or_unit_mismatch_count": counts["formula_or_unit_mismatch"], + "insufficient_numeric_sources_count": counts["insufficient_numeric_sources"], + "absolute_parity_ready_count": 0, + }, + "queue_hash": hashlib.sha256(stable_json(tickets).encode("utf-8")).hexdigest(), + "component_hotspots": component_hotspots, + "tickets": tickets, + "boundary": "Field-level Shadbala closure queue only; no majority-vote truth or production tuning upgrade.", + } + + +def main() -> int: + print(json.dumps(build(), ensure_ascii=False, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/technique_promotion_audit_kp_gochara_muhurta.py b/scripts/technique_promotion_audit_kp_gochara_muhurta.py new file mode 100644 index 00000000..5a947fb9 --- /dev/null +++ b/scripts/technique_promotion_audit_kp_gochara_muhurta.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +"""Audit KP/Gochara/Muhurta/Panchanga fragments and runtime entrypoints.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + + +def _text(path: Path) -> str: + return path.read_text(encoding="utf-8", errors="ignore") if path.exists() else "" + + +def build_audit(root: Path) -> dict: + api = _text(root / "scripts/jyotish_api_server.py") + research_main_js = _text(root / "jyotish-app/main.js") + commercial_page = _text(root / "frontend/src/app/page.tsx") + dashaflow_muhurtha = root / "references/open_source_sources/dashaflow/muhurtha.py" + panchanga_license = _text(root / "references/open_source_sources/panchanga_api/LICENSE").splitlines() + kp_reference = root / "/Users/wuyongnaren/.workbuddy/backups/jyotish-vedic-astrology-20260711-154109/references/kp-astrology-complete-system.md" + gochara_template = Path("/tmp/jyotisha-optimize/assets/event_timing_template.md") + panchanga_called = ( + "/api/panchanga_range" in api + and ( + ("panchanga-range" in research_main_js and "panchanga-csv" in research_main_js) + or ("panchanga-range" in commercial_page and "panchanga-csv" in commercial_page) + ) + ) + + items = [ + { + "technique_id": "panchanga_calendar", + "current_call_status": "formally_called_in_api_and_web" if panchanga_called else "partial", + "main_artifacts": [ + "scripts/jyotish_api_server.py", + "frontend/src/app/page.tsx", + "jyotish-app/main.js (research static UI only, absent in commercial repo)", + ], + "external_or_reference_artifacts": ["references/open_source_sources/panchanga_api"], + "reuse_decision": "do_not_duplicate_runtime", + "source_or_license_boundary": "Existing runtime/UI present; panchanga_api license observed as " + + (panchanga_license[0] if panchanga_license else "unknown") + + ". Treat external panchanga_api as reference unless license/API contract is separately audited.", + "next_action": "add panchanga claim/display contract and source/oracle packet for tithi/nakshatra/yoga/karana/rahu-kalam outputs", + "claim_boundary": "Panchanga is runtime-visible but still needs field-level external oracle examples for high-rigor claims.", + }, + { + "technique_id": "muhurta_dashaflow_candidate", + "current_call_status": "oss_reference_not_main_runtime", + "main_artifacts": [], + "external_or_reference_artifacts": [str(dashaflow_muhurtha)], + "reuse_decision": "license_audit_before_reuse", + "source_or_license_boundary": "dashaflow/muhurtha.py exists under references/open_source_sources; verify license and formula sources before adapting.", + "next_action": "audit dashaflow license, extract formula surface, then compare Tarabala/Chandrabala/Rahu Kalam against local Panchanga.", + "claim_boundary": "Muhurta remains reference-only until license, formula, and worked examples close.", + }, + { + "technique_id": "kp_astrology", + "current_call_status": "reference_only_not_main_runtime", + "main_artifacts": [], + "external_or_reference_artifacts": [str(kp_reference)], + "reuse_decision": "reference_only", + "source_or_license_boundary": "KP backup/reference may contain useful notes but must pass privacy/license/source audit; do not copy blindly.", + "next_action": "create KP separate track: cusp system, ayanamsa, star lord/sub lord, ruling planets, public oracle examples.", + "claim_boundary": "KP is not part of current main Jyotish runtime truth.", + }, + { + "technique_id": "gochara_event_timing_template", + "current_call_status": "template_reference_not_main_runtime", + "main_artifacts": [], + "external_or_reference_artifacts": [str(gochara_template)], + "reuse_decision": "reference_only", + "source_or_license_boundary": "Template in /tmp must be privacy/source reviewed before promotion.", + "next_action": "turn Gochara template into scoring contract only after Dasha+Varga+Transit features and negative holdout are ready.", + "claim_boundary": "Transit template is not a calibrated timing engine.", + }, + ] + return { + "scope": "technique_promotion_audit_kp_gochara_muhurta", + "created_at": "2026-07-19", + "truth_policy": "runtime_presence_not_oracle_closure", + "production_tuning_allowed": False, + "summary": { + "items_checked": len(items), + "formally_called_count": sum("formally_called" in item["current_call_status"] for item in items), + "reference_only_count": sum("not_main_runtime" in item["current_call_status"] or "template_reference" in item["current_call_status"] for item in items), + }, + "items": items, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, default=Path(".")) + parser.add_argument("--output", type=Path) + args = parser.parse_args() + audit = build_audit(args.root) + text = json.dumps(audit, ensure_ascii=False, indent=2, sort_keys=True) + "\n" + if args.output: + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(text, encoding="utf-8") + print(text, end="") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/three_engine_high_rigor_parity.py b/scripts/three_engine_high_rigor_parity.py index e8b637d0..e0d2c58f 100644 --- a/scripts/three_engine_high_rigor_parity.py +++ b/scripts/three_engine_high_rigor_parity.py @@ -13,9 +13,6 @@ from typing import Any ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) -SCRIPTS = ROOT / "scripts" -if str(SCRIPTS) not in sys.path: - sys.path.insert(0, str(SCRIPTS)) from benchmarks.jyotish.scripts.run_pyjhora_compare import build_pyjhora_sample from benchmarks.jyotish.scripts.run_skill_baseline import run_sample diff --git a/scripts/three_engine_mismatch_arbitrator.py b/scripts/three_engine_mismatch_arbitrator.py index cdace7d1..f187d22b 100644 --- a/scripts/three_engine_mismatch_arbitrator.py +++ b/scripts/three_engine_mismatch_arbitrator.py @@ -82,16 +82,52 @@ def arbitrate_manifest(path: str | Path) -> dict[str, Any]: } +def render_markdown_report(report: dict[str, Any]) -> str: + lines = [ + "# Three-engine mismatch arbitration", + "", + f"manifest: `{report['manifest_path']}`", + f"status: `{report['status']}`", + f"truth_policy: `{report['truth_policy']}`", + "commercial_sync: `status_and_claim_boundary_only`", + f"mismatch_count: `{report['mismatch_count']}`", + f"classified_count: `{report['classified_count']}`", + f"unclassified_count: `{report['unclassified_count']}`", + "", + "Do not copy raw research debt into commercial runtime. Commercial receives readiness, claim boundary, and user-safe status only.", + "", + "## Category counts", + "", + "| category | count |", + "|---|---:|", + ] + for category, count in report["category_counts"].items(): + lines.append(f"| `{category}` | {count} |") + lines.extend(["", "## Closure requirements", ""]) + seen: set[str] = set() + for row in report["rows"]: + category = row["category"] + if category in seen: + continue + seen.add(category) + lines.append(f"- `{category}`: {row['closure_requirement']}") + return "\n".join(lines) + "\n" + + def main() -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("manifest", nargs="?", default="references/oracle/three_engine_parity_replay_manifest.json") parser.add_argument("--output", type=Path) + parser.add_argument("--markdown-output", type=Path) args = parser.parse_args() report = arbitrate_manifest(args.manifest) text = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n" if args.output: args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text(text, encoding="utf-8") + if args.markdown_output: + args.markdown_output.parent.mkdir(parents=True, exist_ok=True) + args.markdown_output.write_text(render_markdown_report(report), encoding="utf-8") print(text, end="") return 0 diff --git a/scripts/three_engine_mismatch_closure_queue.py b/scripts/three_engine_mismatch_closure_queue.py new file mode 100644 index 00000000..e4b5f08e --- /dev/null +++ b/scripts/three_engine_mismatch_closure_queue.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Create actionable closure tickets for three-engine mismatch rows.""" +from __future__ import annotations + +import argparse +import json +from collections import Counter +from pathlib import Path +from typing import Any + + +POLICY = { + "endpoint_or_varga_semantics": ("P0", "endpoint_contract", "identified endpoint/method contract with ayanamsa, node mode, varga, timezone semantics"), + "shadbala_formula_variant": ("P0", "formula_source", "public formula source + unit/cap/floor evidence for the component"), + "derived_total_from_component_variants": ("P1", "unit_schema", "component closure before total recomputation; explicit Rupa/Virupa total rule"), + "ashtakavarga_table_or_contributor_variant": ("P1", "worked_example", "public worked BAV/SAV table with contributor set, shodhana state, and Lagna inclusion"), +} + + +def build_queue(arbitration_path: str | Path) -> dict[str, Any]: + path = Path(arbitration_path) + report = json.loads(path.read_text(encoding="utf-8")) + tickets = [] + for index, row in enumerate(report.get("rows") or [], start=1): + priority, owner_track, required = POLICY.get( + row["category"], + ("P2", "worked_example", "manual source review and worked example required"), + ) + tickets.append({ + "ticket_id": f"TEMCQ-{index:03d}", + "priority": priority, + "owner_track": owner_track, + "section": row.get("section"), + "field": row.get("field"), + "category": row.get("category"), + "differing_engines": row.get("differing_engines") or [], + "required_evidence": required, + "closure_status": "open", + "commercial_visibility": "do_not_expose_raw", + }) + return { + "scope": "three_engine_mismatch_closure_queue", + "source_arbitration": str(path), + "status": "open" if tickets else "empty", + "truth_policy": "no_majority_vote", + "production_tuning_allowed": False, + "summary": { + "source_mismatch_count": report.get("mismatch_count", 0), + "queue_count": len(tickets), + "priority_counts": dict(Counter(ticket["priority"] for ticket in tickets)), + "owner_track_counts": dict(Counter(ticket["owner_track"] for ticket in tickets)), + }, + "queue": tickets, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("arbitration", nargs="?", default="references/oracle/three_engine_mismatch_arbitration_2026_07_19.json") + parser.add_argument("--output", type=Path) + args = parser.parse_args() + queue = build_queue(args.arbitration) + text = json.dumps(queue, ensure_ascii=False, indent=2, sort_keys=True) + "\n" + if args.output: + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(text, encoding="utf-8") + print(text, end="") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/vedastro_divisional_contract_probe.py b/scripts/vedastro_divisional_contract_probe.py new file mode 100644 index 00000000..19facb8f --- /dev/null +++ b/scripts/vedastro_divisional_contract_probe.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +"""Capture official VedAstro divisional-degree evidence without overclaiming chart parity.""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + +from scripts.vedastro_contract_probe import _post +from scripts import varga + + +ROOT = Path(__file__).resolve().parents[1] +DIVISIONS = (2, 4, 9, 10) + + +def probe(*, total_degrees: float, timeout: float) -> dict[str, Any]: + rows: dict[str, dict[str, Any]] = {} + all_match = True + for division in DIVISIONS: + official = _post( + "DivisionalLongitude", + {"totalDegrees": total_degrees, "divisionalNo": division}, + timeout, + ) + payload = official.get("payload") or {} + value = (payload.get("DivisionalLongitude") or {}).get("TotalDegrees") + local = varga.calc_varga(total_degrees, division)["degree_in_sign"] + try: + official_degree = float(value) + except (TypeError, ValueError): + official_degree = None + matches_local = official.get("status") == "Pass" and official_degree == local + all_match = all_match and matches_local + rows[f"D{division}"] = { + "official_status": official.get("status"), + "official_degree": official_degree, + "local_degree": local, + "matches_local": matches_local, + "request_body_hash": official.get("request_body_hash"), + "response_payload_hash": official.get("response_payload_hash"), + "raw_hash": official.get("raw_hash"), + } + return { + "scope": "vedastro_divisional_degree_contract_probe", + "input_total_degrees": total_degrees, + "contract_status": "degree_mapping_verified" if all_match else "blocked", + "chart_sign_contract": "blocked", + "boundary": ( + "This probe validates only the divisional degree transformation. " + "It does not establish complete D2/D4/D9/D10 sign, ayanamsa, node, " + "timezone, or hosted-endpoint chart parity." + ), + "rows": rows, + "privacy": {"api_key_persisted": False}, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--total-degrees", type=float, default=3.5) + parser.add_argument("--timeout", type=float, default=20.0) + parser.add_argument( + "--output", + type=Path, + default=ROOT / "references" / "oracle" / "artifacts" / "vedastro_divisional_degree_contract_probe.json", + ) + args = parser.parse_args() + report = probe(total_degrees=args.total_degrees, timeout=args.timeout) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps({"contract_status": report["contract_status"], "output": str(args.output)}, ensure_ascii=False)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_calculation_p0_regressions.py b/tests/test_calculation_p0_regressions.py index 08de70b6..4686b5fe 100644 --- a/tests/test_calculation_p0_regressions.py +++ b/tests/test_calculation_p0_regressions.py @@ -78,7 +78,7 @@ def test_sade_sati_uses_real_saturn_transit_for_reference_date() -> None: assert result["provenance"]["reference_date"] == "2026-07-11" -def test_jupiter_transit_is_available_from_the_native_oracle() -> None: +def test_jupiter_transit_uses_the_canonical_transit_contract() -> None: result = calculation_service.compute_transit_longitude( planet="Jupiter", reference_date="2026-07-11", @@ -89,6 +89,7 @@ def test_jupiter_transit_is_available_from_the_native_oracle() -> None: assert result["planet"] == "Jupiter" assert 0 <= result["longitude"] < 360 assert result["data_layer"] == "true_transit_positions" + assert result["ayanamsa"] == "lahiri" def test_timezone_inference_fails_closed(monkeypatch: pytest.MonkeyPatch) -> None: diff --git a/tests/test_claim_audit_runtime_gate_report.py b/tests/test_claim_audit_runtime_gate_report.py new file mode 100644 index 00000000..a8a53eca --- /dev/null +++ b/tests/test_claim_audit_runtime_gate_report.py @@ -0,0 +1,37 @@ +import json +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def test_claim_gate_report_covers_all_index_domains_for_high_claim() -> None: + data = json.loads( + subprocess.check_output( + ["python3", "scripts/claim_audit_runtime_gate_report.py", "--claim", "production_ready"], + cwd=ROOT, + text=True, + ) + ) + assert data["scope"] == "claim_audit_runtime_gate_report" + assert data["requested_claim"] == "production_ready" + assert data["summary"]["domain_count"] >= 20 + assert data["summary"]["blocked_count"] >= 1 + assert data["summary"]["degraded_count"] >= 1 + assert data["summary"]["production_tuning_allowed_count"] == 0 + + +def test_claim_gate_report_keeps_known_blockers_and_partials_visible() -> None: + data = json.loads( + subprocess.check_output( + ["python3", "scripts/claim_audit_runtime_gate_report.py", "--claim", "production_ready"], + cwd=ROOT, + text=True, + ) + ) + domains = {row["domain"]: row for row in data["domains"]} + assert domains["timing_holdout"]["decision"] == "block" + assert "day_level_holdout_readiness_ledger" in domains["timing_holdout"]["blocking_packets"] + assert domains["shadbala_component_closure"]["decision"] == "degrade" + assert domains["worked_example_collection"]["decision"] == "block" diff --git a/tests/test_commercial_privacy_artifact_scan.py b/tests/test_commercial_privacy_artifact_scan.py new file mode 100644 index 00000000..807c3001 --- /dev/null +++ b/tests/test_commercial_privacy_artifact_scan.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import json +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +def test_commercial_privacy_scan_reuses_public_release_scanner() -> None: + source = (ROOT / "scripts/commercial_privacy_artifact_scan.py").read_text() + assert "from public_release_privacy_scan import build_report" in source + assert "no_real_user_birth_data_private_cases_or_secret_values_in_public_artifacts" in source + assert "hip_main.dat" in source + + +def test_commercial_privacy_scan_json_contract_passes_current_tree() -> None: + completed = subprocess.run( + [sys.executable, "scripts/commercial_privacy_artifact_scan.py", "--json"], + cwd=ROOT, + text=True, + capture_output=True, + check=True, + ) + report = json.loads(completed.stdout) + assert report["scope"] == "commercial_privacy_artifact_scan" + assert report["scanner_reuse"] == "scripts/public_release_privacy_scan.py" + assert report["status"] == "pass" + assert report["finding_count"] == 0 + assert "hip_main.dat" in report["local_runtime_assets_not_committed"] diff --git a/tests/test_commercial_startup_self_check_contract.py b/tests/test_commercial_startup_self_check_contract.py new file mode 100644 index 00000000..30dbe945 --- /dev/null +++ b/tests/test_commercial_startup_self_check_contract.py @@ -0,0 +1,44 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +CONTRACT = ROOT / "references/oracle/commercial_startup_self_check_contract_2026_07_21.json" +GOLDEN = ROOT / "references/oracle/commercial_golden_oss_case_ci_contract_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_commercial_startup_self_check_contract_requires_truth_source_identity(): + contract = json.loads(CONTRACT.read_text(encoding="utf-8")) + + assert contract["scope"] == "commercial_startup_self_check_contract" + required = set(contract["required_fields"]) + assert { + "truth_source_path", + "truth_source_git_commit", + "skill_version", + "evidence_packet_count", + "artifact_gate_status", + "privacy_artifact_status", + "oracle_ready_summary", + }.issubset(required) + assert contract["reject_if"]["truth_source_path_contains"] == ["/WorkBuddy/", "/.workbuddy/"] + assert contract["claim_boundary"] == "startup_identity_gate_only_not_business_runtime" + + +def test_commercial_golden_oss_ci_contract_uses_pyjhora_sphuta_probe(): + contract = json.loads(GOLDEN.read_text(encoding="utf-8")) + + assert contract["scope"] == "commercial_golden_oss_case_ci_contract" + assert contract["golden_case"]["probe"] == "scripts/prashna_sphuta_oss_case_probe.py" + assert contract["golden_case"]["expected_raw_hash"] == "f0705d205440ea8d7f39116042a0723d971f4ab79c94f7d448fc42d683d52326" + assert contract["gate_policy"]["truth_upgrade_allowed"] is False + assert contract["gate_policy"]["fail_if_probe_missing"] is True + + +def test_commercial_contracts_are_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + ids = {row["packet_id"] for row in index["packets"]} + + assert "commercial_startup_self_check_contract_2026_07_21" in ids + assert "commercial_golden_oss_case_ci_contract_2026_07_21" in ids diff --git a/tests/test_cross_project_sync_status.py b/tests/test_cross_project_sync_status.py index 6da125a6..cf8d1795 100644 --- a/tests/test_cross_project_sync_status.py +++ b/tests/test_cross_project_sync_status.py @@ -45,6 +45,12 @@ def test_sync_policy_encodes_research_first_commercial_mature_rule() -> None: "service_role_runtime", } assert "references/cross_project_contract/fixture_manifest.v1.json" in policy["shared_files"] + assert { + "scripts/active_rectification_event_engine.py", + "scripts/active_rectification_events.py", + "scripts/rectification_technique_contract.py", + "scripts/rectification_three_engine_packet.py", + } <= set(policy["shared_files"]) def test_sync_status_passes_when_shared_files_match(tmp_path: Path) -> None: diff --git a/tests/test_jyotishganit_and_vedicastro_probes.py b/tests/test_jyotishganit_and_vedicastro_probes.py new file mode 100644 index 00000000..87406a3e --- /dev/null +++ b/tests/test_jyotishganit_and_vedicastro_probes.py @@ -0,0 +1,56 @@ +import json +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_jyotishganit_field_probe_outputs_raw_hash_and_required_sections(): + out = subprocess.check_output(["python3", "scripts/jyotishganit_field_probe.py"], cwd=ROOT, text=True) + data = json.loads(out) + assert data["scope"] == "jyotishganit_field_probe" + assert data["claim_status"] == "observation_only" + assert data["production_tuning_allowed"] is False + assert data["truth_matrix_allowed"] is False + assert data["raw_hash"] + assert data["selected_hash"] + for key in ["panchanga", "D2", "D4", "D9", "D10", "BAV_SAV", "Shadbala"]: + assert key in data["coverage"] + assert data["coverage"]["D2"] is True + assert data["coverage"]["D4"] is True + assert data["coverage"]["D9"] is True + assert data["coverage"]["D10"] is True + assert data["coverage"]["panchanga"] is True + assert data["coverage"]["BAV_SAV"] is True + assert data["coverage"]["Shadbala"] is False + + +def test_vedicastro_kp_api_probe_is_observation_only_even_when_import_blocks(): + out = subprocess.check_output(["python3", "scripts/vedicastro_kp_api_probe.py"], cwd=ROOT, text=True) + data = json.loads(out) + assert data["scope"] == "vedicastro_kp_api_probe" + assert data["claim_status"] == "observation_only" + assert data["source_sha256"] + assert "get_rl_nl_sl_data" in data["api_surface"]["methods"] + assert data["runtime_probe"]["attempted"] is True + + +def test_public_worked_example_queue_keeps_sources_unverified(): + data = json.loads((ROOT / "references/oracle/public_worked_example_queue_2026_07_19.json").read_text(encoding="utf-8")) + assert data["claim_status"] == "open_queue" + assert data["production_tuning_allowed"] is False + assert data["truth_matrix_allowed"] is False + topics = {row["topic"] for row in data["queues"]} + assert "KP exact cusp star/sub/sub-sub lord" in topics + assert "Muhurta Tarabala/Chandrabala/Rahu Kalam/Abhijit" in topics + assert "Shadbala Virupa and Ashtakavarga component" in topics + + +def test_evidence_index_registers_new_probes(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + packets = {row["packet_id"]: row for row in index["packets"]} + for packet_id in ["jyotishganit_field_probe", "vedicastro_kp_api_probe", "public_worked_example_queue"]: + assert packet_id in packets + assert packets[packet_id]["claim_status"] in {"observation_only", "open_queue"} diff --git a/tests/test_jyotishganit_field_closure_rows.py b/tests/test_jyotishganit_field_closure_rows.py new file mode 100644 index 00000000..2009badf --- /dev/null +++ b/tests/test_jyotishganit_field_closure_rows.py @@ -0,0 +1,37 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/jyotishganit_field_closure_rows_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_jyotishganit_field_closure_rows_are_observation_only(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "jyotishganit_field_closure_rows" + assert data["claim_status"] == "observation_only" + assert data["truth_matrix_allowed"] is False + assert data["source_selected_hash"] == "4709b8ade84efdea4d0a67c15f3e32cea516a5aa2e8abe3885578feda20cb3f4" + assert len(data["rows"]) == 7 + + +def test_jyotishganit_field_rows_mark_shadbala_as_gap(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = {row["field"]: row for row in data["rows"]} + + for field in ["D2", "D4", "D9", "D10", "Panchanga", "BAV", "SAV"]: + assert rows[field]["closure_status"] == "ready_for_field_comparison" + assert data["explicit_gaps"] == [{"field": "Shadbala", "reason": "jyotishganit probe did not expose shadbala/strengths in selected raw"}] + + +def test_jyotishganit_field_rows_are_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "jyotishganit_field_closure_rows_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "observation_only" diff --git a/tests/test_jyotishganit_node_source_attribution.py b/tests/test_jyotishganit_node_source_attribution.py new file mode 100644 index 00000000..66ee87fd --- /dev/null +++ b/tests/test_jyotishganit_node_source_attribution.py @@ -0,0 +1,24 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_node_source_attribution_identifies_boundary_crossing_not_d10_formula(): + data = json.loads((ROOT / "references/oracle/jyotishganit_node_source_attribution_2026_07_19.json").read_text(encoding="utf-8")) + assert data["scope"] == "jyotishganit_node_source_attribution" + assert data["claim_status"] == "partial" + assert data["production_tuning_allowed"] is False + assert data["attribution"]["formula_delta"] == "not_d10_formula_shape" + assert data["attribution"]["primary_delta"] == "node_longitude_source_plus_ayanamsa_boundary_crossing" + assert data["local_engine"]["Rahu"]["d10_part_index_zero_based"] == 3 + assert data["jyotishganit_engine"]["Rahu"]["d10_part_index_zero_based"] == 2 + assert data["local_true_node_control"]["control_result"].startswith("true node moves farther") + + +def test_evidence_index_registers_node_source_attribution(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + packets = {row["packet_id"]: row for row in index["packets"]} + assert packets["jyotishganit_node_source_attribution"]["claim_status"] == "partial" diff --git a/tests/test_jyotishganit_three_engine_closure_bridge.py b/tests/test_jyotishganit_three_engine_closure_bridge.py new file mode 100644 index 00000000..504a0e38 --- /dev/null +++ b/tests/test_jyotishganit_three_engine_closure_bridge.py @@ -0,0 +1,37 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +BRIDGE = ROOT / "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_jyotishganit_bridge_routes_only_available_fields_to_closure_queue(): + data = json.loads(BRIDGE.read_text(encoding="utf-8")) + + assert data["scope"] == "jyotishganit_three_engine_closure_bridge" + assert data["claim_status"] == "observation_only" + assert data["truth_matrix_allowed"] is False + assert data["source_probe"] == "scripts/jyotishganit_field_probe.py" + assert data["source_raw_hash"] == "19fa9ea862b68c4cffb6756fa6cbf0466daf47a8b008b3fe8809e9fc6a1ed30c" + assert set(data["field_routes"]["ready_for_field_comparison"]) == { + "D2", + "D4", + "D9", + "D10", + "Panchanga", + "BAV_SAV", + } + assert data["field_routes"]["explicit_gaps"] == ["Shadbala"] + + +def test_jyotishganit_bridge_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "jyotishganit_three_engine_closure_bridge_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "observation_only" diff --git a/tests/test_kp_public_worked_example_candidate_queue.py b/tests/test_kp_public_worked_example_candidate_queue.py new file mode 100644 index 00000000..be3bd315 --- /dev/null +++ b/tests/test_kp_public_worked_example_candidate_queue.py @@ -0,0 +1,39 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +QUEUE = ROOT / "references/oracle/kp_public_worked_example_candidate_queue_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_kp_public_queue_has_sources_but_no_numeric_oracle_upgrade(): + data = json.loads(QUEUE.read_text(encoding="utf-8")) + + assert data["scope"] == "kp_public_worked_example_candidate_queue" + assert data["claim_status"] == "open_queue" + assert data["numeric_oracle_ready_count"] == 0 + assert data["truth_matrix_allowed"] is False + assert data["boundary"] == "public_source_candidate_queue_only_no_kp_numeric_oracle" + + +def test_kp_public_queue_records_formula_and_runtime_cusp_candidates(): + data = json.loads(QUEUE.read_text(encoding="utf-8")) + rows = {row["id"]: row for row in data["candidates"]} + + assert rows["astrosage_kp_chapter_2"]["candidate_type"] == "formula_and_text_worked_example" + assert rows["astrosage_kp_chapter_2"]["has_numeric_cusp_table"] is False + assert rows["astrosage_kp_sign_star_sub_table"]["candidate_type"] == "reference_table" + assert rows["onlinejyotish_kp_horoscope"]["candidate_type"] == "runtime_form_candidate" + assert rows["astrobix_kp_houses"]["candidate_type"] == "runtime_form_candidate" + + +def test_kp_public_queue_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "kp_public_worked_example_candidate_queue_2026_07_21" + ) + + assert entry["domain"] == "kp_precision_timing" + assert entry["claim_status"] == "open_queue" diff --git a/tests/test_kp_tajika_public_oracle_source_candidates.py b/tests/test_kp_tajika_public_oracle_source_candidates.py new file mode 100644 index 00000000..c5e87701 --- /dev/null +++ b/tests/test_kp_tajika_public_oracle_source_candidates.py @@ -0,0 +1,37 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/kp_tajika_public_oracle_source_candidates_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_public_candidates_are_not_numeric_oracles_yet(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + assert data["scope"] == "kp_tajika_public_oracle_source_candidates" + assert data["claim_status"] == "open_queue" + assert data["truth_matrix_allowed"] is False + domains = {row["domain"] for row in data["candidates"]} + assert {"kp_exact_cusp", "tajika_varshaphala"} <= domains + for row in data["candidates"]: + assert row["promotion_status"] in {"candidate_needs_numeric_extraction", "candidate_reference_only"} + assert row["claim_upgrade"] == "none" + + +def test_candidates_record_why_steve_jobs_tajika_and_kp_are_still_open(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + by_id = {row["candidate_id"]: row for row in data["candidates"]} + assert by_id["kp_249_sub_lord_table_candidate"]["missing_for_oracle"] + assert by_id["tajika_varshaphala_worked_example_pdf_candidate"]["missing_for_oracle"] + assert by_id["steve_jobs_1984_tajika_template"]["promotion_status"] == "candidate_reference_only" + + +def test_public_candidate_packet_is_indexed(): + packets = { + row["packet_id"]: row + for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"] + } + packet = packets["kp_tajika_public_oracle_source_candidates_2026_07_21"] + assert packet["claim_status"] == "open_queue" + assert packet["consumer_policy"] == "research_observation_only" diff --git a/tests/test_panchanga_local_jyotishganit_comparison_packet.py b/tests/test_panchanga_local_jyotishganit_comparison_packet.py new file mode 100644 index 00000000..6b3f3d3b --- /dev/null +++ b/tests/test_panchanga_local_jyotishganit_comparison_packet.py @@ -0,0 +1,66 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/panchanga_local_jyotishganit_comparison_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_panchanga_local_jyotishganit_packet_scope_and_boundary(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + assert data["scope"] == "panchanga_local_jyotishganit_comparison" + assert data["ticket_id"] == "TEMCQ-061" + assert data["claim_status"] == "partial" + assert data["truth_matrix_allowed"] is False + assert data["production_tuning_allowed"] is False + assert data["algorithm_reuse_policy"] == "reuse_existing_local_muhurta_calc_panchanga_no_new_algorithm" + assert data["boundary"] == "local_jyotishganit_panchanga_field_observation_not_global_truth" + + +def test_panchanga_local_values_reuse_existing_muhurta_engine(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + assert data["source_local_method"] == "scripts/muhurta.py::calc_panchanga" + assert data["local_normalized_raw"] == { + "vaara": "Thursday", + "tithi": "Shukla Tritiya", + "nakshatra": "Uttara Bhadrapada", + "yoga": "Shubha", + "karana": "Garija", + } + assert data["jyotishganit_observed_raw"] == { + "@type": "Panchanga", + "karana": "Gara", + "nakshatra": "Uttara Bhadrapada", + "tithi": "Shukla Tritiya", + "vaara": "Thursday", + "yoga": "Shubha", + } + + +def test_panchanga_field_comparison_distinguishes_alias_from_truth(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = {row["field"]: row for row in data["field_comparison"]} + assert set(rows) == {"vaara", "tithi", "nakshatra", "yoga", "karana"} + assert [row["status"] for row in rows.values()].count("within_tolerance") == 4 + assert rows["karana"]["status"] == "alias_match" + assert rows["karana"]["alias_rule"] == "Gara == Garija" + assert data["summary"] == { + "fields_total": 5, + "within_tolerance": 4, + "alias_match": 1, + "formula_mismatch": 0, + "unit_mismatch": 0, + "truth_upgrades": 0, + } + + +def test_panchanga_local_comparison_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "panchanga_local_jyotishganit_comparison_2026_07_21" + ) + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "partial" + assert entry["consumer_policy"] == "research_observation_only" diff --git a/tests/test_panchanga_temcq_061_schema_packet.py b/tests/test_panchanga_temcq_061_schema_packet.py new file mode 100644 index 00000000..bf59fa59 --- /dev/null +++ b/tests/test_panchanga_temcq_061_schema_packet.py @@ -0,0 +1,61 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/panchanga_temcq_061_schema_packet_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_panchanga_temcq_061_records_not_comparable_status(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "panchanga_temcq_061_schema_packet" + assert data["ticket_id"] == "TEMCQ-061" + assert data["claim_status"] == "open_queue" + assert data["truth_matrix_allowed"] is False + assert data["closure_status"] == "schema_mapping_required" + assert data["summary"]["normalized_fields_ready"] == 0 + assert data["summary"]["truth_upgrades"] == 0 + + +def test_panchanga_temcq_061_preserves_jyotishganit_raw_fields(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["jyotishganit_observed_raw"] == { + "@type": "Panchanga", + "karana": "Gara", + "nakshatra": "Uttara Bhadrapada", + "tithi": "Shukla Tritiya", + "vaara": "Thursday", + "yoga": "Shubha", + } + assert data["engine_field_status"]["local"] == "archived_panchanga_field_missing" + assert data["engine_field_status"]["VedAstro"] == "shared_panchanga_endpoint_not_pinned" + assert data["engine_field_status"]["PyJHora_JHora"] == "not_archived_as_normalized_panchanga" + + +def test_panchanga_temcq_061_requires_exact_schema_before_comparison(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["required_schema_fields"] == ["vaara", "tithi", "nakshatra", "yoga", "karana"] + assert data["required_contract"] == [ + "weekday convention", + "tithi naming and paksha convention", + "nakshatra spelling/diacritic alias table", + "yoga calculation convention", + "karana naming convention", + "sunrise-relative vs birth-moment rule" + ] + assert data["boundary"] == "panchanga_schema_mapping_only_no_numeric_truth" + + +def test_panchanga_temcq_061_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "panchanga_temcq_061_schema_packet_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "open_queue" diff --git a/tests/test_prashna_sphuta_candidate_replay_readiness.py b/tests/test_prashna_sphuta_candidate_replay_readiness.py new file mode 100644 index 00000000..3da1d7de --- /dev/null +++ b/tests/test_prashna_sphuta_candidate_replay_readiness.py @@ -0,0 +1,36 @@ +import json +import subprocess +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +ARTIFACT = ROOT / "references/oracle/prashna_sphuta_candidate_replay_readiness_2026_07_20.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_prashna_sphuta_candidate_replay_parses_expected_values_without_truth_upgrade(): + data = json.loads(subprocess.check_output(["python3", "scripts/prashna_sphuta_candidate_replay.py", "--date", "2026-07-20"], cwd=ROOT, text=True)) + assert data["scope"] == "prashna_sphuta_candidate_replay_readiness" + assert data["claim_status"] == "tooling_observation_only" + assert data["summary"]["candidate_count"] == 1 + assert data["summary"]["local_formula_check_pass_count"] == 0 + assert data["summary"]["oracle_ready_count"] == 0 + row = data["rows"][0] + assert row["replay_status"] == "blocked_missing_complete_input" + assert row["local_formula_consistency"] == "mismatch" + assert abs(row["computed_from_expected_degrees"]["trisphuta"] - row["expected_degrees"]["trisphuta"]) < 0.01 + assert abs(row["computed_from_expected_degrees"]["chatusphuta"] - row["expected_degrees"]["chatusphuta"]) > 1 + + +def test_prashna_sphuta_candidate_replay_keeps_missing_inputs_visible(): + data = json.loads(ARTIFACT.read_text(encoding="utf-8")) + row = data["rows"][0] + assert "question_datetime_local" in row["missing_for_true_replay"] + assert "location" in row["missing_for_true_replay"] + assert "ayanamsa" in row["missing_for_true_replay"] + assert row["upgrade_status"] == "not_oracle_ready" + + +def test_prashna_sphuta_candidate_replay_is_indexed(): + packets = {row["packet_id"]: row for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"]} + packet = packets["prashna_sphuta_candidate_replay_readiness_2026_07_20"] + assert packet["claim_status"] == "tooling_observation_only" diff --git a/tests/test_prashna_sphuta_mismatch_arbitration.py b/tests/test_prashna_sphuta_mismatch_arbitration.py new file mode 100644 index 00000000..a0de425e --- /dev/null +++ b/tests/test_prashna_sphuta_mismatch_arbitration.py @@ -0,0 +1,32 @@ +import json +import subprocess +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +ARTIFACT = ROOT / "references/oracle/prashna_sphuta_mismatch_arbitration_2026_07_20.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_prashna_sphuta_mismatch_arbitration_records_formula_and_transcription_candidates(): + data = json.loads(subprocess.check_output(["python3", "scripts/prashna_sphuta_mismatch_arbitration.py", "--date", "2026-07-20"], cwd=ROOT, text=True)) + assert data["scope"] == "prashna_sphuta_mismatch_arbitration" + assert data["claim_status"] == "open_queue" + assert data["summary"]["mismatch_count"] >= 1 + row = data["rows"][0] + assert row["trisphuta_status"] == "matches" + assert row["chatusphuta_status"] == "mismatch" + assert "formula_variant" in row["candidate_causes"] + assert "source_transcription" in row["candidate_causes"] + assert row["next_evidence_owner"] == "worked_example_collection" + + +def test_prashna_sphuta_mismatch_arbitration_adds_second_public_formula_candidate(): + data = json.loads(ARTIFACT.read_text(encoding="utf-8")) + sources = {row["source_id"] for row in data["source_candidates"]} + assert "internet_archive_prasna_marga_bv_raman_sphuta_fragment" in sources + assert all(row["upgrade_status"] == "candidate_not_oracle" for row in data["source_candidates"]) + + +def test_prashna_sphuta_mismatch_arbitration_is_indexed(): + packets = {row["packet_id"]: row for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"]} + assert packets["prashna_sphuta_mismatch_arbitration_2026_07_20"]["claim_status"] == "open_queue" diff --git a/tests/test_pyjhora_shadbala_stdout_parser.py b/tests/test_pyjhora_shadbala_stdout_parser.py new file mode 100644 index 00000000..3bd904c0 --- /dev/null +++ b/tests/test_pyjhora_shadbala_stdout_parser.py @@ -0,0 +1,37 @@ +import json +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_parser_extracts_42_same_unit_component_rows(): + data = json.loads( + subprocess.check_output( + ["python3", "scripts/parse_pyjhora_shadbala_stdout.py"], + cwd=ROOT, + text=True, + ) + ) + assert data["scope"] == "pyjhora_shadbala_stdout_component_packet" + assert data["claim_status"] == "observation_only" + assert data["truth_matrix_allowed"] is False + assert data["summary"]["component_row_count"] == 42 + assert data["summary"]["planet_count"] == 7 + assert data["summary"]["component_count"] == 6 + first = data["component_rows"][0] + assert {"planet", "component", "virupa", "rupa", "source_artifact_sha256"} <= set(first) + + +def test_packet_is_stable_and_indexed_after_capture(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + assert data["summary"]["component_row_count"] == 42 + assert data["source_artifact"].endswith("pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt") + packets = { + row["packet_id"]: row + for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"] + } + assert packets["pyjhora_steve_jobs_shadbala_stdout_components_2026_07_21"]["claim_status"] == "observation_only" diff --git a/tests/test_shadbala_component_closure_queue_v2.py b/tests/test_shadbala_component_closure_queue_v2.py new file mode 100644 index 00000000..c1914807 --- /dev/null +++ b/tests/test_shadbala_component_closure_queue_v2.py @@ -0,0 +1,54 @@ +import json +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +ARTIFACT = ROOT / "references/oracle/shadbala_component_closure_queue_v2_2026_07_19.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_queue_generator_builds_42_field_level_tickets(): + data = json.loads( + subprocess.check_output( + ["python3", "scripts/shadbala_component_closure_queue_v2.py"], + cwd=ROOT, + text=True, + ) + ) + assert data["scope"] == "shadbala_component_closure_queue_v2" + assert data["claim_status"] == "partial" + assert data["production_tuning_allowed"] is False + assert data["summary"]["ticket_count"] == 42 + assert data["summary"]["formula_or_unit_mismatch_count"] == 27 + assert data["summary"]["method_variant_count"] == 8 + assert data["summary"]["within_1_virupa_observation_count"] == 7 + + +def test_queue_artifact_attaches_source_unit_variant_and_owner(): + data = json.loads(ARTIFACT.read_text(encoding="utf-8")) + ticket = next(row for row in data["tickets"] if row["planet"] == "Sun" and row["component"] == "dig") + assert ticket["unit_contract"] + assert ticket["known_variants"] + assert ticket["next_evidence_owner"] in { + "worked_example_numeric_oracle", + "formula_source_arbitration", + "method_variant_decision", + "ready_for_tolerance_freeze", + } + assert ticket["closure_status"] != "absolute_parity_ready" + assert ticket["claim_boundary"].startswith("Do not promote") + + +def test_queue_has_component_hotspot_summary(): + data = json.loads(ARTIFACT.read_text(encoding="utf-8")) + hotspots = {row["component"]: row for row in data["component_hotspots"]} + assert set(hotspots) == {"sthana", "dig", "kala", "chesta", "naisargika", "drik"} + assert hotspots["naisargika"]["within_1_virupa_observation_count"] == 7 + assert hotspots["dig"]["formula_or_unit_mismatch_count"] >= 1 + + +def test_evidence_index_registers_queue_v2(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + packets = {row["packet_id"]: row for row in index["packets"]} + assert packets["shadbala_component_closure_queue_v2"]["claim_status"] == "partial" diff --git a/tests/test_source_runtime_closure_queue_2026_07_21.py b/tests/test_source_runtime_closure_queue_2026_07_21.py new file mode 100644 index 00000000..c5c36554 --- /dev/null +++ b/tests/test_source_runtime_closure_queue_2026_07_21.py @@ -0,0 +1,60 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +QUEUE = ROOT / "references/oracle/source_runtime_closure_queue_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" +KP_RAW = ROOT / "references/oracle/vedicastro_kp_house_cusp_raw_2026_07_21.json" +KP_ENV = ROOT / "references/oracle/vedicastro_kp_tmp_env_identity_2026_07_21.json" + + +def test_queue_prioritizes_jyotishganit_and_vedicastro_without_truth_upgrade(): + data = json.loads(QUEUE.read_text(encoding="utf-8")) + rows = {row["id"]: row for row in data["rows"]} + + assert data["scope"] == "source_runtime_closure_queue" + assert data["claim_status"] == "open_queue" + assert data["truth_matrix_allowed"] is False + assert rows["jyotishganit_field_closure"]["current_status"] == "probe_runs_observation_only" + assert rows["vedicastro_kp_house_cusp_closure"]["current_status"] == "raw_ready_observation_only" + assert rows["vedicastro_kp_house_cusp_closure"]["latest_observed_raw_hash"] == "2e7a6b17eb2965a60846f625f6bd8bc03555216d6225983647bcbfa23d0e345b" + assert rows["vedicastro_kp_house_cusp_closure"]["coverage"]["sub_sub_lord"] is True + + +def test_queue_marks_existing_assets_as_not_fully_invoked(): + data = json.loads(QUEUE.read_text(encoding="utf-8")) + not_closed = data["not_fully_closed_reference_layers"] + + assert "references/open_source_sources/jyotishganit" in not_closed + assert "references/open_source_sources/VedicAstro" in not_closed + assert "references/open_source_sources/rishi-ai-mcp" in not_closed + assert "references/open_source_sources/vedic-astro-skills" in not_closed + assert data["boundary"] == "queue_only_no_adapter_or_truth_upgrade" + + +def test_queue_is_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "source_runtime_closure_queue_2026_07_21" + ) + + assert entry["domain"] == "source_runtime_closure" + assert entry["claim_status"] == "open_queue" + + +def test_vedicastro_kp_raw_and_tmp_env_are_observation_only_packets(): + raw = json.loads(KP_RAW.read_text(encoding="utf-8")) + env = json.loads(KP_ENV.read_text(encoding="utf-8")) + + assert raw["scope"] == "vedicastro_kp_house_cusp_probe" + assert raw["status"] == "complete" + assert raw["claim_status"] == "observation_only" + assert raw["truth_matrix_allowed"] is False + assert raw["raw_hash"] == "2e7a6b17eb2965a60846f625f6bd8bc03555216d6225983647bcbfa23d0e345b" + assert raw["schema_fingerprint"]["house_count"] == 12 + assert "SubLord" in raw["schema_fingerprint"]["fields"] + assert "SubSubLord" in raw["schema_fingerprint"]["fields"] + assert env["claim_status"] == "runtime_dependency_ready" + assert env["project_dependency_mutation_allowed"] is False diff --git a/tests/test_supabase_user_data_contract.py b/tests/test_supabase_user_data_contract.py index 43e7000b..3e634750 100644 --- a/tests/test_supabase_user_data_contract.py +++ b/tests/test_supabase_user_data_contract.py @@ -112,6 +112,9 @@ def test_chat_page_uses_authenticated_cloud_persistence() -> None: assert 'await persistence' in source assert "pendingSessionId || cancellationInFlight.current || pendingConsultation.current" in source assert "setCancellationPending(true)" in source + assert "系统正在以账户记录为准同步点数" in source + assert "回答中途断开,已保留现有内容,本次已计费。" not in source + assert "本次已开始生成并计费" not in source assert 'localStorage.setItem(chartLibraryStorageKey(accountId)' in source assert 'localStorage.setItem("chat_sessions"' not in source diff --git a/tests/test_technique_promotion_audit_kp_gochara_muhurta.py b/tests/test_technique_promotion_audit_kp_gochara_muhurta.py new file mode 100644 index 00000000..e0993091 --- /dev/null +++ b/tests/test_technique_promotion_audit_kp_gochara_muhurta.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import json +from pathlib import Path + +from scripts.technique_promotion_audit_kp_gochara_muhurta import build_audit + +ROOT = Path(__file__).resolve().parents[1] + + +def test_kp_gochara_muhurta_audit_splits_runtime_presence() -> None: + audit = build_audit(ROOT) + statuses = {item["technique_id"]: item["current_call_status"] for item in audit["items"]} + assert audit["scope"] == "technique_promotion_audit_kp_gochara_muhurta" + assert audit["truth_policy"] == "runtime_presence_not_oracle_closure" + assert statuses["panchanga_calendar"] == "partial" + assert statuses["muhurta_dashaflow_candidate"] == "oss_reference_not_main_runtime" + assert statuses["kp_astrology"] == "reference_only_not_main_runtime" + assert statuses["gochara_event_timing_template"] == "template_reference_not_main_runtime" + + +def test_kp_gochara_muhurta_audit_records_reuse_boundaries() -> None: + audit = build_audit(ROOT) + for item in audit["items"]: + assert item["reuse_decision"] in {"do_not_duplicate_runtime", "license_audit_before_reuse", "reference_only"} + assert item["next_action"] + assert item["claim_boundary"] + assert item["source_or_license_boundary"] + + +def test_kp_gochara_muhurta_audit_artifact_exists() -> None: + artifact = ROOT / "references/oracle/technique_promotion_audit_kp_gochara_muhurta_2026_07_19.json" + data = json.loads(artifact.read_text(encoding="utf-8")) + assert data["summary"] == { + "items_checked": 4, + "formally_called_count": 0, + "reference_only_count": 3, + } diff --git a/tests/test_three_engine_bav_sav_field_closure_packet.py b/tests/test_three_engine_bav_sav_field_closure_packet.py new file mode 100644 index 00000000..f0727d96 --- /dev/null +++ b/tests/test_three_engine_bav_sav_field_closure_packet.py @@ -0,0 +1,49 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/three_engine_bav_sav_field_closure_packet_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_bav_sav_packet_classifies_without_truth_upgrade(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "three_engine_bav_sav_field_closure_packet" + assert data["claim_status"] == "partial" + assert data["truth_matrix_allowed"] is False + assert data["summary"]["rows_total"] == 8 + assert data["summary"]["local_pyjhora_jyotishganit_agree"] == 5 + assert data["summary"]["multi_engine_variant"] == 3 + assert data["summary"]["truth_upgrades"] == 0 + + +def test_bav_sav_rows_require_worked_examples_and_method_metadata(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = {row["ticket_id"]: row for row in data["rows"]} + + assert rows["TEMCQ-011"]["closure_status"] == "partial_consensus_vedastro_variant_blocked" + assert rows["TEMCQ-012"]["closure_status"] == "multi_engine_variant_worked_example_required" + assert rows["TEMCQ-016"]["closure_status"] == "multi_engine_variant_worked_example_required" + assert rows["TEMCQ-018"]["closure_status"] == "multi_engine_variant_worked_example_required" + for row in rows.values(): + assert row["required_evidence"] == [ + "public worked BAV/SAV table", + "contributor set", + "Lagna inclusion policy", + "shodhana state", + "rashi order/orientation" + ] + assert row["claim_boundary"] == "ashtakavarga_table_comparison_only_no_formula_truth" + + +def test_bav_sav_packet_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "three_engine_bav_sav_field_closure_packet_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "partial" diff --git a/tests/test_three_engine_d2_field_closure_packet.py b/tests/test_three_engine_d2_field_closure_packet.py new file mode 100644 index 00000000..eee94d88 --- /dev/null +++ b/tests/test_three_engine_d2_field_closure_packet.py @@ -0,0 +1,55 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/three_engine_d2_field_closure_packet_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_d2_packet_closes_local_pyjhora_jyotishganit_agreement_only(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "three_engine_d2_field_closure_packet" + assert data["claim_status"] == "partial" + assert data["truth_matrix_allowed"] is False + assert data["summary"]["rows_total"] == 7 + assert data["summary"]["local_pyjhora_jyotishganit_agree"] == 7 + assert data["summary"]["vedastro_endpoint_semantics_blocked"] == 7 + assert data["summary"]["truth_upgrades"] == 0 + + +def test_d2_rows_keep_vedastro_as_endpoint_semantics_not_formula_error(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + expected = { + "Sun.sign": ("Leo", "Gemini"), + "Moon.sign": ("Cancer", "Pisces"), + "Mars.sign": ("Leo", "Aries"), + "Mercury.sign": ("Leo", "Virgo"), + "Jupiter.sign": ("Cancer", "Aquarius"), + "Venus.sign": ("Cancer", "Leo"), + "Saturn.sign": ("Cancer", "Gemini"), + } + rows = {row["field"]: row for row in data["rows"]} + assert set(rows) == set(expected) + for field, (consensus, vedastro) in expected.items(): + row = rows[field] + assert row["ticket_id"].startswith("TEMCQ-00") + assert row["local_value"] == consensus + assert row["pyjhora_jhora_value"] == consensus + assert row["jyotishganit_value"] == consensus + assert row["vedastro_value"] == vedastro + assert row["closure_status"] == "partial_consensus_vedastro_endpoint_blocked" + assert row["claim_boundary"] == "three_engine_consensus_not_global_truth" + + +def test_d2_packet_is_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "three_engine_d2_field_closure_packet_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "partial" diff --git a/tests/test_three_engine_d4_d9_d10_field_closure_packet.py b/tests/test_three_engine_d4_d9_d10_field_closure_packet.py new file mode 100644 index 00000000..45292a2c --- /dev/null +++ b/tests/test_three_engine_d4_d9_d10_field_closure_packet.py @@ -0,0 +1,51 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/three_engine_d4_d9_d10_field_closure_packet_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_d4_d9_d10_packet_closes_partial_consensus_only(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "three_engine_d4_d9_d10_field_closure_packet" + assert data["claim_status"] == "partial" + assert data["truth_matrix_allowed"] is False + assert data["summary"]["rows_total"] == 3 + assert data["summary"]["local_pyjhora_jyotishganit_agree"] == 3 + assert data["summary"]["vedastro_endpoint_semantics_blocked"] == 3 + assert data["summary"]["truth_upgrades"] == 0 + + +def test_d4_d9_d10_rows_preserve_exact_values_and_boundaries(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = {(row["section"], row["field"]): row for row in data["rows"]} + + expected = { + ("D4", "Moon.sign"): ("TEMCQ-008", "Gemini", "Pisces"), + ("D9", "Moon.sign"): ("TEMCQ-009", "Scorpio", "Leo"), + ("D10", "Moon.sign"): ("TEMCQ-010", "Pisces", "Sagittarius"), + } + assert set(rows) == set(expected) + for key, (ticket, consensus, vedastro) in expected.items(): + row = rows[key] + assert row["ticket_id"] == ticket + assert row["local_value"] == consensus + assert row["pyjhora_jhora_value"] == consensus + assert row["jyotishganit_value"] == consensus + assert row["vedastro_value"] == vedastro + assert row["closure_status"] == "partial_consensus_vedastro_endpoint_blocked" + assert row["claim_boundary"] == "three_engine_consensus_not_global_truth" + + +def test_d4_d9_d10_packet_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "three_engine_d4_d9_d10_field_closure_packet_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "partial" diff --git a/tests/test_three_engine_field_status_batch_2026_07_21.py b/tests/test_three_engine_field_status_batch_2026_07_21.py new file mode 100644 index 00000000..10e292e6 --- /dev/null +++ b/tests/test_three_engine_field_status_batch_2026_07_21.py @@ -0,0 +1,44 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/three_engine_field_status_batch_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_field_status_batch_adds_panchanga_ticket_and_keeps_truth_closed(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "three_engine_field_status_batch" + assert data["claim_status"] == "observation_only" + assert data["truth_matrix_allowed"] is False + assert data["summary"]["truth_upgrades"] == 0 + assert data["panchanga_ticket"]["ticket_id"] == "TEMCQ-061" + assert data["panchanga_ticket"]["closure_status"] == "open" + + +def test_field_status_batch_classifies_all_mapped_rows(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = data["rows"] + + assert len(rows) == 18 + assert data["summary"]["rows_total"] == 18 + assert data["summary"]["endpoint_semantics"] == 10 + assert data["summary"]["worked_example_required"] == 8 + assert {row["status_after_bridge"] for row in rows} == { + "ready_for_endpoint_semantics_check", + "ready_for_worked_example_comparison", + } + assert all(row["claim_boundary"] == "status_classification_only_no_numeric_truth" for row in rows) + + +def test_field_status_batch_is_registered(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "three_engine_field_status_batch_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "observation_only" diff --git a/tests/test_three_engine_high_rigor_parity.py b/tests/test_three_engine_high_rigor_parity.py index ba5c5a11..e8ca896a 100644 --- a/tests/test_three_engine_high_rigor_parity.py +++ b/tests/test_three_engine_high_rigor_parity.py @@ -1,51 +1,6 @@ -import os -from pathlib import Path -import subprocess -import sys - -from benchmarks.jyotish.scripts.run_skill_baseline import run_sample -from benchmarks.jyotish.scripts.run_pyjhora_compare import build_pyjhora_sample, compare_one from scripts import three_engine_high_rigor_parity as parity -ROOT = Path(__file__).resolve().parents[1] - - -def test_runner_imports_from_commercial_root() -> None: - env = os.environ.copy() - env["PYTHONPATH"] = str(ROOT) - result = subprocess.run( - [sys.executable, "-c", "import scripts.three_engine_high_rigor_parity"], - cwd=ROOT, - env=env, - capture_output=True, - text=True, - check=False, - ) - assert result.returncode == 0, result.stderr - - -def test_public_sample_exposes_shadbala_components() -> None: - result = run_sample(parity.SAMPLE) - assert result["ok"] is True - components = result["canonical"]["shadbala_components"] - assert set(components["Sun"]) == set(parity.VED_COMPONENT_FIELDS) - - -def test_pyjhora_sample_exposes_shadbala_components() -> None: - sample = build_pyjhora_sample(parity.SAMPLE) - assert set(sample["shadbala_components"]["Sun"]) == set(parity.VED_COMPONENT_FIELDS) - - -def test_pyjhora_matrix_includes_shadbala_components() -> None: - baseline = { - "ascendant": {}, "planets": {}, "varga": {}, "ashtakavarga": {}, "shadbala": {}, "dasha": {}, - "shadbala_components": {"Sun": {name: 1.0 for name in parity.VED_COMPONENT_FIELDS}}, - } - rows = compare_one("sample", baseline, baseline) - assert {row["field"] for row in rows if row["section"] == "Shadbala_Component" and row["body"] == "Sun"} == set(parity.VED_COMPONENT_FIELDS) - - def test_jyotishganit_planet_map_reads_divisional_occupants() -> None: chart = {"houses": [{"occupants": [{"celestialBody": "Sun", "sign": "Leo"}]}]} assert parity._jyotish_planet_signs(chart) == {"Sun": "Leo"} diff --git a/tests/test_three_engine_jyotishganit_bridge_applied.py b/tests/test_three_engine_jyotishganit_bridge_applied.py new file mode 100644 index 00000000..de508d02 --- /dev/null +++ b/tests/test_three_engine_jyotishganit_bridge_applied.py @@ -0,0 +1,46 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/three_engine_jyotishganit_bridge_applied_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_applied_bridge_maps_jyotishganit_fields_to_existing_temcq_tickets(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + + assert data["scope"] == "three_engine_jyotishganit_bridge_applied" + assert data["claim_status"] == "observation_only" + assert data["truth_matrix_allowed"] is False + assert data["source_bridge"] == "references/oracle/jyotishganit_three_engine_closure_bridge_2026_07_21.json" + assert data["summary"]["existing_ticket_rows"] == 18 + assert data["summary"]["no_existing_ticket_rows"] == 1 + assert data["summary"]["truth_upgrades"] == 0 + + +def test_applied_bridge_keeps_all_rows_open_or_comparison_ready(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + rows = data["rows"] + ticket_rows = [row for row in rows if row["existing_ticket_id"]] + panchanga = next(row for row in rows if row["field"] == "Panchanga") + + assert len(ticket_rows) == 18 + assert {row["closure_status"] for row in rows} == { + "ready_for_field_comparison", + "no_existing_ticket_create_next", + } + assert panchanga["existing_ticket_id"] is None + assert panchanga["closure_status"] == "no_existing_ticket_create_next" + assert all(row["claim_boundary"] == "field_comparison_only_no_formula_truth" for row in rows) + + +def test_applied_bridge_is_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "three_engine_jyotishganit_bridge_applied_2026_07_21" + ) + + assert entry["domain"] == "three_engine_parity" + assert entry["claim_status"] == "observation_only" diff --git a/tests/test_three_engine_mismatch_arbitrator.py b/tests/test_three_engine_mismatch_arbitrator.py index be3ac9d0..f6ca637e 100644 --- a/tests/test_three_engine_mismatch_arbitrator.py +++ b/tests/test_three_engine_mismatch_arbitrator.py @@ -1,7 +1,7 @@ import json from pathlib import Path -from scripts.three_engine_mismatch_arbitrator import arbitrate_manifest +from scripts.three_engine_mismatch_arbitrator import arbitrate_manifest, render_markdown_report ROOT = Path(__file__).resolve().parents[1] @@ -35,13 +35,16 @@ def test_vedastro_only_d2_difference_is_endpoint_semantics(tmp_path: Path) -> No assert row["differing_engines"] == ["VedAstro"] -def test_commercial_receives_mismatch_status_not_raw_truth_upgrade() -> None: - report = json.loads((ROOT / "references/oracle/three_engine_mismatch_arbitration_2026_07_19.json").read_text(encoding="utf-8")) - markdown = (ROOT / "docs/research/three_engine_mismatch_arbitration_2026_07_19.md").read_text(encoding="utf-8") +def test_markdown_report_summarizes_policy_and_category_counts() -> None: + report = arbitrate_manifest(ROOT / "references" / "oracle" / "three_engine_parity_replay_manifest.json") + markdown = render_markdown_report(report) - assert report["mismatch_count"] == 60 - assert report["classified_count"] == 60 - assert report["unclassified_count"] == 0 - assert report["truth_policy"] == "no_majority_vote" + assert "Three-engine mismatch arbitration" in markdown + assert "mismatch_count: `60`" in markdown + assert "truth_policy: `no_majority_vote`" in markdown assert "commercial_sync: `status_and_claim_boundary_only`" in markdown + assert "endpoint_or_varga_semantics" in markdown + assert "shadbala_formula_variant" in markdown + assert "ashtakavarga_table_or_contributor_variant" in markdown + assert "derived_total_from_component_variants" in markdown assert "Do not copy raw research debt into commercial runtime" in markdown diff --git a/tests/test_three_engine_parity_artifact_contract.py b/tests/test_three_engine_parity_artifact_contract.py index c55e5013..3eb7cb65 100644 --- a/tests/test_three_engine_parity_artifact_contract.py +++ b/tests/test_three_engine_parity_artifact_contract.py @@ -19,3 +19,69 @@ def test_verified_oracle_requires_raw_artifact_hash_and_settings(tmp_path): assert result["status"] == "invalid" assert any(error["error"] == "required_for_verified_status" for error in result["errors"]) + + +def test_high_rigor_parity_requires_non_d1_and_shadbala_component_rows(tmp_path): + manifest = { + "engines": { + "VedAstro": {"status": "blocked"}, + "PyJHora_JHora": {"status": "blocked"}, + "jyotishganit": {"status": "blocked"}, + }, + "comparison_rows": [ + { + "section": "D1", + "field": "Sun.sign", + "local_value": "Aquarius", + "oracle_values": {}, + "status": "match", + } + ], + } + path = tmp_path / "manifest.json" + path.write_text(json.dumps(manifest), encoding="utf-8") + + result = validate_manifest(path) + + assert result["status"] == "partial" + assert result["blocked_reason"] == "missing_high_rigor_sections" + assert "D2" in result["missing_high_rigor_sections"] + assert "shadbala_components" in result["missing_high_rigor_sections"] + + +def test_high_rigor_parity_passes_only_when_required_sections_are_present(tmp_path): + rows = [ + { + "section": section, + "field": "sample", + "local_value": 1, + "oracle_values": {"PyJHora_JHora": 1}, + "status": "match", + } + for section in [ + "D1", + "D2", + "D4", + "D9", + "D10", + "ashtakavarga_bav", + "ashtakavarga_sav", + "shadbala_total", + "shadbala_components", + ] + ] + manifest = { + "engines": { + "VedAstro": {"status": "blocked"}, + "PyJHora_JHora": {"status": "blocked"}, + "jyotishganit": {"status": "blocked"}, + }, + "comparison_rows": rows, + } + path = tmp_path / "manifest.json" + path.write_text(json.dumps(manifest), encoding="utf-8") + + result = validate_manifest(path) + + assert result["status"] == "pass" + assert result["missing_high_rigor_sections"] == [] diff --git a/tests/test_truth_source_runtime_identity.py b/tests/test_truth_source_runtime_identity.py new file mode 100644 index 00000000..8df0b28d --- /dev/null +++ b/tests/test_truth_source_runtime_identity.py @@ -0,0 +1,45 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/truth_source_runtime_identity_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_truth_source_runtime_identity_packet_is_governance_only(): + packet = json.loads(PACKET.read_text(encoding="utf-8")) + + assert packet["scope"] == "truth_source_runtime_identity" + assert packet["truth_source"]["path"] == "/Users/wuyongnaren/Documents/印度占星" + assert packet["truth_source"]["role"] == "sole_main_research_truth_source" + assert len(packet["truth_source"]["git_commit"]) == 40 + assert packet["oracle_summary"]["truth_matrix_allowed"] is False + assert packet["oracle_summary"]["production_tuning_allowed"] is False + assert packet["claim_boundary"] == "identity_ready_governance_only_not_oracle_truth" + + +def test_truth_source_runtime_identity_is_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "truth_source_runtime_identity" + ) + + assert entry["path"] == "references/oracle/truth_source_runtime_identity_2026_07_21.json" + assert entry["domain"] == "truth_source_governance" + assert entry["claim_status"] == "ready_contract" + + +def test_workbuddy_old_copy_is_quarantined_as_fragment_only(): + packet = json.loads(PACKET.read_text(encoding="utf-8")) + quarantine = packet["fragment_quarantine"]["workbuddy_old_copies"] + + assert quarantine["status"] == "quarantined" + assert set(quarantine["labels"]) == { + "not_for_truth_source", + "privacy_review_required", + "artifact_incomplete", + "historical_fragment_only", + } + assert all("/WorkBuddy/" in path or "/.workbuddy/" in path for path in quarantine["paths"]) diff --git a/tests/test_vedastro_divisional_contract_probe.py b/tests/test_vedastro_divisional_contract_probe.py new file mode 100644 index 00000000..7d8fe5e9 --- /dev/null +++ b/tests/test_vedastro_divisional_contract_probe.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from scripts import vedastro_divisional_contract_probe as probe + + +def test_probe_marks_degree_mapping_only_when_official_values_match(monkeypatch) -> None: + def fake_post(calculator, body, _timeout): + division = body["divisionalNo"] + return { + "calculator": calculator, + "status": "Pass", + "payload": { + "DivisionalLongitude": {"TotalDegrees": str(3.5 * division % 30)} + }, + } + + monkeypatch.setattr(probe, "_post", fake_post) + result = probe.probe(total_degrees=3.5, timeout=1) + + assert result["contract_status"] == "degree_mapping_verified" + assert result["chart_sign_contract"] == "blocked" + assert result["rows"]["D9"]["matches_local"] is True diff --git a/tests/test_vedastro_divisional_longitude_bridge.py b/tests/test_vedastro_divisional_longitude_bridge.py new file mode 100644 index 00000000..7039076d --- /dev/null +++ b/tests/test_vedastro_divisional_longitude_bridge.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import json +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +SCRIPTS = ROOT / "scripts" +if str(SCRIPTS) not in sys.path: + sys.path.insert(0, str(SCRIPTS)) + +import varga # noqa: E402 + + +def test_vedastro_bridge_divisional_longitudes_match_local_degree_mapping() -> None: + for division in (2, 4, 9, 10): + completed = subprocess.run( + [ + sys.executable, + str(SCRIPTS / "vedastro_python_bridge.py"), + "--method", + "DivisionalLongitude", + "--params-json", + json.dumps({"args": [3.5, division]}), + ], + cwd=ROOT, + text=True, + capture_output=True, + check=False, + ) + assert completed.returncode == 0, completed.stderr + payload = json.loads(completed.stdout) + assert payload["status"] == "ok" + assert float(payload["result"]["TotalDegrees"]) == varga.calc_varga( + 3.5, division + )["degree_in_sign"] diff --git a/tests/test_vedicastro_kp_house_cusp_probe.py b/tests/test_vedicastro_kp_house_cusp_probe.py new file mode 100644 index 00000000..2ae01fd5 --- /dev/null +++ b/tests/test_vedicastro_kp_house_cusp_probe.py @@ -0,0 +1,49 @@ +import json +import os +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +RUNTIME = Path("/tmp/vedicastro_sidereal_flatlib_probe.Nt8ANZ") +ARTIFACT = ROOT / "references/oracle/vedicastro_kp_house_cusp_probe_steve_jobs_2026_07_19.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_vedicastro_kp_house_cusp_artifact_has_12_cusps_and_hash(): + data = json.loads(ARTIFACT.read_text(encoding="utf-8")) + assert data["scope"] == "vedicastro_kp_house_cusp_probe" + assert data["claim_status"] == "observation_only" + assert data["production_tuning_allowed"] is False + assert data["truth_matrix_allowed"] is False + assert data["raw_hash"] + assert data["schema_fingerprint"]["house_count"] == 12 + fields = set(data["schema_fingerprint"]["fields"]) + assert {"LonDecDeg", "NakshatraLord", "SubLord", "SubSubLord"} <= fields + assert data["raw"]["houses"][0]["Object"] == "I" + + +def test_vedicastro_kp_house_cusp_probe_runtime_when_temp_env_exists(): + if not RUNTIME.exists(): + return + env = { + **os.environ, + "PYTHONPATH": f"{RUNTIME}:{ROOT / 'references/open_source_sources/VedicAstro'}", + } + out = subprocess.check_output( + [sys.executable, "scripts/vedicastro_kp_house_cusp_probe.py"], + cwd=ROOT, + text=True, + env=env, + ) + data = json.loads(out) + assert data["schema_fingerprint"]["house_count"] == 12 + assert data["raw"]["houses"][0]["SubLord"] + assert data["dependency_identity"]["observed_pinned_flatlib_commit"] == "2618c348ce1ab2588548f935ff65f031630b4872" + + +def test_evidence_index_registers_house_cusp_probe(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + packets = {row["packet_id"]: row for row in index["packets"]} + assert packets["vedicastro_kp_house_cusp_probe"]["claim_status"] == "observation_only" diff --git a/tests/test_vedicastro_kp_runtime_tmp_probe.py b/tests/test_vedicastro_kp_runtime_tmp_probe.py index 92010012..edcae641 100644 --- a/tests/test_vedicastro_kp_runtime_tmp_probe.py +++ b/tests/test_vedicastro_kp_runtime_tmp_probe.py @@ -26,5 +26,6 @@ def test_vedicastro_probe_reports_dependency_chain_without_truth_upgrade(): assert data["runtime_probe"]["method_present"] is True assert "SubLord" in data["runtime_probe"]["sample_rl_nl_sl"] assert "AY_KRISHNAMURTI" in data["runtime_probe"]["sidereal_ayanamsa_constants_present"] + assert data["dependency_identity"]["observed_pinned_flatlib_commit"] == "2618c348ce1ab2588548f935ff65f031630b4872" else: assert data["status"] == "blocked_runtime_import" diff --git a/tests/test_vedicastro_kp_tmp_env_preparer.py b/tests/test_vedicastro_kp_tmp_env_preparer.py new file mode 100644 index 00000000..14fe1812 --- /dev/null +++ b/tests/test_vedicastro_kp_tmp_env_preparer.py @@ -0,0 +1,36 @@ +import json +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +SCRIPT = ROOT / "scripts/prepare_vedicastro_kp_tmp_env.py" + + +def test_preparer_supports_report_only_mode_without_project_install(): + out = subprocess.check_output( + [sys.executable, str(SCRIPT), "--report-only"], + cwd=ROOT, + text=True, + ) + data = json.loads(out) + + assert data["scope"] == "vedicastro_kp_tmp_env_preparer" + assert data["target"] == "/tmp/vedicastro_flatlib_probe" + assert data["project_dependency_mutation_allowed"] is False + assert data["required_packages"]["flatlib"].startswith("git+https://github.com/diliprk/flatlib.git@sidereal") + assert data["claim_status"] in {"blocked_runtime_dependency", "runtime_dependency_ready"} + + +def test_preparer_result_never_claims_oracle_truth(): + out = subprocess.check_output( + [sys.executable, str(SCRIPT), "--report-only"], + cwd=ROOT, + text=True, + ) + data = json.loads(out) + + assert data["truth_matrix_allowed"] is False + assert data["production_tuning_allowed"] is False + assert data["boundary"] == "dependency_preparation_only_no_kp_oracle_truth" diff --git a/tests/test_whole_machine_jyotish_fragment_scan.py b/tests/test_whole_machine_jyotish_fragment_scan.py new file mode 100644 index 00000000..952fc46e --- /dev/null +++ b/tests/test_whole_machine_jyotish_fragment_scan.py @@ -0,0 +1,55 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +LEDGER = ROOT / "references/oracle/whole_machine_jyotish_fragment_scan_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_whole_machine_fragment_scan_records_external_and_privacy_buckets(): + data = json.loads(LEDGER.read_text(encoding="utf-8")) + summary = data["summary"] + + assert data["scope"] == "whole_machine_jyotish_fragment_scan_2026_07_21" + assert summary["files_with_signals"] >= 2000 + assert summary["external_signal_files"] >= 1500 + assert summary["privacy_blocked_files"] >= 900 + assert summary["reviewable_external_files"] >= 700 + + +def test_scan_keeps_old_workbuddy_out_of_truth_source(): + data = json.loads(LEDGER.read_text(encoding="utf-8")) + policy = data["decision_policy"] + + assert policy["workbuddy_fragment"] == "reference only; never truth source" + assert policy["privacy_review_required"] == "forbidden until human privacy review" + + workbuddy_rows = [ + row for row in data["reviewable_external_candidates"] + if row["category"] == "workbuddy_fragment" + ] + assert workbuddy_rows + assert all(row["decision"] == "reference_only_candidate_not_truth_source" for row in workbuddy_rows) + + +def test_scan_records_reference_layers_that_exist_but_are_not_fully_called(): + data = json.loads(LEDGER.read_text(encoding="utf-8")) + runtime = data["runtime_invocation_findings"] + + assert runtime["interpretation_source_runtime_coverage_status"] == "partial" + assert "references/open_source_sources/jyotishganit" in runtime["not_fully_closed_reference_layers"] + assert "references/open_source_sources/VedicAstro" in runtime["not_fully_closed_reference_layers"] + assert runtime["inventory_gate_status"] == "pass" + + +def test_fragment_scan_is_registered_in_evidence_index(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + entry = next( + row for row in index["packets"] + if row["packet_id"] == "whole_machine_jyotish_fragment_scan_2026_07_21" + ) + + assert entry["domain"] == "fragment_governance" + assert entry["claim_status"] == "open_queue" + assert "not truth source" in entry["claim_boundary"] diff --git a/tests/test_workbuddy_round3_candidate_ledger.py b/tests/test_workbuddy_round3_candidate_ledger.py new file mode 100644 index 00000000..4b9deda3 --- /dev/null +++ b/tests/test_workbuddy_round3_candidate_ledger.py @@ -0,0 +1,42 @@ +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/workbuddy_round3_candidate_ledger_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_workbuddy_round3_candidate_ledger_is_triage_only(): + packet = json.loads(PACKET.read_text(encoding="utf-8")) + assert packet["scope"] == "workbuddy_round3_candidate_ledger" + assert packet["claim_status"] == "open_queue" + assert packet["status"] == "candidate_triage_not_runtime_truth" + assert packet["summary"]["candidate_count"] == len(packet["entries"]) + assert packet["summary"] == { + "candidate_count": 30, + "migrate_to_registry": 14, + "migrate_to_test": 7, + "reference_only": 8, + "forbidden_private_or_obsolete": 1, + } + flags = {flag for entry in packet["entries"] for flag in entry["risk_flags"]} + assert { + "stale_workbuddy_snapshot_review_required", + "privacy_or_fixture_review_required", + "external_license_boundary", + "oracle_claim_must_not_upgrade_without_current_hash", + } <= flags + assert all(entry["risk_flags"] for entry in packet["entries"]) + assert all("Do not bulk copy WorkBuddy text" in entry["migration_boundary"] for entry in packet["entries"]) + + +def test_workbuddy_round3_candidate_ledger_is_indexed_without_truth_upgrade(): + index = json.loads(INDEX.read_text(encoding="utf-8")) + rows = [row for row in index["packets"] if row["packet_id"] == "workbuddy_round3_candidate_ledger_2026_07_21"] + assert len(rows) == 1 + row = rows[0] + assert row["claim_status"] == "open_queue" + assert row["consumer_policy"] == "research_observation_only" + assert "no runtime truth" in row["claim_boundary"] + assert "no commercial technique upgrade" in row["claim_boundary"] + assert index["summary"]["packet_count"] == len(index["packets"]) diff --git a/tests/test_workbuddy_round4_candidate_ledger.py b/tests/test_workbuddy_round4_candidate_ledger.py new file mode 100644 index 00000000..dfb4d22c --- /dev/null +++ b/tests/test_workbuddy_round4_candidate_ledger.py @@ -0,0 +1,46 @@ +import json +from pathlib import Path + + +LEDGER = Path("references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json") +ALLOWED = { + "migrate_to_registry", + "migrate_to_test", + "reference_only", + "forbidden_private_or_obsolete", +} + + +def _load(): + return json.loads(LEDGER.read_text()) + + +def test_round4_ledger_records_non_exhaustive_workbuddy_scan(): + data = _load() + assert data["claim_status"] == "fragment_audit_only" + assert data["status"] == "partial_non_exhaustive" + assert data["summary"]["round3_indexed_entries"] == 30 + assert data["summary"]["unindexed_filename_signal_total"] >= 858 + assert len(data["entries"]) == data["summary"]["round4_entries"] + + +def test_round4_decisions_are_bounded(): + data = _load() + decisions = [entry["decision"] for entry in data["entries"]] + assert set(decisions) <= ALLOWED + for decision, expected in data["summary"]["decisions"].items(): + assert decisions.count(decision) == expected + + +def test_private_or_source_insufficient_packets_are_quarantined(): + data = _load() + quarantined = [ + entry + for entry in data["entries"] + if entry["decision"] == "forbidden_private_or_obsolete" + ] + assert quarantined + for entry in quarantined: + lowered = (entry["source_path"] + " " + entry["reason"]).lower() + assert "private" in lowered or "source-insufficient" in lowered + assert entry["current_repo_same_name"] is None diff --git a/tests/test_workbuddy_round4_formalization_registry.py b/tests/test_workbuddy_round4_formalization_registry.py new file mode 100644 index 00000000..19bfb405 --- /dev/null +++ b/tests/test_workbuddy_round4_formalization_registry.py @@ -0,0 +1,55 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +REGISTRY = ROOT / "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" +ROUND4 = ROOT / "references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json" + + +def test_round4_formalization_promotes_four_domains_without_truth_upgrade(): + data = json.loads(REGISTRY.read_text(encoding="utf-8")) + assert data["scope"] == "workbuddy_round4_formalization_registry" + assert data["claim_status"] == "ready_contract" + assert data["truth_matrix_allowed"] is False + assert data["source_ledger"] == str(ROUND4.relative_to(ROOT)) + domains = {row["domain"]: row for row in data["formalized_domains"]} + assert { + "event_judgment", + "birth_time_rectification", + "muhurta", + "tajika_saham", + } <= set(domains) + for domain in domains.values(): + assert domain["formalization_type"] in {"registry", "test_contract", "registry_and_test_contract"} + assert domain["runtime_copy_allowed"] is False + assert domain["claim_upgrade"] == "none" + assert domain["round4_candidate_ids"] + assert domain["formal_outputs"] + + +def test_round4_formalization_links_specific_high_value_candidates(): + data = json.loads(REGISTRY.read_text(encoding="utf-8")) + linked = { + cid + for domain in data["formalized_domains"] + for cid in domain["round4_candidate_ids"] + } + assert "wb_round4_event_judgment_examples" in linked + assert "wb_round4_birth_time_rectification_cases" in linked + assert "wb_round4_muhurta_complete_guide" in linked + assert "wb_round4_saham_rules" in linked + round4 = json.loads(ROUND4.read_text(encoding="utf-8")) + round4_ids = {entry["candidate_id"] for entry in round4["entries"]} + assert linked <= round4_ids + + +def test_round4_formalization_is_indexed(): + packets = { + row["packet_id"]: row + for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"] + } + packet = packets["workbuddy_round4_formalization_registry_2026_07_21"] + assert packet["claim_status"] == "ready_contract" + assert packet["consumer_policy"] == "research_observation_only" diff --git a/tests/test_workbuddy_round4_remaining_closure_packet.py b/tests/test_workbuddy_round4_remaining_closure_packet.py new file mode 100644 index 00000000..3b05cfb4 --- /dev/null +++ b/tests/test_workbuddy_round4_remaining_closure_packet.py @@ -0,0 +1,40 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PACKET = ROOT / "references/oracle/workbuddy_round4_remaining_closure_packet_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_remaining_workbuddy_candidates_are_explicitly_classified(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + assert data["scope"] == "workbuddy_round4_remaining_closure_packet" + assert data["claim_status"] == "open_queue" + assert data["truth_matrix_allowed"] is False + rows = {row["candidate_id"]: row for row in data["remaining_candidates"]} + assert set(rows) == { + "wb_round4_kp_practical_event_timing", + "wb_round4_pyjhora_steve_jobs_shadbala_stdout", + "wb_round4_tajika_steve_jobs_1984_first_packet", + } + assert rows["wb_round4_kp_practical_event_timing"]["classification"] == "privacy_scrubbed_reference_only" + assert rows["wb_round4_pyjhora_steve_jobs_shadbala_stdout"]["classification"] == "parsed_observation_packet_ready" + assert rows["wb_round4_tajika_steve_jobs_1984_first_packet"]["classification"] == "blank_template_not_oracle" + + +def test_remaining_candidates_do_not_upgrade_claims(): + data = json.loads(PACKET.read_text(encoding="utf-8")) + for row in data["remaining_candidates"]: + assert row["claim_upgrade"] == "none" + assert row["next_action"] + + +def test_remaining_closure_packet_is_indexed(): + packets = { + row["packet_id"]: row + for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"] + } + packet = packets["workbuddy_round4_remaining_closure_packet_2026_07_21"] + assert packet["claim_status"] == "open_queue" + assert packet["consumer_policy"] == "research_observation_only" diff --git a/tests/test_workbuddy_round4_usage_closure_queue.py b/tests/test_workbuddy_round4_usage_closure_queue.py new file mode 100644 index 00000000..4b4d6433 --- /dev/null +++ b/tests/test_workbuddy_round4_usage_closure_queue.py @@ -0,0 +1,59 @@ +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +ROUND4 = ROOT / "references/oracle/workbuddy_round4_candidate_ledger_2026_07_21.json" +FORMAL = ROOT / "references/oracle/workbuddy_round4_formalization_registry_2026_07_21.json" +QUEUE = ROOT / "references/oracle/workbuddy_round4_usage_closure_queue_2026_07_21.json" +INDEX = ROOT / "references/oracle/evidence_packet_index_2026_07_19.json" + + +def test_every_round4_migrate_candidate_has_usage_status(): + round4 = json.loads(ROUND4.read_text(encoding="utf-8")) + queue = json.loads(QUEUE.read_text(encoding="utf-8")) + migrate_ids = { + entry["candidate_id"] + for entry in round4["entries"] + if entry["decision"] in {"migrate_to_registry", "migrate_to_test"} + } + queued_ids = {row["candidate_id"] for row in queue["candidate_status"]} + assert migrate_ids <= queued_ids + + +def test_usage_queue_separates_used_from_deferred_without_truth_upgrade(): + queue = json.loads(QUEUE.read_text(encoding="utf-8")) + assert queue["claim_status"] == "open_queue" + assert queue["truth_matrix_allowed"] is False + statuses = {row["usage_status"] for row in queue["candidate_status"]} + assert {"formalized", "deferred_pending_oracle"} <= statuses + for row in queue["candidate_status"]: + assert row["usage_status"] in { + "formalized", + "deferred_pending_oracle", + "deferred_pending_invocation_audit", + } + assert row["claim_upgrade"] == "none" + + +def test_formalized_ids_are_consistent_with_formalization_registry(): + formal = json.loads(FORMAL.read_text(encoding="utf-8")) + formalized_ids = { + cid + for domain in formal["formalized_domains"] + for cid in domain["round4_candidate_ids"] + } + queue = json.loads(QUEUE.read_text(encoding="utf-8")) + for row in queue["candidate_status"]: + if row["usage_status"] == "formalized": + assert row["candidate_id"] in formalized_ids + + +def test_usage_queue_is_indexed(): + packets = { + row["packet_id"]: row + for row in json.loads(INDEX.read_text(encoding="utf-8"))["packets"] + } + packet = packets["workbuddy_round4_usage_closure_queue_2026_07_21"] + assert packet["claim_status"] == "open_queue" + assert packet["consumer_policy"] == "research_observation_only"