variancelabs-mcp 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- variancelabs_mcp-0.3.1/.gitignore +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/.gitignore +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-fix-py-report.md +517 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-fix-web-report.md +336 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-r1.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-r2.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-review-py.md +27 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-review-web.md +32 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/global-constraints.md +21 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/implementer-rules.md +54 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/progress.md +155 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final-fix.diff +2568 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final-fix2.diff +806 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final-py.diff +5847 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final-trim.diff +9729 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final-web.diff +3882 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-final.diff +11847 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t1.diff +275 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t10-fix.diff +244 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t10.diff +433 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t11.diff +429 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t12-trim.diff +872 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t12.diff +2781 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t13-14.diff +608 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t15.diff +854 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t16.diff +571 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t17.diff +1008 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t18-fix.diff +274 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t18.diff +997 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t2.diff +323 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t3-4-fix1.diff +153 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t3-4.diff +477 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t5.diff +583 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t6.diff +551 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t7.diff +376 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t8-fix1.diff +348 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t8.diff +469 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/review-t9.diff +631 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/reviewer-instructions.md +60 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t1-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t1-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t10-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t10-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t10-r1.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t11-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t11-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t12-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t12-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t13-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t14-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t15-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t15-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t16-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t16-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t17-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t17-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t18-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t18-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t18-r1.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t19-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t2-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t2-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t3-4-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t3-4-r1.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t3-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t5-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t5-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t6-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t6-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t7-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t7-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t8-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t8-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t8-r1.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t9-base.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/t9-r0.index +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-1-brief.md +233 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-1-report.md +87 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-10-brief.md +396 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-10-report.md +182 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-11-brief.md +316 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-11-report.md +95 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-12-brief.md +512 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-12-report.md +159 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-13-14-report.md +103 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-13-brief.md +324 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-14-brief.md +237 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-15-brief.md +859 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-15-report.md +105 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-16-brief.md +546 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-16-report.md +102 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-17-brief.md +578 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-17-report.md +99 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-18-brief.md +405 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-18-report.md +273 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-19-brief.md +204 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-19-report.md +150 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-2-brief.md +220 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-2-report.md +83 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-20-brief.md +73 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-20-report.md +126 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-3-4-report.md +182 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-3-brief.md +187 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-4-brief.md +294 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-5-brief.md +596 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-5-report.md +96 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-6-brief.md +561 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-6-report.md +99 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-7-brief.md +380 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-7-report.md +85 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-8-brief.md +477 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-8-report.md +246 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-9-brief.md +653 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/task-9-report.md +123 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/wt-review +26 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/wt-snapshot +9 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/baseline.log +135 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/full.log +104 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/progress.md +33 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/t3.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/t6.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-1-brief.md +156 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-1-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-10-brief.md +304 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-10-tests.log +37 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-11-brief.md +102 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-11-tests.log +141 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-2-brief.md +432 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-2-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-3-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-4-brief.md +320 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-4-tests.log +3 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-5-brief.md +884 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-5-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-6-brief.md +209 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-6-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-7-brief.md +55 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-7-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-8-brief.md +286 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-8-tests.log +36 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-9-brief.md +113 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-block-model-estimates/task-9-tests.log +12 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/final-pytest.log +95 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/full-pytest.log +95 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/integration.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/progress.md +37 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-1-brief.md +90 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-1-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-10-brief.md +51 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-10-tests.log +65 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-11-brief.md +14 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-11-tests.log +67 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-12-brief.md +14 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-12-tests.log +66 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-13-brief.md +12 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-13-tests.log +161 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-2-brief.md +67 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-2-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-3-brief.md +60 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-3-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-4-brief.md +85 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-4-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-5-brief.md +58 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-5-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-6-brief.md +135 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-6-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-7-brief.md +66 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-7-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-8-brief.md +48 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-8-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-9-brief.md +83 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-01-eda-module/task-9-tests.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/controller-diagnostic.md +17 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/final-fix-brief.md +42 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/final-fix-report.md +150 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/pkg +16 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/progress.md +52 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-final.diff +856 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-fixwave.diff +273 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-task1.diff +63 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-task2.diff +270 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-task3.diff +475 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/review-task4.diff +105 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/snap +10 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-1-brief.md +64 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-1-report.md +88 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-2-brief.md +243 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-2-report.md +115 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-3-brief.md +343 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-3-report.md +129 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-4-brief.md +94 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-02-ray-traced-volume-performance/task-4-report.md +341 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/baseline-pytest.log +96 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/baseline-web.log +55 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/final-fix-brief.md +85 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/final-fix-report.md +163 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/final-review-context.md +75 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/global-constraints.md +15 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/implementer-rules.md +65 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/pkg +16 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/pkgp +16 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/progress.md +271 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-final-fix.diff +1405 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-final.diff +12908 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task1.diff +2221 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task10-fix1.diff +353 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task10.diff +774 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task11.diff +580 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task12.diff +1152 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task13-fix1.diff +322 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task13.diff +1982 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task14.diff +981 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task15-fix1.diff +152 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task15.diff +637 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task16.diff +744 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task17.diff +287 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task2.diff +367 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task3-fix1.diff +482 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task3.diff +884 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task4-fix1.diff +404 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task4-fix2.diff +173 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task4.diff +524 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task5.diff +504 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task6-fix1.diff +236 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task6.diff +721 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task7-fix1.diff +82 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task7.diff +703 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task8.diff +651 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/review-task9.diff +177 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/snap +10 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-1-brief.md +41 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-1-report.md +126 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-10-brief.md +113 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-10-carries.md +18 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-10-report.md +81 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-11-brief.md +113 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-11-carries.md +8 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-11-report.md +32 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-12-brief.md +29 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-12-report.md +137 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-13-brief.md +101 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-13-report.md +385 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-14-brief.md +31 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-14-report.md +34 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-15-brief.md +15 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-15-report.md +38 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-16-brief.md +43 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-16-carries.md +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-16-report.md +41 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-17-brief.md +6 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-17-report.md +144 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-2-brief.md +115 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-2-report.md +147 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-3-brief.md +116 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-3-report.md +248 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-4-brief.md +146 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-4-report.md +429 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-5-brief.md +83 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-5-report.md +169 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-6-brief.md +95 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-6-report.md +270 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-7-brief.md +74 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-7-report.md +197 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-8-brief.md +137 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-8-report.md +36 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-9-brief.md +66 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-06-qaqc-module/task-9-report.md +36 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/baseline-pytest.log +29 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/baseline-web.log +58 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/det-benchmark.log +8 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/det-cpu-timing.log +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/det-default-suite.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/det-integration.log +5 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/final-default-suite.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/final-integration.log +4 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/fix-benchmark.log +8 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/fix-default-suite.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/fix-integration.log +20 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/fix-nexus-unit.log +21 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/plan-path +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/progress.md +116 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/review-worktree.diff +8025 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-1-brief.md +490 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-1-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-10-brief.md +309 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-10-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-11-brief.md +260 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-11-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-12-brief.md +448 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-12-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-13-brief.md +591 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-13-red.log +195 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-13-step8.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-13-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-14-brief.md +220 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-14-green.log +22 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-14-red.log +61 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-14-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-15-brief.md +278 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-15-green.log +18 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-15-red.log +113 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-15-tests.log +18 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-brief.md +286 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-build.log +30 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-red.log +44 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-step3.log +40 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-step4.log +63 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-16-tests.log +3 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-bench-s2.log +0 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-benchmark.log +8 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-brief.md +233 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-done.out +5 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-gates-2.log +4 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-gates.log +31 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-17-tests.log +4 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-benchmark.log +8 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-brief.md +139 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-cpu-timing.log +1 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-default-suite.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-integration.log +4 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-tests.log +11 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-web-build.log +30 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-18-web-test.log +63 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-2-brief.md +476 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-2-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-3-brief.md +426 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-3-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-4-brief.md +444 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-4-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-5-brief.md +434 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-5-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-6-brief.md +451 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-6-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-7-brief.md +226 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-7-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-8-brief.md +429 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-8-tests.log +2 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-9-brief.md +292 -0
- variancelabs_mcp-0.3.1/.superpowers/sdd/2026-10-10-nexus-estimator/task-9-tests.log +2 -0
- variancelabs_mcp-0.3.1/CLAUDE.md +19 -0
- variancelabs_mcp-0.3.1/LICENSE +5 -0
- variancelabs_mcp-0.3.1/NEXUS.md +271 -0
- variancelabs_mcp-0.3.1/PKG-INFO +325 -0
- variancelabs_mcp-0.3.1/README.md +300 -0
- variancelabs_mcp-0.3.1/amazonas.md +104 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/assay_qaqc.csv +1517 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/collar.csv +57 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/repeats_and_duplicates_qaqc.csv +101 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/standards_qaqc.csv +101 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/standards_reference_qaqc.csv +3 -0
- variancelabs_mcp-0.3.1/data/test-dataset-QAQC/survey.csv +220 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/data-processing.md +47 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/eda.md +57 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/geometry.md +107 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/projects.md +77 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/property-modelling.md +67 -0
- variancelabs_mcp-0.3.1/doc/varianceLabs-doc/qaqc.md +97 -0
- variancelabs_mcp-0.3.1/docs/reviews/2026-10-11-nexus-vs-lva-dknn-stress-test.md +62 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-06-09-qaqc-mcp.md +2404 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-06-11-3d-viewer.md +5752 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-09-28-geometry-block-model.md +279 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-09-28-project-data-management.md +8116 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-01-block-model-estimates.md +3497 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-01-eda-module.md +860 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-02-ray-traced-volume-performance.md +880 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-02-ray-traced-volumes.md +3803 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-06-qaqc-module.md +1410 -0
- variancelabs_mcp-0.3.1/docs/superpowers/plans/2026-10-10-nexus-estimator.md +6510 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-06-09-qaqc-mcp-design.md +325 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-06-11-3d-viewer-design.md +388 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-26-web-app-shell-design.md +154 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-27-data-processing-design.md +124 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-27-property-modelling-design.md +234 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-28-geometry-block-model-design.md +290 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-28-geometry-wireframes-design.md +152 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-09-28-project-data-management-design.md +455 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-10-01-block-model-estimates-design.md +263 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-10-01-eda-module-design.md +315 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-10-02-ray-traced-volumes-design.md +369 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-10-06-qaqc-module-design.md +528 -0
- variancelabs_mcp-0.3.1/docs/superpowers/specs/2026-10-10-nexus-estimator-design.md +402 -0
- variancelabs_mcp-0.3.1/pyproject.toml +46 -0
- variancelabs_mcp-0.3.1/scripts/benchmark_nexus.py +102 -0
- variancelabs_mcp-0.3.1/scripts/dev_app_server.py +62 -0
- variancelabs_mcp-0.3.1/scripts/generate_synthetic_3d.py +213 -0
- variancelabs_mcp-0.3.1/scripts/generate_viewer_demo.py +77 -0
- variancelabs_mcp-0.3.1/src/data_processing/__init__.py +5 -0
- variancelabs_mcp-0.3.1/src/data_processing/api.py +241 -0
- variancelabs_mcp-0.3.1/src/data_processing/auto.py +80 -0
- variancelabs_mcp-0.3.1/src/data_processing/columns.py +126 -0
- variancelabs_mcp-0.3.1/src/data_processing/composite.py +104 -0
- variancelabs_mcp-0.3.1/src/data_processing/desurvey.py +371 -0
- variancelabs_mcp-0.3.1/src/data_processing/errors.py +15 -0
- variancelabs_mcp-0.3.1/src/data_processing/params.py +47 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/__init__.py +6 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/__main__.py +63 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/conditioning.py +80 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/config.py +120 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/dataset.py +106 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/preprocessing/__init__.py +7 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/preprocessing/base.py +89 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/preprocessing/coordinate.py +139 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/preprocessing/features.py +153 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/data/samples.py +215 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/errors.py +15 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/base.py +142 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/attention/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/attention/base.py +108 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/attention/ssan.py +167 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/encoders/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/encoders/base.py +79 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/encoders/numerical.py +90 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/kriging/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/kriging/attention.py +110 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/kriging/base.py +68 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/lva/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/lva/provider.py +103 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/pgrn.py +170 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/positional/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/positional/base.py +143 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/components/positional/lva.py +81 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/models/dknn.py +303 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/pipeline.py +333 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/runs.py +87 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/status.py +87 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/callbacks/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/callbacks/base.py +146 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/callbacks/common.py +199 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/losses/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/losses/base.py +45 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/losses/regression.py +22 -0
- variancelabs_mcp-0.3.1/src/deep_modelling/training/trainer.py +340 -0
- variancelabs_mcp-0.3.1/src/eda/__init__.py +2 -0
- variancelabs_mcp-0.3.1/src/eda/bivariate.py +111 -0
- variancelabs_mcp-0.3.1/src/eda/errors.py +24 -0
- variancelabs_mcp-0.3.1/src/eda/grade_tonnage.py +78 -0
- variancelabs_mcp-0.3.1/src/eda/outliers.py +169 -0
- variancelabs_mcp-0.3.1/src/eda/section.py +174 -0
- variancelabs_mcp-0.3.1/src/eda/stats.py +157 -0
- variancelabs_mcp-0.3.1/src/eda/swath.py +98 -0
- variancelabs_mcp-0.3.1/src/eda/univariate.py +83 -0
- variancelabs_mcp-0.3.1/src/geometry/__init__.py +5 -0
- variancelabs_mcp-0.3.1/src/geometry/api.py +548 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/auto.py +166 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/build.py +188 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/model.py +134 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/points.py +82 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/raycast.py +140 -0
- variancelabs_mcp-0.3.1/src/geometry/block_model/rotation.py +29 -0
- variancelabs_mcp-0.3.1/src/geometry/errors.py +15 -0
- variancelabs_mcp-0.3.1/src/geometry/params.py +143 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/grid.py +155 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/isosurface.py +112 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/mesh_io.py +42 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/points.py +153 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/rbf.py +204 -0
- variancelabs_mcp-0.3.1/src/geometry/wireframe/trend.py +56 -0
- variancelabs_mcp-0.3.1/src/nexus/__init__.py +4 -0
- variancelabs_mcp-0.3.1/src/nexus/audit.py +219 -0
- variancelabs_mcp-0.3.1/src/nexus/backend.py +97 -0
- variancelabs_mcp-0.3.1/src/nexus/config.py +177 -0
- variancelabs_mcp-0.3.1/src/nexus/covariance.py +80 -0
- variancelabs_mcp-0.3.1/src/nexus/data.py +141 -0
- variancelabs_mcp-0.3.1/src/nexus/errors.py +15 -0
- variancelabs_mcp-0.3.1/src/nexus/fields.py +99 -0
- variancelabs_mcp-0.3.1/src/nexus/krige.py +199 -0
- variancelabs_mcp-0.3.1/src/nexus/lattice.py +102 -0
- variancelabs_mcp-0.3.1/src/nexus/model.py +95 -0
- variancelabs_mcp-0.3.1/src/nexus/pipeline.py +344 -0
- variancelabs_mcp-0.3.1/src/nexus/prepare.py +148 -0
- variancelabs_mcp-0.3.1/src/nexus/search.py +154 -0
- variancelabs_mcp-0.3.1/src/nexus/select.py +219 -0
- variancelabs_mcp-0.3.1/src/nexus/structure.py +194 -0
- variancelabs_mcp-0.3.1/src/nexus/tensors.py +77 -0
- variancelabs_mcp-0.3.1/src/nexus/transform.py +218 -0
- variancelabs_mcp-0.3.1/src/nexus/trend.py +141 -0
- variancelabs_mcp-0.3.1/src/nexus/validate.py +178 -0
- variancelabs_mcp-0.3.1/src/nexus/variography.py +332 -0
- variancelabs_mcp-0.3.1/src/nexus/windows.py +177 -0
- variancelabs_mcp-0.3.1/src/project/__init__.py +3 -0
- variancelabs_mcp-0.3.1/src/project/api.py +517 -0
- variancelabs_mcp-0.3.1/src/project/eda.py +415 -0
- variancelabs_mcp-0.3.1/src/project/eda_inputs.py +221 -0
- variancelabs_mcp-0.3.1/src/project/errors.py +17 -0
- variancelabs_mcp-0.3.1/src/project/estimate.py +625 -0
- variancelabs_mcp-0.3.1/src/project/graph.py +41 -0
- variancelabs_mcp-0.3.1/src/project/kinds/__init__.py +15 -0
- variancelabs_mcp-0.3.1/src/project/kinds/base.py +148 -0
- variancelabs_mcp-0.3.1/src/project/kinds/block_model.py +143 -0
- variancelabs_mcp-0.3.1/src/project/kinds/composites.py +85 -0
- variancelabs_mcp-0.3.1/src/project/kinds/drillholes.py +131 -0
- variancelabs_mcp-0.3.1/src/project/kinds/estimate.py +80 -0
- variancelabs_mcp-0.3.1/src/project/kinds/qaqc.py +94 -0
- variancelabs_mcp-0.3.1/src/project/kinds/wireframe.py +106 -0
- variancelabs_mcp-0.3.1/src/project/lock.py +110 -0
- variancelabs_mcp-0.3.1/src/project/qaqc.py +637 -0
- variancelabs_mcp-0.3.1/src/project/qaqc_inputs.py +60 -0
- variancelabs_mcp-0.3.1/src/project/qaqc_state.py +114 -0
- variancelabs_mcp-0.3.1/src/project/rebuild.py +315 -0
- variancelabs_mcp-0.3.1/src/project/store.py +248 -0
- variancelabs_mcp-0.3.1/src/project/view.py +358 -0
- variancelabs_mcp-0.3.1/src/project/volume.py +374 -0
- variancelabs_mcp-0.3.1/src/qaqc/__init__.py +3 -0
- variancelabs_mcp-0.3.1/src/qaqc/assays.py +157 -0
- variancelabs_mcp-0.3.1/src/qaqc/blanks.py +81 -0
- variancelabs_mcp-0.3.1/src/qaqc/columns.py +114 -0
- variancelabs_mcp-0.3.1/src/qaqc/control.py +89 -0
- variancelabs_mcp-0.3.1/src/qaqc/errors.py +24 -0
- variancelabs_mcp-0.3.1/src/qaqc/flags.py +118 -0
- variancelabs_mcp-0.3.1/src/qaqc/geometry.py +515 -0
- variancelabs_mcp-0.3.1/src/qaqc/grades.py +357 -0
- variancelabs_mcp-0.3.1/src/qaqc/precision.py +223 -0
- variancelabs_mcp-0.3.1/src/qaqc/settings.py +85 -0
- variancelabs_mcp-0.3.1/src/qaqc/spatial.py +178 -0
- variancelabs_mcp-0.3.1/src/qaqc/standards.py +285 -0
- variancelabs_mcp-0.3.1/src/qaqc/tables.py +407 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/__init__.py +3 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/http.py +371 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/commodity-BeghJJO5.js +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/data-BBR8ohi9.js +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/data-BRn88FhW.css +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/eda-CY4tQx12.js +24 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/favicon-CIQSujzg.svg +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/model-C9RVWWHg.js +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/panel-C0gWHtYp.js +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/panel-CS8ygObe.css +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/qaqc-DMsmbNNl.css +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/qaqc-DqMkqumO.js +14 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/toast-IrarPPYk.css +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/toast-QrpmyZNy.js +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/viewer-BSSt0_Hc.js +4303 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/assets/viewer-C4FoFwwc.css +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/data/index.html +19 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/eda/index.html +19 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/index.html +10 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/qaqc/index.html +21 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/app/static/viewer/index.html +21 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/common/__init__.py +0 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/common/columns.py +20 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/common/errors.py +21 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/config.py +24 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/eda/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/eda/tools.py +211 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/geometry/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/geometry/tools.py +138 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/modelling/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/modelling/tools.py +96 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/processing/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/processing/tools.py +102 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/project/__init__.py +1 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/project/tools.py +235 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/qaqc/__init__.py +0 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/qaqc/tools.py +254 -0
- variancelabs_mcp-0.3.1/src/variancelabs_mcp/server.py +31 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/favicon.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db1-icon-filled-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db1-icon-filled.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db1-icon-outline-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db1-icon-outline.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db2-icon-filled-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db2-icon-filled.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db2-icon-outline-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db2-icon-outline.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db3-icon-filled-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db3-icon-filled.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db3-icon-outline-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db3-icon-outline.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db4-icon-filled-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db4-icon-filled.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db4-icon-outline-purple.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/assets/icons/updated-icons_db4-icon-outline.svg +1 -0
- variancelabs_mcp-0.3.1/src/web-app/data/index.html +14 -0
- variancelabs_mcp-0.3.1/src/web-app/eda/index.html +14 -0
- variancelabs_mcp-0.3.1/src/web-app/index.html +10 -0
- variancelabs_mcp-0.3.1/src/web-app/package-lock.json +2234 -0
- variancelabs_mcp-0.3.1/src/web-app/package.json +22 -0
- variancelabs_mcp-0.3.1/src/web-app/qaqc/index.html +14 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/analysis.css +122 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/Chart.ts +620 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/scale.test.ts +34 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/scale.ts +124 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/theme.ts +43 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/view.test.ts +22 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/chart/view.ts +53 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/panel.ts +38 -0
- variancelabs_mcp-0.3.1/src/web-app/src/analysis/ui.ts +154 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/CommodityPicker.test.ts +27 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/CommodityPicker.ts +25 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/DataList.test.ts +89 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/DataList.ts +83 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/EditPanel.test.ts +458 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/EditPanel.ts +670 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/ObjectMenu.test.ts +74 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/ObjectMenu.ts +34 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/dialogs.ts +26 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/forms/spec.test.ts +37 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/forms/spec.ts +306 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/forms/state.test.ts +116 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/forms/state.ts +129 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/main.ts +138 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/model.test.ts +139 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/model.ts +192 -0
- variancelabs_mcp-0.3.1/src/web-app/src/data/style.css +125 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/main.ts +186 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/bivariate.ts +130 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/common.ts +25 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/gradeTonnage.ts +80 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/index.ts +17 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/outliers.ts +139 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/section.test.ts +28 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/section.ts +186 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/swath.ts +84 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/types.ts +22 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/panels/univariate.ts +127 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/state.test.ts +30 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/state.ts +91 -0
- variancelabs_mcp-0.3.1/src/web-app/src/eda/types.ts +137 -0
- variancelabs_mcp-0.3.1/src/web-app/src/project/ProjectClient.test.ts +143 -0
- variancelabs_mcp-0.3.1/src/web-app/src/project/ProjectClient.ts +179 -0
- variancelabs_mcp-0.3.1/src/web-app/src/project/commodity.test.ts +28 -0
- variancelabs_mcp-0.3.1/src/web-app/src/project/commodity.ts +31 -0
- variancelabs_mcp-0.3.1/src/web-app/src/project/types.ts +162 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/flags.test.ts +41 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/flags.ts +219 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/main.test.ts +66 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/main.ts +272 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/blanks.ts +100 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/checks.test.ts +122 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/common.ts +59 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/duplicates.test.ts +10 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/duplicates.ts +160 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/geometry.ts +164 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/grades.ts +120 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/index.ts +22 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/issues.ts +154 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/panels.test.ts +105 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/spatial.ts +106 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/standards.ts +167 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/summary.ts +111 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/panels/types.ts +35 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/state.test.ts +51 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/state.ts +129 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/style.css +89 -0
- variancelabs_mcp-0.3.1/src/web-app/src/qaqc/types.ts +335 -0
- variancelabs_mcp-0.3.1/src/web-app/src/shell/modules.ts +53 -0
- variancelabs_mcp-0.3.1/src/web-app/src/shell/shell.test.ts +67 -0
- variancelabs_mcp-0.3.1/src/web-app/src/shell/shell.ts +59 -0
- variancelabs_mcp-0.3.1/src/web-app/src/shell/theme.css +45 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/CameraRig.test.ts +15 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/CameraRig.ts +67 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/ColormapLUT.ts +24 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/Engine.ts +109 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/Gizmo.ts +52 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/SceneManager.test.ts +48 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/SceneManager.ts +59 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/SelectionOutline.test.ts +26 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/SelectionOutline.ts +231 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/core/shaders.ts +33 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/data/poll.test.ts +64 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/data/poll.ts +43 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/data/types.ts +144 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/interaction/SelectionInput.ts +61 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/BlockModelLayer.test.ts +301 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/BlockModelLayer.ts +525 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/DrillholeLayer.test.ts +23 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/DrillholeLayer.ts +388 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/GridLayer.test.ts +35 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/GridLayer.ts +70 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/Layer.ts +13 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/WireframeLayer.test.ts +208 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/layers/WireframeLayer.ts +282 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/categories.test.ts +18 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/categories.ts +19 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/classes.test.ts +39 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/classes.ts +58 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/colormaps.test.ts +65 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/colormaps.ts +102 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/cylinder.test.ts +53 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/cylinder.ts +52 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/diff.test.ts +52 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/diff.ts +65 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/estimates.test.ts +38 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/estimates.ts +33 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/format.test.ts +22 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/format.ts +7 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/holeStats.test.ts +60 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/holeStats.ts +80 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/pick.test.ts +67 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/pick.ts +64 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/segments.test.ts +58 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/segments.ts +76 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/visibility.test.ts +61 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/lib/visibility.ts +53 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/main.ts +365 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/objects/blockModels.test.ts +187 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/objects/blockModels.ts +159 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/objects/drillholes.ts +102 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/objects/wireframes.test.ts +138 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/objects/wireframes.ts +108 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/state/Selection.test.ts +95 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/state/Selection.ts +98 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/style.css +155 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/BlockModelDisplay.test.ts +155 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/BlockModelDisplay.ts +458 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/ColorBar.ts +34 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/DrillholeDisplay.ts +310 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/PalettePicker.ts +76 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/ProjectBrowser.test.ts +70 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/ProjectBrowser.ts +238 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/PropertiesPanel.ts +56 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/Toolbar.ts +33 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/WireframeDisplay.ts +83 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/dom.ts +13 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/facts.ts +13 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/ui/toast.ts +9 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/ChunkCache.test.ts +75 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/ChunkCache.ts +110 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/FakeVolume.ts +30 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/VolumeModel.test.ts +89 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/VolumeModel.ts +415 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/VolumeOverlay.ts +166 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/fixtures.ts +19 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/frame.test.ts +34 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/frame.ts +47 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/lod.test.ts +66 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/lod.ts +77 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/records.test.ts +33 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/records.ts +45 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/shaders.test.ts +11 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/shaders.ts +221 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/tree.test.ts +32 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/tree.ts +63 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/types.ts +85 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/walk.test.ts +174 -0
- variancelabs_mcp-0.3.1/src/web-app/src/viewer/volume/walk.ts +123 -0
- variancelabs_mcp-0.3.1/src/web-app/tsconfig.json +15 -0
- variancelabs_mcp-0.3.1/src/web-app/viewer/index.html +17 -0
- variancelabs_mcp-0.3.1/src/web-app/vite.config.ts +30 -0
- variancelabs_mcp-0.3.1/tests/__init__.py +0 -0
- variancelabs_mcp-0.3.1/tests/bm_meshes.py +30 -0
- variancelabs_mcp-0.3.1/tests/conftest.py +63 -0
- variancelabs_mcp-0.3.1/tests/estimate_helpers.py +110 -0
- variancelabs_mcp-0.3.1/tests/nexus_helpers.py +70 -0
- variancelabs_mcp-0.3.1/tests/project_helpers.py +64 -0
- variancelabs_mcp-0.3.1/tests/qaqc_helpers.py +43 -0
- variancelabs_mcp-0.3.1/tests/test_app_e2e.py +61 -0
- variancelabs_mcp-0.3.1/tests/test_app_http.py +300 -0
- variancelabs_mcp-0.3.1/tests/test_columns.py +14 -0
- variancelabs_mcp-0.3.1/tests/test_eda_engine.py +291 -0
- variancelabs_mcp-0.3.1/tests/test_eda_tools.py +80 -0
- variancelabs_mcp-0.3.1/tests/test_errors.py +14 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_api.py +152 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_api.py +213 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_build.py +122 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_model.py +71 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_points.py +36 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_raycast.py +127 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_rotation.py +66 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_bm_tools.py +106 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_holes_input.py +76 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_isosurface.py +127 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_mesh_io.py +36 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_points.py +110 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_rbf.py +110 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_tools.py +93 -0
- variancelabs_mcp-0.3.1/tests/test_geometry_trend.py +49 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_conditioning.py +67 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_data.py +250 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_model.py +112 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_pipeline.py +150 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_runs.py +170 -0
- variancelabs_mcp-0.3.1/tests/test_modelling_tools.py +92 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_audit.py +73 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_config.py +79 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_core.py +124 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_covariance.py +148 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_gates.py +110 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_krige.py +113 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_pipeline.py +182 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_prepare.py +130 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_select.py +88 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_structure.py +132 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_trend.py +51 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_validate.py +80 -0
- variancelabs_mcp-0.3.1/tests/test_nexus_windows.py +137 -0
- variancelabs_mcp-0.3.1/tests/test_processing_api.py +162 -0
- variancelabs_mcp-0.3.1/tests/test_processing_columns.py +66 -0
- variancelabs_mcp-0.3.1/tests/test_processing_composite.py +132 -0
- variancelabs_mcp-0.3.1/tests/test_processing_coordinates.py +90 -0
- variancelabs_mcp-0.3.1/tests/test_processing_desurvey.py +226 -0
- variancelabs_mcp-0.3.1/tests/test_processing_tools.py +101 -0
- variancelabs_mcp-0.3.1/tests/test_project_api.py +334 -0
- variancelabs_mcp-0.3.1/tests/test_project_eda.py +112 -0
- variancelabs_mcp-0.3.1/tests/test_project_estimate.py +295 -0
- variancelabs_mcp-0.3.1/tests/test_project_estimate_kind.py +123 -0
- variancelabs_mcp-0.3.1/tests/test_project_estimate_nexus.py +162 -0
- variancelabs_mcp-0.3.1/tests/test_project_kinds_geometry.py +121 -0
- variancelabs_mcp-0.3.1/tests/test_project_kinds_intervals.py +113 -0
- variancelabs_mcp-0.3.1/tests/test_project_lock.py +148 -0
- variancelabs_mcp-0.3.1/tests/test_project_qaqc.py +222 -0
- variancelabs_mcp-0.3.1/tests/test_project_rebuild.py +329 -0
- variancelabs_mcp-0.3.1/tests/test_project_store.py +100 -0
- variancelabs_mcp-0.3.1/tests/test_project_tools.py +129 -0
- variancelabs_mcp-0.3.1/tests/test_project_view.py +307 -0
- variancelabs_mcp-0.3.1/tests/test_qaqc_demo.py +25 -0
- variancelabs_mcp-0.3.1/tests/test_qaqc_engine.py +953 -0
- variancelabs_mcp-0.3.1/tests/test_qaqc_state.py +55 -0
- variancelabs_mcp-0.3.1/tests/test_qaqc_tools.py +114 -0
- variancelabs_mcp-0.3.1/tests/test_server.py +17 -0
- variancelabs_mcp-0.3.1/tests/test_smoke.py +7 -0
- variancelabs_mcp-0.3.1/tests/test_volume.py +119 -0
- variancelabs_mcp-0.3.1/uv.lock +1854 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*
|
variancelabs_mcp-0.3.1/.superpowers/sdd/2026-09-28-project-data-management/final-fix-py-report.md
ADDED
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
# Final review fix pass — Python (implementer report)
|
|
2
|
+
|
|
3
|
+
Scope: every "Important" and "Minor (fix now)" item in `final-review-py.md`, Python side
|
|
4
|
+
only. Nothing under "Left as is" was touched. `src/web-app/` was not touched, no `npm`
|
|
5
|
+
commands were run.
|
|
6
|
+
|
|
7
|
+
Commits created: none (uncommitted by rule — CLAUDE.md forbids commits).
|
|
8
|
+
|
|
9
|
+
## Method
|
|
10
|
+
|
|
11
|
+
For each item: wrote/extended the test, reverted the corresponding source hunk back to
|
|
12
|
+
its pre-fix form (recorded from the edit I was about to make), ran the test to confirm
|
|
13
|
+
RED, restored the fix, ran again to confirm GREEN. RED/GREEN evidence is per item below.
|
|
14
|
+
At the end, ran the full suite once.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Important #1 — recovery skipped forever after a fresh build.lock at open time
|
|
19
|
+
|
|
20
|
+
`src/project/rebuild.py`
|
|
21
|
+
|
|
22
|
+
- `recover()` now returns `bool`: `False` when it was skipped (`TimeoutError` acquiring
|
|
23
|
+
`build.lock`), `True` once it actually ran.
|
|
24
|
+
- `ensure_recovered()` no longer marks the project "recovered" before calling `recover()`.
|
|
25
|
+
It now: returns immediately if already recovered; treats the project as recovered
|
|
26
|
+
without touching the lock if this process already owns a live `_Worker` for it (a
|
|
27
|
+
worker means this process's own jobs already keep the index in sync — recovering here
|
|
28
|
+
too could race a build it just started); otherwise calls `recover()` and only records
|
|
29
|
+
the project as recovered if it returned `True`. So a later call (the next `_store()` or
|
|
30
|
+
`open_project()`) retries once the lock is free.
|
|
31
|
+
- `src/variancelabs_mcp/app/http.py`: `_store()` now calls `rebuild.ensure_recovered(s)`
|
|
32
|
+
before returning the store, so every HTTP request (not just `project_open`) can trigger
|
|
33
|
+
the retry — closing "it clears only when B's MCP process restarts".
|
|
34
|
+
|
|
35
|
+
Tests (`tests/test_project_rebuild.py`):
|
|
36
|
+
- `test_ensure_recovered_retries_once_the_lock_is_gone` — holds `build.lock`, calls
|
|
37
|
+
`ensure_recovered` (must be skipped, object stays "building"), releases the lock, calls
|
|
38
|
+
`ensure_recovered` again (must now run: object becomes "failed"/"interrupted").
|
|
39
|
+
- `test_ensure_recovered_is_skipped_once_this_process_has_a_worker` — submits a job first
|
|
40
|
+
(creating a worker), then calls `ensure_recovered`; the stuck "building" object must be
|
|
41
|
+
left alone (no attempt to grab the lock from under the worker).
|
|
42
|
+
|
|
43
|
+
RED (old `ensure_recovered`, marked recovered before calling `recover()`):
|
|
44
|
+
```
|
|
45
|
+
$ uv run pytest tests/test_project_rebuild.py -k ensure_recovered -q
|
|
46
|
+
FAILED tests/test_project_rebuild.py::test_ensure_recovered_retries_once_the_lock_is_gone
|
|
47
|
+
FAILED tests/test_project_rebuild.py::test_ensure_recovered_is_skipped_once_this_process_has_a_worker
|
|
48
|
+
2 failed
|
|
49
|
+
```
|
|
50
|
+
GREEN:
|
|
51
|
+
```
|
|
52
|
+
$ uv run pytest tests/test_project_rebuild.py -k ensure_recovered -q
|
|
53
|
+
2 passed
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Important #2 — merge() turns transform: "auto" into "delete the key"
|
|
59
|
+
|
|
60
|
+
`src/project/api.py`: added `LITERAL_AUTO = ("transform",)`; `merge()` only pops the key
|
|
61
|
+
on `"auto"` when the key is not in `LITERAL_AUTO`.
|
|
62
|
+
|
|
63
|
+
Test (`tests/test_project_api.py::test_merge_keeps_a_literal_auto_for_transform`).
|
|
64
|
+
|
|
65
|
+
RED:
|
|
66
|
+
```
|
|
67
|
+
$ uv run pytest tests/test_project_api.py -k merge_keeps_a_literal_auto -q
|
|
68
|
+
FAILED ... assert {'options': {}} == {'options': {'transform': 'auto'}}
|
|
69
|
+
1 failed
|
|
70
|
+
```
|
|
71
|
+
GREEN:
|
|
72
|
+
```
|
|
73
|
+
$ uv run pytest tests/test_project_api.py -k merge_keeps_a_literal_auto -q
|
|
74
|
+
1 passed
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Important #3 — Windows delete-pending PermissionError is fatal in FileLock
|
|
80
|
+
|
|
81
|
+
`src/project/lock.py`:
|
|
82
|
+
- `held()` now also catches `PermissionError` and returns `True` (a delete-pending file
|
|
83
|
+
is treated as held/fresh rather than "gone", so it is never stolen or removed
|
|
84
|
+
mid-flight).
|
|
85
|
+
- `acquire()` now catches `(FileExistsError, PermissionError)` from `os.open` and retries
|
|
86
|
+
through the same contended-lock path instead of propagating the raw error.
|
|
87
|
+
|
|
88
|
+
Tests (`tests/test_project_lock.py`):
|
|
89
|
+
- `test_held_treats_a_permission_error_as_held` — monkeypatches `Path.stat` to raise
|
|
90
|
+
`PermissionError`; `held()` must return `True`.
|
|
91
|
+
- `test_acquire_retries_past_a_permission_error_from_open` — monkeypatches `os.open` to
|
|
92
|
+
raise `PermissionError` once, then succeed; `acquire()` must retry transparently.
|
|
93
|
+
|
|
94
|
+
RED:
|
|
95
|
+
```
|
|
96
|
+
$ uv run pytest tests/test_project_lock.py -k "permission_error" -q
|
|
97
|
+
FAILED tests/test_project_lock.py::test_held_treats_a_permission_error_as_held
|
|
98
|
+
FAILED tests/test_project_lock.py::test_acquire_retries_past_a_permission_error_from_open
|
|
99
|
+
2 failed
|
|
100
|
+
```
|
|
101
|
+
GREEN:
|
|
102
|
+
```
|
|
103
|
+
$ uv run pytest tests/test_project_lock.py -k "permission_error" -q
|
|
104
|
+
2 passed
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Important #4 — update/retry accept building/waiting/version-0 objects; stale version
|
|
110
|
+
|
|
111
|
+
`src/project/api.py`:
|
|
112
|
+
- New `_busy_object(o, verb)` helper builds the `project_busy` `ProjectError`.
|
|
113
|
+
- `update(s, oid, params, *, wait=None, version=None)`: after the existing
|
|
114
|
+
`object_not_found` (via `_object`) and `imported` → `not_rebuildable` checks, refuses
|
|
115
|
+
with `project_busy` when `status in rebuild.ACTIVE` or `version == 0`; then, if
|
|
116
|
+
`version` is given and differs from the object's current version, refuses with
|
|
117
|
+
`stale_object` ("Changed elsewhere" / "Close and reopen Edit parameters."). Only then
|
|
118
|
+
does it merge/validate/submit.
|
|
119
|
+
- `retry(s, oid, *, wait=None)`: same busy check before the existing
|
|
120
|
+
failed/out_of_date check (so building/waiting/version-0 now answer 409 `project_busy`
|
|
121
|
+
instead of 400 `invalid_params`; a merely "ready" object still answers 400).
|
|
122
|
+
- `src/variancelabs_mcp/app/http.py`: `STATUS["stale_object"] = 409`; POST
|
|
123
|
+
`/api/object/update` now reads `body.get("version")` and passes it through to
|
|
124
|
+
`api.update` only when it is a (non-bool) `int`.
|
|
125
|
+
|
|
126
|
+
Tests:
|
|
127
|
+
- `tests/test_project_api.py::test_update_and_retry_refuse_while_the_object_is_active_or_unbuilt`
|
|
128
|
+
- `tests/test_project_api.py::test_update_refuses_a_stale_version`
|
|
129
|
+
- `tests/test_app_http.py::test_update_conflict_returns_409_stale_object_on_a_version_mismatch`
|
|
130
|
+
|
|
131
|
+
RED:
|
|
132
|
+
```
|
|
133
|
+
$ uv run pytest tests/test_project_api.py -k "active_or_unbuilt or stale_version" tests/test_app_http.py -k "stale_object" -q
|
|
134
|
+
FAILED tests/test_project_api.py::test_update_and_retry_refuse_while_the_object_is_active_or_unbuilt
|
|
135
|
+
FAILED tests/test_project_api.py::test_update_refuses_a_stale_version - TypeError: update() got an unexpected keyword argument 'version'
|
|
136
|
+
FAILED tests/test_app_http.py::test_update_conflict_returns_409_stale_object_on_a_version_mismatch
|
|
137
|
+
3 failed
|
|
138
|
+
```
|
|
139
|
+
GREEN:
|
|
140
|
+
```
|
|
141
|
+
$ uv run pytest tests/test_project_api.py -k "active_or_unbuilt or stale_version" tests/test_app_http.py -k "stale_object" -q
|
|
142
|
+
3 passed
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Important #5 — a crafted project.json can read/delete outside the project
|
|
148
|
+
|
|
149
|
+
`src/project/store.py`: `ProjectStore.read()` now validates, for every entry in
|
|
150
|
+
`data["objects"]`: the key matches `SAFE_KEY_RE` (new: `^[A-Za-z0-9_-]{1,128}$` — a
|
|
151
|
+
single path segment, no `..`, no separators) **and** `o["id"] == key`; and `version` is a
|
|
152
|
+
non-bool `int >= 0`. Any violation raises `project_corrupt`. Since `source_dir`/
|
|
153
|
+
`object_dir` are built directly from the key, this is the single gate that protects both
|
|
154
|
+
the Data-page `Remove` route and `/api/object`/`/files` from a crafted or foreign
|
|
155
|
+
`project.json`.
|
|
156
|
+
|
|
157
|
+
**Deviation from the brief**: the brief says "every key must match `UUID_RE`". I used a
|
|
158
|
+
looser `SAFE_KEY_RE` (alnum/`_`/`-` only) instead of the full canonical-UUID pattern.
|
|
159
|
+
Reason: production code always creates object ids via `store.new_id()` (a real uuid4),
|
|
160
|
+
so this doesn't weaken anything in real use — but the existing unit-test suite (
|
|
161
|
+
`tests/project_helpers.py:rec()` and its callers in `test_project_rebuild.py`,
|
|
162
|
+
`test_project_kinds_geometry.py`, `test_project_kinds_intervals.py`, pre-dating this fix
|
|
163
|
+
pass) hand-builds objects with short ids like `"a"`, `"dh"`, `"wf"`, `"bm"` for
|
|
164
|
+
readability. Enforcing strict `UUID_RE` broke that whole convention (16+ pre-existing
|
|
165
|
+
tests started raising `project_corrupt`). `SAFE_KEY_RE` still closes the actual
|
|
166
|
+
vulnerability (any key containing `/`, `\`, or `..` is rejected), while keeping those
|
|
167
|
+
fixtures valid. Flagging this in case the intent was specifically to force test fixtures
|
|
168
|
+
onto real UUIDs too — happy to switch if so, but it looked like an oversight rather than
|
|
169
|
+
a requirement.
|
|
170
|
+
|
|
171
|
+
Test (`tests/test_project_api.py::test_read_rejects_object_keys_that_are_not_valid_ids`) —
|
|
172
|
+
plants `"../../victim"` as an object key via `mutate`, expects `s.read()` to raise
|
|
173
|
+
`project_corrupt`, and checks the legitimate object's source folder is untouched.
|
|
174
|
+
|
|
175
|
+
RED:
|
|
176
|
+
```
|
|
177
|
+
$ uv run pytest tests/test_project_api.py -k rejects_object_keys -q
|
|
178
|
+
FAILED tests/test_project_api.py::test_read_rejects_object_keys_that_are_not_valid_ids
|
|
179
|
+
1 failed
|
|
180
|
+
```
|
|
181
|
+
GREEN:
|
|
182
|
+
```
|
|
183
|
+
$ uv run pytest tests/test_project_api.py -k rejects_object_keys -q
|
|
184
|
+
1 passed
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Important #6 — has_view never reaches the client
|
|
190
|
+
|
|
191
|
+
`src/project/api.py`: added `"has_view"` to `SUMMARY_KEYS`, so it now flows through
|
|
192
|
+
`object_summary()` into `summary()`, `project_view()` and `details()["object"]`.
|
|
193
|
+
|
|
194
|
+
Test (`tests/test_project_api.py::test_summary_includes_has_view`).
|
|
195
|
+
|
|
196
|
+
RED:
|
|
197
|
+
```
|
|
198
|
+
$ uv run pytest tests/test_project_api.py -k summary_includes_has_view -q
|
|
199
|
+
FAILED ... KeyError: 'has_view'
|
|
200
|
+
1 failed
|
|
201
|
+
```
|
|
202
|
+
GREEN:
|
|
203
|
+
```
|
|
204
|
+
$ uv run pytest tests/test_project_api.py -k summary_includes_has_view -q
|
|
205
|
+
1 passed
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Minor fixes (all ruled "fix now")
|
|
211
|
+
|
|
212
|
+
1. **`hmac.compare_digest` TypeError on a non-ASCII token** — `http.py:_authorized` now
|
|
213
|
+
compares UTF-8-encoded bytes on both sides instead of raw `str`, so a non-ASCII
|
|
214
|
+
`?token=` is a clean 403 instead of a dropped connection.
|
|
215
|
+
Test: `test_app_http.py::test_a_non_ascii_token_is_a_clean_403_not_a_dropped_connection`.
|
|
216
|
+
|
|
217
|
+
2. **HTTP only caught `ProjectError`** — both `do_GET`'s `/api/*` dispatch and `do_POST`'s
|
|
218
|
+
dispatch now also catch bare `Exception` and answer `500 {"error": problem_of(e)}`
|
|
219
|
+
(`rebuild.problem_of`), instead of letting e.g. a `PermissionError` or
|
|
220
|
+
`ProcessingError` drop the socket.
|
|
221
|
+
Test: `test_app_http.py::test_unexpected_exceptions_return_a_problem_not_a_dropped_connection`
|
|
222
|
+
(monkeypatches `api.details` to raise `PermissionError`).
|
|
223
|
+
|
|
224
|
+
3. **Rename during a new object's first build overwritten by `auto_name` at commit** —
|
|
225
|
+
`api.rename_object` now also sets `auto_name=False`, so `rebuild.py`'s
|
|
226
|
+
`commit()` (`if o.pop("auto_name", False): o["name"] = module.default_name(...)`) no
|
|
227
|
+
longer clobbers a rename that happened mid-build.
|
|
228
|
+
Test: `test_project_rebuild.py::test_rename_during_build_is_not_overwritten_by_auto_name_commit`.
|
|
229
|
+
|
|
230
|
+
4. **MAX_PATH / raw OSError past the tool boundary** — `variancelabs_mcp/project/tools.py`:
|
|
231
|
+
`call()` and `_project_create()` now also catch `(OSError, TimeoutError)`; `problem()`
|
|
232
|
+
turns them into a `Problem(type="io_error", ...)` whose remediation mentions Windows
|
|
233
|
+
error 206 / `LongPathsEnabled`, instead of propagating a raw traceback past the tool.
|
|
234
|
+
One line added to `doc/varianceLabs-doc/projects.md`... (see docs section below;
|
|
235
|
+
MAX_PATH itself is not separately documented beyond the remediation text, per "must be
|
|
236
|
+
minimal").
|
|
237
|
+
Tests: `test_project_tools.py::test_os_errors_become_a_problem_not_a_raw_crash`.
|
|
238
|
+
|
|
239
|
+
5. **Empty default project name at a drive-root cwd** — `open_store()` now falls back to
|
|
240
|
+
`"project"` when `Path.cwd().name` is empty.
|
|
241
|
+
Test: `test_project_tools.py::test_default_project_name_falls_back_when_cwd_name_is_empty`.
|
|
242
|
+
|
|
243
|
+
6. **Heartbeat gives up for good on one transient read failure** — `lock.py:_beat` now
|
|
244
|
+
only stops when `_read_token()` returns a *readable, different* token; a `None` read
|
|
245
|
+
(transient failure) or an `OSError` from `os.utime` is `continue`d past instead of
|
|
246
|
+
returning.
|
|
247
|
+
Tests: `test_project_lock.py::test_heartbeat_ignores_a_transient_read_failure` (stays
|
|
248
|
+
held across the full window despite one failed read) and
|
|
249
|
+
`test_heartbeat_stops_once_a_foreign_token_takes_the_lock` (unchanged correct-stop
|
|
250
|
+
behaviour, added as a companion so the fix doesn't accidentally make the heartbeat
|
|
251
|
+
immortal).
|
|
252
|
+
|
|
253
|
+
7. **`ensure_recovered` retry test** — covered under Important #1 above (same fix).
|
|
254
|
+
|
|
255
|
+
RED (minors #1-3, #6 together — #4/#5 shown above under their own item):
|
|
256
|
+
```
|
|
257
|
+
$ uv run pytest tests/test_app_http.py -k "non_ascii or unexpected_exceptions" tests/test_project_rebuild.py -k rename_during_build tests/test_project_lock.py -k "heartbeat_ignores" -q
|
|
258
|
+
FAILED tests/test_app_http.py::test_a_non_ascii_token_is_a_clean_403_not_a_dropped_connection
|
|
259
|
+
FAILED tests/test_app_http.py::test_unexpected_exceptions_return_a_problem_not_a_dropped_connection
|
|
260
|
+
FAILED tests/test_project_rebuild.py::test_rename_during_build_is_not_overwritten_by_auto_name_commit
|
|
261
|
+
FAILED tests/test_project_lock.py::test_heartbeat_ignores_a_transient_read_failure
|
|
262
|
+
4 failed
|
|
263
|
+
```
|
|
264
|
+
GREEN:
|
|
265
|
+
```
|
|
266
|
+
$ uv run pytest tests/test_app_http.py -k "non_ascii or unexpected_exceptions" tests/test_project_rebuild.py -k rename_during_build tests/test_project_lock.py -k "heartbeat_ignores" -q
|
|
267
|
+
4 passed
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Docs (minor, no tests)
|
|
271
|
+
|
|
272
|
+
- `doc/varianceLabs-doc/projects.md`: corrected "what depends on it is marked out of
|
|
273
|
+
date" (true only for a downstream failure, not when the edited object itself fails —
|
|
274
|
+
its dependents keep their current version, per `rebuild.py`'s
|
|
275
|
+
`test_failure_of_the_edited_object_keeps_its_version`); added one line on
|
|
276
|
+
`VARIANCELABS_OUTPUT_DIR` spanning project resolution across folders.
|
|
277
|
+
- `README.md`: `project_create(name)` → `project_create(name, open?)`.
|
|
278
|
+
- `src/variancelabs_mcp/project/tools.py` (`LOAD_DH_DOC`): named the six roles
|
|
279
|
+
(`x_from, y_from, z_from, x_to, y_to, z_to`) instead of the `X_FROM ... Z_TO` ellipsis.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Full suite
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
$ uv run pytest -q
|
|
287
|
+
474 passed, 225 warnings in 109.98s (0:01:49)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
225 warnings, all the pre-existing kaleido/plotly ones (same set as the stated baseline);
|
|
291
|
+
no new warnings introduced. `tests/test_app_e2e.py` (reads the committed web bundle) is
|
|
292
|
+
included and passed — no web-side dependency issue observed.
|
|
293
|
+
|
|
294
|
+
## Files changed
|
|
295
|
+
|
|
296
|
+
- `src/project/rebuild.py` — `recover()`/`ensure_recovered()` (Important #1)
|
|
297
|
+
- `src/project/lock.py` — `held()`, `acquire()`, `_beat()` (Important #3, Minor #6)
|
|
298
|
+
- `src/project/store.py` — `ProjectStore.read()` object-key/version validation
|
|
299
|
+
(Important #5, with the `SAFE_KEY_RE` deviation noted above)
|
|
300
|
+
- `src/project/api.py` — `SUMMARY_KEYS` (#6), `merge()`/`LITERAL_AUTO` (#2),
|
|
301
|
+
`update()`/`retry()`/`_busy_object()` (#4), `rename_object()` (Minor #3)
|
|
302
|
+
- `src/variancelabs_mcp/app/http.py` — `STATUS["stale_object"]`, `_authorized()`,
|
|
303
|
+
`_store()` calling `ensure_recovered`, broad-`Exception` handling in GET/POST,
|
|
304
|
+
`version` passthrough on `/api/object/update` (#1, #4, Minor #1, Minor #2)
|
|
305
|
+
- `src/variancelabs_mcp/project/tools.py` — `open_store()` default-name fallback,
|
|
306
|
+
`problem()`/`call()`/`_project_create()` OSError/TimeoutError handling, `LOAD_DH_DOC`
|
|
307
|
+
wording (Minor #4, #5, docs)
|
|
308
|
+
- `README.md`, `doc/varianceLabs-doc/projects.md` — docs (Minor)
|
|
309
|
+
- Tests: `tests/test_project_rebuild.py`, `tests/test_project_lock.py`,
|
|
310
|
+
`tests/test_project_api.py`, `tests/test_app_http.py`, `tests/test_project_tools.py`
|
|
311
|
+
|
|
312
|
+
## Self-review findings
|
|
313
|
+
|
|
314
|
+
- Confirmed `update()`'s check order matches the brief: `object_not_found` (via
|
|
315
|
+
`_object`) → `not_rebuildable` (imported) → `project_busy` → `stale_object` → param
|
|
316
|
+
validation. `retry()`: `object_not_found` → `project_busy` → the existing
|
|
317
|
+
failed/out_of_date check.
|
|
318
|
+
- `version` passthrough in `http.py` explicitly excludes `bool` (JSON `true`/`false`
|
|
319
|
+
would otherwise satisfy Python's `isinstance(v, int)`).
|
|
320
|
+
- Did not touch `_project_update` (the MCP tool) to accept `version` — the shared
|
|
321
|
+
contract only calls for it on `api.update` and the HTTP route; the MCP tool has no
|
|
322
|
+
notion of "the version the caller last saw" since it always waits synchronously.
|
|
323
|
+
|
|
324
|
+
## Concerns
|
|
325
|
+
|
|
326
|
+
- The `SAFE_KEY_RE` vs `UUID_RE` deviation on Important #5 (see above) — the security
|
|
327
|
+
property the reviewer asked for is intact (path traversal via a crafted key is
|
|
328
|
+
rejected), but the exact pattern differs from the brief's literal instruction. Worth a
|
|
329
|
+
second look from the reviewer.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
# Fix round 2 (Python side)
|
|
334
|
+
|
|
335
|
+
A scoped opus re-review of round 1 found two issues introduced by/around the round-1
|
|
336
|
+
fixes, plus one leftover gap and a doc line. All four addressed below, same file
|
|
337
|
+
boundaries (no `src/web-app/`, no `npm`).
|
|
338
|
+
|
|
339
|
+
## N1 (Important) - PermissionError spins acquire() past its deadline
|
|
340
|
+
|
|
341
|
+
`src/project/lock.py:acquire()`. The round-1 fix caught `(FileExistsError,
|
|
342
|
+
PermissionError)` in one branch and used `held()` to decide "stale, take over now" vs
|
|
343
|
+
"contended, sleep and check the deadline". For `PermissionError` with **no lock file
|
|
344
|
+
present** (an unwritable folder, Windows Controlled Folder Access), `held()` - which
|
|
345
|
+
`stat()`s the path - hits `FileNotFoundError` and returns `False`, so the code took the
|
|
346
|
+
"stale, retry immediately" branch: `os.remove` (harmlessly fails), then `continue` with
|
|
347
|
+
**no sleep and no deadline check**. The reviewer measured ~37,000 `os.open` calls in 2 s
|
|
348
|
+
on `FileLock(timeout=0)`; `project_open` -> `ensure_recovered` -> `recover` would hang the
|
|
349
|
+
MCP process on such a folder.
|
|
350
|
+
|
|
351
|
+
Fix: split the `except` clause. `FileExistsError` keeps the existing stale-takeover
|
|
352
|
+
logic (a lock *file* exists, so `held()` is meaningful). `PermissionError` now always
|
|
353
|
+
takes the plain sleep + deadline path - it tells us nothing about whether a stale lock
|
|
354
|
+
can be taken over, so assuming so is unsafe.
|
|
355
|
+
|
|
356
|
+
Test (`tests/test_project_lock.py::test_acquire_times_out_on_a_persistent_permission_error_without_spinning`):
|
|
357
|
+
monkeypatches `os.open` to always raise `PermissionError` with no lock file present;
|
|
358
|
+
`acquire(timeout=0.3)` must raise `TimeoutError` within ~2 s and call `os.open` well
|
|
359
|
+
under 100 times.
|
|
360
|
+
|
|
361
|
+
RED (old combined-branch code - had to be killed; it never returns):
|
|
362
|
+
```
|
|
363
|
+
$ uv run pytest tests/test_project_lock.py -k persistent_permission_error -q
|
|
364
|
+
# hung indefinitely (background run killed after >30s, thousands of os.open calls
|
|
365
|
+
# already made); reproduces the reviewer's spin exactly.
|
|
366
|
+
```
|
|
367
|
+
GREEN:
|
|
368
|
+
```
|
|
369
|
+
$ uv run pytest tests/test_project_lock.py -k persistent_permission_error -q
|
|
370
|
+
1 passed, 9 deselected in 0.44s
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## N3 (Important) - a live worker permanently short-circuited recovery
|
|
374
|
+
|
|
375
|
+
`src/project/rebuild.py`. Round 1's `ensure_recovered` treated "this process already has
|
|
376
|
+
a worker for the project" as "already recovered" (added the key to `_recovered` without
|
|
377
|
+
ever calling `recover()`). That meant: if process B submits *any* job before dead process
|
|
378
|
+
A's `build.lock` goes stale, A's orphaned `building` object is never settled for the rest
|
|
379
|
+
of B's lifetime - `update`/`retry`/`remove` on it keep returning `project_busy` forever.
|
|
380
|
+
Round 1's own test (`test_ensure_recovered_is_skipped_once_this_process_has_a_worker`)
|
|
381
|
+
asserted exactly that broken behaviour, per the finding.
|
|
382
|
+
|
|
383
|
+
Fix (controller's design, simpler than the round-1 approach):
|
|
384
|
+
- `_Worker` now tracks `active_ids: set[str]` - the object ids of jobs currently queued
|
|
385
|
+
or running in *this process's* worker for the project - updated in `submit()` (ids
|
|
386
|
+
added before the job is queued) and in `_loop()`'s `finally` (ids removed once the job
|
|
387
|
+
finishes, before `job.done.set()`).
|
|
388
|
+
- `recover(store, exclude=())` gained an `exclude` parameter: the status-fixing pass
|
|
389
|
+
skips excluded ids entirely (never marks them failed/drops them), and the orphan-folder
|
|
390
|
+
cleanup pass skips excluded ids' `objects/`/`sources/` entries entirely (not just the
|
|
391
|
+
version-folder pruning) - so a build this process is mid-way through writing into
|
|
392
|
+
`v<n+1>/` is never touched.
|
|
393
|
+
- `ensure_recovered()` now always calls `recover(store, exclude=_worker_active_ids(key))`
|
|
394
|
+
(dropped the "has_worker -> treat as recovered" shortcut) and marks the project
|
|
395
|
+
recovered **only when `recover()` returns `True`** - i.e. only when it actually
|
|
396
|
+
acquired `build.lock` and ran. If the lock is held (by another process, or by this
|
|
397
|
+
process's own worker mid-job), the call is a no-op and the next `ensure_recovered`
|
|
398
|
+
call (next `_store()`/`open_project()`) retries.
|
|
399
|
+
|
|
400
|
+
Since `ensure_recovered` runs on every app-server `_store()` call, this means: A's fresh
|
|
401
|
+
lock -> skipped; B's own job holds the lock while running -> skipped; once both are clear,
|
|
402
|
+
the very next request settles A's orphan, without ever touching B's own in-flight or
|
|
403
|
+
queued work.
|
|
404
|
+
|
|
405
|
+
Round 1's `test_ensure_recovered_is_skipped_once_this_process_has_a_worker` was replaced
|
|
406
|
+
(per the coordinator's note that it "must change") with:
|
|
407
|
+
- `tests/test_project_rebuild.py::test_recover_with_exclude_leaves_those_ids_alone` -
|
|
408
|
+
direct-level test: two `waiting` objects, `recover(chain, exclude={"c"})` settles `"b"`
|
|
409
|
+
to `failed`/`interrupted` and leaves `"c"` exactly as it was.
|
|
410
|
+
- `tests/test_project_rebuild.py::test_ensure_recovered_settles_an_orphan_once_this_processs_job_is_done` -
|
|
411
|
+
the reconnect scenario: A's fresh lock held, B submits a job on an unrelated object;
|
|
412
|
+
`ensure_recovered` is a no-op while A's lock is fresh; once A's lock is released, B's
|
|
413
|
+
queued job runs to completion; the next `ensure_recovered` call then settles A's orphan
|
|
414
|
+
and B's own object is confirmed rebuilt (`ready`, version bumped) - undisturbed.
|
|
415
|
+
|
|
416
|
+
RED (old `recover()`/`ensure_recovered()`, no `exclude` param):
|
|
417
|
+
```
|
|
418
|
+
$ uv run pytest tests/test_project_rebuild.py -k "recover_with_exclude or settles_an_orphan" -q
|
|
419
|
+
FAILED test_recover_with_exclude_leaves_those_ids_alone - TypeError: recover() got an
|
|
420
|
+
unexpected keyword argument 'exclude'
|
|
421
|
+
FAILED test_ensure_recovered_settles_an_orphan_once_this_processs_job_is_done -
|
|
422
|
+
AssertionError: assert 'building' == 'failed' (orphan never settled)
|
|
423
|
+
2 failed, 19 deselected
|
|
424
|
+
```
|
|
425
|
+
GREEN:
|
|
426
|
+
```
|
|
427
|
+
$ uv run pytest tests/test_project_rebuild.py -q
|
|
428
|
+
21 passed in 5.16s
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## m1 (Minor) - recovery errors outside http.py's try blocks drop the connection
|
|
432
|
+
|
|
433
|
+
`src/variancelabs_mcp/app/http.py`. Round 1 moved `rebuild.ensure_recovered(s)` into
|
|
434
|
+
`_store()`, but `_store()` is called *before* the `try`/`except ProjectError`/`except
|
|
435
|
+
Exception` blocks in `do_GET`'s `/api/*` dispatch and in `do_POST`; `_file()` had no
|
|
436
|
+
try/except around its `_store()` call at all. A `project_corrupt` (or any other)
|
|
437
|
+
exception raised while recovering a not-yet-recovered project therefore propagated out of
|
|
438
|
+
the request handler entirely and dropped the connection instead of answering with a JSON
|
|
439
|
+
error.
|
|
440
|
+
|
|
441
|
+
Fix: `_store()` is back to a pure lookup (no recovery). A new `_recover(self, s)` helper
|
|
442
|
+
runs `rebuild.ensure_recovered(s)` inside its own `try`/`except ProjectError`/`except
|
|
443
|
+
Exception`, replies with the appropriate Problem (`_problem`/500 `{"error":
|
|
444
|
+
problem_of(e)}`) on failure, and returns `False`; all three call sites (`do_GET`'s
|
|
445
|
+
`/api/*` block, `do_POST`, `_file`) now call `if not self._recover(s): return` right
|
|
446
|
+
after obtaining the store and before doing anything else with it.
|
|
447
|
+
|
|
448
|
+
Test (`tests/test_app_http.py::test_recovery_error_on_first_access_returns_a_problem_not_a_dropped_connection`):
|
|
449
|
+
the `served` fixture's project is created directly via `project.store`/`project.api`
|
|
450
|
+
(never through `project_open`/`_store()`), so it has never been through
|
|
451
|
+
`ensure_recovered`. The test corrupts `project.json`, then makes the *first* request
|
|
452
|
+
(`GET /api/revision`) - triggering recovery inline - and asserts a `500`
|
|
453
|
+
`project_corrupt` JSON body rather than a dropped connection.
|
|
454
|
+
|
|
455
|
+
RED (old `_store()`-does-recovery, no wrapping):
|
|
456
|
+
```
|
|
457
|
+
$ uv run pytest tests/test_app_http.py -k recovery_error_on_first_access -q
|
|
458
|
+
FAILED ... http.client.RemoteDisconnected: Remote end closed connection without response
|
|
459
|
+
(server-side traceback: ProjectError("project_corrupt", ...) raised from
|
|
460
|
+
_store -> rebuild.ensure_recovered -> recover -> store.read(), uncaught)
|
|
461
|
+
1 failed
|
|
462
|
+
```
|
|
463
|
+
GREEN:
|
|
464
|
+
```
|
|
465
|
+
$ uv run pytest tests/test_app_http.py -q
|
|
466
|
+
12 passed in 9.08s
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Docs - MAX_PATH line
|
|
470
|
+
|
|
471
|
+
Round 1's report claimed the MAX_PATH remediation was documented but it was only in the
|
|
472
|
+
`Problem`'s `remediation` text, not in `doc/varianceLabs-doc/`. Added one line to
|
|
473
|
+
`doc/varianceLabs-doc/projects.md`:
|
|
474
|
+
|
|
475
|
+
> On Windows, a project's files add about 140 characters under the working folder path:
|
|
476
|
+
> if loads start failing with a path-length error, keep the working folder path short, or
|
|
477
|
+
> turn on `LongPathsEnabled`.
|
|
478
|
+
|
|
479
|
+
No test (docs-only).
|
|
480
|
+
|
|
481
|
+
## Full suite
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
$ uv run pytest -q
|
|
485
|
+
477 passed, 225 warnings in 97.28s (0:01:37)
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
225 warnings, same pre-existing kaleido/plotly set as round 1's baseline; no new
|
|
489
|
+
warnings. 477 vs round 1's 474: +1 net test in `test_project_rebuild.py` (one test
|
|
490
|
+
replaced by two, per N3), +1 in `test_project_lock.py` (N1), +1 in `test_app_http.py`
|
|
491
|
+
(m1).
|
|
492
|
+
|
|
493
|
+
## Files changed (round 2, in addition to round 1)
|
|
494
|
+
|
|
495
|
+
- `src/project/lock.py` - split `PermissionError`/`FileExistsError` handling in
|
|
496
|
+
`acquire()` (N1)
|
|
497
|
+
- `src/project/rebuild.py` - `_Worker.active_ids`, `_worker_active_ids()`,
|
|
498
|
+
`recover(..., exclude=...)`, `ensure_recovered()` redesign (N3)
|
|
499
|
+
- `src/variancelabs_mcp/app/http.py` - `_store()` reverted to pure lookup, new
|
|
500
|
+
`_recover()` helper, called from `do_GET`, `do_POST`, `_file` (m1)
|
|
501
|
+
- `doc/varianceLabs-doc/projects.md` - MAX_PATH line
|
|
502
|
+
- Tests: `tests/test_project_lock.py`, `tests/test_project_rebuild.py`,
|
|
503
|
+
`tests/test_app_http.py`
|
|
504
|
+
|
|
505
|
+
## Concerns (round 2)
|
|
506
|
+
|
|
507
|
+
- Same as round 1: the `SAFE_KEY_RE` vs `UUID_RE` deviation on Important #5 still stands
|
|
508
|
+
(not part of this round's scope, unchanged).
|
|
509
|
+
- N3's exclusion is by object id, scoped to a single project's worker; a brand-new
|
|
510
|
+
object's id is added to the index (status `building`, version 0) and then to
|
|
511
|
+
`active_ids` in two separate steps (`api._run_new`'s `mutate` then `rebuild.submit`).
|
|
512
|
+
If `ensure_recovered` ran from another thread in that exact gap, it would not yet see
|
|
513
|
+
the id in `exclude` and - since version is 0 - could drop the just-created record. This
|
|
514
|
+
is a pre-existing-style narrow race (same shape as the one already accepted for the
|
|
515
|
+
"has_worker" check in round 1), not newly introduced; flagging rather than fixing since
|
|
516
|
+
closing it would need moving object-record creation and job submission behind one lock,
|
|
517
|
+
a bigger structural change than this fix round's brief.
|