freeweight 1.0.0rc1__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.
- freeweight-1.0.0rc1/.editorconfig +23 -0
- freeweight-1.0.0rc1/.github/workflows/ci.yml +199 -0
- freeweight-1.0.0rc1/.github/workflows/nightly.yml +41 -0
- freeweight-1.0.0rc1/.github/workflows/release.yml +58 -0
- freeweight-1.0.0rc1/.gitignore +100 -0
- freeweight-1.0.0rc1/.gitleaks.toml +38 -0
- freeweight-1.0.0rc1/.importlinter +40 -0
- freeweight-1.0.0rc1/.pre-commit-config.yaml +22 -0
- freeweight-1.0.0rc1/CHANGELOG.md +899 -0
- freeweight-1.0.0rc1/CONTRIBUTING.md +50 -0
- freeweight-1.0.0rc1/LICENSE +201 -0
- freeweight-1.0.0rc1/PHASE10.diff +17158 -0
- freeweight-1.0.0rc1/PHASE10_ISSUES.md +496 -0
- freeweight-1.0.0rc1/PHASE11_ISSUES.md +214 -0
- freeweight-1.0.0rc1/PHASE7_ISSUES.md +160 -0
- freeweight-1.0.0rc1/PHASE8_DECISIONS.md +318 -0
- freeweight-1.0.0rc1/PHASE8_ISSUES.md +336 -0
- freeweight-1.0.0rc1/PHASE9_ISSUES.md +171 -0
- freeweight-1.0.0rc1/PKG-INFO +107 -0
- freeweight-1.0.0rc1/README.md +59 -0
- freeweight-1.0.0rc1/SECURITY.md +39 -0
- freeweight-1.0.0rc1/docs/README.md +27 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/api.md +362 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/benchmark-catalog.md +569 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/data-model.md +566 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/development-plan.md +1220 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/risks.md +125 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/spec.md +652 -0
- freeweight-1.0.0rc1/docs/apps/freeweight/subjective-goals.md +499 -0
- freeweight-1.0.0rc1/docs/configuration.md +187 -0
- freeweight-1.0.0rc1/docs/image.png +0 -0
- freeweight-1.0.0rc1/docs/openapi.json +3156 -0
- freeweight-1.0.0rc1/pyproject.toml +149 -0
- freeweight-1.0.0rc1/requirements/README.md +63 -0
- freeweight-1.0.0rc1/requirements/release.in +6 -0
- freeweight-1.0.0rc1/requirements/release.lock +493 -0
- freeweight-1.0.0rc1/scripts/generate_config_reference.py +243 -0
- freeweight-1.0.0rc1/scripts/generate_openapi_snapshot.py +71 -0
- freeweight-1.0.0rc1/scripts/sync_docs.py +104 -0
- freeweight-1.0.0rc1/src/freeweight/__about__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/__main__.py +12 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/agent/benchmark.py +84 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/agent/cases.json +91 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/agent/manifest.json +96 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/audit/__init__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/audit/benchmark.py +171 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/audit/cases.json +26 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/audit/manifest.json +98 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/corpora/__init__.py +73 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/corpora/audit_code.json +160 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/corpora/critique_answers.json +144 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/corpora/judge_comparisons.json +105 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/corpora/long_context_needles.json +125 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/critique/__init__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/critique/benchmark.py +135 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/critique/cases.json +33 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/critique/manifest.json +97 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/echo/benchmark.py +227 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/echo/manifest.json +29 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/energy/benchmark.py +460 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/energy/energy.py +345 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/energy/manifest.json +111 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/inventory.json +4 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/records.json +5 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/repo/README.md +5 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/repo/pkg/inventory.py +14 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/repo/pkg/pricing.py +14 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/repo/tests/test_pricing.py +8 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/tables.json +11 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/tests.json +15 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/data/tools.json +127 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/fixtures/tools.py +700 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/goal/__init__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/goal/runner.py +639 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/instruction_following/benchmark.py +108 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/instruction_following/cases.json +171 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/instruction_following/manifest.json +87 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/interaction.py +370 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/judge/__init__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/judge/benchmark.py +262 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/judge/cases.json +67 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/judge/manifest.json +126 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/judge/session.py +237 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/loading.py +260 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/__init__.py +1 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/benchmark.py +335 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/cases.json +47 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/haystack.py +181 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/manifest.json +72 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/long_context/scoring.py +88 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/memory_kv/benchmark.py +599 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/memory_kv/kv.py +438 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/memory_kv/manifest.json +99 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/performance/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/performance/benchmark.py +502 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/performance/manifest.json +112 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/reliability/benchmark.py +425 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/reliability/cases.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/reliability/manifest.json +111 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/reliability/reliability.py +237 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/structured_output/benchmark.py +100 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/structured_output/cases.json +92 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/structured_output/manifest.json +94 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/token_economy/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/token_economy/benchmark.py +341 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/token_economy/manifest.json +99 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_recovery/benchmark.py +85 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_recovery/cases.json +95 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_recovery/manifest.json +82 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_use/benchmark.py +123 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_use/cases.json +168 -0
- freeweight-1.0.0rc1/src/freeweight/benchmarks/tool_use/manifest.json +124 -0
- freeweight-1.0.0rc1/src/freeweight/bootstrap.py +114 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/config.py +128 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/db.py +299 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/evidence.py +296 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/external.py +4 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/goals.py +970 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/judges.py +183 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/models.py +279 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/prompts.py +233 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/results.py +579 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/runs.py +631 -0
- freeweight-1.0.0rc1/src/freeweight/cli/commands/system.py +126 -0
- freeweight-1.0.0rc1/src/freeweight/cli/main.py +80 -0
- freeweight-1.0.0rc1/src/freeweight/config/capability_weights.toml +164 -0
- freeweight-1.0.0rc1/src/freeweight/config.py +1173 -0
- freeweight-1.0.0rc1/src/freeweight/domain/aggregation.py +504 -0
- freeweight-1.0.0rc1/src/freeweight/domain/agreement.py +481 -0
- freeweight-1.0.0rc1/src/freeweight/domain/benchmark.py +415 -0
- freeweight-1.0.0rc1/src/freeweight/domain/calibration.py +392 -0
- freeweight-1.0.0rc1/src/freeweight/domain/capability_mapping.py +364 -0
- freeweight-1.0.0rc1/src/freeweight/domain/comparison.py +455 -0
- freeweight-1.0.0rc1/src/freeweight/domain/confidence.py +629 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/__init__.py +18 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/composite.py +162 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/criteria.py +362 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/hashing.py +113 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/lint.py +490 -0
- freeweight-1.0.0rc1/src/freeweight/domain/goals/pack.py +650 -0
- freeweight-1.0.0rc1/src/freeweight/domain/judging.py +662 -0
- freeweight-1.0.0rc1/src/freeweight/domain/jury.py +210 -0
- freeweight-1.0.0rc1/src/freeweight/domain/metrics.py +500 -0
- freeweight-1.0.0rc1/src/freeweight/domain/provenance.py +391 -0
- freeweight-1.0.0rc1/src/freeweight/domain/run_state.py +262 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/agent.py +174 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/audit.py +404 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/critique.py +295 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/exact.py +191 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/judge.py +418 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/judged.py +340 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rule.py +460 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/__init__.py +322 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/length.py +218 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/phrases.py +143 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/pov_tense.py +272 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/punctuation.py +109 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/readability.py +158 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/reference.py +369 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/regex.py +140 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/repetition.py +117 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/structure.py +173 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/rules/vocabulary.py +129 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/schema.py +421 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scorers/tools.py +571 -0
- freeweight-1.0.0rc1/src/freeweight/domain/scoring.py +129 -0
- freeweight-1.0.0rc1/src/freeweight/domain/statistics.py +566 -0
- freeweight-1.0.0rc1/src/freeweight/external/adapters/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/external/environment.py +4 -0
- freeweight-1.0.0rc1/src/freeweight/external/framework.py +4 -0
- freeweight-1.0.0rc1/src/freeweight/external/sandbox.py +4 -0
- freeweight-1.0.0rc1/src/freeweight/goals/__init__.py +10 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/__init__.py +319 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/brand_voice/calibration.json +115 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/brand_voice/goal.json +146 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/brand_voice/tasks/001.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/brand_voice/tasks/002.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/creative_voice/calibration.json +195 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/creative_voice/goal.json +122 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/creative_voice/tasks/001.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/creative_voice/tasks/002.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/creative_voice/tasks/003.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/summary_faithfulness/calibration.json +115 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/summary_faithfulness/goal.json +97 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/summary_faithfulness/tasks/001.json +71 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/summary_faithfulness/tasks/002.json +70 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/technical_explanation/calibration.json +195 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/technical_explanation/goal.json +99 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/technical_explanation/tasks/001.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/goals/starters/technical_explanation/tasks/002.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/backup.py +609 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/base.py +51 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/engine.py +209 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/errors.py +83 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migration.py +325 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/env.py +45 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/script.py.mako +26 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0001_initial_schema.py +198 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0002_run_engine_tables.py +440 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0003_telemetry_tables.py +120 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0004_tool_calls.py +76 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0005_goal_tables.py +182 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0006_calibration_tables.py +234 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/migrations/versions/0007_capability_evidence.py +184 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/models.py +237 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/models_evidence.py +139 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/models_goals.py +393 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/models_runs.py +602 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/calibration.py +237 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/evidence.py +134 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/goals.py +222 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/machines.py +141 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/model_descriptors.py +130 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/models.py +375 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/runs.py +917 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/settings.py +53 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/repositories/telemetry.py +118 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/session.py +71 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/types.py +116 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/db/upsert.py +85 -0
- freeweight-1.0.0rc1/src/freeweight/infrastructure/providers/factory.py +67 -0
- freeweight-1.0.0rc1/src/freeweight/observability/logging.py +144 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/agent.task.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/audit.detect_defects.v1.json +50 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/critique.review.v1.json +45 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/energy.workload.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/instruction_following.constrained.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/judge.answer.v1.json +40 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/judge.pairwise.v1.json +51 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/long_context.retrieve.v1.json +45 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/memory_kv.context_probe.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/performance.probe.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/reliability.probe.v1.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/structured_output.repair.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/structured_output.schema.v1.json +42 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/token_economy.probe.v1.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/tool_recovery.task.v1.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/benchmarks/tool_use.task.v1.json +37 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/goals/judge.pairwise.v1.json +56 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/goals/judge.rubric.v1.json +74 -0
- freeweight-1.0.0rc1/src/freeweight/prompts/manifest.json +99 -0
- freeweight-1.0.0rc1/src/freeweight/services/calibration.py +1621 -0
- freeweight-1.0.0rc1/src/freeweight/services/comparison.py +824 -0
- freeweight-1.0.0rc1/src/freeweight/services/database.py +425 -0
- freeweight-1.0.0rc1/src/freeweight/services/database_admin.py +814 -0
- freeweight-1.0.0rc1/src/freeweight/services/events.py +354 -0
- freeweight-1.0.0rc1/src/freeweight/services/evidence.py +1975 -0
- freeweight-1.0.0rc1/src/freeweight/services/export.py +1396 -0
- freeweight-1.0.0rc1/src/freeweight/services/goals.py +1086 -0
- freeweight-1.0.0rc1/src/freeweight/services/health.py +320 -0
- freeweight-1.0.0rc1/src/freeweight/services/inventory.py +164 -0
- freeweight-1.0.0rc1/src/freeweight/services/jury.py +599 -0
- freeweight-1.0.0rc1/src/freeweight/services/machine.py +116 -0
- freeweight-1.0.0rc1/src/freeweight/services/models.py +621 -0
- freeweight-1.0.0rc1/src/freeweight/services/prompts.py +943 -0
- freeweight-1.0.0rc1/src/freeweight/services/results.py +1356 -0
- freeweight-1.0.0rc1/src/freeweight/services/runs.py +4235 -0
- freeweight-1.0.0rc1/src/freeweight/services/scheduler.py +326 -0
- freeweight-1.0.0rc1/src/freeweight/services/settings.py +480 -0
- freeweight-1.0.0rc1/src/freeweight/services/telemetry.py +209 -0
- freeweight-1.0.0rc1/src/freeweight/services/telemetry_recording.py +641 -0
- freeweight-1.0.0rc1/src/freeweight/services/wizard.py +1178 -0
- freeweight-1.0.0rc1/src/freeweight/web/app.py +232 -0
- freeweight-1.0.0rc1/src/freeweight/web/errors.py +180 -0
- freeweight-1.0.0rc1/src/freeweight/web/middleware.py +166 -0
- freeweight-1.0.0rc1/src/freeweight/web/rendering.py +77 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/benchmarks.py +113 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/calibration.py +335 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/compare.py +205 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/dashboard.py +94 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/database.py +294 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/evidence.py +261 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/goals.py +375 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/grading.py +114 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/machines.py +120 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/models.py +322 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/results.py +443 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/runs.py +791 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/settings.py +169 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/sources.py +4 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/system.py +209 -0
- freeweight-1.0.0rc1/src/freeweight/web/routes/wizard.py +594 -0
- freeweight-1.0.0rc1/src/freeweight/web/static/js/charts.js +45 -0
- freeweight-1.0.0rc1/src/freeweight/web/static/js/dashboard.js +51 -0
- freeweight-1.0.0rc1/src/freeweight/web/static/js/runs.js +105 -0
- freeweight-1.0.0rc1/src/freeweight/web/static/js/table.js +174 -0
- freeweight-1.0.0rc1/src/freeweight/web/static/js/telemetry.js +99 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/base.html +410 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/compare/index.html +248 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/dashboard/index.html +232 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/database/index.html +202 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/evidence/index.html +152 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/grade.html +120 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/index.html +80 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/report.html +164 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/starters.html +108 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/wizard_criteria.html +179 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/wizard_intent.html +34 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/wizard_rules.html +58 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/wizard_save.html +80 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/goals/wizard_tasks.html +71 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/grading/run.html +107 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/machines/index.html +45 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/models/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/models/detail.html +69 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/models/index.html +66 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/partials/_inventory_states.html +22 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/partials/_scatter.html +71 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/partials/_wizard_steps.html +21 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/partials/telemetry_bar.html +50 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/results/case.html +217 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/results/goal_detail.html +135 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/results/index.html +133 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/runs/.gitkeep +0 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/runs/detail.html +244 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/runs/index.html +80 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/runs/samples.html +84 -0
- freeweight-1.0.0rc1/src/freeweight/web/templates/settings/index.html +97 -0
- freeweight-1.0.0rc1/tests/accessibility/test_ui_checklist.py +384 -0
- freeweight-1.0.0rc1/tests/conftest.py +132 -0
- freeweight-1.0.0rc1/tests/contract/test_declared_surface.py +108 -0
- freeweight-1.0.0rc1/tests/contract/test_evidence_export.py +958 -0
- freeweight-1.0.0rc1/tests/contract/test_evidence_schema.py +227 -0
- freeweight-1.0.0rc1/tests/contract/test_export_schemas.py +535 -0
- freeweight-1.0.0rc1/tests/e2e/test_cli_basics.py +261 -0
- freeweight-1.0.0rc1/tests/e2e/test_cli_db.py +190 -0
- freeweight-1.0.0rc1/tests/e2e/test_dashboard.py +365 -0
- freeweight-1.0.0rc1/tests/e2e/test_declared_endpoints.py +208 -0
- freeweight-1.0.0rc1/tests/e2e/test_delete_preview.py +372 -0
- freeweight-1.0.0rc1/tests/e2e/test_drilldown.py +318 -0
- freeweight-1.0.0rc1/tests/e2e/test_export.py +596 -0
- freeweight-1.0.0rc1/tests/e2e/test_full_journeys.py +4 -0
- freeweight-1.0.0rc1/tests/e2e/test_goal_wizard_journey.py +586 -0
- freeweight-1.0.0rc1/tests/e2e/test_goals_api.py +507 -0
- freeweight-1.0.0rc1/tests/e2e/test_grading_resumable.py +369 -0
- freeweight-1.0.0rc1/tests/e2e/test_models_flow.py +212 -0
- freeweight-1.0.0rc1/tests/e2e/test_pages.py +226 -0
- freeweight-1.0.0rc1/tests/e2e/test_run_journey.py +641 -0
- freeweight-1.0.0rc1/tests/e2e/test_server_boot.py +167 -0
- freeweight-1.0.0rc1/tests/integration/conftest.py +109 -0
- freeweight-1.0.0rc1/tests/integration/test_backup_restore.py +439 -0
- freeweight-1.0.0rc1/tests/integration/test_calibration_flow.py +860 -0
- freeweight-1.0.0rc1/tests/integration/test_goal_run_rules_only.py +509 -0
- freeweight-1.0.0rc1/tests/integration/test_human_grading.py +504 -0
- freeweight-1.0.0rc1/tests/integration/test_integration_milestones.py +154 -0
- freeweight-1.0.0rc1/tests/integration/test_jury_assembly.py +488 -0
- freeweight-1.0.0rc1/tests/integration/test_migrations.py +287 -0
- freeweight-1.0.0rc1/tests/integration/test_performance_benchmark.py +594 -0
- freeweight-1.0.0rc1/tests/integration/test_quality_suites.py +665 -0
- freeweight-1.0.0rc1/tests/integration/test_recovery.py +269 -0
- freeweight-1.0.0rc1/tests/integration/test_repositories.py +316 -0
- freeweight-1.0.0rc1/tests/integration/test_run_execution.py +538 -0
- freeweight-1.0.0rc1/tests/integration/test_sandbox_tiers.py +4 -0
- freeweight-1.0.0rc1/tests/integration/test_sse_replay.py +332 -0
- freeweight-1.0.0rc1/tests/integration/test_starter_packs.py +423 -0
- freeweight-1.0.0rc1/tests/integration/test_telemetry_sse.py +222 -0
- freeweight-1.0.0rc1/tests/integration/test_transactions.py +94 -0
- freeweight-1.0.0rc1/tests/integration/test_two_phase_judging.py +372 -0
- freeweight-1.0.0rc1/tests/live/test_real_run.py +1074 -0
- freeweight-1.0.0rc1/tests/performance/test_dashboard_queries.py +416 -0
- freeweight-1.0.0rc1/tests/security/test_goal_pack_import.py +365 -0
- freeweight-1.0.0rc1/tests/security/test_mock_tools_contained.py +468 -0
- freeweight-1.0.0rc1/tests/security/test_sandbox_refusal.py +4 -0
- freeweight-1.0.0rc1/tests/security/test_settings_boundary.py +211 -0
- freeweight-1.0.0rc1/tests/unit/test_aggregation.py +353 -0
- freeweight-1.0.0rc1/tests/unit/test_agreement.py +222 -0
- freeweight-1.0.0rc1/tests/unit/test_audit_metrics.py +229 -0
- freeweight-1.0.0rc1/tests/unit/test_bootstrap.py +36 -0
- freeweight-1.0.0rc1/tests/unit/test_capability_mapping.py +244 -0
- freeweight-1.0.0rc1/tests/unit/test_comparison_rules.py +277 -0
- freeweight-1.0.0rc1/tests/unit/test_composite.py +267 -0
- freeweight-1.0.0rc1/tests/unit/test_confidence.py +366 -0
- freeweight-1.0.0rc1/tests/unit/test_config.py +255 -0
- freeweight-1.0.0rc1/tests/unit/test_context_sweep.py +200 -0
- freeweight-1.0.0rc1/tests/unit/test_critique_metrics.py +243 -0
- freeweight-1.0.0rc1/tests/unit/test_database_admin.py +52 -0
- freeweight-1.0.0rc1/tests/unit/test_db_types.py +164 -0
- freeweight-1.0.0rc1/tests/unit/test_effective_context.py +351 -0
- freeweight-1.0.0rc1/tests/unit/test_energy_integration.py +226 -0
- freeweight-1.0.0rc1/tests/unit/test_event_sequence.py +297 -0
- freeweight-1.0.0rc1/tests/unit/test_external_output_parsing.py +4 -0
- freeweight-1.0.0rc1/tests/unit/test_gate.py +164 -0
- freeweight-1.0.0rc1/tests/unit/test_goal_hash.py +225 -0
- freeweight-1.0.0rc1/tests/unit/test_goal_lint.py +492 -0
- freeweight-1.0.0rc1/tests/unit/test_judge_bias.py +511 -0
- freeweight-1.0.0rc1/tests/unit/test_kappa_weighted.py +225 -0
- freeweight-1.0.0rc1/tests/unit/test_krippendorff.py +102 -0
- freeweight-1.0.0rc1/tests/unit/test_kv_math.py +381 -0
- freeweight-1.0.0rc1/tests/unit/test_logging.py +154 -0
- freeweight-1.0.0rc1/tests/unit/test_machine_profile.py +120 -0
- freeweight-1.0.0rc1/tests/unit/test_metric_formulas.py +224 -0
- freeweight-1.0.0rc1/tests/unit/test_model_discovery.py +386 -0
- freeweight-1.0.0rc1/tests/unit/test_partition.py +119 -0
- freeweight-1.0.0rc1/tests/unit/test_prompt_pack.py +625 -0
- freeweight-1.0.0rc1/tests/unit/test_provenance.py +301 -0
- freeweight-1.0.0rc1/tests/unit/test_provider_factory.py +58 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_length.py +163 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_phrases.py +104 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_pov_tense.py +85 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_punctuation.py +72 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_readability.py +109 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_reference.py +220 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_regex.py +116 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_repetition.py +70 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_structure.py +118 -0
- freeweight-1.0.0rc1/tests/unit/test_rules_vocabulary.py +84 -0
- freeweight-1.0.0rc1/tests/unit/test_run_state_machine.py +181 -0
- freeweight-1.0.0rc1/tests/unit/test_runtime_profile.py +172 -0
- freeweight-1.0.0rc1/tests/unit/test_scheduler.py +232 -0
- freeweight-1.0.0rc1/tests/unit/test_scorers_agent.py +211 -0
- freeweight-1.0.0rc1/tests/unit/test_scorers_exact.py +103 -0
- freeweight-1.0.0rc1/tests/unit/test_scorers_rule.py +174 -0
- freeweight-1.0.0rc1/tests/unit/test_scorers_schema.py +141 -0
- freeweight-1.0.0rc1/tests/unit/test_scorers_tools.py +288 -0
- freeweight-1.0.0rc1/tests/unit/test_statistics.py +310 -0
- freeweight-1.0.0rc1/tests/unit/test_sweep_ladder.py +98 -0
- freeweight-1.0.0rc1/tests/unit/test_telemetry_service.py +221 -0
- freeweight-1.0.0rc1/tests/unit/test_validity_factor.py +146 -0
- freeweight-1.0.0rc1/tests/unit/test_web_errors.py +87 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
indent_style = space
|
|
9
|
+
indent_size = 4
|
|
10
|
+
|
|
11
|
+
[*.py]
|
|
12
|
+
indent_size = 4
|
|
13
|
+
max_line_length = 100
|
|
14
|
+
|
|
15
|
+
[*.{toml,yml,yaml,json}]
|
|
16
|
+
indent_size = 2
|
|
17
|
+
|
|
18
|
+
[*.md]
|
|
19
|
+
trim_trailing_whitespace = false
|
|
20
|
+
max_line_length = off
|
|
21
|
+
|
|
22
|
+
[Makefile]
|
|
23
|
+
indent_style = tab
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
format:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with: { python-version: "3.12" }
|
|
15
|
+
- run: pip install ruff
|
|
16
|
+
- run: ruff format --check .
|
|
17
|
+
|
|
18
|
+
lint:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with: { python-version: "3.12" }
|
|
24
|
+
- run: pip install ruff
|
|
25
|
+
- run: ruff check .
|
|
26
|
+
|
|
27
|
+
types:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with: { python-version: "3.12" }
|
|
33
|
+
- run: pip install -e ".[dev]"
|
|
34
|
+
- run: mypy src tests
|
|
35
|
+
|
|
36
|
+
boundaries:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
- uses: actions/setup-python@v5
|
|
41
|
+
with: { python-version: "3.12" }
|
|
42
|
+
- run: pip install -e ".[dev]"
|
|
43
|
+
- run: lint-imports
|
|
44
|
+
|
|
45
|
+
tests:
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
strategy:
|
|
48
|
+
matrix:
|
|
49
|
+
python-version: ["3.12", "3.13"]
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
- uses: actions/setup-python@v5
|
|
53
|
+
with: { python-version: "${{ matrix.python-version }}" }
|
|
54
|
+
- run: pip install -e ".[dev]"
|
|
55
|
+
- run: pytest -m "not live and not performance" --cov --cov-report=xml
|
|
56
|
+
|
|
57
|
+
postgresql-tests:
|
|
58
|
+
# Database standards §5.2: the migration suite runs on both supported dialects in CI, not
|
|
59
|
+
# just SQLite. FREEWEIGHT_REQUIRE_POSTGRES turns tests/integration/conftest.py's ordinary
|
|
60
|
+
# "skip if unreachable" behaviour into a failure here, so a broken service container fails
|
|
61
|
+
# the job instead of silently testing one dialect and calling it both.
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
services:
|
|
64
|
+
postgres:
|
|
65
|
+
image: postgres:16
|
|
66
|
+
env:
|
|
67
|
+
POSTGRES_USER: freeweight
|
|
68
|
+
POSTGRES_PASSWORD: freeweight
|
|
69
|
+
POSTGRES_DB: freeweight_test
|
|
70
|
+
ports: ["5432:5432"]
|
|
71
|
+
options: >-
|
|
72
|
+
--health-cmd pg_isready
|
|
73
|
+
--health-interval 10s
|
|
74
|
+
--health-timeout 5s
|
|
75
|
+
--health-retries 5
|
|
76
|
+
env:
|
|
77
|
+
# Deliberately not the FREEWEIGHT_ prefix: tests/conftest.py strips those so no test reads
|
|
78
|
+
# the developer's environment, which would delete these before the fixture could read them.
|
|
79
|
+
FWTEST_REQUIRE_POSTGRES: "1"
|
|
80
|
+
FWTEST_POSTGRES_URL: postgresql+psycopg://freeweight:freeweight@localhost:5432/freeweight_test
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@v4
|
|
83
|
+
- uses: actions/setup-python@v5
|
|
84
|
+
with: { python-version: "3.12" }
|
|
85
|
+
# pg_dump is what `freeweight db backup` shells out to on this dialect; without the client
|
|
86
|
+
# tools that branch skips itself and the job reports green having never run it.
|
|
87
|
+
- run: sudo apt-get update && sudo apt-get install -y postgresql-client
|
|
88
|
+
- run: pip install -e ".[dev]"
|
|
89
|
+
- run: pytest -m "not live and not performance" tests/integration
|
|
90
|
+
|
|
91
|
+
tests-314-early-warning:
|
|
92
|
+
runs-on: ubuntu-latest
|
|
93
|
+
continue-on-error: true
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v4
|
|
96
|
+
- uses: actions/setup-python@v5
|
|
97
|
+
with: { python-version: "3.14" }
|
|
98
|
+
- run: pip install -e ".[dev]"
|
|
99
|
+
- run: pytest -m "not live and not performance"
|
|
100
|
+
|
|
101
|
+
coverage:
|
|
102
|
+
needs: [tests]
|
|
103
|
+
runs-on: ubuntu-latest
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@v4
|
|
106
|
+
- uses: actions/setup-python@v5
|
|
107
|
+
with: { python-version: "3.12" }
|
|
108
|
+
- run: pip install -e ".[dev]"
|
|
109
|
+
- run: pytest -m "not live and not performance" --cov --cov-report=term-missing --cov-fail-under=85
|
|
110
|
+
|
|
111
|
+
diff-coverage:
|
|
112
|
+
# Testing standards §10 lists `diff-cover` among the gates required before merge: the
|
|
113
|
+
# repository-wide floor says nothing about whether *this change* was tested, and a large
|
|
114
|
+
# well-covered codebase absorbs an untested addition without the floor moving.
|
|
115
|
+
needs: [tests]
|
|
116
|
+
runs-on: ubuntu-latest
|
|
117
|
+
if: github.event_name == 'pull_request'
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@v4
|
|
120
|
+
# diff-cover compares against the merge base, so the base branch has to be in the object
|
|
121
|
+
# store; a depth-1 clone does not have it.
|
|
122
|
+
with: { fetch-depth: 0 }
|
|
123
|
+
- uses: actions/setup-python@v5
|
|
124
|
+
with: { python-version: "3.12" }
|
|
125
|
+
- run: pip install -e ".[dev]"
|
|
126
|
+
- run: pytest -m "not live and not performance" --cov --cov-report=xml
|
|
127
|
+
- run: diff-cover coverage.xml --compare-branch=origin/${{ github.base_ref }} --fail-under=90
|
|
128
|
+
|
|
129
|
+
contracts:
|
|
130
|
+
runs-on: ubuntu-latest
|
|
131
|
+
steps:
|
|
132
|
+
- uses: actions/checkout@v4
|
|
133
|
+
- uses: actions/setup-python@v5
|
|
134
|
+
with: { python-version: "3.12" }
|
|
135
|
+
- run: pip install -e ".[dev]"
|
|
136
|
+
- run: pytest -m contract
|
|
137
|
+
|
|
138
|
+
docs:
|
|
139
|
+
# Packaging standards §5's `docs` job: the generated documents must match what the code
|
|
140
|
+
# generates. `docs/configuration.md` is produced from the settings model (configuration
|
|
141
|
+
# standards §8) and `docs/openapi.json` from the served application (API standards §11); a
|
|
142
|
+
# field or a route changed without regenerating either fails here rather than drifting.
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
steps:
|
|
145
|
+
- uses: actions/checkout@v4
|
|
146
|
+
- uses: actions/setup-python@v5
|
|
147
|
+
with: { python-version: "3.12" }
|
|
148
|
+
- run: pip install -e ".[dev]"
|
|
149
|
+
- run: python scripts/generate_config_reference.py --check
|
|
150
|
+
- run: python scripts/generate_openapi_snapshot.py --check
|
|
151
|
+
|
|
152
|
+
security:
|
|
153
|
+
# `pip-audit` audits the locked set, not the job's own environment: a bare `pip-audit` here
|
|
154
|
+
# inspects an environment containing only pip-audit itself and reports nothing (Security
|
|
155
|
+
# Standards §11). It audits `requirements/ci.lock` too once that file exists — it is blocked
|
|
156
|
+
# on `setspec 0.3.0` reaching PyPI, for the reason requirements/README.md gives.
|
|
157
|
+
runs-on: ubuntu-latest
|
|
158
|
+
steps:
|
|
159
|
+
- uses: actions/checkout@v4
|
|
160
|
+
# gitleaks scans *history*, and `actions/checkout` fetches a single commit by default.
|
|
161
|
+
# For a push it is handed `<first-pushed>^..<last-pushed>`, so the parent of the first
|
|
162
|
+
# pushed commit has to be in the object store; in a depth-1 clone it is not, and git
|
|
163
|
+
# answers "unknown revision", which the action reports as exit code 1. It fails the same
|
|
164
|
+
# way whether or not a secret exists, so a green run would not have meant anything either.
|
|
165
|
+
with: { fetch-depth: 0 }
|
|
166
|
+
- uses: actions/setup-python@v5
|
|
167
|
+
with: { python-version: "3.12" }
|
|
168
|
+
- run: pip install pip-audit
|
|
169
|
+
- run: pip-audit --require-hashes -r requirements/release.lock
|
|
170
|
+
- uses: gitleaks/gitleaks-action@v2
|
|
171
|
+
env:
|
|
172
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
173
|
+
|
|
174
|
+
build:
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
steps:
|
|
177
|
+
- uses: actions/checkout@v4
|
|
178
|
+
- uses: actions/setup-python@v5
|
|
179
|
+
with: { python-version: "3.12" }
|
|
180
|
+
# The same pinned build chain the release uses, so a wheel that builds here is the wheel
|
|
181
|
+
# that ships: `--no-isolation` takes the backend from this lock rather than re-resolving
|
|
182
|
+
# hatchling from the index at build time (requirements/README.md).
|
|
183
|
+
- run: pip install --require-hashes -r requirements/release.lock
|
|
184
|
+
- run: python -m build --no-isolation
|
|
185
|
+
- run: twine check dist/*
|
|
186
|
+
- uses: actions/upload-artifact@v4
|
|
187
|
+
with: { name: dist, path: dist/ }
|
|
188
|
+
|
|
189
|
+
install-check:
|
|
190
|
+
needs: [build]
|
|
191
|
+
runs-on: ubuntu-latest
|
|
192
|
+
steps:
|
|
193
|
+
- uses: actions/checkout@v4
|
|
194
|
+
- uses: actions/setup-python@v5
|
|
195
|
+
with: { python-version: "3.12" }
|
|
196
|
+
- uses: actions/download-artifact@v4
|
|
197
|
+
with: { name: dist, path: dist/ }
|
|
198
|
+
- run: pip install dist/*.whl
|
|
199
|
+
- run: python -c "import freeweight"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Testing Standards §10: the default suite runs on every push and must stay under three minutes,
|
|
2
|
+
# so the two suites that cannot be fast run here instead — `live` needs real weights and `performance`
|
|
3
|
+
# needs a machine whose timings mean something.
|
|
4
|
+
#
|
|
5
|
+
# On a GitHub-hosted runner the live suite **skips itself**: its provider fixture calls
|
|
6
|
+
# `OllamaProvider.health()` and skips when nothing answers on 127.0.0.1:11434. That is deliberate
|
|
7
|
+
# and is not a silent pass — the job prints the skip reasons with `-rs`, so "no Ollama here" is
|
|
8
|
+
# visible rather than indistinguishable from "everything passed". Point a self-hosted runner with a
|
|
9
|
+
# GPU at this workflow and the same job measures a real model.
|
|
10
|
+
#
|
|
11
|
+
# `performance` runs everywhere: its budgets are generous precisely so that shared CI hardware
|
|
12
|
+
# produces information rather than flakes, and the query-plan assertions beside them are
|
|
13
|
+
# hardware-independent.
|
|
14
|
+
name: Nightly
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
schedule:
|
|
18
|
+
# 03:00 UTC — after any working day's pushes, before any working morning.
|
|
19
|
+
- cron: "0 3 * * *"
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
performance:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-python@v5
|
|
28
|
+
with: { python-version: "3.12" }
|
|
29
|
+
- run: pip install -e ".[dev]"
|
|
30
|
+
- run: pytest -m performance -rs
|
|
31
|
+
|
|
32
|
+
live:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with: { python-version: "3.12" }
|
|
38
|
+
- run: pip install -e ".[dev]"
|
|
39
|
+
# `-rs` reports every skip with its reason: a live suite that skipped because nothing was
|
|
40
|
+
# serving must not look like a live suite that passed.
|
|
41
|
+
- run: pytest -m live -rs
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*.*.*"]
|
|
6
|
+
workflow_dispatch: # manual TestPyPI dry run; see publish-testpypi below
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write # required for PyPI Trusted Publishing
|
|
10
|
+
contents: write # required to create the GitHub release
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
release:
|
|
14
|
+
if: github.event_name == 'push'
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: pypi # must match the Environment name set on the PyPI trusted publisher
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with: { python-version: "3.12" }
|
|
21
|
+
# The pinned build chain, so the wheel that ships is built by the same backend CI checked:
|
|
22
|
+
# `--no-isolation` takes hatchling from this lock rather than re-resolving it at build time.
|
|
23
|
+
- run: pip install --require-hashes -r requirements/release.lock
|
|
24
|
+
- run: python -m build --no-isolation
|
|
25
|
+
- run: twine check dist/*
|
|
26
|
+
- run: pip install "dist/$(ls dist | grep .whl)[dev]"
|
|
27
|
+
- run: pytest -m "not live and not performance"
|
|
28
|
+
- name: Publish to PyPI
|
|
29
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
30
|
+
- name: Create GitHub release
|
|
31
|
+
uses: softprops/action-gh-release@v2
|
|
32
|
+
with:
|
|
33
|
+
generate_release_notes: true
|
|
34
|
+
files: dist/*
|
|
35
|
+
|
|
36
|
+
publish-testpypi:
|
|
37
|
+
# Manual only, via Actions -> Release -> Run workflow. Packaging and Release Standards §6
|
|
38
|
+
# requires a successful TestPyPI publish ahead of a package's **first** real release, and
|
|
39
|
+
# `freeweight` is an unclaimed distribution name — v1.0.0rc1 is that first release, so run
|
|
40
|
+
# this once before tagging it. Later releases may skip it, or use it again as a dry run.
|
|
41
|
+
if: github.event_name == 'workflow_dispatch'
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
# No `environment:` here, matching the package repositories. The OIDC claim must match the
|
|
44
|
+
# trusted publisher exactly: declaring an environment the TestPyPI publisher was not
|
|
45
|
+
# configured with fails the exchange. Add one only alongside configuring it there.
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
- uses: actions/setup-python@v5
|
|
49
|
+
with: { python-version: "3.12" }
|
|
50
|
+
- run: pip install --require-hashes -r requirements/release.lock
|
|
51
|
+
- run: python -m build --no-isolation
|
|
52
|
+
- run: twine check dist/*
|
|
53
|
+
- run: pip install "dist/$(ls dist | grep .whl)[dev]"
|
|
54
|
+
- run: pytest -m "not live and not performance"
|
|
55
|
+
- name: Publish to TestPyPI
|
|
56
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
|
+
with:
|
|
58
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# ---- Python ----
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
MANIFEST
|
|
23
|
+
|
|
24
|
+
# ---- Packaging / build backends ----
|
|
25
|
+
pip-wheel-metadata/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
|
|
28
|
+
# ---- Testing / coverage ----
|
|
29
|
+
.pytest_cache/
|
|
30
|
+
.cache
|
|
31
|
+
.coverage
|
|
32
|
+
.coverage.*
|
|
33
|
+
coverage.xml
|
|
34
|
+
*.cover
|
|
35
|
+
*.py,cover
|
|
36
|
+
htmlcov/
|
|
37
|
+
nosetests.xml
|
|
38
|
+
.hypothesis/
|
|
39
|
+
|
|
40
|
+
# ---- Type checking / linting ----
|
|
41
|
+
.mypy_cache/
|
|
42
|
+
.dmypy.json
|
|
43
|
+
dmypy.json
|
|
44
|
+
.ruff_cache/
|
|
45
|
+
.pytype/
|
|
46
|
+
|
|
47
|
+
# ---- Virtual environments ----
|
|
48
|
+
.venv/
|
|
49
|
+
venv/
|
|
50
|
+
ENV/
|
|
51
|
+
env/
|
|
52
|
+
env.bak/
|
|
53
|
+
venv.bak/
|
|
54
|
+
.python-version
|
|
55
|
+
|
|
56
|
+
# ---- Distribution / dependency locking ----
|
|
57
|
+
# requirements/*.lock is deliberately NOT ignored. The lock files are committed
|
|
58
|
+
# inputs: CI and release jobs install from them with --require-hashes (Packaging
|
|
59
|
+
# and Release Standards §4, Security Standards §11), so an ignored lock file
|
|
60
|
+
# means a checkout that cannot build.
|
|
61
|
+
|
|
62
|
+
# ---- Editors / OS ----
|
|
63
|
+
.vscode/
|
|
64
|
+
.idea/
|
|
65
|
+
*.swp
|
|
66
|
+
*.swo
|
|
67
|
+
.DS_Store
|
|
68
|
+
Thumbs.db
|
|
69
|
+
|
|
70
|
+
# ---- Suite runtime state (this component's local data) ----
|
|
71
|
+
# The application writes to XDG paths at runtime (~/.config, ~/.local/share,
|
|
72
|
+
# ~/.local/state per Master Architecture §1.2), never inside the repository.
|
|
73
|
+
# These entries only guard against a developer pointing XDG_* at the repo
|
|
74
|
+
# during local testing.
|
|
75
|
+
.local/
|
|
76
|
+
.config/
|
|
77
|
+
*.sqlite3
|
|
78
|
+
*.sqlite3-journal
|
|
79
|
+
*.sqlite3-wal
|
|
80
|
+
*.sqlite3-shm
|
|
81
|
+
/data/
|
|
82
|
+
/logs/
|
|
83
|
+
/backups/
|
|
84
|
+
/artifacts/
|
|
85
|
+
/exports/
|
|
86
|
+
|
|
87
|
+
# ---- Secrets ----
|
|
88
|
+
# Per Security Standards §8: secrets are never committed. Config files may
|
|
89
|
+
# only name where a secret comes from (*_env / *_file), never the value.
|
|
90
|
+
.env
|
|
91
|
+
.env.*
|
|
92
|
+
*.key
|
|
93
|
+
*.pem
|
|
94
|
+
secrets.toml
|
|
95
|
+
|
|
96
|
+
# ---- Node-free JS assets (MirrorWall consumers may still use a local tool) ----
|
|
97
|
+
node_modules/
|
|
98
|
+
|
|
99
|
+
# ---- Build artifacts from docs generation ----
|
|
100
|
+
docs/api/openapi-v1.json.tmp
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# gitleaks configuration — see the `security` job in .github/workflows/ci.yml.
|
|
2
|
+
#
|
|
3
|
+
# The default rule set is kept in full. This file adds one allowlist and disables nothing: a rule
|
|
4
|
+
# is never turned off, and a finding is never allowlisted by fingerprint, because a fingerprint
|
|
5
|
+
# carries the commit SHA and stops matching the moment the file moves — which turns "a person
|
|
6
|
+
# looked at this and it is not a secret" into a silently unscanned line later.
|
|
7
|
+
|
|
8
|
+
title = "FreeWeight"
|
|
9
|
+
|
|
10
|
+
[extend]
|
|
11
|
+
useDefault = true
|
|
12
|
+
|
|
13
|
+
[allowlist]
|
|
14
|
+
description = "A metric key is vocabulary, not a credential."
|
|
15
|
+
# `generic-api-key` fires on any `…key = <high-entropy value>` assignment, and this suite names
|
|
16
|
+
# every measurement with a `metric_key` — 129 of them across 51 files, and one per new benchmark.
|
|
17
|
+
# `inter_chunk_ms_p50` and `inter_chunk_ms_p95` clear the rule's entropy floor, so they are
|
|
18
|
+
# reported as secrets; the rest are one lucky character away from joining them, which is why this
|
|
19
|
+
# matches the *shape* of a metric key rather than listing the two names that happen to trip it
|
|
20
|
+
# today.
|
|
21
|
+
#
|
|
22
|
+
# The scan is diff-scoped, so this fails only on a push whose commit touches one of those lines —
|
|
23
|
+
# it has fired three times (a2a0ac5, 92f5602, e6d3c88, the last on the `key` → `metric_key`
|
|
24
|
+
# rename) and passed on every commit that leaves them alone. A green run on an unrelated commit is
|
|
25
|
+
# not evidence that it is fixed.
|
|
26
|
+
#
|
|
27
|
+
# What this permits is narrow: a `…key` field bound to a lowercase snake_case identifier, quoted
|
|
28
|
+
# and ending the match. A real credential is excluded by any of the things it almost always has
|
|
29
|
+
# and an identifier never does — an uppercase letter, a hyphen, a dot, a `+` or `/`, or no
|
|
30
|
+
# underscore at all. Keywords other than `key` are untouched, so `password = "correct_horse_..."`
|
|
31
|
+
# is still a finding.
|
|
32
|
+
#
|
|
33
|
+
# `regexTarget` must be `match`: in a history scan — the mode CI runs in — a finding's `line` is
|
|
34
|
+
# empty, so an allowlist written against the source line matches nothing and silently does not
|
|
35
|
+
# apply. The match text differs between the two modes as well (`metric_key="…"` scanning a working
|
|
36
|
+
# tree, `key="…"` scanning a diff), so the pattern deliberately starts at `key`.
|
|
37
|
+
regexTarget = "match"
|
|
38
|
+
regexes = ['''key["']?\s*[:=]\s*["'][a-z][a-z0-9]*(?:_[a-z0-9]+)+["']$''']
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[importlinter]
|
|
2
|
+
root_package = freeweight
|
|
3
|
+
include_external_packages = True
|
|
4
|
+
|
|
5
|
+
[importlinter:contract:layers]
|
|
6
|
+
name = FreeWeight internal layering
|
|
7
|
+
type = layers
|
|
8
|
+
layers =
|
|
9
|
+
web
|
|
10
|
+
cli
|
|
11
|
+
services
|
|
12
|
+
domain
|
|
13
|
+
containers = freeweight
|
|
14
|
+
|
|
15
|
+
[importlinter:contract:web-cli-independence]
|
|
16
|
+
name = Web and CLI never import each other
|
|
17
|
+
type = independence
|
|
18
|
+
modules =
|
|
19
|
+
freeweight.web
|
|
20
|
+
freeweight.cli
|
|
21
|
+
|
|
22
|
+
[importlinter:contract:domain-purity]
|
|
23
|
+
name = Domain imports no frameworks
|
|
24
|
+
type = forbidden
|
|
25
|
+
source_modules = freeweight.domain
|
|
26
|
+
forbidden_modules =
|
|
27
|
+
fastapi
|
|
28
|
+
starlette
|
|
29
|
+
sqlalchemy
|
|
30
|
+
typer
|
|
31
|
+
httpx
|
|
32
|
+
jinja2
|
|
33
|
+
|
|
34
|
+
[importlinter:contract:no-other-applications]
|
|
35
|
+
name = FreeWeight must not import other applications
|
|
36
|
+
type = forbidden
|
|
37
|
+
source_modules = freeweight
|
|
38
|
+
forbidden_modules =
|
|
39
|
+
loadcoach
|
|
40
|
+
ideapress
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
9
|
+
rev: v4.6.0
|
|
10
|
+
hooks:
|
|
11
|
+
- id: trailing-whitespace
|
|
12
|
+
- id: end-of-file-fixer
|
|
13
|
+
- id: check-toml
|
|
14
|
+
- id: check-json
|
|
15
|
+
- id: check-added-large-files
|
|
16
|
+
- id: check-merge-conflict
|
|
17
|
+
- id: mixed-line-ending
|
|
18
|
+
args: [--fix=lf]
|
|
19
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
20
|
+
rev: v8.18.4
|
|
21
|
+
hooks:
|
|
22
|
+
- id: gitleaks
|